]> sigrok.org Git - libsigrok.git/blob - hardware/common/serial.c
serial: Only sleep when no characters are received.
[libsigrok.git] / hardware / common / 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 <sys/types.h>
24 #include <sys/stat.h>
25 #include <fcntl.h>
26 #include <unistd.h>
27 #ifdef _WIN32
28 #include <windows.h>
29 #else
30 #include <termios.h>
31 #include <sys/ioctl.h>
32 #endif
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <glib.h>
36 #include "libsigrok.h"
37 #include "libsigrok-internal.h"
38
39 /* Message logging helpers with subsystem-specific prefix string. */
40 #define LOG_PREFIX "serial: "
41 #define sr_log(l, s, args...) sr_log(l, LOG_PREFIX s, ## args)
42 #define sr_spew(s, args...) sr_spew(LOG_PREFIX s, ## args)
43 #define sr_dbg(s, args...) sr_dbg(LOG_PREFIX s, ## args)
44 #define sr_info(s, args...) sr_info(LOG_PREFIX s, ## args)
45 #define sr_warn(s, args...) sr_warn(LOG_PREFIX s, ## args)
46 #define sr_err(s, args...) sr_err(LOG_PREFIX s, ## args)
47
48 // FIXME: Must be moved, or rather passed as function argument.
49 #ifdef _WIN32
50 static HANDLE hdl;
51 #endif
52
53 /**
54  * Open the specified serial port.
55  *
56  * @param serial Previously initialized serial port structure.
57  * @param flags Flags to use when opening the serial port. Possible flags
58  *              include SERIAL_RDWR, SERIAL_RDONLY, SERIAL_NONBLOCK.
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  * @return SR_OK on success, SR_ERR on failure.
64  */
65 SR_PRIV int serial_open(struct sr_serial_dev_inst *serial, int flags)
66 {
67         int flags_local = 0;
68 #ifdef _WIN32
69         DWORD desired_access = 0, flags_and_attributes = 0;
70 #endif
71
72         if (!serial) {
73                 sr_dbg("Invalid serial port.");
74                 return SR_ERR;
75         }
76
77         sr_spew("Opening serial port '%s' (flags %d).", serial->port, flags);
78
79 #ifdef _WIN32
80         /* Map 'flags' to the OS-specific settings. */
81         desired_access |= GENERIC_READ;
82         flags_and_attributes = FILE_ATTRIBUTE_NORMAL;
83         if (flags & SERIAL_RDWR)
84                 desired_access |= GENERIC_WRITE;
85         if (flags & SERIAL_NONBLOCK)
86                 flags_and_attributes |= FILE_FLAG_OVERLAPPED;
87
88         hdl = CreateFile(serial->port, desired_access, 0, 0,
89                          OPEN_EXISTING, flags_and_attributes, 0);
90         if (hdl == INVALID_HANDLE_VALUE) {
91                 sr_err("Error opening serial port '%s'.", serial->port);
92                 return SR_ERR;
93         }
94 #else
95         /* Map 'flags' to the OS-specific settings. */
96         if (flags & SERIAL_RDWR)
97                 flags_local |= O_RDWR;
98         if (flags & SERIAL_RDONLY)
99                 flags_local |= O_RDONLY;
100         if (flags & SERIAL_NONBLOCK)
101                 flags_local |= O_NONBLOCK;
102
103         if ((serial->fd = open(serial->port, flags_local)) < 0) {
104                 sr_err("Error opening serial port '%s': %s.", serial->port,
105                        strerror(errno));
106                 return SR_ERR;
107         }
108
109         sr_spew("Opened serial port '%s' (fd %d).", serial->port, serial->fd);
110 #endif
111
112         if (serial->serialcomm)
113                 return serial_set_paramstr(serial, serial->serialcomm);
114         else
115                 return SR_OK;
116 }
117
118 /**
119  * Close the specified serial port.
120  *
121  * @param serial Previously initialized serial port structure.
122  *
123  * @return SR_OK on success, SR_ERR on failure.
124  */
125 SR_PRIV int serial_close(struct sr_serial_dev_inst *serial)
126 {
127         int ret;
128
129         if (!serial) {
130                 sr_dbg("Invalid serial port.");
131                 return SR_ERR;
132         }
133
134         if (serial->fd == -1) {
135                 sr_dbg("Cannot close unopened serial port %s (fd %d).",
136                                 serial->port, serial->fd);
137                 return SR_ERR;
138         }
139
140         sr_spew("Closing serial port %s (fd %d).", serial->port, serial->fd);
141         ret = SR_OK;
142
143 #ifdef _WIN32
144         /* Returns non-zero upon success, 0 upon failure. */
145         if (CloseHandle(hdl) == 0)
146                 ret = SR_ERR;
147 #else
148         /* Returns 0 upon success, -1 upon failure. */
149         if (close(serial->fd) < 0) {
150                 sr_err("Error closing serial port: %s (fd %d).", strerror(errno),
151                                 serial->fd);
152                 ret = SR_ERR;
153         }
154 #endif
155
156         serial->fd = -1;
157
158         return ret;
159 }
160
161 /**
162  * Flush serial port buffers.
163  *
164  * @param serial Previously initialized serial port structure.
165  *
166  * @return SR_OK on success, SR_ERR on failure.
167  */
168 SR_PRIV int serial_flush(struct sr_serial_dev_inst *serial)
169 {
170         int ret;
171
172         if (!serial) {
173                 sr_dbg("Invalid serial port.");
174                 return SR_ERR;
175         }
176
177         if (serial->fd == -1) {
178                 sr_dbg("Cannot flush unopened serial port %s (fd %d).",
179                                 serial->port, serial->fd);
180                 return SR_ERR;
181         }
182
183         sr_spew("Flushing serial port %s (fd %d).", serial->port, serial->fd);
184         ret = SR_OK;
185
186 #ifdef _WIN32
187         /* Returns non-zero upon success, 0 upon failure. */
188         if (PurgeComm(hdl, PURGE_RXCLEAR | PURGE_TXCLEAR) == 0) {
189                 sr_err("Error flushing serial port: %s.", strerror(errno));
190                 ret = SR_ERR;
191         }
192 #else
193         /* Returns 0 upon success, -1 upon failure. */
194         if (tcflush(serial->fd, TCIOFLUSH) < 0) {
195                 sr_err("Error flushing serial port: %s.", strerror(errno));
196                 ret = SR_ERR;
197         }
198
199         return ret;
200 #endif
201 }
202
203 /**
204  * Write a number of bytes to the specified serial port.
205  *
206  * @param serial Previously initialized serial port structure.
207  * @param buf Buffer containing the bytes to write.
208  * @param count Number of bytes to write.
209  *
210  * @return The number of bytes written, or -1 upon failure.
211  */
212 SR_PRIV int serial_write(struct sr_serial_dev_inst *serial,
213                 const void *buf, size_t count)
214 {
215         ssize_t ret;
216
217         if (!serial) {
218                 sr_dbg("Invalid serial port.");
219                 return -1;
220         }
221
222         if (serial->fd == -1) {
223                 sr_dbg("Cannot use unopened serial port %s (fd %d).",
224                                 serial->port, serial->fd);
225                 return -1;
226         }
227
228 #ifdef _WIN32
229         DWORD tmp = 0;
230
231         /* FIXME */
232         /* Returns non-zero upon success, 0 upon failure. */
233         WriteFile(hdl, buf, count, &tmp, NULL);
234 #else
235         /* Returns the number of bytes written, or -1 upon failure. */
236         ret = write(serial->fd, buf, count);
237         if (ret < 0)
238                 sr_err("Write error: %s.", strerror(errno));
239         else
240                 sr_spew("Wrote %d/%d bytes (fd %d).", ret, count, serial->fd);
241 #endif
242
243         return ret;
244 }
245
246 /**
247  * Read a number of bytes from the specified serial port.
248  *
249  * @param serial Previously initialized serial port structure.
250  * @param buf Buffer where to store the bytes that are read.
251  * @param count The number of bytes to read.
252  *
253  * @return The number of bytes read, or -1 upon failure.
254  */
255 SR_PRIV int serial_read(struct sr_serial_dev_inst *serial, void *buf,
256                 size_t count)
257 {
258         ssize_t ret;
259
260         if (!serial) {
261                 sr_dbg("Invalid serial port.");
262                 return -1;
263         }
264
265         if (serial->fd == -1) {
266                 sr_dbg("Cannot use unopened serial port %s (fd %d).",
267                                 serial->port, serial->fd);
268                 return -1;
269         }
270
271 #ifdef _WIN32
272         DWORD tmp = 0;
273
274         /* FIXME */
275         /* Returns non-zero upon success, 0 upon failure. */
276         return ReadFile(hdl, buf, count, &tmp, NULL);
277 #else
278         /* Returns the number of bytes read, or -1 upon failure. */
279         ret = read(serial->fd, buf, count);
280 #endif
281
282         return ret;
283 }
284
285 /**
286  * Set serial parameters for the specified serial port.
287  *
288  * @param serial Previously initialized serial port structure.
289  * @param baudrate The baudrate to set.
290  * @param bits The number of data bits to use.
291  * @param parity The parity setting to use (0 = none, 1 = even, 2 = odd).
292  * @param stopbits The number of stop bits to use (1 or 2).
293  * @param flowcontrol The flow control settings to use (0 = none, 1 = RTS/CTS,
294  *                    2 = XON/XOFF).
295  *
296  * @return SR_OK upon success, SR_ERR upon failure.
297  */
298 SR_PRIV int serial_set_params(struct sr_serial_dev_inst *serial, int baudrate,
299                               int bits, int parity, int stopbits,
300                               int flowcontrol, int rts, int dtr)
301 {
302         if (!serial) {
303                 sr_dbg("Invalid serial port.");
304                 return SR_ERR;
305         }
306
307         if (serial->fd == -1) {
308                 sr_dbg("Cannot configure unopened serial port %s (fd %d).",
309                        serial->port, serial->fd);
310                 return SR_ERR;
311         }
312
313         sr_spew("Setting serial parameters on port %s (fd %d).", serial->port,
314                 serial->fd);
315
316 #ifdef _WIN32
317         DCB dcb;
318
319         if (!GetCommState(hdl, &dcb)) {
320                 sr_err("Failed to get comm state on port %s (fd %d): %d.",
321                        serial->port, serial->fd, GetLastError());
322                 return SR_ERR;
323         }
324
325         switch (baudrate) {
326         /*
327          * The baudrates 50/75/134/150/200/1800/230400/460800 do not seem to
328          * have documented CBR_* macros.
329          */
330         case 110:
331                 dcb.BaudRate = CBR_110;
332                 break;
333         case 300:
334                 dcb.BaudRate = CBR_300;
335                 break;
336         case 600:
337                 dcb.BaudRate = CBR_600;
338                 break;
339         case 1200:
340                 dcb.BaudRate = CBR_1200;
341                 break;
342         case 2400:
343                 dcb.BaudRate = CBR_2400;
344                 break;
345         case 4800:
346                 dcb.BaudRate = CBR_4800;
347                 break;
348         case 9600:
349                 dcb.BaudRate = CBR_9600;
350                 break;
351         case 14400:
352                 dcb.BaudRate = CBR_14400; /* Not available on Unix? */
353                 break;
354         case 19200:
355                 dcb.BaudRate = CBR_19200;
356                 break;
357         case 38400:
358                 dcb.BaudRate = CBR_38400;
359                 break;
360         case 57600:
361                 dcb.BaudRate = CBR_57600;
362                 break;
363         case 115200:
364                 dcb.BaudRate = CBR_115200;
365                 break;
366         case 128000:
367                 dcb.BaudRate = CBR_128000; /* Not available on Unix? */
368                 break;
369         case 256000:
370                 dcb.BaudRate = CBR_256000; /* Not available on Unix? */
371                 break;
372         default:
373                 sr_err("Unsupported baudrate: %d.", baudrate);
374                 return SR_ERR;
375         }
376         sr_spew("Configuring baudrate to %d (%d).", baudrate, dcb.BaudRate);
377
378         sr_spew("Configuring %d data bits.", bits);
379         dcb.ByteSize = bits;
380
381         sr_spew("Configuring %d stop bits.", stopbits);
382         switch (stopbits) {
383         /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
384         case 1:
385                 dcb.StopBits = ONESTOPBIT;
386                 break;
387         case 2:
388                 dcb.StopBits = TWOSTOPBITS;
389                 break;
390         default:
391                 sr_err("Unsupported stopbits number: %d.", stopbits);
392                 return SR_ERR;
393         }
394
395         switch (parity) {
396         /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
397         case SERIAL_PARITY_NONE:
398                 sr_spew("Configuring no parity.");
399                 dcb.Parity = NOPARITY;
400                 break;
401         case SERIAL_PARITY_EVEN:
402                 sr_spew("Configuring even parity.");
403                 dcb.Parity = EVENPARITY;
404                 break;
405         case SERIAL_PARITY_ODD:
406                 sr_spew("Configuring odd parity.");
407                 dcb.Parity = ODDPARITY;
408                 break;
409         default:
410                 sr_err("Unsupported parity setting: %d.", parity);
411                 return SR_ERR;
412         }
413
414         if (rts != -1) {
415                 sr_spew("Setting RTS %s.", rts ? "high" : "low");
416                 if (rts)
417                         dcb.fRtsControl = RTS_CONTROL_ENABLE;
418                 else
419                         dcb.fRtsControl = RTS_CONTROL_DISABLE;
420         }
421
422         if (dtr != -1) {
423                 sr_spew("Setting DTR %s.", dtr ? "high" : "low");
424                 if (dtr)
425                         dcb.fDtrControl = DTR_CONTROL_ENABLE;
426                 else
427                         dcb.fDtrControl = DTR_CONTROL_DISABLE;
428         }
429
430         if (!SetCommState(hdl, &dcb)) {
431                 sr_err("Failed to set comm state on port %s (fd %d): %d.",
432                        serial->port, serial->fd, GetLastError());
433                 return SR_ERR;
434         }
435 #else
436         struct termios term;
437         speed_t baud;
438         int ret, controlbits;
439
440         if (tcgetattr(serial->fd, &term) < 0) {
441                 sr_err("tcgetattr() error on port %s (fd %d): %s.",
442                                 serial->port, serial->fd, strerror(errno));
443                 return SR_ERR;
444         }
445
446         switch (baudrate) {
447         case 50:
448                 baud = B50;
449                 break;
450         case 75:
451                 baud = B75;
452                 break;
453         case 110:
454                 baud = B110;
455                 break;
456         case 134:
457                 baud = B134;
458                 break;
459         case 150:
460                 baud = B150;
461                 break;
462         case 200:
463                 baud = B200;
464                 break;
465         case 300:
466                 baud = B300;
467                 break;
468         case 600:
469                 baud = B600;
470                 break;
471         case 1200:
472                 baud = B1200;
473                 break;
474         case 1800:
475                 baud = B1800;
476                 break;
477         case 2400:
478                 baud = B2400;
479                 break;
480         case 4800:
481                 baud = B4800;
482                 break;
483         case 9600:
484                 baud = B9600;
485                 break;
486         case 19200:
487                 baud = B19200;
488                 break;
489         case 38400:
490                 baud = B38400;
491                 break;
492         case 57600:
493                 baud = B57600;
494                 break;
495         case 115200:
496                 baud = B115200;
497                 break;
498         case 230400:
499                 baud = B230400;
500                 break;
501 #if !defined(__APPLE__) && !defined(__OpenBSD__)
502         case 460800:
503                 baud = B460800;
504                 break;
505 #endif
506         default:
507                 sr_err("Unsupported baudrate: %d.", baudrate);
508                 return SR_ERR;
509         }
510
511         sr_spew("Configuring output baudrate to %d (%d).", baudrate, baud);
512         if (cfsetospeed(&term, baud) < 0) {
513                 sr_err("cfsetospeed() error: %s.", strerror(errno));
514                 return SR_ERR;
515         }
516
517         sr_spew("Configuring input baudrate to %d (%d).", baudrate, baud);
518         if (cfsetispeed(&term, baud) < 0) {
519                 sr_err("cfsetispeed() error: %s.", strerror(errno));
520                 return SR_ERR;
521         }
522
523         sr_spew("Configuring %d data bits.", bits);
524         term.c_cflag &= ~CSIZE;
525         switch (bits) {
526         case 8:
527                 term.c_cflag |= CS8;
528                 break;
529         case 7:
530                 term.c_cflag |= CS7;
531                 break;
532         default:
533                 sr_err("Unsupported data bits number %d.", bits);
534                 return SR_ERR;
535         }
536
537         sr_spew("Configuring %d stop bits.", stopbits);
538         term.c_cflag &= ~CSTOPB;
539         switch (stopbits) {
540         case 1:
541                 term.c_cflag &= ~CSTOPB;
542                 break;
543         case 2:
544                 term.c_cflag |= CSTOPB;
545                 break;
546         default:
547                 sr_err("Unsupported stopbits number %d.", stopbits);
548                 return SR_ERR;
549         }
550
551         term.c_iflag &= ~(IXON | IXOFF);
552         term.c_cflag &= ~CRTSCTS;
553         switch (flowcontrol) {
554         case 0:
555                 /* No flow control. */
556                 sr_spew("Configuring no flow control.");
557                 break;
558         case 1:
559                 sr_spew("Configuring RTS/CTS flow control.");
560                 term.c_cflag |= CRTSCTS;
561                 break;
562         case 2:
563                 sr_spew("Configuring XON/XOFF flow control.");
564                 term.c_iflag |= IXON | IXOFF;
565                 break;
566         default:
567                 sr_err("Unsupported flow control setting %d.", flowcontrol);
568                 return SR_ERR;
569         }
570
571         term.c_iflag &= ~IGNPAR;
572         term.c_cflag &= ~(PARODD | PARENB);
573         switch (parity) {
574         case SERIAL_PARITY_NONE:
575                 sr_spew("Configuring no parity.");
576                 term.c_iflag |= IGNPAR;
577                 break;
578         case SERIAL_PARITY_EVEN:
579                 sr_spew("Configuring even parity.");
580                 term.c_cflag |= PARENB;
581                 break;
582         case SERIAL_PARITY_ODD:
583                 sr_spew("Configuring odd parity.");
584                 term.c_cflag |= PARENB | PARODD;
585                 break;
586         default:
587                 sr_err("Unsupported parity setting %d.", parity);
588                 return SR_ERR;
589         }
590
591         /* Turn off all serial port cooking. */
592         term.c_iflag &= ~(ISTRIP | INLCR | ICRNL);
593         term.c_oflag &= ~(ONLCR | OCRNL | ONOCR);
594 #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
595         term.c_oflag &= ~OFILL;
596 #endif
597
598         /* Disable canonical mode, and don't echo input characters. */
599         term.c_lflag &= ~(ICANON | ECHO);
600
601         /* Write the configured settings. */
602         if (tcsetattr(serial->fd, TCSADRAIN, &term) < 0) {
603                 sr_err("tcsetattr() error: %s.", strerror(errno));
604                 return SR_ERR;
605         }
606
607         if (rts != -1) {
608                 sr_spew("Setting RTS %s.", rts ? "high" : "low");
609                 controlbits = TIOCM_RTS;
610                 if ((ret = ioctl(serial->fd, rts ? TIOCMBIS : TIOCMBIC,
611                                 &controlbits)) < 0) {
612                         sr_err("Error setting RTS: %s.", strerror(errno));
613                         return SR_ERR;
614                 }
615         }
616
617         if (dtr != -1) {
618                 sr_spew("Setting DTR %s.", dtr ? "high" : "low");
619                 controlbits = TIOCM_DTR;
620                 if ((ret = ioctl(serial->fd, dtr ? TIOCMBIS : TIOCMBIC,
621                                 &controlbits)) < 0) {
622                         sr_err("Error setting DTR: %s.", strerror(errno));
623                         return SR_ERR;
624                 }
625         }
626
627 #endif
628
629         return SR_OK;
630 }
631
632 /**
633  * Set serial parameters for the specified serial port.
634  *
635  * @param serial Previously initialized serial port structure.
636  * @param paramstr A serial communication parameters string, in the form
637  * of <speed>/<data bits><parity><stopbits><flow>, for example "9600/8n1" or
638  * "600/7o2" or "460800/8n1/flow=2" where flow is 0 for none, 1 for rts/cts and 2 for xon/xoff.
639  *
640  * @return SR_OK upon success, SR_ERR upon failure.
641  */
642 #define SERIAL_COMM_SPEC "^(\\d+)/([78])([neo])([12])(.*)$"
643 SR_PRIV int serial_set_paramstr(struct sr_serial_dev_inst *serial,
644                 const char *paramstr)
645 {
646         GRegex *reg;
647         GMatchInfo *match;
648         int speed, databits, parity, stopbits, flow, rts, dtr, i;
649         char *mstr, **opts, **kv;
650
651         speed = databits = parity = stopbits = flow = 0;
652         rts = dtr = -1;
653         sr_spew("Parsing parameters from \"%s\".", paramstr);
654         reg = g_regex_new(SERIAL_COMM_SPEC, 0, 0, NULL);
655         if (g_regex_match(reg, paramstr, 0, &match)) {
656                 if ((mstr = g_match_info_fetch(match, 1)))
657                         speed = strtoul(mstr, NULL, 10);
658                 g_free(mstr);
659                 if ((mstr = g_match_info_fetch(match, 2)))
660                         databits = strtoul(mstr, NULL, 10);
661                 g_free(mstr);
662                 if ((mstr = g_match_info_fetch(match, 3))) {
663                         switch (mstr[0]) {
664                         case 'n':
665                                 parity = SERIAL_PARITY_NONE;
666                                 break;
667                         case 'e':
668                                 parity = SERIAL_PARITY_EVEN;
669                                 break;
670                         case 'o':
671                                 parity = SERIAL_PARITY_ODD;
672                                 break;
673                         }
674                 }
675                 g_free(mstr);
676                 if ((mstr = g_match_info_fetch(match, 4)))
677                         stopbits = strtoul(mstr, NULL, 10);
678                 g_free(mstr);
679                 if ((mstr = g_match_info_fetch(match, 5)) && mstr[0] != '\0') {
680                         if (mstr[0] != '/') {
681                                 sr_dbg("missing separator before extra options");
682                                 speed = 0;
683                         } else {
684                                 /* A set of "key=value" options separated by / */
685                                 opts = g_strsplit(mstr + 1, "/", 0);
686                                 for (i = 0; opts[i]; i++) {
687                                         kv = g_strsplit(opts[i], "=", 2);
688                                         if (!strncmp(kv[0], "rts", 3)) {
689                                                 if (kv[1][0] == '1')
690                                                         rts = 1;
691                                                 else if (kv[1][0] == '0')
692                                                         rts = 0;
693                                                 else {
694                                                         sr_dbg("invalid value for rts: %c", kv[1][0]);
695                                                         speed = 0;
696                                                 }
697                                         } else if (!strncmp(kv[0], "dtr", 3)) {
698                                                 if (kv[1][0] == '1')
699                                                         dtr = 1;
700                                                 else if (kv[1][0] == '0')
701                                                         dtr = 0;
702                                                 else {
703                                                         sr_dbg("invalid value for dtr: %c", kv[1][0]);
704                                                         speed = 0;
705                                                 }
706                                         } else if (!strncmp(kv[0], "flow", 4)) {
707                                                 if (kv[1][0] == '0')
708                                                         flow = 0;
709                                                 else if (kv[1][0] == '1')
710                                                         flow = 1;
711                                                 else if (kv[1][0] == '2')
712                                                         flow = 2;
713                                                 else {
714                                                         sr_dbg("invalid value for flow: %c", kv[1][0]);
715                                                         speed = 0;
716                                                 }
717                                         }
718                                         g_strfreev(kv);
719                                 }
720                                 g_strfreev(opts);
721                         }
722                 }
723                 g_free(mstr);
724         }
725         g_match_info_unref(match);
726         g_regex_unref(reg);
727
728         if (speed) {
729                 return serial_set_params(serial, speed, databits, parity,
730                                          stopbits, flow, rts, dtr);
731         } else {
732                 sr_dbg("Could not infer speed from parameter string.");
733                 return SR_ERR_ARG;
734         }
735 }
736
737 /**
738  * Read a line from the specified serial port.
739  *
740  * @param serial Previously initialized serial port structure.
741  * @param buf Buffer where to store the bytes that are read.
742  * @param buflen Size of the buffer.
743  * @param timeout_ms How long to wait for a line to come in.
744  *
745  * Reading stops when CR of LR is found, which is stripped from the buffer.
746  *
747  * @return SR_OK on success, SR_ERR on failure.
748  */
749 SR_PRIV int serial_readline(struct sr_serial_dev_inst *serial, char **buf,
750                 int *buflen, gint64 timeout_ms)
751 {
752         gint64 start;
753         int maxlen, len;
754
755         if (!serial || serial->fd == -1) {
756                 sr_dbg("Invalid serial port.");
757                 return SR_ERR;
758         }
759
760         if (serial->fd == -1) {
761                 sr_dbg("Cannot use unopened serial port %s (fd %d).",
762                                 serial->port, serial->fd);
763                 return -1;
764         }
765
766         timeout_ms *= 1000;
767         start = g_get_monotonic_time();
768
769         maxlen = *buflen;
770         *buflen = len = 0;
771         while(1) {
772                 len = maxlen - *buflen - 1;
773                 if (len < 1)
774                         break;
775                 len = serial_read(serial, *buf + *buflen, 1);
776                 if (len > 0) {
777                         *buflen += len;
778                         *(*buf + *buflen) = '\0';
779                         if (*buflen > 0 && (*(*buf + *buflen - 1) == '\r'
780                                         || *(*buf + *buflen - 1) == '\n')) {
781                                 /* Strip CR/LF and terminate. */
782                                 *(*buf + --*buflen) = '\0';
783                                 break;
784                         }
785                 }
786                 if (g_get_monotonic_time() - start > timeout_ms)
787                         /* Timeout */
788                         break;
789                 if (len < 1)
790                         g_usleep(2000);
791         }
792         if (*buflen)
793                 sr_dbg("Received %d: '%s'.", *buflen, *buf);
794
795         return SR_OK;
796 }
797
798 /**
799  * Try to find a valid packet in a serial data stream.
800  *
801  * @param serial Previously initialized serial port structure.
802  * @param buf Buffer containing the bytes to write.
803  * @param count Size of the buffer.
804  * @param packet_size Size, in bytes, of a valid packet.
805  * @param is_valid Callback that assesses whether the packet is valid or not.
806  * @param timeout_ms The timeout after which, if no packet is detected, to
807  *                   abort scanning.
808  * @param baudrate The baudrate of the serial port. This parameter is not
809  *                 critical, but it helps fine tune the serial port polling
810  *                 delay.
811  *
812  * @return SR_OK if a valid packet is found within the given timeout,
813  *         SR_ERR upon failure.
814  */
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_t is_valid,
818                                  uint64_t timeout_ms, int baudrate)
819 {
820         uint64_t start, time, byte_delay_us;
821         size_t ibuf, i, maxlen;
822         int len;
823
824         maxlen = *buflen;
825
826         sr_dbg("Detecting packets on FD %d (timeout = %" PRIu64
827                "ms, baudrate = %d).", serial->fd, timeout_ms, baudrate);
828
829         if (maxlen < (packet_size / 2) ) {
830                 sr_err("Buffer size must be at least twice the packet size.");
831                 return SR_ERR;
832         }
833
834         /* Assume 8n1 transmission. That is 10 bits for every byte. */
835         byte_delay_us = 10 * (1000000 / baudrate);
836         start = g_get_monotonic_time();
837
838         i = ibuf = len = 0;
839         while (ibuf < maxlen) {
840                 len = serial_read(serial, &buf[ibuf], 1);
841                 if (len > 0) {
842                         ibuf += len;
843                 } else if (len == 0) {
844                         /* No logging, already done in serial_read(). */
845                 } else {
846                         /* Error reading byte, but continuing anyway. */
847                 }
848
849                 time = g_get_monotonic_time() - start;
850                 time /= 1000;
851
852                 if ((ibuf - i) >= packet_size) {
853                         /* We have at least a packet's worth of data. */
854                         if (is_valid(&buf[i])) {
855                                 sr_spew("Found valid %d-byte packet after "
856                                         "%" PRIu64 "ms.", (ibuf - i), time);
857                                 *buflen = ibuf;
858                                 return SR_OK;
859                         } else {
860                                 sr_spew("Got %d bytes, but not a valid "
861                                         "packet.", (ibuf - i));
862                         }
863                         /* Not a valid packet. Continue searching. */
864                         i++;
865                 }
866                 if (time >= timeout_ms) {
867                         /* Timeout */
868                         sr_dbg("Detection timed out after %dms.", time);
869                         break;
870                 }
871                 if (len < 1)
872                         g_usleep(byte_delay_us);
873         }
874
875         *buflen = ibuf;
876
877         sr_err("Didn't find a valid packet (read %d bytes).", *buflen);
878
879         return SR_ERR;
880 }