]> sigrok.org Git - libsigrok.git/blob - src/serial.c
Add a timeout parameter to blocking serial calls.
[libsigrok.git] / src / serial.c
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  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <string.h>
23 #include <stdlib.h>
24 #include <glib.h>
25 #include <glib/gstdio.h>
26 #include <libserialport.h>
27 #include "libsigrok.h"
28 #include "libsigrok-internal.h"
29
30 #define LOG_PREFIX "serial"
31
32 /**
33  * Open the specified serial port.
34  *
35  * @param serial Previously initialized serial port structure.
36  * @param[in] flags Flags to use when opening the serial port. Possible flags
37  *              include SERIAL_RDWR, SERIAL_RDONLY.
38  *
39  * If the serial structure contains a serialcomm string, it will be
40  * passed to serial_set_paramstr() after the port is opened.
41  *
42  * @retval SR_OK Success.
43  * @retval SR_ERR Failure.
44  */
45 SR_PRIV int serial_open(struct sr_serial_dev_inst *serial, int flags)
46 {
47         int ret;
48         char *error;
49         int sp_flags = 0;
50
51         if (!serial) {
52                 sr_dbg("Invalid serial port.");
53                 return SR_ERR;
54         }
55
56         sr_spew("Opening serial port '%s' (flags %d).", serial->port, flags);
57
58         sp_get_port_by_name(serial->port, &serial->data);
59
60         if (flags & SERIAL_RDWR)
61                 sp_flags = (SP_MODE_READ | SP_MODE_WRITE);
62         else if (flags & SERIAL_RDONLY)
63                 sp_flags = SP_MODE_READ;
64
65         ret = sp_open(serial->data, sp_flags);
66
67         switch (ret) {
68         case SP_ERR_ARG:
69                 sr_err("Attempt to open serial port with invalid parameters.");
70                 return SR_ERR_ARG;
71         case SP_ERR_FAIL:
72                 error = sp_last_error_message();
73                 sr_err("Error opening port (%d): %s.",
74                         sp_last_error_code(), error);
75                 sp_free_error_message(error);
76                 return SR_ERR;
77         }
78
79         if (serial->serialcomm)
80                 return serial_set_paramstr(serial, serial->serialcomm);
81         else
82                 return SR_OK;
83 }
84
85 /**
86  * Close the specified serial port.
87  *
88  * @param serial Previously initialized serial port structure.
89  *
90  * @retval SR_OK Success.
91  * @retval SR_ERR Failure.
92  */
93 SR_PRIV int serial_close(struct sr_serial_dev_inst *serial)
94 {
95         int ret;
96         char *error;
97
98         if (!serial) {
99                 sr_dbg("Invalid serial port.");
100                 return SR_ERR;
101         }
102
103         if (!serial->data) {
104                 sr_dbg("Cannot close unopened serial port %s.", serial->port);
105                 return SR_ERR;
106         }
107
108         sr_spew("Closing serial port %s.", serial->port);
109
110         ret = sp_close(serial->data);
111
112         switch (ret) {
113         case SP_ERR_ARG:
114                 sr_err("Attempt to close an invalid serial port.");
115                 return SR_ERR_ARG;
116         case SP_ERR_FAIL:
117                 error = sp_last_error_message();
118                 sr_err("Error closing port (%d): %s.",
119                         sp_last_error_code(), error);
120                 sp_free_error_message(error);
121                 return SR_ERR;
122         }
123
124         sp_free_port(serial->data);
125         serial->data = NULL;
126
127         return SR_OK;
128 }
129
130 /**
131  * Flush serial port buffers.
132  *
133  * @param serial Previously initialized serial port structure.
134  *
135  * @retval SR_OK Success.
136  * @retval SR_ERR Failure.
137  */
138 SR_PRIV int serial_flush(struct sr_serial_dev_inst *serial)
139 {
140         int ret;
141         char *error;
142
143         if (!serial) {
144                 sr_dbg("Invalid serial port.");
145                 return SR_ERR;
146         }
147
148         if (!serial->data) {
149                 sr_dbg("Cannot flush unopened serial port %s.", serial->port);
150                 return SR_ERR;
151         }
152
153         sr_spew("Flushing serial port %s.", serial->port);
154
155         ret = sp_flush(serial->data, SP_BUF_BOTH);
156
157         switch (ret) {
158         case SP_ERR_ARG:
159                 sr_err("Attempt to flush an invalid serial port.");
160                 return SR_ERR_ARG;
161         case SP_ERR_FAIL:
162                 error = sp_last_error_message();
163                 sr_err("Error flushing port (%d): %s.",
164                         sp_last_error_code(), error);
165                 sp_free_error_message(error);
166                 return SR_ERR;
167         }
168
169         return SR_OK;
170 }
171
172 static int _serial_write(struct sr_serial_dev_inst *serial,
173                 const void *buf, size_t count, int nonblocking, unsigned int timeout_ms)
174 {
175         ssize_t ret;
176         char *error;
177
178         if (!serial) {
179                 sr_dbg("Invalid serial port.");
180                 return SR_ERR;
181         }
182
183         if (!serial->data) {
184                 sr_dbg("Cannot use unopened serial port %s.", serial->port);
185                 return SR_ERR;
186         }
187
188         if (nonblocking)
189                 ret = sp_nonblocking_write(serial->data, buf, count);
190         else
191                 ret = sp_blocking_write(serial->data, buf, count, timeout_ms);
192
193         switch (ret) {
194         case SP_ERR_ARG:
195                 sr_err("Attempted serial port write with invalid arguments.");
196                 return SR_ERR_ARG;
197         case SP_ERR_FAIL:
198                 error = sp_last_error_message();
199                 sr_err("Write error (%d): %s.", sp_last_error_code(), error);
200                 sp_free_error_message(error);
201                 return SR_ERR;
202         }
203
204         sr_spew("Wrote %d/%d bytes.", ret, count);
205
206         return ret;
207 }
208
209 /**
210  * Write a number of bytes to the specified serial port, blocking until finished.
211  *
212  * @param serial Previously initialized serial port structure.
213  * @param[in] buf Buffer containing the bytes to write.
214  * @param[in] count Number of bytes to write.
215  * @param[in] timeout_ms Timeout in ms, or 0 for no timeout.
216  *
217  * @retval SR_ERR_ARG Invalid argument.
218  * @retval SR_ERR Other error.
219  * @retval other The number of bytes written. If this is less than the number
220  * specified in the call, the timeout was reached.
221  */
222 SR_PRIV int serial_write_blocking(struct sr_serial_dev_inst *serial,
223                 const void *buf, size_t count, unsigned int timeout_ms)
224 {
225         return _serial_write(serial, buf, count, 0, timeout_ms);
226 }
227
228 /**
229  * Write a number of bytes to the specified serial port, return immediately.
230  *
231  * @param serial Previously initialized serial port structure.
232  * @param[in] buf Buffer containing the bytes to write.
233  * @param[in] count Number of bytes to write.
234  *
235  * @retval SR_ERR_ARG Invalid argument.
236  * @retval SR_ERR Other error.
237  * @retval other The number of bytes written.
238 */
239 SR_PRIV int serial_write_nonblocking(struct sr_serial_dev_inst *serial,
240                 const void *buf, size_t count)
241 {
242         return _serial_write(serial, buf, count, 1, 0);
243 }
244
245 static int _serial_read(struct sr_serial_dev_inst *serial, void *buf,
246                 size_t count, int nonblocking, unsigned int timeout_ms)
247 {
248         ssize_t ret;
249         char *error;
250
251         if (!serial) {
252                 sr_dbg("Invalid serial port.");
253                 return SR_ERR;
254         }
255
256         if (!serial->data) {
257                 sr_dbg("Cannot use unopened serial port %s.", serial->port);
258                 return SR_ERR;
259         }
260
261         if (nonblocking)
262                 ret = sp_nonblocking_read(serial->data, buf, count);
263         else
264                 ret = sp_blocking_read(serial->data, buf, count, timeout_ms);
265
266         switch (ret) {
267         case SP_ERR_ARG:
268                 sr_err("Attempted serial port read with invalid arguments.");
269                 return SR_ERR_ARG;
270         case SP_ERR_FAIL:
271                 error = sp_last_error_message();
272                 sr_err("Read error (%d): %s.", sp_last_error_code(), error);
273                 sp_free_error_message(error);
274                 return SR_ERR;
275         }
276
277         if (ret > 0)
278                 sr_spew("Read %d/%d bytes.", ret, count);
279
280         return ret;
281 }
282
283 /**
284  * Read a number of bytes from the specified serial port, block until finished.
285  *
286  * @param serial Previously initialized serial port structure.
287  * @param buf Buffer where to store the bytes that are read.
288  * @param[in] count The number of bytes to read.
289  * @param[in] timeout_ms Timeout in ms, or 0 for no timeout.
290  *
291  * @retval SR_ERR_ARG Invalid argument.
292  * @retval SR_ERR     Other error.
293  * @retval other      The number of bytes read. If this is less than the number
294  * requested, the timeout was reached.
295  */
296 SR_PRIV int serial_read_blocking(struct sr_serial_dev_inst *serial, void *buf,
297                 size_t count, unsigned int timeout_ms)
298 {
299         return _serial_read(serial, buf, count, 0, timeout_ms);
300 }
301
302 /**
303  * Try to read up to @a count bytes from the specified serial port, return
304  * immediately with what's available.
305  *
306  * @param serial Previously initialized serial port structure.
307  * @param buf Buffer where to store the bytes that are read.
308  * @param[in] count The number of bytes to read.
309  *
310  * @retval SR_ERR_ARG Invalid argument.
311  * @retval SR_ERR     Other error.
312  * @retval other      The number of bytes read.
313  */
314 SR_PRIV int serial_read_nonblocking(struct sr_serial_dev_inst *serial, void *buf,
315                 size_t count)
316 {
317         return _serial_read(serial, buf, count, 1, 0);
318 }
319
320 /**
321  * Set serial parameters for the specified serial port.
322  *
323  * @param serial Previously initialized serial port structure.
324  * @param[in] baudrate The baudrate to set.
325  * @param[in] bits The number of data bits to use (5, 6, 7 or 8).
326  * @param[in] parity The parity setting to use (0 = none, 1 = even, 2 = odd).
327  * @param[in] stopbits The number of stop bits to use (1 or 2).
328  * @param[in] flowcontrol The flow control settings to use (0 = none,
329  *                      1 = RTS/CTS, 2 = XON/XOFF).
330  * @param[in] rts Status of RTS line (0 or 1; required by some interfaces).
331  * @param[in] dtr Status of DTR line (0 or 1; required by some interfaces).
332  *
333  * @retval SR_OK Success.
334  * @retval SR_ERR Failure.
335  */
336 SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial, int baudrate,
337                               int bits, int parity, int stopbits,
338                               int flowcontrol, int rts, int dtr)
339 {
340         int ret;
341         char *error;
342         struct sp_port_config *config;
343
344         if (!serial) {
345                 sr_dbg("Invalid serial port.");
346                 return SR_ERR;
347         }
348
349         if (!serial->data) {
350                 sr_dbg("Cannot configure unopened serial port %s.", serial->port);
351                 return SR_ERR;
352         }
353
354         sr_spew("Setting serial parameters on port %s.", serial->port);
355
356         sp_new_config(&config);
357         sp_set_config_baudrate(config, baudrate);
358         sp_set_config_bits(config, bits);
359         switch (parity) {
360         case 0:
361                 sp_set_config_parity(config, SP_PARITY_NONE);
362                 break;
363         case 1:
364                 sp_set_config_parity(config, SP_PARITY_EVEN);
365                 break;
366         case 2:
367                 sp_set_config_parity(config, SP_PARITY_ODD);
368                 break;
369         default:
370                 return SR_ERR_ARG;
371         }
372         sp_set_config_stopbits(config, stopbits);
373         sp_set_config_rts(config, flowcontrol == 1 ? SP_RTS_FLOW_CONTROL : rts);
374         sp_set_config_cts(config, flowcontrol == 1 ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE);
375         sp_set_config_dtr(config, dtr);
376         sp_set_config_dsr(config, SP_DSR_IGNORE);
377         sp_set_config_xon_xoff(config, flowcontrol == 2 ? SP_XONXOFF_INOUT : SP_XONXOFF_DISABLED);
378
379         ret = sp_set_config(serial->data, config);
380         sp_free_config(config);
381
382         switch (ret) {
383         case SP_ERR_ARG:
384                 sr_err("Invalid arguments for setting serial port parameters.");
385                 return SR_ERR_ARG;
386         case SP_ERR_FAIL:
387                 error = sp_last_error_message();
388                 sr_err("Error setting serial port parameters (%d): %s.",
389                         sp_last_error_code(), error);
390                 sp_free_error_message(error);
391                 return SR_ERR;
392         }
393
394         return SR_OK;
395 }
396
397 /**
398  * Set serial parameters for the specified serial port from parameter string.
399  *
400  * @param serial Previously initialized serial port structure.
401  * @param[in] paramstr A serial communication parameters string of the form
402  * "<baudrate>/<bits><parity><stopbits>{/<option>}".\n
403  *  Examples: "9600/8n1", "600/7o2/dtr=1/rts=0" or "460800/8n1/flow=2".\n
404  * \<baudrate\>=integer Baud rate.\n
405  * \<bits\>=5|6|7|8 Number of data bits.\n
406  * \<parity\>=n|e|o None, even, odd.\n
407  * \<stopbits\>=1|2 One or two stop bits.\n
408  * Options:\n
409  * dtr=0|1 Set DTR off resp. on.\n
410  * flow=0|1|2 Flow control. 0 for none, 1 for RTS/CTS, 2 for XON/XOFF.\n
411  * rts=0|1 Set RTS off resp. on.\n
412  * Please note that values and combinations of these parameters must be
413  * supported by the concrete serial interface hardware and the drivers for it.
414  * @retval SR_OK Success.
415  * @retval SR_ERR Failure.
416  */
417 SR_PRIV int serial_set_paramstr(struct sr_serial_dev_inst *serial,
418                 const char *paramstr)
419 {
420 #define SERIAL_COMM_SPEC "^(\\d+)/([5678])([neo])([12])(.*)$"
421
422         GRegex *reg;
423         GMatchInfo *match;
424         int speed, databits, parity, stopbits, flow, rts, dtr, i;
425         char *mstr, **opts, **kv;
426
427         speed = databits = parity = stopbits = flow = 0;
428         rts = dtr = -1;
429         sr_spew("Parsing parameters from \"%s\".", paramstr);
430         reg = g_regex_new(SERIAL_COMM_SPEC, 0, 0, NULL);
431         if (g_regex_match(reg, paramstr, 0, &match)) {
432                 if ((mstr = g_match_info_fetch(match, 1)))
433                         speed = strtoul(mstr, NULL, 10);
434                 g_free(mstr);
435                 if ((mstr = g_match_info_fetch(match, 2)))
436                         databits = strtoul(mstr, NULL, 10);
437                 g_free(mstr);
438                 if ((mstr = g_match_info_fetch(match, 3))) {
439                         switch (mstr[0]) {
440                         case 'n':
441                                 parity = SERIAL_PARITY_NONE;
442                                 break;
443                         case 'e':
444                                 parity = SERIAL_PARITY_EVEN;
445                                 break;
446                         case 'o':
447                                 parity = SERIAL_PARITY_ODD;
448                                 break;
449                         }
450                 }
451                 g_free(mstr);
452                 if ((mstr = g_match_info_fetch(match, 4)))
453                         stopbits = strtoul(mstr, NULL, 10);
454                 g_free(mstr);
455                 if ((mstr = g_match_info_fetch(match, 5)) && mstr[0] != '\0') {
456                         if (mstr[0] != '/') {
457                                 sr_dbg("missing separator before extra options");
458                                 speed = 0;
459                         } else {
460                                 /* A set of "key=value" options separated by / */
461                                 opts = g_strsplit(mstr + 1, "/", 0);
462                                 for (i = 0; opts[i]; i++) {
463                                         kv = g_strsplit(opts[i], "=", 2);
464                                         if (!strncmp(kv[0], "rts", 3)) {
465                                                 if (kv[1][0] == '1')
466                                                         rts = 1;
467                                                 else if (kv[1][0] == '0')
468                                                         rts = 0;
469                                                 else {
470                                                         sr_dbg("invalid value for rts: %c", kv[1][0]);
471                                                         speed = 0;
472                                                 }
473                                         } else if (!strncmp(kv[0], "dtr", 3)) {
474                                                 if (kv[1][0] == '1')
475                                                         dtr = 1;
476                                                 else if (kv[1][0] == '0')
477                                                         dtr = 0;
478                                                 else {
479                                                         sr_dbg("invalid value for dtr: %c", kv[1][0]);
480                                                         speed = 0;
481                                                 }
482                                         } else if (!strncmp(kv[0], "flow", 4)) {
483                                                 if (kv[1][0] == '0')
484                                                         flow = 0;
485                                                 else if (kv[1][0] == '1')
486                                                         flow = 1;
487                                                 else if (kv[1][0] == '2')
488                                                         flow = 2;
489                                                 else {
490                                                         sr_dbg("invalid value for flow: %c", kv[1][0]);
491                                                         speed = 0;
492                                                 }
493                                         }
494                                         g_strfreev(kv);
495                                 }
496                                 g_strfreev(opts);
497                         }
498                 }
499                 g_free(mstr);
500         }
501         g_match_info_unref(match);
502         g_regex_unref(reg);
503
504         if (speed) {
505                 return serial_set_params(serial, speed, databits, parity,
506                                          stopbits, flow, rts, dtr);
507         } else {
508                 sr_dbg("Could not infer speed from parameter string.");
509                 return SR_ERR_ARG;
510         }
511 }
512
513 /**
514  * Read a line from the specified serial port.
515  *
516  * @param serial Previously initialized serial port structure.
517  * @param buf Buffer where to store the bytes that are read.
518  * @param buflen Size of the buffer.
519  * @param[in] timeout_ms How long to wait for a line to come in.
520  *
521  * Reading stops when CR of LR is found, which is stripped from the buffer.
522  *
523  * @retval SR_OK Success.
524  * @retval SR_ERR Failure.
525  */
526 SR_PRIV int serial_readline(struct sr_serial_dev_inst *serial, char **buf,
527                 int *buflen, gint64 timeout_ms)
528 {
529         gint64 start, remaining;
530         int maxlen, len;
531
532         if (!serial) {
533                 sr_dbg("Invalid serial port.");
534                 return SR_ERR;
535         }
536
537         if (!serial->data) {
538                 sr_dbg("Cannot use unopened serial port %s.", serial->port);
539                 return -1;
540         }
541
542         start = g_get_monotonic_time();
543         remaining = timeout_ms;
544
545         maxlen = *buflen;
546         *buflen = len = 0;
547         while(1) {
548                 len = maxlen - *buflen - 1;
549                 if (len < 1)
550                         break;
551                 len = sp_blocking_read(serial->data, *buf + *buflen, 1, remaining);
552                 if (len > 0) {
553                         *buflen += len;
554                         *(*buf + *buflen) = '\0';
555                         if (*buflen > 0 && (*(*buf + *buflen - 1) == '\r'
556                                         || *(*buf + *buflen - 1) == '\n')) {
557                                 /* Strip CR/LF and terminate. */
558                                 *(*buf + --*buflen) = '\0';
559                                 break;
560                         }
561                 }
562                 /* Reduce timeout by time elapsed. */
563                 remaining = timeout_ms - ((g_get_monotonic_time() - start) / 1000);
564                 if (remaining <= 0)
565                         /* Timeout */
566                         break;
567                 if (len < 1)
568                         g_usleep(2000);
569         }
570         if (*buflen)
571                 sr_dbg("Received %d: '%s'.", *buflen, *buf);
572
573         return SR_OK;
574 }
575
576 /**
577  * Try to find a valid packet in a serial data stream.
578  *
579  * @param serial Previously initialized serial port structure.
580  * @param buf Buffer containing the bytes to write.
581  * @param buflen Size of the buffer.
582  * @param[in] packet_size Size, in bytes, of a valid packet.
583  * @param is_valid Callback that assesses whether the packet is valid or not.
584  * @param[in] timeout_ms The timeout after which, if no packet is detected, to
585  *                   abort scanning.
586  * @param[in] baudrate The baudrate of the serial port. This parameter is not
587  *                 critical, but it helps fine tune the serial port polling
588  *                 delay.
589  *
590  * @retval SR_OK Valid packet was found within the given timeout.
591  * @retval SR_ERR Failure.
592  */
593 SR_PRIV int serial_stream_detect(struct sr_serial_dev_inst *serial,
594                                  uint8_t *buf, size_t *buflen,
595                                  size_t packet_size,
596                                  packet_valid_callback is_valid,
597                                  uint64_t timeout_ms, int baudrate)
598 {
599         uint64_t start, time, byte_delay_us;
600         size_t ibuf, i, maxlen;
601         int len;
602
603         maxlen = *buflen;
604
605         sr_dbg("Detecting packets on %s (timeout = %" PRIu64
606                "ms, baudrate = %d).", serial->port, timeout_ms, baudrate);
607
608         if (maxlen < (packet_size / 2) ) {
609                 sr_err("Buffer size must be at least twice the packet size.");
610                 return SR_ERR;
611         }
612
613         /* Assume 8n1 transmission. That is 10 bits for every byte. */
614         byte_delay_us = 10 * (1000000 / baudrate);
615         start = g_get_monotonic_time();
616
617         i = ibuf = len = 0;
618         while (ibuf < maxlen) {
619                 len = serial_read_nonblocking(serial, &buf[ibuf], 1);
620                 if (len > 0) {
621                         ibuf += len;
622                 } else if (len == 0) {
623                         /* No logging, already done in serial_read(). */
624                 } else {
625                         /* Error reading byte, but continuing anyway. */
626                 }
627
628                 time = g_get_monotonic_time() - start;
629                 time /= 1000;
630
631                 if ((ibuf - i) >= packet_size) {
632                         /* We have at least a packet's worth of data. */
633                         if (is_valid(&buf[i])) {
634                                 sr_spew("Found valid %d-byte packet after "
635                                         "%" PRIu64 "ms.", (ibuf - i), time);
636                                 *buflen = ibuf;
637                                 return SR_OK;
638                         } else {
639                                 sr_spew("Got %d bytes, but not a valid "
640                                         "packet.", (ibuf - i));
641                         }
642                         /* Not a valid packet. Continue searching. */
643                         i++;
644                 }
645                 if (time >= timeout_ms) {
646                         /* Timeout */
647                         sr_dbg("Detection timed out after %dms.", time);
648                         break;
649                 }
650                 if (len < 1)
651                         g_usleep(byte_delay_us);
652         }
653
654         *buflen = ibuf;
655
656         sr_err("Didn't find a valid packet (read %d bytes).", *buflen);
657
658         return SR_ERR;
659 }
660
661 /**
662  * Extract the serial device and options from the options linked list.
663  *
664  * @param options List of options passed from the command line.
665  * @param serial_device Pointer where to store the exctracted serial device.
666  * @param serial_options Pointer where to store the optional extracted serial
667  * options.
668  *
669  * @return SR_OK if a serial_device is found, SR_ERR if no device is found. The
670  * returned string should not be freed by the caller.
671  */
672 SR_PRIV int sr_serial_extract_options(GSList *options, const char **serial_device,
673                                       const char **serial_options)
674 {
675         GSList *l;
676         struct sr_config *src;
677
678         *serial_device = NULL;
679
680         for (l = options; l; l = l->next) {
681                 src = l->data;
682                 switch (src->key) {
683                 case SR_CONF_CONN:
684                         *serial_device = g_variant_get_string(src->data, NULL);
685                         sr_dbg("Parsed serial device: %s", *serial_device);
686                         break;
687
688                 case SR_CONF_SERIALCOMM:
689                         *serial_options = g_variant_get_string(src->data, NULL);
690                         sr_dbg("Parsed serial options: %s", *serial_options);
691                         break;
692                 }
693         }
694
695         if (!*serial_device) {
696                 sr_dbg("No serial device specified");
697                 return SR_ERR;
698         }
699
700         return SR_OK;
701 }
702
703 #ifdef _WIN32
704 typedef HANDLE event_handle;
705 #else
706 typedef int event_handle;
707 #endif
708
709 SR_PRIV int serial_source_add(struct sr_session *session,
710                 struct sr_serial_dev_inst *serial, int events, int timeout,
711                 sr_receive_data_callback cb, void *cb_data)
712 {
713         enum sp_event mask = 0;
714         unsigned int i;
715
716         if (sp_new_event_set(&serial->event_set) != SP_OK)
717                 return SR_ERR;
718
719         if (events & G_IO_IN)
720                 mask |= SP_EVENT_RX_READY;
721         if (events & G_IO_OUT)
722                 mask |= SP_EVENT_TX_READY;
723         if (events & G_IO_ERR)
724                 mask |= SP_EVENT_ERROR;
725
726         if (sp_add_port_events(serial->event_set, serial->data, mask) != SP_OK) {
727                 sp_free_event_set(serial->event_set);
728                 return SR_ERR;
729         }
730
731         serial->pollfds = (GPollFD *) g_malloc0(sizeof(GPollFD) * serial->event_set->count);
732
733         for (i = 0; i < serial->event_set->count; i++) {
734
735                 serial->pollfds[i].fd = ((event_handle *) serial->event_set->handles)[i];
736
737                 mask = serial->event_set->masks[i];
738
739                 if (mask & SP_EVENT_RX_READY)
740                         serial->pollfds[i].events |= G_IO_IN;
741                 if (mask & SP_EVENT_TX_READY)
742                         serial->pollfds[i].events |= G_IO_OUT;
743                 if (mask & SP_EVENT_ERROR)
744                         serial->pollfds[i].events |= G_IO_ERR;
745
746                 if (sr_session_source_add_pollfd(session, &serial->pollfds[i],
747                                         timeout, cb, cb_data) != SR_OK)
748                         return SR_ERR;
749         }
750
751         return SR_OK;
752 }
753
754 SR_PRIV int serial_source_remove(struct sr_session *session,
755                 struct sr_serial_dev_inst *serial)
756 {
757         unsigned int i;
758
759         for (i = 0; i < serial->event_set->count; i++)
760                 if (sr_session_source_remove_pollfd(session, &serial->pollfds[i]) != SR_OK)
761                         return SR_ERR;
762
763         g_free(serial->pollfds);
764         sp_free_event_set(serial->event_set);
765
766         serial->pollfds = NULL;
767         serial->event_set = NULL;
768
769         return SR_OK;
770 }
771
772 /**
773  * Find USB serial devices via the USB vendor ID and product ID.
774  *
775  * @param[in] vendor_id Vendor ID of the USB device.
776  * @param[in] product_id Product ID of the USB device.
777  *
778  * @return A GSList of strings containing the path of the serial device or
779  *         NULL if no serial device is found. The returned list must be freed
780  *         by the caller.
781  */
782 SR_PRIV GSList *sr_serial_find_usb(uint16_t vendor_id, uint16_t product_id)
783 {
784         GSList *tty_devs = NULL;
785         struct sp_port **ports;
786         int i, vid, pid;
787
788         if (sp_list_ports(&ports) != SP_OK)
789                 return NULL;
790
791         for (i=0; ports[i]; i++)
792                 if (sp_get_port_transport(ports[i]) == SP_TRANSPORT_USB &&
793                     sp_get_port_usb_vid_pid(ports[i], &vid, &pid) == SP_OK &&
794                     vid == vendor_id && pid == product_id)
795                         tty_devs = g_slist_prepend(tty_devs,
796                                                    g_strdup(sp_get_port_name(ports[i])));
797
798         sp_free_port_list(ports);
799         return tty_devs;
800 }