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;
102 else if (ser_name_is_tcpraw(serial))
103 serial->lib_funcs = ser_lib_funcs_tcpraw;
105 serial->lib_funcs = ser_lib_funcs_libsp;
106 if (!serial->lib_funcs)
121 if (!serial->lib_funcs->open)
123 ret = serial->lib_funcs->open(serial, flags);
127 if (serial->serialcomm) {
128 ret = serial_set_paramstr(serial, serial->serialcomm);
138 ret = serial_flush(serial);
157 SR_PRIV int serial_close(
struct sr_serial_dev_inst *serial)
162 sr_dbg(
"Invalid serial port.");
166 sr_spew(
"Closing serial port %s.", serial->port);
168 if (!serial->lib_funcs || !serial->lib_funcs->close)
171 rc = serial->lib_funcs->close(serial);
172 if (rc ==
SR_OK && serial->rcv_buffer) {
173 g_string_free(serial->rcv_buffer, TRUE);
174 serial->rcv_buffer = NULL;
190 SR_PRIV int serial_flush(
struct sr_serial_dev_inst *serial)
193 sr_dbg(
"Invalid serial port.");
197 sr_spew(
"Flushing serial port %s.", serial->port);
199 sr_ser_discard_queued_data(serial);
201 if (!serial->lib_funcs || !serial->lib_funcs->flush)
204 return serial->lib_funcs->flush(serial);
217 SR_PRIV int serial_drain(
struct sr_serial_dev_inst *serial)
220 sr_dbg(
"Invalid serial port.");
224 sr_spew(
"Draining serial port %s.", serial->port);
226 if (!serial->lib_funcs || !serial->lib_funcs->drain)
229 return serial->lib_funcs->drain(serial);
267 SR_PRIV int serial_set_read_chunk_cb(
struct sr_serial_dev_inst *serial,
268 serial_rx_chunk_callback cb,
void *cb_data)
273 serial->rx_chunk_cb_func = cb;
274 serial->rx_chunk_cb_data = cb_data;
287 SR_PRIV void sr_ser_discard_queued_data(
struct sr_serial_dev_inst *serial)
289 if (!serial || !serial->rcv_buffer)
292 g_string_truncate(serial->rcv_buffer, 0);
303 SR_PRIV size_t sr_ser_has_queued_data(
struct sr_serial_dev_inst *serial)
305 if (!serial || !serial->rcv_buffer)
308 return serial->rcv_buffer->len;
321 SR_PRIV void sr_ser_queue_rx_data(
struct sr_serial_dev_inst *serial,
322 const uint8_t *data,
size_t len)
324 if (!serial || !data || !len)
327 if (serial->rx_chunk_cb_func)
328 serial->rx_chunk_cb_func(serial, serial->rx_chunk_cb_data, data, len);
329 else if (serial->rcv_buffer)
330 g_string_append_len(serial->rcv_buffer, (
const gchar *)data, len);
343 SR_PRIV size_t sr_ser_unqueue_rx_data(
struct sr_serial_dev_inst *serial,
344 uint8_t *data,
size_t len)
349 if (!serial || !data || !len)
352 qlen = sr_ser_has_queued_data(serial);
356 buf = serial->rcv_buffer;
360 memcpy(data, buf->str, len);
361 g_string_erase(buf, 0, len);
379 SR_PRIV size_t serial_has_receive_data(
struct sr_serial_dev_inst *serial)
381 size_t lib_count, buf_count;
387 if (serial->lib_funcs && serial->lib_funcs->get_rx_avail)
388 lib_count = serial->lib_funcs->get_rx_avail(serial);
390 buf_count = sr_ser_has_queued_data(serial);
392 return lib_count + buf_count;
395 static int _serial_write(
struct sr_serial_dev_inst *serial,
396 const void *buf,
size_t count,
397 int nonblocking,
unsigned int timeout_ms)
402 sr_dbg(
"Invalid serial port.");
406 if (!serial->lib_funcs || !serial->lib_funcs->write)
408 ret = serial->lib_funcs->write(serial, buf, count,
409 nonblocking, timeout_ms);
410 sr_spew(
"Wrote %zd/%zu bytes.", ret, count);
430 SR_PRIV int serial_write_blocking(
struct sr_serial_dev_inst *serial,
431 const void *buf,
size_t count,
unsigned int timeout_ms)
433 return _serial_write(serial, buf, count, 0, timeout_ms);
449 SR_PRIV int serial_write_nonblocking(
struct sr_serial_dev_inst *serial,
450 const void *buf,
size_t count)
452 return _serial_write(serial, buf, count, 1, 0);
455 static int _serial_read(
struct sr_serial_dev_inst *serial,
456 void *buf,
size_t count,
int nonblocking,
unsigned int timeout_ms)
461 sr_dbg(
"Invalid serial port.");
465 if (!serial->lib_funcs || !serial->lib_funcs->read)
467 ret = serial->lib_funcs->read(serial, buf, count,
468 nonblocking, timeout_ms);
470 sr_spew(
"Read %zd/%zu bytes.", ret, count);
490 SR_PRIV int serial_read_blocking(
struct sr_serial_dev_inst *serial,
491 void *buf,
size_t count,
unsigned int timeout_ms)
493 return _serial_read(serial, buf, count, 0, timeout_ms);
510 SR_PRIV int serial_read_nonblocking(
struct sr_serial_dev_inst *serial,
511 void *buf,
size_t count)
513 return _serial_read(serial, buf, count, 1, 0);
534 SR_PRIV int serial_set_params(
struct sr_serial_dev_inst *serial,
535 int baudrate,
int bits,
int parity,
int stopbits,
536 int flowcontrol,
int rts,
int dtr)
541 sr_dbg(
"Invalid serial port.");
545 sr_spew(
"Setting serial parameters on port %s.", serial->port);
547 if (!serial->lib_funcs || !serial->lib_funcs->set_params)
549 ret = serial->lib_funcs->set_params(serial,
550 baudrate, bits, parity, stopbits,
551 flowcontrol, rts, dtr);
553 serial->comm_params.bit_rate = baudrate;
554 serial->comm_params.data_bits = bits;
555 serial->comm_params.parity_bits = parity ? 1 : 0;
556 serial->comm_params.stop_bits = stopbits;
557 sr_dbg(
"DBG: %s() rate %d, %d%s%d", __func__,
559 (parity == 0) ?
"n" :
"x",
578 SR_PRIV int serial_set_handshake(
struct sr_serial_dev_inst *serial,
584 sr_dbg(
"Invalid serial port.");
588 sr_spew(
"Modifying serial parameters on port %s.", serial->port);
590 if (!serial->lib_funcs || !serial->lib_funcs->set_handshake)
592 ret = serial->lib_funcs->set_handshake(serial, rts, dtr);
620 SR_PRIV int serial_set_paramstr(
struct sr_serial_dev_inst *serial,
621 const char *paramstr)
624 #define SERIAL_COMM_SPEC "^(\\d+)(/([5678])([neo])([12]))?(.*)$" 629 int speed, databits, parity, stopbits, flow, rts, dtr, i;
630 char *mstr, **opts, **kv;
634 parity = SP_PARITY_NONE;
637 sr_spew(
"Parsing parameters from \"%s\".", paramstr);
638 reg = g_regex_new(SERIAL_COMM_SPEC, 0, 0, NULL);
639 if (g_regex_match(reg, paramstr, 0, &match)) {
640 if ((mstr = g_match_info_fetch(match, 1)))
641 speed = strtoul(mstr, NULL, 10);
643 if ((mstr = g_match_info_fetch(match, 3)) && mstr[0])
644 databits = strtoul(mstr, NULL, 10);
646 if ((mstr = g_match_info_fetch(match, 4)) && mstr[0]) {
649 parity = SP_PARITY_NONE;
652 parity = SP_PARITY_EVEN;
655 parity = SP_PARITY_ODD;
660 if ((mstr = g_match_info_fetch(match, 5)) && mstr[0])
661 stopbits = strtoul(mstr, NULL, 10);
663 if ((mstr = g_match_info_fetch(match, 6)) && mstr[0] !=
'\0') {
664 if (mstr[0] !=
'/') {
665 sr_dbg(
"missing separator before extra options");
669 opts = g_strsplit(mstr + 1,
"/", 0);
670 for (i = 0; opts[i]; i++) {
671 kv = g_strsplit(opts[i],
"=", 2);
672 if (!strncmp(kv[0],
"rts", 3)) {
675 else if (kv[1][0] ==
'0')
678 sr_dbg(
"invalid value for rts: %c", kv[1][0]);
681 }
else if (!strncmp(kv[0],
"dtr", 3)) {
684 else if (kv[1][0] ==
'0')
687 sr_dbg(
"invalid value for dtr: %c", kv[1][0]);
690 }
else if (!strncmp(kv[0],
"flow", 4)) {
693 else if (kv[1][0] ==
'1')
695 else if (kv[1][0] ==
'2')
698 sr_dbg(
"invalid value for flow: %c", kv[1][0]);
709 g_match_info_unref(match);
711 sr_spew(
"Got params: rate %d, frame %d/%d/%d, flow %d, rts %d, dtr %d.",
712 speed, databits, parity, stopbits, flow, rts, dtr);
715 sr_dbg(
"Could not infer speed from parameter string.");
719 return serial_set_params(serial, speed,
720 databits, parity, stopbits,
739 SR_PRIV int serial_readline(
struct sr_serial_dev_inst *serial,
740 char **buf,
int *buflen, gint64 timeout_ms)
742 gint64 start, remaining;
746 sr_dbg(
"Invalid serial port.");
750 if (!dev_is_supported(serial)) {
751 sr_dbg(
"Cannot use unopened serial port %s.", serial->port);
755 start = g_get_monotonic_time();
756 remaining = timeout_ms;
761 len = maxlen - *buflen - 1;
764 len = serial_read_blocking(serial, *buf + *buflen, 1, remaining);
767 *(*buf + *buflen) =
'\0';
768 if (*buflen > 0 && (*(*buf + *buflen - 1) ==
'\r' 769 || *(*buf + *buflen - 1) ==
'\n')) {
771 *(*buf + --*buflen) =
'\0';
776 remaining = timeout_ms - ((g_get_monotonic_time() - start) / 1000);
784 sr_dbg(
"Received %d: '%s'.", *buflen, *buf);
815 SR_PRIV int serial_stream_detect(
struct sr_serial_dev_inst *serial,
816 uint8_t *buf,
size_t *buflen,
817 size_t packet_size, packet_valid_callback is_valid,
818 packet_valid_len_callback is_valid_len,
size_t *return_size,
821 uint64_t start_us, elapsed_ms, byte_delay_us;
822 size_t fill_idx, check_idx, max_fill_idx;
824 const uint8_t *check_ptr;
825 size_t check_len, pkt_len;
829 sr_dbg(
"Detecting packets on %s (timeout = %" PRIu64
"ms).",
830 serial->port, timeout_ms);
832 max_fill_idx = *buflen;
833 if (max_fill_idx < 2 * packet_size) {
839 sr_err(
"Small stream detect RX buffer, want 2x packet size.");
843 byte_delay_us = serial_timeout(serial, 1) * 1000;
844 start_us = g_get_monotonic_time();
846 check_idx = fill_idx = 0;
847 while (fill_idx < max_fill_idx) {
854 recv_len = serial_read_nonblocking(serial, &buf[fill_idx], 1);
856 fill_idx += recv_len;
859 check_ptr = &buf[check_idx];
860 check_len = fill_idx - check_idx;
861 do_dump = check_len >= packet_size;
866 text = sr_hexdump_new(check_ptr, check_len);
867 sr_spew(
"Trying packet: len %zu, bytes %s",
868 check_len, text->str);
869 sr_hexdump_free(text);
873 elapsed_ms = g_get_monotonic_time() - start_us;
875 if (is_valid_len && check_len >= packet_size) {
876 pkt_len = packet_size;
877 ret = is_valid_len(NULL, check_ptr, check_len, &pkt_len);
880 sr_spew(
"Valid packet after %" PRIu64
"ms.",
882 sr_spew(
"RX count %zu, packet len %zu.",
886 *return_size = pkt_len;
891 sr_spew(
"Checker needs more RX data.");
894 sr_spew(
"Invalid packet, advancing read pos.");
898 if (is_valid && check_len >= packet_size) {
899 if (is_valid(check_ptr)) {
901 sr_spew(
"Valid packet after %" PRIu64
"ms.",
903 sr_spew(
"RX count %zu, packet len %zu.",
904 fill_idx, packet_size);
907 *return_size = packet_size;
911 sr_spew(
"Invalid packet, advancing read pointer.");
916 if (elapsed_ms >= timeout_ms) {
917 sr_dbg(
"Detection timed out after %" PRIu64
"ms.",
922 g_usleep(byte_delay_us);
924 sr_info(
"Didn't find a valid packet (read %zu bytes).", fill_idx);
952 SR_PRIV int sr_serial_extract_options(GSList *options,
953 const char **serial_device,
const char **serial_options)
958 for (l = options; l; l = l->next) {
964 *serial_device = g_variant_get_string(src->
data, NULL);
965 sr_dbg(
"Parsed serial device: %s.", *serial_device);
970 *serial_options = g_variant_get_string(src->
data, NULL);
971 sr_dbg(
"Parsed serial options: %s.", *serial_options);
976 if (serial_device && !*serial_device) {
977 sr_dbg(
"No serial device specified.");
984 #ifdef HAVE_SERIAL_COMM 988 struct sr_serial_dev_inst *serial,
int events,
int timeout,
991 if ((events & (G_IO_IN | G_IO_ERR)) && (events & G_IO_OUT)) {
992 sr_err(
"Cannot poll input/error and output simultaneously.");
996 if (!dev_is_supported(serial)) {
997 sr_err(
"Invalid serial port.");
1001 if (!serial->lib_funcs || !serial->lib_funcs->setup_source_add)
1004 return serial->lib_funcs->setup_source_add(session, serial,
1005 events, timeout, cb, cb_data);
1010 struct sr_serial_dev_inst *serial)
1012 if (!dev_is_supported(serial)) {
1013 sr_err(
"Invalid serial port.");
1017 if (!serial->lib_funcs || !serial->lib_funcs->setup_source_remove)
1020 return serial->lib_funcs->setup_source_remove(session, serial);
1041 serial = g_malloc0(
sizeof(*serial));
1042 serial->
name = g_strdup(name);
1043 serial->
description = g_strdup(description ? description :
"");
1057 g_free(serial->
name);
1062 static GSList *append_port_list(GSList *devs,
const char *name,
const char *desc)
1064 return g_slist_append(devs, sr_serial_new(name, desc));
1077 GSList *(*list_func)(GSList *list, sr_ser_list_append_t append);
1083 if (ser_lib_funcs_libsp && ser_lib_funcs_libsp->list) {
1084 list_func = ser_lib_funcs_libsp->list;
1085 tty_devs = list_func(tty_devs, append_port_list);
1087 if (ser_lib_funcs_hid && ser_lib_funcs_hid->list) {
1088 list_func = ser_lib_funcs_hid->list;
1089 tty_devs = list_func(tty_devs, append_port_list);
1091 if (ser_lib_funcs_bt && ser_lib_funcs_bt->list) {
1092 list_func = ser_lib_funcs_bt->list;
1093 tty_devs = list_func(tty_devs, append_port_list);
1099 static GSList *append_port_find(GSList *devs,
const char *name)
1101 if (!name || !*name)
1104 return g_slist_append(devs, g_strdup(name));
1119 SR_PRIV GSList *sr_serial_find_usb(uint16_t vendor_id, uint16_t product_id)
1122 GSList *(*find_func)(GSList *list, sr_ser_find_append_t append,
1123 uint16_t vid, uint16_t pid);
1126 if (ser_lib_funcs_libsp && ser_lib_funcs_libsp->find_usb) {
1127 find_func = ser_lib_funcs_libsp->find_usb;
1128 tty_devs = find_func(tty_devs, append_port_find,
1129 vendor_id, product_id);
1131 if (ser_lib_funcs_hid && ser_lib_funcs_hid->find_usb) {
1132 find_func = ser_lib_funcs_hid->find_usb;
1133 tty_devs = find_func(tty_devs, append_port_find,
1134 vendor_id, product_id);
1141 SR_PRIV int serial_timeout(
struct sr_serial_dev_inst *port,
int num_bytes)
1143 int bits, baud, ret, timeout_ms;
1147 if (port->lib_funcs && port->lib_funcs->get_frame_format) {
1148 ret = port->lib_funcs->get_frame_format(port, &baud, &bits);
1152 baud = port->comm_params.bit_rate;
1153 bits = 1 + port->comm_params.data_bits +
1154 port->comm_params.parity_bits +
1155 port->comm_params.stop_bits;
1163 timeout_ms += ((1000.0 / baud) * bits) * num_bytes;
Specification on how to connect to a device.
uint32_t key
Config key like SR_CONF_CONN, etc.
GSList * sr_serial_list(const struct sr_dev_driver *driver)
List available serial devices.
char * description
An end user friendly description for the serial port.
Output very noisy debug messages.
int sr_log_loglevel_get(void)
Get the libsigrok loglevel.
GVariant * data
Key-specific data.
typedef void(__LZO_CDECL *lzo_free_func_t)(lzo_callback_p self
void sr_serial_free(struct sr_serial_port *serial)
Free a previously allocated sr_serial_port structure.
Used for setting or getting value of a config item.
Generic/unspecified error.
Serial communication specification, in the form:
Opaque structure representing a libsigrok session.
char * name
The OS dependent name of the serial port.
The public libsigrok header file to be used by frontends.
int(* sr_receive_data_callback)(int fd, int revents, void *cb_data)
Type definition for callback function for data reception.