28 #include <glib/gstdio.h>
29 #ifdef HAVE_LIBSERIALPORT
30 #include <libserialport.h>
33 #include "libsigrok-internal.h"
39 #define LOG_PREFIX "serial"
56 #ifdef HAVE_SERIAL_COMM
59 static int dev_is_supported(
struct sr_serial_dev_inst *serial)
61 if (!serial || !serial->lib_funcs)
82 SR_PRIV int serial_open(
struct sr_serial_dev_inst *serial,
int flags)
87 sr_dbg(
"Invalid serial port.");
91 sr_spew(
"Opening serial port '%s' (flags %d).", serial->port, flags);
98 if (ser_name_is_hid(serial))
99 serial->lib_funcs = ser_lib_funcs_hid;
100 else if (ser_name_is_bt(serial))
101 serial->lib_funcs = ser_lib_funcs_bt;
104 if (!serial->lib_funcs)
119 if (!serial->lib_funcs->open)
121 ret = serial->lib_funcs->open(serial, flags);
125 if (serial->serialcomm)
126 return serial_set_paramstr(serial, serial->serialcomm);
141 SR_PRIV int serial_close(
struct sr_serial_dev_inst *serial)
146 sr_dbg(
"Invalid serial port.");
150 sr_spew(
"Closing serial port %s.", serial->port);
152 if (!serial->lib_funcs || !serial->lib_funcs->close)
155 rc = serial->lib_funcs->close(serial);
156 if (rc ==
SR_OK && serial->rcv_buffer) {
157 g_string_free(serial->rcv_buffer, TRUE);
158 serial->rcv_buffer = NULL;
174 SR_PRIV int serial_flush(
struct sr_serial_dev_inst *serial)
177 sr_dbg(
"Invalid serial port.");
181 sr_spew(
"Flushing serial port %s.", serial->port);
183 sr_ser_discard_queued_data(serial);
185 if (!serial->lib_funcs || !serial->lib_funcs->flush)
188 return serial->lib_funcs->flush(serial);
201 SR_PRIV int serial_drain(
struct sr_serial_dev_inst *serial)
204 sr_dbg(
"Invalid serial port.");
208 sr_spew(
"Draining serial port %s.", serial->port);
210 if (!serial->lib_funcs || !serial->lib_funcs->drain)
213 return serial->lib_funcs->drain(serial);
249 SR_PRIV int serial_set_read_chunk_cb(
struct sr_serial_dev_inst *serial,
250 serial_rx_chunk_callback cb,
void *cb_data)
255 serial->rx_chunk_cb_func = cb;
256 serial->rx_chunk_cb_data = cb_data;
269 SR_PRIV void sr_ser_discard_queued_data(
struct sr_serial_dev_inst *serial)
271 if (!serial || !serial->rcv_buffer)
274 g_string_truncate(serial->rcv_buffer, 0);
285 SR_PRIV size_t sr_ser_has_queued_data(
struct sr_serial_dev_inst *serial)
287 if (!serial || !serial->rcv_buffer)
290 return serial->rcv_buffer->len;
303 SR_PRIV void sr_ser_queue_rx_data(
struct sr_serial_dev_inst *serial,
304 const uint8_t *data,
size_t len)
306 if (!serial || !data || !len)
309 if (serial->rx_chunk_cb_func)
310 serial->rx_chunk_cb_func(serial, serial->rx_chunk_cb_data, data, len);
311 else if (serial->rcv_buffer)
312 g_string_append_len(serial->rcv_buffer, (
const gchar *)data, len);
325 SR_PRIV size_t sr_ser_unqueue_rx_data(
struct sr_serial_dev_inst *serial,
326 uint8_t *data,
size_t len)
331 if (!serial || !data || !len)
334 qlen = sr_ser_has_queued_data(serial);
338 buf = serial->rcv_buffer;
342 memcpy(data, buf->str, len);
343 g_string_erase(buf, 0, len);
359 SR_PRIV size_t serial_has_receive_data(
struct sr_serial_dev_inst *serial)
361 size_t lib_count, buf_count;
367 if (serial->lib_funcs && serial->lib_funcs->get_rx_avail)
368 lib_count = serial->lib_funcs->get_rx_avail(serial);
370 buf_count = sr_ser_has_queued_data(serial);
372 return lib_count + buf_count;
375 static int _serial_write(
struct sr_serial_dev_inst *serial,
376 const void *buf,
size_t count,
377 int nonblocking,
unsigned int timeout_ms)
382 sr_dbg(
"Invalid serial port.");
386 if (!serial->lib_funcs || !serial->lib_funcs->write)
388 ret = serial->lib_funcs->write(serial, buf, count,
389 nonblocking, timeout_ms);
390 sr_spew(
"Wrote %zd/%zu bytes.", ret, count);
410 SR_PRIV int serial_write_blocking(
struct sr_serial_dev_inst *serial,
411 const void *buf,
size_t count,
unsigned int timeout_ms)
413 return _serial_write(serial, buf, count, 0, timeout_ms);
429 SR_PRIV int serial_write_nonblocking(
struct sr_serial_dev_inst *serial,
430 const void *buf,
size_t count)
432 return _serial_write(serial, buf, count, 1, 0);
435 static int _serial_read(
struct sr_serial_dev_inst *serial,
436 void *buf,
size_t count,
int nonblocking,
unsigned int timeout_ms)
441 sr_dbg(
"Invalid serial port.");
445 if (!serial->lib_funcs || !serial->lib_funcs->read)
447 ret = serial->lib_funcs->read(serial, buf, count,
448 nonblocking, timeout_ms);
450 sr_spew(
"Read %zd/%zu bytes.", ret, count);
470 SR_PRIV int serial_read_blocking(
struct sr_serial_dev_inst *serial,
471 void *buf,
size_t count,
unsigned int timeout_ms)
473 return _serial_read(serial, buf, count, 0, timeout_ms);
490 SR_PRIV int serial_read_nonblocking(
struct sr_serial_dev_inst *serial,
491 void *buf,
size_t count)
493 return _serial_read(serial, buf, count, 1, 0);
514 SR_PRIV int serial_set_params(
struct sr_serial_dev_inst *serial,
515 int baudrate,
int bits,
int parity,
int stopbits,
516 int flowcontrol,
int rts,
int dtr)
521 sr_dbg(
"Invalid serial port.");
525 sr_spew(
"Setting serial parameters on port %s.", serial->port);
527 if (!serial->lib_funcs || !serial->lib_funcs->set_params)
529 ret = serial->lib_funcs->set_params(serial,
530 baudrate, bits, parity, stopbits,
531 flowcontrol, rts, dtr);
533 serial->comm_params.bit_rate = baudrate;
534 serial->comm_params.data_bits = bits;
535 serial->comm_params.parity_bits = parity ? 1 : 0;
536 serial->comm_params.stop_bits = stopbits;
537 sr_dbg(
"DBG: %s() rate %d, %d%s%d", __func__,
539 (parity == 0) ?
"n" :
"x",
569 SR_PRIV int serial_set_paramstr(
struct sr_serial_dev_inst *serial,
570 const char *paramstr)
573 #define SERIAL_COMM_SPEC "^(\\d+)/([5678])([neo])([12])(.*)$"
578 int speed, databits, parity, stopbits, flow, rts, dtr, i;
579 char *mstr, **opts, **kv;
581 speed = databits = parity = stopbits = flow = 0;
583 sr_spew(
"Parsing parameters from \"%s\".", paramstr);
584 reg = g_regex_new(SERIAL_COMM_SPEC, 0, 0, NULL);
585 if (g_regex_match(reg, paramstr, 0, &match)) {
586 if ((mstr = g_match_info_fetch(match, 1)))
587 speed = strtoul(mstr, NULL, 10);
589 if ((mstr = g_match_info_fetch(match, 2)))
590 databits = strtoul(mstr, NULL, 10);
592 if ((mstr = g_match_info_fetch(match, 3))) {
595 parity = SP_PARITY_NONE;
598 parity = SP_PARITY_EVEN;
601 parity = SP_PARITY_ODD;
606 if ((mstr = g_match_info_fetch(match, 4)))
607 stopbits = strtoul(mstr, NULL, 10);
609 if ((mstr = g_match_info_fetch(match, 5)) && mstr[0] !=
'\0') {
610 if (mstr[0] !=
'/') {
611 sr_dbg(
"missing separator before extra options");
615 opts = g_strsplit(mstr + 1,
"/", 0);
616 for (i = 0; opts[i]; i++) {
617 kv = g_strsplit(opts[i],
"=", 2);
618 if (!strncmp(kv[0],
"rts", 3)) {
621 else if (kv[1][0] ==
'0')
624 sr_dbg(
"invalid value for rts: %c", kv[1][0]);
627 }
else if (!strncmp(kv[0],
"dtr", 3)) {
630 else if (kv[1][0] ==
'0')
633 sr_dbg(
"invalid value for dtr: %c", kv[1][0]);
636 }
else if (!strncmp(kv[0],
"flow", 4)) {
639 else if (kv[1][0] ==
'1')
641 else if (kv[1][0] ==
'2')
644 sr_dbg(
"invalid value for flow: %c", kv[1][0]);
655 g_match_info_unref(match);
659 return serial_set_params(serial, speed, databits, parity,
660 stopbits, flow, rts, dtr);
662 sr_dbg(
"Could not infer speed from parameter string.");
682 SR_PRIV int serial_readline(
struct sr_serial_dev_inst *serial,
683 char **buf,
int *buflen, gint64 timeout_ms)
685 gint64 start, remaining;
689 sr_dbg(
"Invalid serial port.");
693 if (!dev_is_supported(serial)) {
694 sr_dbg(
"Cannot use unopened serial port %s.", serial->port);
698 start = g_get_monotonic_time();
699 remaining = timeout_ms;
704 len = maxlen - *buflen - 1;
707 len = serial_read_blocking(serial, *buf + *buflen, 1, remaining);
710 *(*buf + *buflen) =
'\0';
711 if (*buflen > 0 && (*(*buf + *buflen - 1) ==
'\r'
712 || *(*buf + *buflen - 1) ==
'\n')) {
714 *(*buf + --*buflen) =
'\0';
719 remaining = timeout_ms - ((g_get_monotonic_time() - start) / 1000);
727 sr_dbg(
"Received %d: '%s'.", *buflen, *buf);
748 SR_PRIV int serial_stream_detect(
struct sr_serial_dev_inst *serial,
749 uint8_t *buf,
size_t *buflen,
751 packet_valid_callback is_valid,
754 uint64_t start, time, byte_delay_us;
755 size_t ibuf, i, maxlen;
760 sr_dbg(
"Detecting packets on %s (timeout = %" PRIu64
"ms).",
761 serial->port, timeout_ms);
763 if (maxlen < (packet_size * 2) ) {
764 sr_err(
"Buffer size must be at least twice the packet size.");
769 byte_delay_us = serial_timeout(serial, 1) * 1000;
770 start = g_get_monotonic_time();
773 while (ibuf < maxlen) {
774 len = serial_read_nonblocking(serial, &buf[ibuf], 1);
777 }
else if (len == 0) {
783 time = g_get_monotonic_time() - start;
786 if ((ibuf - i) >= packet_size) {
790 sr_spew(
"Trying packet: %s", text->str);
792 if (is_valid(&buf[i])) {
793 sr_spew(
"Found valid %zu-byte packet after "
794 "%" PRIu64
"ms.", (ibuf - i), time);
798 sr_spew(
"Got %zu bytes, but not a valid "
799 "packet.", (ibuf - i));
804 if (time >= timeout_ms) {
806 sr_dbg(
"Detection timed out after %" PRIu64
"ms.", time);
810 g_usleep(byte_delay_us);
815 sr_err(
"Didn't find a valid packet (read %zu bytes).", *buflen);
833 SR_PRIV int sr_serial_extract_options(GSList *options,
834 const char **serial_device,
const char **serial_options)
839 *serial_device = NULL;
841 for (l = options; l; l = l->next) {
845 *serial_device = g_variant_get_string(src->
data, NULL);
846 sr_dbg(
"Parsed serial device: %s.", *serial_device);
849 *serial_options = g_variant_get_string(src->
data, NULL);
850 sr_dbg(
"Parsed serial options: %s.", *serial_options);
855 if (!*serial_device) {
856 sr_dbg(
"No serial device specified.");
865 struct sr_serial_dev_inst *serial,
int events,
int timeout,
868 if ((events & (G_IO_IN | G_IO_ERR)) && (events & G_IO_OUT)) {
869 sr_err(
"Cannot poll input/error and output simultaneously.");
873 if (!dev_is_supported(serial)) {
874 sr_err(
"Invalid serial port.");
878 if (!serial->lib_funcs || !serial->lib_funcs->setup_source_add)
881 return serial->lib_funcs->setup_source_add(session, serial,
882 events, timeout, cb, cb_data);
887 struct sr_serial_dev_inst *serial)
889 if (!dev_is_supported(serial)) {
890 sr_err(
"Invalid serial port.");
894 if (!serial->lib_funcs || !serial->lib_funcs->setup_source_remove)
897 return serial->lib_funcs->setup_source_remove(session, serial);
918 serial = g_malloc0(
sizeof(*serial));
919 serial->
name = g_strdup(name);
920 serial->
description = g_strdup(description ? description :
"");
934 g_free(serial->
name);
939 static GSList *append_port_list(GSList *devs,
const char *name,
const char *desc)
941 return g_slist_append(devs, sr_serial_new(name, desc));
954 GSList *(*list_func)(GSList *list, sr_ser_list_append_t append);
962 tty_devs = list_func(tty_devs, append_port_list);
964 if (ser_lib_funcs_hid && ser_lib_funcs_hid->list) {
965 list_func = ser_lib_funcs_hid->list;
966 tty_devs = list_func(tty_devs, append_port_list);
968 if (ser_lib_funcs_bt && ser_lib_funcs_bt->list) {
969 list_func = ser_lib_funcs_bt->list;
970 tty_devs = list_func(tty_devs, append_port_list);
976 static GSList *append_port_find(GSList *devs,
const char *name)
981 return g_slist_append(devs, g_strdup(name));
996 SR_PRIV GSList *sr_serial_find_usb(uint16_t vendor_id, uint16_t product_id)
999 GSList *(*find_func)(GSList *list, sr_ser_find_append_t append,
1000 uint16_t vid, uint16_t pid);
1005 tty_devs = find_func(tty_devs, append_port_find,
1006 vendor_id, product_id);
1008 if (ser_lib_funcs_hid && ser_lib_funcs_hid->find_usb) {
1009 find_func = ser_lib_funcs_hid->find_usb;
1010 tty_devs = find_func(tty_devs, append_port_find,
1011 vendor_id, product_id);
1018 SR_PRIV int serial_timeout(
struct sr_serial_dev_inst *port,
int num_bytes)
1020 int bits, baud, ret, timeout_ms;
1024 if (port->lib_funcs && port->lib_funcs->get_frame_format) {
1025 ret = port->lib_funcs->get_frame_format(port, &baud, &bits);
1029 baud = port->comm_params.bit_rate;
1030 bits = 1 + port->comm_params.data_bits +
1031 port->comm_params.parity_bits +
1032 port->comm_params.stop_bits;
1040 timeout_ms += ((1000.0 / baud) * bits) * num_bytes;
Generic/unspecified error.
The public libsigrok header file to be used by frontends.
char * name
The OS dependent name of the serial port.
SR_PRIV GString * sr_hexdump_new(const uint8_t *data, const size_t len)
Convert a sequence of bytes to its textual representation ("hex dump").
GSList * sr_serial_list(const struct sr_dev_driver *driver)
SR_PRIV void sr_hexdump_free(GString *s)
Free a hex dump text that was created by sr_hexdump_new().
Used for setting or getting value of a config item.
Specification on how to connect to a device.
GVariant * data
Key-specific data.
void sr_serial_free(struct sr_serial_port *serial)
int(* sr_receive_data_callback)(int fd, int revents, void *cb_data)
Type definition for callback function for data reception.
char * description
An end user friendly description for the serial port.
Serial communication specification, in the form:
uint32_t key
Config key like SR_CONF_CONN, etc.
SR_PRIV struct ser_lib_functions * ser_lib_funcs_libsp
Opaque structure representing a libsigrok session.