libsigrok  0.4.0
sigrok hardware access and backend library
serial.c
Go to the documentation of this file.
1 /*
2  * This file is part of the libsigrok project.
3  *
4  * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
5  * Copyright (C) 2010-2012 Uwe Hermann <uwe@hermann-uwe.de>
6  * Copyright (C) 2012 Alexandru Gagniuc <mr.nuke.me@gmail.com>
7  * Copyright (C) 2014 Uffe Jakobsen <uffe@uffe.org>
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <http://www.gnu.org/licenses/>.
21  */
22 
23 #include <config.h>
24 #include <string.h>
25 #include <stdlib.h>
26 #include <glib.h>
27 #include <glib/gstdio.h>
28 #include <libserialport.h>
29 #include <libsigrok/libsigrok.h>
30 #include "libsigrok-internal.h"
31 #ifdef G_OS_WIN32
32 #include <windows.h> /* for HANDLE */
33 #endif
34 
35 /** @cond PRIVATE */
36 #define LOG_PREFIX "serial"
37 /** @endcond */
38 
39 /**
40  * @file
41  *
42  * Serial port handling.
43  */
44 
45 /**
46  * @defgroup grp_serial Serial port handling
47  *
48  * Serial port handling functions.
49  *
50  * @{
51  */
52 
53 /**
54  * Open the specified serial port.
55  *
56  * @param serial Previously initialized serial port structure.
57  * @param[in] flags Flags to use when opening the serial port. Possible flags
58  * include SERIAL_RDWR, SERIAL_RDONLY.
59  *
60  * If the serial structure contains a serialcomm string, it will be
61  * passed to serial_set_paramstr() after the port is opened.
62  *
63  * @retval SR_OK Success.
64  * @retval SR_ERR Failure.
65  *
66  * @private
67  */
68 SR_PRIV int serial_open(struct sr_serial_dev_inst *serial, int flags)
69 {
70  int ret;
71  char *error;
72  int sp_flags = 0;
73 
74  if (!serial) {
75  sr_dbg("Invalid serial port.");
76  return SR_ERR;
77  }
78 
79  sr_spew("Opening serial port '%s' (flags %d).", serial->port, flags);
80 
81  sp_get_port_by_name(serial->port, &serial->data);
82 
83  if (flags & SERIAL_RDWR)
84  sp_flags = (SP_MODE_READ | SP_MODE_WRITE);
85  else if (flags & SERIAL_RDONLY)
86  sp_flags = SP_MODE_READ;
87 
88  ret = sp_open(serial->data, sp_flags);
89 
90  switch (ret) {
91  case SP_ERR_ARG:
92  sr_err("Attempt to open serial port with invalid parameters.");
93  return SR_ERR_ARG;
94  case SP_ERR_FAIL:
95  error = sp_last_error_message();
96  sr_err("Error opening port (%d): %s.",
97  sp_last_error_code(), error);
98  sp_free_error_message(error);
99  return SR_ERR;
100  }
101 
102  if (serial->serialcomm)
103  return serial_set_paramstr(serial, serial->serialcomm);
104  else
105  return SR_OK;
106 }
107 
108 /**
109  * Close the specified serial port.
110  *
111  * @param serial Previously initialized serial port structure.
112  *
113  * @retval SR_OK Success.
114  * @retval SR_ERR Failure.
115  *
116  * @private
117  */
118 SR_PRIV int serial_close(struct sr_serial_dev_inst *serial)
119 {
120  int ret;
121  char *error;
122 
123  if (!serial) {
124  sr_dbg("Invalid serial port.");
125  return SR_ERR;
126  }
127 
128  if (!serial->data) {
129  sr_dbg("Cannot close unopened serial port %s.", serial->port);
130  return SR_ERR;
131  }
132 
133  sr_spew("Closing serial port %s.", serial->port);
134 
135  ret = sp_close(serial->data);
136 
137  switch (ret) {
138  case SP_ERR_ARG:
139  sr_err("Attempt to close an invalid serial port.");
140  return SR_ERR_ARG;
141  case SP_ERR_FAIL:
142  error = sp_last_error_message();
143  sr_err("Error closing port (%d): %s.",
144  sp_last_error_code(), error);
145  sp_free_error_message(error);
146  return SR_ERR;
147  }
148 
149  sp_free_port(serial->data);
150  serial->data = NULL;
151 
152  return SR_OK;
153 }
154 
155 /**
156  * Flush serial port buffers.
157  *
158  * @param serial Previously initialized serial port structure.
159  *
160  * @retval SR_OK Success.
161  * @retval SR_ERR Failure.
162  *
163  * @private
164  */
165 SR_PRIV int serial_flush(struct sr_serial_dev_inst *serial)
166 {
167  int ret;
168  char *error;
169 
170  if (!serial) {
171  sr_dbg("Invalid serial port.");
172  return SR_ERR;
173  }
174 
175  if (!serial->data) {
176  sr_dbg("Cannot flush unopened serial port %s.", serial->port);
177  return SR_ERR;
178  }
179 
180  sr_spew("Flushing serial port %s.", serial->port);
181 
182  ret = sp_flush(serial->data, SP_BUF_BOTH);
183 
184  switch (ret) {
185  case SP_ERR_ARG:
186  sr_err("Attempt to flush an invalid serial port.");
187  return SR_ERR_ARG;
188  case SP_ERR_FAIL:
189  error = sp_last_error_message();
190  sr_err("Error flushing port (%d): %s.",
191  sp_last_error_code(), error);
192  sp_free_error_message(error);
193  return SR_ERR;
194  }
195 
196  return SR_OK;
197 }
198 
199 /**
200  * Drain serial port buffers.
201  *
202  * @param serial Previously initialized serial port structure.
203  *
204  * @retval SR_OK Success.
205  * @retval SR_ERR Failure.
206  *
207  * @private
208  */
209 SR_PRIV int serial_drain(struct sr_serial_dev_inst *serial)
210 {
211  int ret;
212  char *error;
213 
214  if (!serial) {
215  sr_dbg("Invalid serial port.");
216  return SR_ERR;
217  }
218 
219  if (!serial->data) {
220  sr_dbg("Cannot drain unopened serial port %s.", serial->port);
221  return SR_ERR;
222  }
223 
224  sr_spew("Draining serial port %s.", serial->port);
225 
226  ret = sp_drain(serial->data);
227 
228  if (ret == SP_ERR_FAIL) {
229  error = sp_last_error_message();
230  sr_err("Error draining port (%d): %s.",
231  sp_last_error_code(), error);
232  sp_free_error_message(error);
233  return SR_ERR;
234  }
235 
236  return SR_OK;
237 }
238 
239 static int _serial_write(struct sr_serial_dev_inst *serial,
240  const void *buf, size_t count, int nonblocking, unsigned int timeout_ms)
241 {
242  ssize_t ret;
243  char *error;
244 
245  if (!serial) {
246  sr_dbg("Invalid serial port.");
247  return SR_ERR;
248  }
249 
250  if (!serial->data) {
251  sr_dbg("Cannot use unopened serial port %s.", serial->port);
252  return SR_ERR;
253  }
254 
255  if (nonblocking)
256  ret = sp_nonblocking_write(serial->data, buf, count);
257  else
258  ret = sp_blocking_write(serial->data, buf, count, timeout_ms);
259 
260  switch (ret) {
261  case SP_ERR_ARG:
262  sr_err("Attempted serial port write with invalid arguments.");
263  return SR_ERR_ARG;
264  case SP_ERR_FAIL:
265  error = sp_last_error_message();
266  sr_err("Write error (%d): %s.", sp_last_error_code(), error);
267  sp_free_error_message(error);
268  return SR_ERR;
269  }
270 
271  sr_spew("Wrote %zd/%zu bytes.", ret, count);
272 
273  return ret;
274 }
275 
276 /**
277  * Write a number of bytes to the specified serial port, blocking until finished.
278  *
279  * @param serial Previously initialized serial port structure.
280  * @param[in] buf Buffer containing the bytes to write.
281  * @param[in] count Number of bytes to write.
282  * @param[in] timeout_ms Timeout in ms, or 0 for no timeout.
283  *
284  * @retval SR_ERR_ARG Invalid argument.
285  * @retval SR_ERR Other error.
286  * @retval other The number of bytes written. If this is less than the number
287  * specified in the call, the timeout was reached.
288  *
289  * @private
290  */
291 SR_PRIV int serial_write_blocking(struct sr_serial_dev_inst *serial,
292  const void *buf, size_t count, unsigned int timeout_ms)
293 {
294  return _serial_write(serial, buf, count, 0, timeout_ms);
295 }
296 
297 /**
298  * Write a number of bytes to the specified serial port, return immediately.
299  *
300  * @param serial Previously initialized serial port structure.
301  * @param[in] buf Buffer containing the bytes to write.
302  * @param[in] count Number of bytes to write.
303  *
304  * @retval SR_ERR_ARG Invalid argument.
305  * @retval SR_ERR Other error.
306  * @retval other The number of bytes written.
307  *
308  * @private
309  */
310 SR_PRIV int serial_write_nonblocking(struct sr_serial_dev_inst *serial,
311  const void *buf, size_t count)
312 {
313  return _serial_write(serial, buf, count, 1, 0);
314 }
315 
316 static int _serial_read(struct sr_serial_dev_inst *serial, void *buf,
317  size_t count, int nonblocking, unsigned int timeout_ms)
318 {
319  ssize_t ret;
320  char *error;
321 
322  if (!serial) {
323  sr_dbg("Invalid serial port.");
324  return SR_ERR;
325  }
326 
327  if (!serial->data) {
328  sr_dbg("Cannot use unopened serial port %s.", serial->port);
329  return SR_ERR;
330  }
331 
332  if (nonblocking)
333  ret = sp_nonblocking_read(serial->data, buf, count);
334  else
335  ret = sp_blocking_read(serial->data, buf, count, timeout_ms);
336 
337  switch (ret) {
338  case SP_ERR_ARG:
339  sr_err("Attempted serial port read with invalid arguments.");
340  return SR_ERR_ARG;
341  case SP_ERR_FAIL:
342  error = sp_last_error_message();
343  sr_err("Read error (%d): %s.", sp_last_error_code(), error);
344  sp_free_error_message(error);
345  return SR_ERR;
346  }
347 
348  if (ret > 0)
349  sr_spew("Read %zd/%zu bytes.", ret, count);
350 
351  return ret;
352 }
353 
354 /**
355  * Read a number of bytes from the specified serial port, block until finished.
356  *
357  * @param serial Previously initialized serial port structure.
358  * @param buf Buffer where to store the bytes that are read.
359  * @param[in] count The number of bytes to read.
360  * @param[in] timeout_ms Timeout in ms, or 0 for no timeout.
361  *
362  * @retval SR_ERR_ARG Invalid argument.
363  * @retval SR_ERR Other error.
364  * @retval other The number of bytes read. If this is less than the number
365  * requested, the timeout was reached.
366  *
367  * @private
368  */
369 SR_PRIV int serial_read_blocking(struct sr_serial_dev_inst *serial, void *buf,
370  size_t count, unsigned int timeout_ms)
371 {
372  return _serial_read(serial, buf, count, 0, timeout_ms);
373 }
374 
375 /**
376  * Try to read up to @a count bytes from the specified serial port, return
377  * immediately with what's available.
378  *
379  * @param serial Previously initialized serial port structure.
380  * @param buf Buffer where to store the bytes that are read.
381  * @param[in] count The number of bytes to read.
382  *
383  * @retval SR_ERR_ARG Invalid argument.
384  * @retval SR_ERR Other error.
385  * @retval other The number of bytes read.
386  *
387  * @private
388  */
389 SR_PRIV int serial_read_nonblocking(struct sr_serial_dev_inst *serial, void *buf,
390  size_t count)
391 {
392  return _serial_read(serial, buf, count, 1, 0);
393 }
394 
395 /**
396  * Set serial parameters for the specified serial port.
397  *
398  * @param serial Previously initialized serial port structure.
399  * @param[in] baudrate The baudrate to set.
400  * @param[in] bits The number of data bits to use (5, 6, 7 or 8).
401  * @param[in] parity The parity setting to use (0 = none, 1 = even, 2 = odd).
402  * @param[in] stopbits The number of stop bits to use (1 or 2).
403  * @param[in] flowcontrol The flow control settings to use (0 = none,
404  * 1 = RTS/CTS, 2 = XON/XOFF).
405  * @param[in] rts Status of RTS line (0 or 1; required by some interfaces).
406  * @param[in] dtr Status of DTR line (0 or 1; required by some interfaces).
407  *
408  * @retval SR_OK Success.
409  * @retval SR_ERR Failure.
410  *
411  * @private
412  */
413 SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial, int baudrate,
414  int bits, int parity, int stopbits,
415  int flowcontrol, int rts, int dtr)
416 {
417  int ret;
418  char *error;
419  struct sp_port_config *config;
420 
421  if (!serial) {
422  sr_dbg("Invalid serial port.");
423  return SR_ERR;
424  }
425 
426  if (!serial->data) {
427  sr_dbg("Cannot configure unopened serial port %s.", serial->port);
428  return SR_ERR;
429  }
430 
431  sr_spew("Setting serial parameters on port %s.", serial->port);
432 
433  sp_new_config(&config);
434  sp_set_config_baudrate(config, baudrate);
435  sp_set_config_bits(config, bits);
436  switch (parity) {
437  case 0:
438  sp_set_config_parity(config, SP_PARITY_NONE);
439  break;
440  case 1:
441  sp_set_config_parity(config, SP_PARITY_EVEN);
442  break;
443  case 2:
444  sp_set_config_parity(config, SP_PARITY_ODD);
445  break;
446  default:
447  return SR_ERR_ARG;
448  }
449  sp_set_config_stopbits(config, stopbits);
450  sp_set_config_rts(config, flowcontrol == 1 ? SP_RTS_FLOW_CONTROL : rts);
451  sp_set_config_cts(config, flowcontrol == 1 ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE);
452  sp_set_config_dtr(config, dtr);
453  sp_set_config_dsr(config, SP_DSR_IGNORE);
454  sp_set_config_xon_xoff(config, flowcontrol == 2 ? SP_XONXOFF_INOUT : SP_XONXOFF_DISABLED);
455 
456  ret = sp_set_config(serial->data, config);
457  sp_free_config(config);
458 
459  switch (ret) {
460  case SP_ERR_ARG:
461  sr_err("Invalid arguments for setting serial port parameters.");
462  return SR_ERR_ARG;
463  case SP_ERR_FAIL:
464  error = sp_last_error_message();
465  sr_err("Error setting serial port parameters (%d): %s.",
466  sp_last_error_code(), error);
467  sp_free_error_message(error);
468  return SR_ERR;
469  }
470 
471  return SR_OK;
472 }
473 
474 /**
475  * Set serial parameters for the specified serial port from parameter string.
476  *
477  * @param serial Previously initialized serial port structure.
478  * @param[in] paramstr A serial communication parameters string of the form
479  * "<baudrate>/<bits><parity><stopbits>{/<option>}".\n
480  * Examples: "9600/8n1", "600/7o2/dtr=1/rts=0" or "460800/8n1/flow=2".\n
481  * <baudrate>=integer Baud rate.\n
482  * <bits>=5|6|7|8 Number of data bits.\n
483  * <parity>=n|e|o None, even, odd.\n
484  * <stopbits>=1|2 One or two stop bits.\n
485  * Options:\n
486  * dtr=0|1 Set DTR off resp. on.\n
487  * flow=0|1|2 Flow control. 0 for none, 1 for RTS/CTS, 2 for XON/XOFF.\n
488  * rts=0|1 Set RTS off resp. on.\n
489  * Please note that values and combinations of these parameters must be
490  * supported by the concrete serial interface hardware and the drivers for it.
491  *
492  * @retval SR_OK Success.
493  * @retval SR_ERR Failure.
494  *
495  * @private
496  */
497 SR_PRIV int serial_set_paramstr(struct sr_serial_dev_inst *serial,
498  const char *paramstr)
499 {
500 /** @cond PRIVATE */
501 #define SERIAL_COMM_SPEC "^(\\d+)/([5678])([neo])([12])(.*)$"
502 /** @endcond */
503 
504  GRegex *reg;
505  GMatchInfo *match;
506  int speed, databits, parity, stopbits, flow, rts, dtr, i;
507  char *mstr, **opts, **kv;
508 
509  speed = databits = parity = stopbits = flow = 0;
510  rts = dtr = -1;
511  sr_spew("Parsing parameters from \"%s\".", paramstr);
512  reg = g_regex_new(SERIAL_COMM_SPEC, 0, 0, NULL);
513  if (g_regex_match(reg, paramstr, 0, &match)) {
514  if ((mstr = g_match_info_fetch(match, 1)))
515  speed = strtoul(mstr, NULL, 10);
516  g_free(mstr);
517  if ((mstr = g_match_info_fetch(match, 2)))
518  databits = strtoul(mstr, NULL, 10);
519  g_free(mstr);
520  if ((mstr = g_match_info_fetch(match, 3))) {
521  switch (mstr[0]) {
522  case 'n':
523  parity = SP_PARITY_NONE;
524  break;
525  case 'e':
526  parity = SP_PARITY_EVEN;
527  break;
528  case 'o':
529  parity = SP_PARITY_ODD;
530  break;
531  }
532  }
533  g_free(mstr);
534  if ((mstr = g_match_info_fetch(match, 4)))
535  stopbits = strtoul(mstr, NULL, 10);
536  g_free(mstr);
537  if ((mstr = g_match_info_fetch(match, 5)) && mstr[0] != '\0') {
538  if (mstr[0] != '/') {
539  sr_dbg("missing separator before extra options");
540  speed = 0;
541  } else {
542  /* A set of "key=value" options separated by / */
543  opts = g_strsplit(mstr + 1, "/", 0);
544  for (i = 0; opts[i]; i++) {
545  kv = g_strsplit(opts[i], "=", 2);
546  if (!strncmp(kv[0], "rts", 3)) {
547  if (kv[1][0] == '1')
548  rts = 1;
549  else if (kv[1][0] == '0')
550  rts = 0;
551  else {
552  sr_dbg("invalid value for rts: %c", kv[1][0]);
553  speed = 0;
554  }
555  } else if (!strncmp(kv[0], "dtr", 3)) {
556  if (kv[1][0] == '1')
557  dtr = 1;
558  else if (kv[1][0] == '0')
559  dtr = 0;
560  else {
561  sr_dbg("invalid value for dtr: %c", kv[1][0]);
562  speed = 0;
563  }
564  } else if (!strncmp(kv[0], "flow", 4)) {
565  if (kv[1][0] == '0')
566  flow = 0;
567  else if (kv[1][0] == '1')
568  flow = 1;
569  else if (kv[1][0] == '2')
570  flow = 2;
571  else {
572  sr_dbg("invalid value for flow: %c", kv[1][0]);
573  speed = 0;
574  }
575  }
576  g_strfreev(kv);
577  }
578  g_strfreev(opts);
579  }
580  }
581  g_free(mstr);
582  }
583  g_match_info_unref(match);
584  g_regex_unref(reg);
585 
586  if (speed) {
587  return serial_set_params(serial, speed, databits, parity,
588  stopbits, flow, rts, dtr);
589  } else {
590  sr_dbg("Could not infer speed from parameter string.");
591  return SR_ERR_ARG;
592  }
593 }
594 
595 /**
596  * Read a line from the specified serial port.
597  *
598  * @param serial Previously initialized serial port structure.
599  * @param buf Buffer where to store the bytes that are read.
600  * @param buflen Size of the buffer.
601  * @param[in] timeout_ms How long to wait for a line to come in.
602  *
603  * Reading stops when CR of LR is found, which is stripped from the buffer.
604  *
605  * @retval SR_OK Success.
606  * @retval SR_ERR Failure.
607  *
608  * @private
609  */
610 SR_PRIV int serial_readline(struct sr_serial_dev_inst *serial, char **buf,
611  int *buflen, gint64 timeout_ms)
612 {
613  gint64 start, remaining;
614  int maxlen, len;
615 
616  if (!serial) {
617  sr_dbg("Invalid serial port.");
618  return SR_ERR;
619  }
620 
621  if (!serial->data) {
622  sr_dbg("Cannot use unopened serial port %s.", serial->port);
623  return -1;
624  }
625 
626  start = g_get_monotonic_time();
627  remaining = timeout_ms;
628 
629  maxlen = *buflen;
630  *buflen = len = 0;
631  while (1) {
632  len = maxlen - *buflen - 1;
633  if (len < 1)
634  break;
635  len = sp_blocking_read(serial->data, *buf + *buflen, 1, remaining);
636  if (len > 0) {
637  *buflen += len;
638  *(*buf + *buflen) = '\0';
639  if (*buflen > 0 && (*(*buf + *buflen - 1) == '\r'
640  || *(*buf + *buflen - 1) == '\n')) {
641  /* Strip CR/LF and terminate. */
642  *(*buf + --*buflen) = '\0';
643  break;
644  }
645  }
646  /* Reduce timeout by time elapsed. */
647  remaining = timeout_ms - ((g_get_monotonic_time() - start) / 1000);
648  if (remaining <= 0)
649  /* Timeout */
650  break;
651  if (len < 1)
652  g_usleep(2000);
653  }
654  if (*buflen)
655  sr_dbg("Received %d: '%s'.", *buflen, *buf);
656 
657  return SR_OK;
658 }
659 
660 /**
661  * Try to find a valid packet in a serial data stream.
662  *
663  * @param serial Previously initialized serial port structure.
664  * @param buf Buffer containing the bytes to write.
665  * @param buflen Size of the buffer.
666  * @param[in] packet_size Size, in bytes, of a valid packet.
667  * @param is_valid Callback that assesses whether the packet is valid or not.
668  * @param[in] timeout_ms The timeout after which, if no packet is detected, to
669  * abort scanning.
670  * @param[in] baudrate The baudrate of the serial port. This parameter is not
671  * critical, but it helps fine tune the serial port polling
672  * delay.
673  *
674  * @retval SR_OK Valid packet was found within the given timeout.
675  * @retval SR_ERR Failure.
676  *
677  * @private
678  */
679 SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial,
680  uint8_t *buf, size_t *buflen,
681  size_t packet_size,
682  packet_valid_callback is_valid,
683  uint64_t timeout_ms, int baudrate)
684 {
685  uint64_t start, time, byte_delay_us;
686  size_t ibuf, i, maxlen;
687  ssize_t len;
688 
689  maxlen = *buflen;
690 
691  sr_dbg("Detecting packets on %s (timeout = %" PRIu64
692  "ms, baudrate = %d).", serial->port, timeout_ms, baudrate);
693 
694  if (maxlen < (packet_size / 2) ) {
695  sr_err("Buffer size must be at least twice the packet size.");
696  return SR_ERR;
697  }
698 
699  /* Assume 8n1 transmission. That is 10 bits for every byte. */
700  byte_delay_us = 10 * ((1000 * 1000) / baudrate);
701  start = g_get_monotonic_time();
702 
703  i = ibuf = len = 0;
704  while (ibuf < maxlen) {
705  len = serial_read_nonblocking(serial, &buf[ibuf], 1);
706  if (len > 0) {
707  ibuf += len;
708  } else if (len == 0) {
709  /* No logging, already done in serial_read(). */
710  } else {
711  /* Error reading byte, but continuing anyway. */
712  }
713 
714  time = g_get_monotonic_time() - start;
715  time /= 1000;
716 
717  if ((ibuf - i) >= packet_size) {
718  /* We have at least a packet's worth of data. */
719  if (is_valid(&buf[i])) {
720  sr_spew("Found valid %zu-byte packet after "
721  "%" PRIu64 "ms.", (ibuf - i), time);
722  *buflen = ibuf;
723  return SR_OK;
724  } else {
725  sr_spew("Got %zu bytes, but not a valid "
726  "packet.", (ibuf - i));
727  }
728  /* Not a valid packet. Continue searching. */
729  i++;
730  }
731  if (time >= timeout_ms) {
732  /* Timeout */
733  sr_dbg("Detection timed out after %" PRIu64 "ms.", time);
734  break;
735  }
736  if (len < 1)
737  g_usleep(byte_delay_us);
738  }
739 
740  *buflen = ibuf;
741 
742  sr_err("Didn't find a valid packet (read %zu bytes).", *buflen);
743 
744  return SR_ERR;
745 }
746 
747 /**
748  * Extract the serial device and options from the options linked list.
749  *
750  * @param options List of options passed from the command line.
751  * @param serial_device Pointer where to store the extracted serial device.
752  * @param serial_options Pointer where to store the optional extracted serial
753  * options.
754  *
755  * @return SR_OK if a serial_device is found, SR_ERR if no device is found. The
756  * returned string should not be freed by the caller.
757  *
758  * @private
759  */
760 SR_PRIV int sr_serial_extract_options(GSList *options, const char **serial_device,
761  const char **serial_options)
762 {
763  GSList *l;
764  struct sr_config *src;
765 
766  *serial_device = NULL;
767 
768  for (l = options; l; l = l->next) {
769  src = l->data;
770  switch (src->key) {
771  case SR_CONF_CONN:
772  *serial_device = g_variant_get_string(src->data, NULL);
773  sr_dbg("Parsed serial device: %s.", *serial_device);
774  break;
775  case SR_CONF_SERIALCOMM:
776  *serial_options = g_variant_get_string(src->data, NULL);
777  sr_dbg("Parsed serial options: %s.", *serial_options);
778  break;
779  }
780  }
781 
782  if (!*serial_device) {
783  sr_dbg("No serial device specified.");
784  return SR_ERR;
785  }
786 
787  return SR_OK;
788 }
789 
790 /** @cond PRIVATE */
791 #ifdef G_OS_WIN32
792 typedef HANDLE event_handle;
793 #else
794 typedef int event_handle;
795 #endif
796 /** @endcond */
797 
798 /** @private */
799 SR_PRIV int serial_source_add(struct sr_session *session,
800  struct sr_serial_dev_inst *serial, int events, int timeout,
801  sr_receive_data_callback cb, void *cb_data)
802 {
803  struct sp_event_set *event_set;
804  gintptr poll_fd;
805  unsigned int poll_events;
806  enum sp_event mask = 0;
807 
808  if ((events & (G_IO_IN|G_IO_ERR)) && (events & G_IO_OUT)) {
809  sr_err("Cannot poll input/error and output simultaneously.");
810  return SR_ERR_ARG;
811  }
812 
813  if (sp_new_event_set(&event_set) != SP_OK)
814  return SR_ERR;
815 
816  if (events & G_IO_IN)
817  mask |= SP_EVENT_RX_READY;
818  if (events & G_IO_OUT)
819  mask |= SP_EVENT_TX_READY;
820  if (events & G_IO_ERR)
821  mask |= SP_EVENT_ERROR;
822 
823  if (sp_add_port_events(event_set, serial->data, mask) != SP_OK) {
824  sp_free_event_set(event_set);
825  return SR_ERR;
826  }
827  if (event_set->count != 1) {
828  sr_err("Unexpected number (%u) of event handles to poll.",
829  event_set->count);
830  sp_free_event_set(event_set);
831  return SR_ERR;
832  }
833 
834  poll_fd = (gintptr) ((event_handle *)event_set->handles)[0];
835  mask = event_set->masks[0];
836 
837  sp_free_event_set(event_set);
838 
839  poll_events = 0;
840  if (mask & SP_EVENT_RX_READY)
841  poll_events |= G_IO_IN;
842  if (mask & SP_EVENT_TX_READY)
843  poll_events |= G_IO_OUT;
844  if (mask & SP_EVENT_ERROR)
845  poll_events |= G_IO_ERR;
846  /*
847  * Using serial->data as the key for the event source is not quite
848  * proper, as it makes it impossible to create another event source
849  * for the same serial port. However, these fixed keys will soon be
850  * removed from the API anyway, so this is OK for now.
851  */
852  return sr_session_fd_source_add(session, serial->data,
853  poll_fd, poll_events, timeout, cb, cb_data);
854 }
855 
856 /** @private */
857 SR_PRIV int serial_source_remove(struct sr_session *session,
858  struct sr_serial_dev_inst *serial)
859 {
860  return sr_session_source_remove_internal(session, serial->data);
861 }
862 
863 /**
864  * Create/allocate a new sr_serial_port structure.
865  *
866  * @param name The OS dependent name of the serial port. Must not be NULL.
867  * @param description An end user friendly description for the serial port.
868  * Can be NULL (in that case the empty string is used
869  * as description).
870  *
871  * @return The newly allocated sr_serial_port struct.
872  */
873 static struct sr_serial_port *sr_serial_new(const char *name,
874  const char *description)
875 {
876  struct sr_serial_port *serial;
877 
878  if (!name)
879  return NULL;
880 
881  serial = g_malloc(sizeof(struct sr_serial_port));
882  serial->name = g_strdup(name);
883  serial->description = g_strdup(description ? description : "");
884 
885  return serial;
886 }
887 
888 /**
889  * Free a previously allocated sr_serial_port structure.
890  *
891  * @param serial The sr_serial_port struct to free. Must not be NULL.
892  */
894 {
895  if (!serial)
896  return;
897  g_free(serial->name);
898  g_free(serial->description);
899  g_free(serial);
900 }
901 
902 /**
903  * List available serial devices.
904  *
905  * @return A GSList of strings containing the path of the serial devices or
906  * NULL if no serial device is found. The returned list must be freed
907  * by the caller.
908  */
909 SR_API GSList *sr_serial_list(const struct sr_dev_driver *driver)
910 {
911  GSList *tty_devs = NULL;
912  struct sp_port **ports;
913  struct sr_serial_port *port;
914  int i;
915 
916  /* Currently unused, but will be used by some drivers later on. */
917  (void)driver;
918 
919  if (sp_list_ports(&ports) != SP_OK)
920  return NULL;
921 
922  for (i = 0; ports[i]; i++) {
923  port = sr_serial_new(sp_get_port_name(ports[i]),
924  sp_get_port_description(ports[i]));
925  tty_devs = g_slist_append(tty_devs, port);
926  }
927 
928  sp_free_port_list(ports);
929 
930  return tty_devs;
931 }
932 
933 /**
934  * Find USB serial devices via the USB vendor ID and product ID.
935  *
936  * @param[in] vendor_id Vendor ID of the USB device.
937  * @param[in] product_id Product ID of the USB device.
938  *
939  * @return A GSList of strings containing the path of the serial device or
940  * NULL if no serial device is found. The returned list must be freed
941  * by the caller.
942  *
943  * @private
944  */
945 SR_PRIV GSList *sr_serial_find_usb(uint16_t vendor_id, uint16_t product_id)
946 {
947  GSList *tty_devs = NULL;
948  struct sp_port **ports;
949  int i, vid, pid;
950 
951  if (sp_list_ports(&ports) != SP_OK)
952  return NULL;
953 
954  for (i = 0; ports[i]; i++)
955  if (sp_get_port_transport(ports[i]) == SP_TRANSPORT_USB &&
956  sp_get_port_usb_vid_pid(ports[i], &vid, &pid) == SP_OK &&
957  vid == vendor_id && pid == product_id) {
958  tty_devs = g_slist_prepend(tty_devs,
959  g_strdup(sp_get_port_name(ports[i])));
960  }
961 
962  sp_free_port_list(ports);
963 
964  return tty_devs;
965 }
966 
967 /** @private */
968 SR_PRIV int serial_timeout(struct sr_serial_dev_inst *port, int num_bytes)
969 {
970  struct sp_port_config *config;
971  int timeout_ms, bits, baud, tmp;
972 
973  /* Default to 1s. */
974  timeout_ms = 1000;
975 
976  if (sp_new_config(&config) < 0)
977  return timeout_ms;
978 
979  bits = baud = 0;
980  do {
981  if (sp_get_config(port->data, config) < 0)
982  break;
983 
984  /* Start bit. */
985  bits = 1;
986  if (sp_get_config_bits(config, &tmp) < 0)
987  break;
988  bits += tmp;
989  if (sp_get_config_stopbits(config, &tmp) < 0)
990  break;
991  bits += tmp;
992  if (sp_get_config_baudrate(config, &tmp) < 0)
993  break;
994  baud = tmp;
995  } while (FALSE);
996 
997  if (bits && baud) {
998  /* Throw in 10ms for misc OS overhead. */
999  timeout_ms = 10;
1000  timeout_ms += ((1000.0 / baud) * bits) * num_bytes;
1001  }
1002 
1003  sp_free_config(config);
1004 
1005  return timeout_ms;
1006 }
1007 
1008 /** @} */
char * name
The OS dependent name of the serial port.
Definition: libsigrok.h:1162
Serial port descriptor.
Definition: libsigrok.h:1160
GSList * sr_serial_list(const struct sr_dev_driver *driver)
List available serial devices.
Definition: serial.c:909
The public libsigrok header file to be used by frontends.
Device driver data.
Definition: libsigrok.h:1090
void sr_serial_free(struct sr_serial_port *serial)
Free a previously allocated sr_serial_port structure.
Definition: serial.c:893
Generic/unspecified error.
Definition: libsigrok.h:68
Opaque structure representing a libsigrok session.
Definition: libsigrok.h:454
char * description
An end user friendly description for the serial port.
Definition: libsigrok.h:1164
#define SR_API
Definition: libsigrok.h:121
No error.
Definition: libsigrok.h:67
SR_PRIV int sr_session_fd_source_add(struct sr_session *session, void *key, gintptr fd, int events, int timeout, sr_receive_data_callback cb, void *cb_data)
Definition: session.c:1233
GVariant * data
Key-specific data.
Definition: libsigrok.h:632
Specification on how to connect to a device.
Definition: libsigrok.h:722
int(* sr_receive_data_callback)(int fd, int revents, void *cb_data)
Type definition for callback function for data reception.
Definition: libsigrok.h:134
Serial communication specification, in the form:
Definition: libsigrok.h:743
uint32_t key
Config key like SR_CONF_CONN, etc.
Definition: libsigrok.h:630
#define SR_PRIV
Definition: libsigrok.h:128
Function argument error.
Definition: libsigrok.h:70
Used for setting or getting value of a config item.
Definition: libsigrok.h:628