]> sigrok.org Git - libserialport.git/blob - serialport.c
Move commonly used start flag into timeout helpers.
[libserialport.git] / serialport.c
1 /*
2  * This file is part of the libserialport project.
3  *
4  * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
5  * Copyright (C) 2010-2015 Uwe Hermann <uwe@hermann-uwe.de>
6  * Copyright (C) 2013-2015 Martin Ling <martin-libserialport@earth.li>
7  * Copyright (C) 2013 Matthias Heidbrink <m-sigrok@heidbrink.biz>
8  * Copyright (C) 2014 Aurelien Jacobs <aurel@gnuage.org>
9  *
10  * This program is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU Lesser General Public License as
12  * published by the Free Software Foundation, either version 3 of the
13  * License, or (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU Lesser General Public License
21  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22  */
23
24 #include <config.h>
25 #include "libserialport.h"
26 #include "libserialport_internal.h"
27
28 static const struct std_baudrate std_baudrates[] = {
29 #ifdef _WIN32
30         /*
31          * The baudrates 50/75/134/150/200/1800/230400/460800 do not seem to
32          * have documented CBR_* macros.
33          */
34         BAUD(110), BAUD(300), BAUD(600), BAUD(1200), BAUD(2400), BAUD(4800),
35         BAUD(9600), BAUD(14400), BAUD(19200), BAUD(38400), BAUD(57600),
36         BAUD(115200), BAUD(128000), BAUD(256000),
37 #else
38         BAUD(50), BAUD(75), BAUD(110), BAUD(134), BAUD(150), BAUD(200),
39         BAUD(300), BAUD(600), BAUD(1200), BAUD(1800), BAUD(2400), BAUD(4800),
40         BAUD(9600), BAUD(19200), BAUD(38400), BAUD(57600), BAUD(115200),
41         BAUD(230400),
42 #if !defined(__APPLE__) && !defined(__OpenBSD__)
43         BAUD(460800),
44 #endif
45 #endif
46 };
47
48 #define NUM_STD_BAUDRATES ARRAY_SIZE(std_baudrates)
49
50 void (*sp_debug_handler)(const char *format, ...) = sp_default_debug_handler;
51
52 static enum sp_return get_config(struct sp_port *port, struct port_data *data,
53         struct sp_port_config *config);
54
55 static enum sp_return set_config(struct sp_port *port, struct port_data *data,
56         const struct sp_port_config *config);
57
58 /* Timing abstraction */
59
60 struct time {
61 #ifdef _WIN32
62         int64_t ticks;
63 #else
64         struct timeval tv;
65 #endif
66 };
67
68 struct timeout {
69         unsigned int ms, limit_ms;
70         struct time start, now, end, delta, delta_max;
71         struct timeval delta_tv;
72         bool calls_started, overflow;
73 };
74
75 static void time_get(struct time *time)
76 {
77 #ifdef _WIN32
78         LARGE_INTEGER count;
79         QueryPerformanceCounter(&count);
80         time->ticks = count.QuadPart;
81 #elif defined(HAVE_CLOCK_GETTIME)
82         struct timespec ts;
83         if (clock_gettime(CLOCK_MONOTONIC, &ts) == -1)
84                 clock_gettime(CLOCK_REALTIME, &ts);
85         time->tv.tv_sec = ts.tv_sec;
86         time->tv.tv_usec = ts.tv_nsec / 1000;
87 #elif defined(__APPLE__)
88         mach_timebase_info_data_t info;
89         mach_timebase_info(&info);
90         uint64_t ticks = mach_absolute_time();
91         uint64_t ns = (ticks * info.numer) / info.denom;
92         time->tv.tv_sec = ns / 1000000000;
93         time->tv.tv_usec = (ns % 1000000000) / 1000;
94 #else
95         gettimeofday(&time->tv, NULL);
96 #endif
97 }
98
99 static void time_set_ms(struct time *time, unsigned int ms)
100 {
101 #ifdef _WIN32
102         LARGE_INTEGER frequency;
103         QueryPerformanceFrequency(&frequency);
104         time->ticks = ms * (frequency.QuadPart / 1000);
105 #else
106         time->tv.tv_sec = ms / 1000;
107         time->tv.tv_usec = (ms % 1000) * 1000;
108 #endif
109 }
110
111 static void time_add(const struct time *a,
112                 const struct time *b, struct time *result)
113 {
114 #ifdef _WIN32
115         result->ticks = a->ticks + b->ticks;
116 #else
117         timeradd(&a->tv, &b->tv, &result->tv);
118 #endif
119 }
120
121 static void time_sub(const struct time *a,
122                 const struct time *b, struct time *result)
123 {
124 #ifdef _WIN32
125         result->ticks = a->ticks - b->ticks;
126 #else
127         timersub(&a->tv, &b->tv, &result->tv);
128 #endif
129 }
130
131 static bool time_greater(const struct time *a, const struct time *b)
132 {
133 #ifdef _WIN32
134         return (a->ticks > b->ticks);
135 #else
136         return timercmp(&a->tv, &b->tv, >);
137 #endif
138 }
139
140 static void time_as_timeval(const struct time *time, struct timeval *tv)
141 {
142 #ifdef _WIN32
143         LARGE_INTEGER frequency;
144         QueryPerformanceFrequency(&frequency);
145         tv->tv_sec = time->ticks / frequency.QuadPart;
146         tv->tv_usec = (time->ticks % frequency.QuadPart) /
147                 (frequency.QuadPart / 1000000);
148 #else
149         *tv = time->tv;
150 #endif
151 }
152
153 static unsigned int time_as_ms(const struct time *time)
154 {
155 #ifdef _WIN32
156         LARGE_INTEGER frequency;
157         QueryPerformanceFrequency(&frequency);
158         return time->ticks / (frequency.QuadPart / 1000);
159 #else
160         return time->tv.tv_sec * 1000 + time->tv.tv_usec / 1000;
161 #endif
162 }
163
164 static void timeout_start(struct timeout *timeout, unsigned int timeout_ms)
165 {
166         timeout->ms = timeout_ms;
167
168         /* Get time at start of operation. */
169         time_get(&timeout->start);
170         /* Define duration of timeout. */
171         time_set_ms(&timeout->delta, timeout_ms);
172         /* Calculate time at which we should give up. */
173         time_add(&timeout->start, &timeout->delta, &timeout->end);
174         /* Disable limit unless timeout_limit() called. */
175         timeout->limit_ms = 0;
176         /* First blocking call has not yet been made. */
177         timeout->calls_started = false;
178 }
179
180 static void timeout_limit(struct timeout *timeout, unsigned int limit_ms)
181 {
182         timeout->limit_ms = limit_ms;
183         timeout->overflow = (timeout->ms > timeout->limit_ms);
184         time_set_ms(&timeout->delta_max, timeout->limit_ms);
185 }
186
187 static bool timeout_check(struct timeout *timeout)
188 {
189         if (!timeout->calls_started)
190                 return false;
191
192         if (timeout->ms == 0)
193                 return false;
194
195         time_get(&timeout->now);
196         time_sub(&timeout->end, &timeout->now, &timeout->delta);
197         if (timeout->limit_ms)
198                 if ((timeout->overflow = time_greater(&timeout->delta, &timeout->delta_max)))
199                         timeout->delta = timeout->delta_max;
200
201         return time_greater(&timeout->now, &timeout->end);
202 }
203
204 static void timeout_update(struct timeout *timeout)
205 {
206         timeout->calls_started = true;
207 }
208
209 #ifndef _WIN32
210 static struct timeval *timeout_timeval(struct timeout *timeout)
211 {
212         if (timeout->ms == 0)
213                 return NULL;
214
215         time_as_timeval(&timeout->delta, &timeout->delta_tv);
216
217         return &timeout->delta_tv;
218 }
219 #endif
220
221 static unsigned int timeout_remaining_ms(struct timeout *timeout)
222 {
223         if (timeout->limit_ms && timeout->overflow)
224                 return timeout->limit_ms;
225         else
226                 return time_as_ms(&timeout->delta);
227 }
228
229 SP_API enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_ptr)
230 {
231         struct sp_port *port;
232 #ifndef NO_PORT_METADATA
233         enum sp_return ret;
234 #endif
235         int len;
236
237         TRACE("%s, %p", portname, port_ptr);
238
239         if (!port_ptr)
240                 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
241
242         *port_ptr = NULL;
243
244         if (!portname)
245                 RETURN_ERROR(SP_ERR_ARG, "Null port name");
246
247         DEBUG_FMT("Building structure for port %s", portname);
248
249 #if !defined(_WIN32) && defined(HAVE_REALPATH)
250         /*
251          * get_port_details() below tries to be too smart and figure out
252          * some transport properties from the port name which breaks with
253          * symlinks. Therefore we canonicalize the portname first.
254          */
255         char pathbuf[PATH_MAX + 1];
256         char *res = realpath(portname, pathbuf);
257         if (!res)
258                 RETURN_ERROR(SP_ERR_ARG, "Could not retrieve realpath behind port name");
259
260         portname = pathbuf;
261 #endif
262
263         if (!(port = malloc(sizeof(struct sp_port))))
264                 RETURN_ERROR(SP_ERR_MEM, "Port structure malloc failed");
265
266         len = strlen(portname) + 1;
267
268         if (!(port->name = malloc(len))) {
269                 free(port);
270                 RETURN_ERROR(SP_ERR_MEM, "Port name malloc failed");
271         }
272
273         memcpy(port->name, portname, len);
274
275 #ifdef _WIN32
276         port->usb_path = NULL;
277         port->hdl = INVALID_HANDLE_VALUE;
278         port->write_buf = NULL;
279         port->write_buf_size = 0;
280 #else
281         port->fd = -1;
282 #endif
283
284         port->description = NULL;
285         port->transport = SP_TRANSPORT_NATIVE;
286         port->usb_bus = -1;
287         port->usb_address = -1;
288         port->usb_vid = -1;
289         port->usb_pid = -1;
290         port->usb_manufacturer = NULL;
291         port->usb_product = NULL;
292         port->usb_serial = NULL;
293         port->bluetooth_address = NULL;
294
295 #ifndef NO_PORT_METADATA
296         if ((ret = get_port_details(port)) != SP_OK) {
297                 sp_free_port(port);
298                 return ret;
299         }
300 #endif
301
302         *port_ptr = port;
303
304         RETURN_OK();
305 }
306
307 SP_API char *sp_get_port_name(const struct sp_port *port)
308 {
309         TRACE("%p", port);
310
311         if (!port)
312                 return NULL;
313
314         RETURN_STRING(port->name);
315 }
316
317 SP_API char *sp_get_port_description(const struct sp_port *port)
318 {
319         TRACE("%p", port);
320
321         if (!port || !port->description)
322                 return NULL;
323
324         RETURN_STRING(port->description);
325 }
326
327 SP_API enum sp_transport sp_get_port_transport(const struct sp_port *port)
328 {
329         TRACE("%p", port);
330
331         if (!port)
332                 RETURN_ERROR(SP_ERR_ARG, "Null port");
333
334         RETURN_INT(port->transport);
335 }
336
337 SP_API enum sp_return sp_get_port_usb_bus_address(const struct sp_port *port,
338                                                   int *usb_bus,int *usb_address)
339 {
340         TRACE("%p", port);
341
342         if (!port)
343                 RETURN_ERROR(SP_ERR_ARG, "Null port");
344         if (port->transport != SP_TRANSPORT_USB)
345                 RETURN_ERROR(SP_ERR_ARG, "Port does not use USB transport");
346         if (port->usb_bus < 0 || port->usb_address < 0)
347                 RETURN_ERROR(SP_ERR_SUPP, "Bus and address values are not available");
348
349         if (usb_bus)
350                 *usb_bus = port->usb_bus;
351         if (usb_address)
352                 *usb_address = port->usb_address;
353
354         RETURN_OK();
355 }
356
357 SP_API enum sp_return sp_get_port_usb_vid_pid(const struct sp_port *port,
358                                               int *usb_vid, int *usb_pid)
359 {
360         TRACE("%p", port);
361
362         if (!port)
363                 RETURN_ERROR(SP_ERR_ARG, "Null port");
364         if (port->transport != SP_TRANSPORT_USB)
365                 RETURN_ERROR(SP_ERR_ARG, "Port does not use USB transport");
366         if (port->usb_vid < 0 || port->usb_pid < 0)
367                 RETURN_ERROR(SP_ERR_SUPP, "VID:PID values are not available");
368
369         if (usb_vid)
370                 *usb_vid = port->usb_vid;
371         if (usb_pid)
372                 *usb_pid = port->usb_pid;
373
374         RETURN_OK();
375 }
376
377 SP_API char *sp_get_port_usb_manufacturer(const struct sp_port *port)
378 {
379         TRACE("%p", port);
380
381         if (!port || port->transport != SP_TRANSPORT_USB || !port->usb_manufacturer)
382                 return NULL;
383
384         RETURN_STRING(port->usb_manufacturer);
385 }
386
387 SP_API char *sp_get_port_usb_product(const struct sp_port *port)
388 {
389         TRACE("%p", port);
390
391         if (!port || port->transport != SP_TRANSPORT_USB || !port->usb_product)
392                 return NULL;
393
394         RETURN_STRING(port->usb_product);
395 }
396
397 SP_API char *sp_get_port_usb_serial(const struct sp_port *port)
398 {
399         TRACE("%p", port);
400
401         if (!port || port->transport != SP_TRANSPORT_USB || !port->usb_serial)
402                 return NULL;
403
404         RETURN_STRING(port->usb_serial);
405 }
406
407 SP_API char *sp_get_port_bluetooth_address(const struct sp_port *port)
408 {
409         TRACE("%p", port);
410
411         if (!port || port->transport != SP_TRANSPORT_BLUETOOTH
412             || !port->bluetooth_address)
413                 return NULL;
414
415         RETURN_STRING(port->bluetooth_address);
416 }
417
418 SP_API enum sp_return sp_get_port_handle(const struct sp_port *port,
419                                          void *result_ptr)
420 {
421         TRACE("%p, %p", port, result_ptr);
422
423         if (!port)
424                 RETURN_ERROR(SP_ERR_ARG, "Null port");
425         if (!result_ptr)
426                 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
427
428 #ifdef _WIN32
429         HANDLE *handle_ptr = result_ptr;
430         *handle_ptr = port->hdl;
431 #else
432         int *fd_ptr = result_ptr;
433         *fd_ptr = port->fd;
434 #endif
435
436         RETURN_OK();
437 }
438
439 SP_API enum sp_return sp_copy_port(const struct sp_port *port,
440                                    struct sp_port **copy_ptr)
441 {
442         TRACE("%p, %p", port, copy_ptr);
443
444         if (!copy_ptr)
445                 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
446
447         *copy_ptr = NULL;
448
449         if (!port)
450                 RETURN_ERROR(SP_ERR_ARG, "Null port");
451
452         if (!port->name)
453                 RETURN_ERROR(SP_ERR_ARG, "Null port name");
454
455         DEBUG("Copying port structure");
456
457         RETURN_INT(sp_get_port_by_name(port->name, copy_ptr));
458 }
459
460 SP_API void sp_free_port(struct sp_port *port)
461 {
462         TRACE("%p", port);
463
464         if (!port) {
465                 DEBUG("Null port");
466                 RETURN();
467         }
468
469         DEBUG("Freeing port structure");
470
471         if (port->name)
472                 free(port->name);
473         if (port->description)
474                 free(port->description);
475         if (port->usb_manufacturer)
476                 free(port->usb_manufacturer);
477         if (port->usb_product)
478                 free(port->usb_product);
479         if (port->usb_serial)
480                 free(port->usb_serial);
481         if (port->bluetooth_address)
482                 free(port->bluetooth_address);
483 #ifdef _WIN32
484         if (port->usb_path)
485                 free(port->usb_path);
486         if (port->write_buf)
487                 free(port->write_buf);
488 #endif
489
490         free(port);
491
492         RETURN();
493 }
494
495 SP_PRIV struct sp_port **list_append(struct sp_port **list,
496                                      const char *portname)
497 {
498         void *tmp;
499         unsigned int count;
500
501         for (count = 0; list[count]; count++)
502                 ;
503         if (!(tmp = realloc(list, sizeof(struct sp_port *) * (count + 2))))
504                 goto fail;
505         list = tmp;
506         if (sp_get_port_by_name(portname, &list[count]) != SP_OK)
507                 goto fail;
508         list[count + 1] = NULL;
509         return list;
510
511 fail:
512         sp_free_port_list(list);
513         return NULL;
514 }
515
516 SP_API enum sp_return sp_list_ports(struct sp_port ***list_ptr)
517 {
518 #ifndef NO_ENUMERATION
519         struct sp_port **list;
520         int ret;
521 #endif
522
523         TRACE("%p", list_ptr);
524
525         if (!list_ptr)
526                 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
527
528         *list_ptr = NULL;
529
530 #ifdef NO_ENUMERATION
531         RETURN_ERROR(SP_ERR_SUPP, "Enumeration not supported on this platform");
532 #else
533         DEBUG("Enumerating ports");
534
535         if (!(list = malloc(sizeof(struct sp_port *))))
536                 RETURN_ERROR(SP_ERR_MEM, "Port list malloc failed");
537
538         list[0] = NULL;
539
540         ret = list_ports(&list);
541
542         if (ret == SP_OK) {
543                 *list_ptr = list;
544         } else {
545                 sp_free_port_list(list);
546                 *list_ptr = NULL;
547         }
548
549         RETURN_CODEVAL(ret);
550 #endif
551 }
552
553 SP_API void sp_free_port_list(struct sp_port **list)
554 {
555         unsigned int i;
556
557         TRACE("%p", list);
558
559         if (!list) {
560                 DEBUG("Null list");
561                 RETURN();
562         }
563
564         DEBUG("Freeing port list");
565
566         for (i = 0; list[i]; i++)
567                 sp_free_port(list[i]);
568         free(list);
569
570         RETURN();
571 }
572
573 #define CHECK_PORT() do { \
574         if (!port) \
575                 RETURN_ERROR(SP_ERR_ARG, "Null port"); \
576         if (!port->name) \
577                 RETURN_ERROR(SP_ERR_ARG, "Null port name"); \
578 } while (0)
579 #ifdef _WIN32
580 #define CHECK_PORT_HANDLE() do { \
581         if (port->hdl == INVALID_HANDLE_VALUE) \
582                 RETURN_ERROR(SP_ERR_ARG, "Port not open"); \
583 } while (0)
584 #else
585 #define CHECK_PORT_HANDLE() do { \
586         if (port->fd < 0) \
587                 RETURN_ERROR(SP_ERR_ARG, "Port not open"); \
588 } while (0)
589 #endif
590 #define CHECK_OPEN_PORT() do { \
591         CHECK_PORT(); \
592         CHECK_PORT_HANDLE(); \
593 } while (0)
594
595 #ifdef WIN32
596 /** To be called after port receive buffer is emptied. */
597 static enum sp_return restart_wait(struct sp_port *port)
598 {
599         DWORD wait_result;
600
601         if (port->wait_running) {
602                 /* Check status of running wait operation. */
603                 if (GetOverlappedResult(port->hdl, &port->wait_ovl,
604                                 &wait_result, FALSE)) {
605                         DEBUG("Previous wait completed");
606                         port->wait_running = FALSE;
607                 } else if (GetLastError() == ERROR_IO_INCOMPLETE) {
608                         DEBUG("Previous wait still running");
609                         RETURN_OK();
610                 } else {
611                         RETURN_FAIL("GetOverlappedResult() failed");
612                 }
613         }
614
615         if (!port->wait_running) {
616                 /* Start new wait operation. */
617                 if (WaitCommEvent(port->hdl, &port->events,
618                                 &port->wait_ovl)) {
619                         DEBUG("New wait returned, events already pending");
620                 } else if (GetLastError() == ERROR_IO_PENDING) {
621                         DEBUG("New wait running in background");
622                         port->wait_running = TRUE;
623                 } else {
624                         RETURN_FAIL("WaitCommEvent() failed");
625                 }
626         }
627
628         RETURN_OK();
629 }
630 #endif
631
632 SP_API enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
633 {
634         struct port_data data;
635         struct sp_port_config config;
636         enum sp_return ret;
637
638         TRACE("%p, 0x%x", port, flags);
639
640         CHECK_PORT();
641
642         if (flags > SP_MODE_READ_WRITE)
643                 RETURN_ERROR(SP_ERR_ARG, "Invalid flags");
644
645         DEBUG_FMT("Opening port %s", port->name);
646
647 #ifdef _WIN32
648         DWORD desired_access = 0, flags_and_attributes = 0, errors;
649         char *escaped_port_name;
650         COMSTAT status;
651
652         /* Prefix port name with '\\.\' to work with ports above COM9. */
653         if (!(escaped_port_name = malloc(strlen(port->name) + 5)))
654                 RETURN_ERROR(SP_ERR_MEM, "Escaped port name malloc failed");
655         sprintf(escaped_port_name, "\\\\.\\%s", port->name);
656
657         /* Map 'flags' to the OS-specific settings. */
658         flags_and_attributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED;
659         if (flags & SP_MODE_READ)
660                 desired_access |= GENERIC_READ;
661         if (flags & SP_MODE_WRITE)
662                 desired_access |= GENERIC_WRITE;
663
664         port->hdl = CreateFile(escaped_port_name, desired_access, 0, 0,
665                          OPEN_EXISTING, flags_and_attributes, 0);
666
667         free(escaped_port_name);
668
669         if (port->hdl == INVALID_HANDLE_VALUE)
670                 RETURN_FAIL("Port CreateFile() failed");
671
672         /* All timeouts initially disabled. */
673         port->timeouts.ReadIntervalTimeout = 0;
674         port->timeouts.ReadTotalTimeoutMultiplier = 0;
675         port->timeouts.ReadTotalTimeoutConstant = 0;
676         port->timeouts.WriteTotalTimeoutMultiplier = 0;
677         port->timeouts.WriteTotalTimeoutConstant = 0;
678
679         if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) {
680                 sp_close(port);
681                 RETURN_FAIL("SetCommTimeouts() failed");
682         }
683
684         /* Prepare OVERLAPPED structures. */
685 #define INIT_OVERLAPPED(ovl) do { \
686         memset(&port->ovl, 0, sizeof(port->ovl)); \
687         port->ovl.hEvent = INVALID_HANDLE_VALUE; \
688         if ((port->ovl.hEvent = CreateEvent(NULL, TRUE, TRUE, NULL)) \
689                         == INVALID_HANDLE_VALUE) { \
690                 sp_close(port); \
691                 RETURN_FAIL(#ovl "CreateEvent() failed"); \
692         } \
693 } while (0)
694
695         INIT_OVERLAPPED(read_ovl);
696         INIT_OVERLAPPED(write_ovl);
697         INIT_OVERLAPPED(wait_ovl);
698
699         /* Set event mask for RX and error events. */
700         if (SetCommMask(port->hdl, EV_RXCHAR | EV_ERR) == 0) {
701                 sp_close(port);
702                 RETURN_FAIL("SetCommMask() failed");
703         }
704
705         port->writing = FALSE;
706         port->wait_running = FALSE;
707
708         ret = restart_wait(port);
709
710         if (ret < 0) {
711                 sp_close(port);
712                 RETURN_CODEVAL(ret);
713         }
714 #else
715         int flags_local = O_NONBLOCK | O_NOCTTY | O_CLOEXEC;
716
717         /* Map 'flags' to the OS-specific settings. */
718         if ((flags & SP_MODE_READ_WRITE) == SP_MODE_READ_WRITE)
719                 flags_local |= O_RDWR;
720         else if (flags & SP_MODE_READ)
721                 flags_local |= O_RDONLY;
722         else if (flags & SP_MODE_WRITE)
723                 flags_local |= O_WRONLY;
724
725         if ((port->fd = open(port->name, flags_local)) < 0)
726                 RETURN_FAIL("open() failed");
727 #endif
728
729         ret = get_config(port, &data, &config);
730
731         if (ret < 0) {
732                 sp_close(port);
733                 RETURN_CODEVAL(ret);
734         }
735
736         /* Set sane port settings. */
737 #ifdef _WIN32
738         data.dcb.fBinary = TRUE;
739         data.dcb.fDsrSensitivity = FALSE;
740         data.dcb.fErrorChar = FALSE;
741         data.dcb.fNull = FALSE;
742         data.dcb.fAbortOnError = FALSE;
743 #else
744         /* Turn off all fancy termios tricks, give us a raw channel. */
745         data.term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IMAXBEL);
746 #ifdef IUCLC
747         data.term.c_iflag &= ~IUCLC;
748 #endif
749         data.term.c_oflag &= ~(OPOST | ONLCR | OCRNL | ONOCR | ONLRET);
750 #ifdef OLCUC
751         data.term.c_oflag &= ~OLCUC;
752 #endif
753 #ifdef NLDLY
754         data.term.c_oflag &= ~NLDLY;
755 #endif
756 #ifdef CRDLY
757         data.term.c_oflag &= ~CRDLY;
758 #endif
759 #ifdef TABDLY
760         data.term.c_oflag &= ~TABDLY;
761 #endif
762 #ifdef BSDLY
763         data.term.c_oflag &= ~BSDLY;
764 #endif
765 #ifdef VTDLY
766         data.term.c_oflag &= ~VTDLY;
767 #endif
768 #ifdef FFDLY
769         data.term.c_oflag &= ~FFDLY;
770 #endif
771 #ifdef OFILL
772         data.term.c_oflag &= ~OFILL;
773 #endif
774         data.term.c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN);
775         data.term.c_cc[VMIN] = 0;
776         data.term.c_cc[VTIME] = 0;
777
778         /* Ignore modem status lines; enable receiver; leave control lines alone on close. */
779         data.term.c_cflag |= (CLOCAL | CREAD | HUPCL);
780 #endif
781
782 #ifdef _WIN32
783         if (ClearCommError(port->hdl, &errors, &status) == 0)
784                 RETURN_FAIL("ClearCommError() failed");
785 #endif
786
787         ret = set_config(port, &data, &config);
788
789         if (ret < 0) {
790                 sp_close(port);
791                 RETURN_CODEVAL(ret);
792         }
793
794         RETURN_OK();
795 }
796
797 SP_API enum sp_return sp_close(struct sp_port *port)
798 {
799         TRACE("%p", port);
800
801         CHECK_OPEN_PORT();
802
803         DEBUG_FMT("Closing port %s", port->name);
804
805 #ifdef _WIN32
806         /* Returns non-zero upon success, 0 upon failure. */
807         if (CloseHandle(port->hdl) == 0)
808                 RETURN_FAIL("Port CloseHandle() failed");
809         port->hdl = INVALID_HANDLE_VALUE;
810
811         /* Close event handles for overlapped structures. */
812 #define CLOSE_OVERLAPPED(ovl) do { \
813         if (port->ovl.hEvent != INVALID_HANDLE_VALUE && \
814                 CloseHandle(port->ovl.hEvent) == 0) \
815                 RETURN_FAIL(# ovl "event CloseHandle() failed"); \
816 } while (0)
817         CLOSE_OVERLAPPED(read_ovl);
818         CLOSE_OVERLAPPED(write_ovl);
819         CLOSE_OVERLAPPED(wait_ovl);
820
821         if (port->write_buf) {
822                 free(port->write_buf);
823                 port->write_buf = NULL;
824         }
825 #else
826         /* Returns 0 upon success, -1 upon failure. */
827         if (close(port->fd) == -1)
828                 RETURN_FAIL("close() failed");
829         port->fd = -1;
830 #endif
831
832         RETURN_OK();
833 }
834
835 SP_API enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers)
836 {
837         TRACE("%p, 0x%x", port, buffers);
838
839         CHECK_OPEN_PORT();
840
841         if (buffers > SP_BUF_BOTH)
842                 RETURN_ERROR(SP_ERR_ARG, "Invalid buffer selection");
843
844         const char *buffer_names[] = {"no", "input", "output", "both"};
845
846         DEBUG_FMT("Flushing %s buffers on port %s",
847                 buffer_names[buffers], port->name);
848
849 #ifdef _WIN32
850         DWORD flags = 0;
851         if (buffers & SP_BUF_INPUT)
852                 flags |= PURGE_RXCLEAR;
853         if (buffers & SP_BUF_OUTPUT)
854                 flags |= PURGE_TXCLEAR;
855
856         /* Returns non-zero upon success, 0 upon failure. */
857         if (PurgeComm(port->hdl, flags) == 0)
858                 RETURN_FAIL("PurgeComm() failed");
859
860         if (buffers & SP_BUF_INPUT)
861                 TRY(restart_wait(port));
862 #else
863         int flags = 0;
864         if (buffers == SP_BUF_BOTH)
865                 flags = TCIOFLUSH;
866         else if (buffers == SP_BUF_INPUT)
867                 flags = TCIFLUSH;
868         else if (buffers == SP_BUF_OUTPUT)
869                 flags = TCOFLUSH;
870
871         /* Returns 0 upon success, -1 upon failure. */
872         if (tcflush(port->fd, flags) < 0)
873                 RETURN_FAIL("tcflush() failed");
874 #endif
875         RETURN_OK();
876 }
877
878 SP_API enum sp_return sp_drain(struct sp_port *port)
879 {
880         TRACE("%p", port);
881
882         CHECK_OPEN_PORT();
883
884         DEBUG_FMT("Draining port %s", port->name);
885
886 #ifdef _WIN32
887         /* Returns non-zero upon success, 0 upon failure. */
888         if (FlushFileBuffers(port->hdl) == 0)
889                 RETURN_FAIL("FlushFileBuffers() failed");
890         RETURN_OK();
891 #else
892         int result;
893         while (1) {
894 #if defined(__ANDROID__) && (__ANDROID_API__ < 21)
895                 /* Android only has tcdrain from platform 21 onwards.
896                  * On previous API versions, use the ioctl directly. */
897                 int arg = 1;
898                 result = ioctl(port->fd, TCSBRK, &arg);
899 #else
900                 result = tcdrain(port->fd);
901 #endif
902                 if (result < 0) {
903                         if (errno == EINTR) {
904                                 DEBUG("tcdrain() was interrupted");
905                                 continue;
906                         } else {
907                                 RETURN_FAIL("tcdrain() failed");
908                         }
909                 } else {
910                         RETURN_OK();
911                 }
912         }
913 #endif
914 }
915
916 #ifdef _WIN32
917 static enum sp_return await_write_completion(struct sp_port *port)
918 {
919         TRACE("%p", port);
920         DWORD bytes_written;
921         BOOL result;
922
923         /* Wait for previous non-blocking write to complete, if any. */
924         if (port->writing) {
925                 DEBUG("Waiting for previous write to complete");
926                 result = GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE);
927                 port->writing = 0;
928                 if (!result)
929                         RETURN_FAIL("Previous write failed to complete");
930                 DEBUG("Previous write completed");
931         }
932
933         RETURN_OK();
934 }
935 #endif
936
937 SP_API enum sp_return sp_blocking_write(struct sp_port *port, const void *buf,
938                                         size_t count, unsigned int timeout_ms)
939 {
940         TRACE("%p, %p, %d, %d", port, buf, count, timeout_ms);
941
942         CHECK_OPEN_PORT();
943
944         if (!buf)
945                 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
946
947         if (timeout_ms)
948                 DEBUG_FMT("Writing %d bytes to port %s, timeout %d ms",
949                         count, port->name, timeout_ms);
950         else
951                 DEBUG_FMT("Writing %d bytes to port %s, no timeout",
952                         count, port->name);
953
954         if (count == 0)
955                 RETURN_INT(0);
956
957 #ifdef _WIN32
958         DWORD bytes_written = 0;
959
960         TRY(await_write_completion(port));
961
962         /* Set timeout. */
963         if (port->timeouts.WriteTotalTimeoutConstant != timeout_ms) {
964                 port->timeouts.WriteTotalTimeoutConstant = timeout_ms;
965                 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
966                         RETURN_FAIL("SetCommTimeouts() failed");
967         }
968
969         /* Reduce count if it exceeds the WriteFile limit. */
970         if (count > WRITEFILE_MAX_SIZE)
971                 count = WRITEFILE_MAX_SIZE;
972
973         /* Start write. */
974         if (WriteFile(port->hdl, buf, count, NULL, &port->write_ovl)) {
975                 DEBUG("Write completed immediately");
976                 RETURN_INT(count);
977         } else if (GetLastError() == ERROR_IO_PENDING) {
978                 DEBUG("Waiting for write to complete");
979                 if (GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE) == 0) {
980                         if (GetLastError() == ERROR_SEM_TIMEOUT) {
981                                 DEBUG("Write timed out");
982                                 RETURN_INT(0);
983                         } else {
984                                 RETURN_FAIL("GetOverlappedResult() failed");
985                         }
986                 }
987                 DEBUG_FMT("Write completed, %d/%d bytes written", bytes_written, count);
988                 RETURN_INT(bytes_written);
989         } else {
990                 RETURN_FAIL("WriteFile() failed");
991         }
992 #else
993         size_t bytes_written = 0;
994         unsigned char *ptr = (unsigned char *) buf;
995         struct timeout timeout;
996         fd_set fds;
997         int result;
998
999         timeout_start(&timeout, timeout_ms);
1000
1001         FD_ZERO(&fds);
1002         FD_SET(port->fd, &fds);
1003
1004         /* Loop until we have written the requested number of bytes. */
1005         while (bytes_written < count) {
1006
1007                 if (timeout_check(&timeout))
1008                         break;
1009
1010                 result = select(port->fd + 1, NULL, &fds, NULL, timeout_timeval(&timeout));
1011
1012                 timeout_update(&timeout);
1013
1014                 if (result < 0) {
1015                         if (errno == EINTR) {
1016                                 DEBUG("select() call was interrupted, repeating");
1017                                 continue;
1018                         } else {
1019                                 RETURN_FAIL("select() failed");
1020                         }
1021                 } else if (result == 0) {
1022                         /* Timeout has expired. */
1023                         break;
1024                 }
1025
1026                 /* Do write. */
1027                 result = write(port->fd, ptr, count - bytes_written);
1028
1029                 if (result < 0) {
1030                         if (errno == EAGAIN)
1031                                 /* This shouldn't happen because we did a select() first, but handle anyway. */
1032                                 continue;
1033                         else
1034                                 /* This is an actual failure. */
1035                                 RETURN_FAIL("write() failed");
1036                 }
1037
1038                 bytes_written += result;
1039                 ptr += result;
1040         }
1041
1042         if (bytes_written < count)
1043                 DEBUG("Write timed out");
1044
1045         RETURN_INT(bytes_written);
1046 #endif
1047 }
1048
1049 SP_API enum sp_return sp_nonblocking_write(struct sp_port *port,
1050                                            const void *buf, size_t count)
1051 {
1052         TRACE("%p, %p, %d", port, buf, count);
1053
1054         CHECK_OPEN_PORT();
1055
1056         if (!buf)
1057                 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
1058
1059         DEBUG_FMT("Writing up to %d bytes to port %s", count, port->name);
1060
1061         if (count == 0)
1062                 RETURN_INT(0);
1063
1064 #ifdef _WIN32
1065         DWORD buf_bytes;
1066
1067         /* Check whether previous write is complete. */
1068         if (port->writing) {
1069                 if (HasOverlappedIoCompleted(&port->write_ovl)) {
1070                         DEBUG("Previous write completed");
1071                         port->writing = 0;
1072                 } else {
1073                         DEBUG("Previous write not complete");
1074                         /* Can't take a new write until the previous one finishes. */
1075                         RETURN_INT(0);
1076                 }
1077         }
1078
1079         /* Set timeout. */
1080         if (port->timeouts.WriteTotalTimeoutConstant != 0) {
1081                 port->timeouts.WriteTotalTimeoutConstant = 0;
1082                 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
1083                         RETURN_FAIL("SetCommTimeouts() failed");
1084         }
1085
1086         /* Reduce count if it exceeds the WriteFile limit. */
1087         if (count > WRITEFILE_MAX_SIZE)
1088                 count = WRITEFILE_MAX_SIZE;
1089
1090         /* Copy data to our write buffer. */
1091         buf_bytes = min(port->write_buf_size, count);
1092         memcpy(port->write_buf, buf, buf_bytes);
1093
1094         /* Start asynchronous write. */
1095         if (WriteFile(port->hdl, port->write_buf, buf_bytes, NULL, &port->write_ovl) == 0) {
1096                 if (GetLastError() == ERROR_IO_PENDING) {
1097                         if ((port->writing = !HasOverlappedIoCompleted(&port->write_ovl)))
1098                                 DEBUG("Asynchronous write completed immediately");
1099                         else
1100                                 DEBUG("Asynchronous write running");
1101                 } else {
1102                         /* Actual failure of some kind. */
1103                         RETURN_FAIL("WriteFile() failed");
1104                 }
1105         }
1106
1107         DEBUG("All bytes written immediately");
1108
1109         RETURN_INT(buf_bytes);
1110 #else
1111         /* Returns the number of bytes written, or -1 upon failure. */
1112         ssize_t written = write(port->fd, buf, count);
1113
1114         if (written < 0) {
1115                 if (errno == EAGAIN)
1116                         // Buffer is full, no bytes written.
1117                         RETURN_INT(0);
1118                 else
1119                         RETURN_FAIL("write() failed");
1120         } else {
1121                 RETURN_INT(written);
1122         }
1123 #endif
1124 }
1125
1126 #ifdef _WIN32
1127 /* Restart wait operation if buffer was emptied. */
1128 static enum sp_return restart_wait_if_needed(struct sp_port *port, unsigned int bytes_read)
1129 {
1130         DWORD errors;
1131         COMSTAT comstat;
1132
1133         if (bytes_read == 0)
1134                 RETURN_OK();
1135
1136         if (ClearCommError(port->hdl, &errors, &comstat) == 0)
1137                 RETURN_FAIL("ClearCommError() failed");
1138
1139         if (comstat.cbInQue == 0)
1140                 TRY(restart_wait(port));
1141
1142         RETURN_OK();
1143 }
1144 #endif
1145
1146 SP_API enum sp_return sp_blocking_read(struct sp_port *port, void *buf,
1147                                        size_t count, unsigned int timeout_ms)
1148 {
1149         TRACE("%p, %p, %d, %d", port, buf, count, timeout_ms);
1150
1151         CHECK_OPEN_PORT();
1152
1153         if (!buf)
1154                 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
1155
1156         if (timeout_ms)
1157                 DEBUG_FMT("Reading %d bytes from port %s, timeout %d ms",
1158                         count, port->name, timeout_ms);
1159         else
1160                 DEBUG_FMT("Reading %d bytes from port %s, no timeout",
1161                         count, port->name);
1162
1163         if (count == 0)
1164                 RETURN_INT(0);
1165
1166 #ifdef _WIN32
1167         DWORD bytes_read = 0;
1168
1169         /* Set timeout. */
1170         if (port->timeouts.ReadIntervalTimeout != 0 ||
1171                         port->timeouts.ReadTotalTimeoutMultiplier != 0 ||
1172                         port->timeouts.ReadTotalTimeoutConstant != timeout_ms) {
1173                 port->timeouts.ReadIntervalTimeout = 0;
1174                 port->timeouts.ReadTotalTimeoutMultiplier = 0;
1175                 port->timeouts.ReadTotalTimeoutConstant = timeout_ms;
1176                 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
1177                         RETURN_FAIL("SetCommTimeouts() failed");
1178         }
1179
1180         /* Start read. */
1181         if (ReadFile(port->hdl, buf, count, NULL, &port->read_ovl)) {
1182                 DEBUG("Read completed immediately");
1183                 bytes_read = count;
1184         } else if (GetLastError() == ERROR_IO_PENDING) {
1185                 DEBUG("Waiting for read to complete");
1186                 if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE) == 0)
1187                         RETURN_FAIL("GetOverlappedResult() failed");
1188                 DEBUG_FMT("Read completed, %d/%d bytes read", bytes_read, count);
1189         } else {
1190                 RETURN_FAIL("ReadFile() failed");
1191         }
1192
1193         TRY(restart_wait_if_needed(port, bytes_read));
1194
1195         RETURN_INT(bytes_read);
1196
1197 #else
1198         size_t bytes_read = 0;
1199         unsigned char *ptr = (unsigned char *) buf;
1200         struct timeout timeout;
1201         fd_set fds;
1202         int result;
1203
1204         timeout_start(&timeout, timeout_ms);
1205
1206         FD_ZERO(&fds);
1207         FD_SET(port->fd, &fds);
1208
1209         /* Loop until we have the requested number of bytes. */
1210         while (bytes_read < count) {
1211
1212                 if (timeout_check(&timeout))
1213                         /* Timeout has expired. */
1214                         break;
1215
1216                 result = select(port->fd + 1, &fds, NULL, NULL, timeout_timeval(&timeout));
1217
1218                 timeout_update(&timeout);
1219
1220                 if (result < 0) {
1221                         if (errno == EINTR) {
1222                                 DEBUG("select() call was interrupted, repeating");
1223                                 continue;
1224                         } else {
1225                                 RETURN_FAIL("select() failed");
1226                         }
1227                 } else if (result == 0) {
1228                         /* Timeout has expired. */
1229                         break;
1230                 }
1231
1232                 /* Do read. */
1233                 result = read(port->fd, ptr, count - bytes_read);
1234
1235                 if (result < 0) {
1236                         if (errno == EAGAIN)
1237                                 /*
1238                                  * This shouldn't happen because we did a
1239                                  * select() first, but handle anyway.
1240                                  */
1241                                 continue;
1242                         else
1243                                 /* This is an actual failure. */
1244                                 RETURN_FAIL("read() failed");
1245                 }
1246
1247                 bytes_read += result;
1248                 ptr += result;
1249         }
1250
1251         if (bytes_read < count)
1252                 DEBUG("Read timed out");
1253
1254         RETURN_INT(bytes_read);
1255 #endif
1256 }
1257
1258 SP_API enum sp_return sp_blocking_read_next(struct sp_port *port, void *buf,
1259                                             size_t count, unsigned int timeout_ms)
1260 {
1261         TRACE("%p, %p, %d, %d", port, buf, count, timeout_ms);
1262
1263         CHECK_OPEN_PORT();
1264
1265         if (!buf)
1266                 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
1267
1268         if (count == 0)
1269                 RETURN_ERROR(SP_ERR_ARG, "Zero count");
1270
1271         if (timeout_ms)
1272                 DEBUG_FMT("Reading next max %d bytes from port %s, timeout %d ms",
1273                         count, port->name, timeout_ms);
1274         else
1275                 DEBUG_FMT("Reading next max %d bytes from port %s, no timeout",
1276                         count, port->name);
1277
1278 #ifdef _WIN32
1279         DWORD bytes_read = 0;
1280
1281         /* If timeout_ms == 0, set maximum timeout. */
1282         DWORD timeout_val = (timeout_ms == 0 ? MAXDWORD - 1 : timeout_ms);
1283
1284         /* Set timeout. */
1285         if (port->timeouts.ReadIntervalTimeout != MAXDWORD ||
1286                         port->timeouts.ReadTotalTimeoutMultiplier != MAXDWORD ||
1287                         port->timeouts.ReadTotalTimeoutConstant != timeout_val) {
1288                 port->timeouts.ReadIntervalTimeout = MAXDWORD;
1289                 port->timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
1290                 port->timeouts.ReadTotalTimeoutConstant = timeout_val;
1291                 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
1292                         RETURN_FAIL("SetCommTimeouts() failed");
1293         }
1294
1295         /* Loop until we have at least one byte, or timeout is reached. */
1296         while (bytes_read == 0) {
1297                 /* Start read. */
1298                 if (ReadFile(port->hdl, buf, count, &bytes_read, &port->read_ovl)) {
1299                         DEBUG("Read completed immediately");
1300                 } else if (GetLastError() == ERROR_IO_PENDING) {
1301                         DEBUG("Waiting for read to complete");
1302                         if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE) == 0)
1303                                 RETURN_FAIL("GetOverlappedResult() failed");
1304                         if (bytes_read > 0) {
1305                                 DEBUG("Read completed");
1306                         } else if (timeout_ms > 0) {
1307                                 DEBUG("Read timed out");
1308                                 break;
1309                         } else {
1310                                 DEBUG("Restarting read");
1311                         }
1312                 } else {
1313                         RETURN_FAIL("ReadFile() failed");
1314                 }
1315         }
1316
1317         TRY(restart_wait_if_needed(port, bytes_read));
1318
1319         RETURN_INT(bytes_read);
1320
1321 #else
1322         size_t bytes_read = 0;
1323         struct timeout timeout;
1324         fd_set fds;
1325         int result;
1326
1327         timeout_start(&timeout, timeout_ms);
1328
1329         FD_ZERO(&fds);
1330         FD_SET(port->fd, &fds);
1331
1332         /* Loop until we have at least one byte, or timeout is reached. */
1333         while (bytes_read == 0) {
1334
1335                 if (timeout_check(&timeout))
1336                         /* Timeout has expired. */
1337                         break;
1338
1339                 result = select(port->fd + 1, &fds, NULL, NULL, timeout_timeval(&timeout));
1340
1341                 timeout_update(&timeout);
1342
1343                 if (result < 0) {
1344                         if (errno == EINTR) {
1345                                 DEBUG("select() call was interrupted, repeating");
1346                                 continue;
1347                         } else {
1348                                 RETURN_FAIL("select() failed");
1349                         }
1350                 } else if (result == 0) {
1351                         /* Timeout has expired. */
1352                         break;
1353                 }
1354
1355                 /* Do read. */
1356                 result = read(port->fd, buf, count);
1357
1358                 if (result < 0) {
1359                         if (errno == EAGAIN)
1360                                 /* This shouldn't happen because we did a select() first, but handle anyway. */
1361                                 continue;
1362                         else
1363                                 /* This is an actual failure. */
1364                                 RETURN_FAIL("read() failed");
1365                 }
1366
1367                 bytes_read = result;
1368         }
1369
1370         if (bytes_read == 0)
1371                 DEBUG("Read timed out");
1372
1373         RETURN_INT(bytes_read);
1374 #endif
1375 }
1376
1377 SP_API enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf,
1378                                           size_t count)
1379 {
1380         TRACE("%p, %p, %d", port, buf, count);
1381
1382         CHECK_OPEN_PORT();
1383
1384         if (!buf)
1385                 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
1386
1387         DEBUG_FMT("Reading up to %d bytes from port %s", count, port->name);
1388
1389 #ifdef _WIN32
1390         DWORD bytes_read;
1391
1392         /* Set timeout. */
1393         if (port->timeouts.ReadIntervalTimeout != MAXDWORD ||
1394                         port->timeouts.ReadTotalTimeoutMultiplier != 0 ||
1395                         port->timeouts.ReadTotalTimeoutConstant != 0) {
1396                 port->timeouts.ReadIntervalTimeout = MAXDWORD;
1397                 port->timeouts.ReadTotalTimeoutMultiplier = 0;
1398                 port->timeouts.ReadTotalTimeoutConstant = 0;
1399                 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
1400                         RETURN_FAIL("SetCommTimeouts() failed");
1401         }
1402
1403         /* Do read. */
1404         if (ReadFile(port->hdl, buf, count, NULL, &port->read_ovl) == 0)
1405                 if (GetLastError() != ERROR_IO_PENDING)
1406                         RETURN_FAIL("ReadFile() failed");
1407
1408         /* Get number of bytes read. */
1409         if (GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, FALSE) == 0)
1410                 RETURN_FAIL("GetOverlappedResult() failed");
1411
1412         TRY(restart_wait_if_needed(port, bytes_read));
1413
1414         RETURN_INT(bytes_read);
1415 #else
1416         ssize_t bytes_read;
1417
1418         /* Returns the number of bytes read, or -1 upon failure. */
1419         if ((bytes_read = read(port->fd, buf, count)) < 0) {
1420                 if (errno == EAGAIN)
1421                         /* No bytes available. */
1422                         bytes_read = 0;
1423                 else
1424                         /* This is an actual failure. */
1425                         RETURN_FAIL("read() failed");
1426         }
1427         RETURN_INT(bytes_read);
1428 #endif
1429 }
1430
1431 SP_API enum sp_return sp_input_waiting(struct sp_port *port)
1432 {
1433         TRACE("%p", port);
1434
1435         CHECK_OPEN_PORT();
1436
1437         DEBUG_FMT("Checking input bytes waiting on port %s", port->name);
1438
1439 #ifdef _WIN32
1440         DWORD errors;
1441         COMSTAT comstat;
1442
1443         if (ClearCommError(port->hdl, &errors, &comstat) == 0)
1444                 RETURN_FAIL("ClearCommError() failed");
1445         RETURN_INT(comstat.cbInQue);
1446 #else
1447         int bytes_waiting;
1448         if (ioctl(port->fd, TIOCINQ, &bytes_waiting) < 0)
1449                 RETURN_FAIL("TIOCINQ ioctl failed");
1450         RETURN_INT(bytes_waiting);
1451 #endif
1452 }
1453
1454 SP_API enum sp_return sp_output_waiting(struct sp_port *port)
1455 {
1456         TRACE("%p", port);
1457
1458         CHECK_OPEN_PORT();
1459
1460         DEBUG_FMT("Checking output bytes waiting on port %s", port->name);
1461
1462 #ifdef _WIN32
1463         DWORD errors;
1464         COMSTAT comstat;
1465
1466         if (ClearCommError(port->hdl, &errors, &comstat) == 0)
1467                 RETURN_FAIL("ClearCommError() failed");
1468         RETURN_INT(comstat.cbOutQue);
1469 #else
1470         int bytes_waiting;
1471         if (ioctl(port->fd, TIOCOUTQ, &bytes_waiting) < 0)
1472                 RETURN_FAIL("TIOCOUTQ ioctl failed");
1473         RETURN_INT(bytes_waiting);
1474 #endif
1475 }
1476
1477 SP_API enum sp_return sp_new_event_set(struct sp_event_set **result_ptr)
1478 {
1479         struct sp_event_set *result;
1480
1481         TRACE("%p", result_ptr);
1482
1483         if (!result_ptr)
1484                 RETURN_ERROR(SP_ERR_ARG, "Null result");
1485
1486         *result_ptr = NULL;
1487
1488         if (!(result = malloc(sizeof(struct sp_event_set))))
1489                 RETURN_ERROR(SP_ERR_MEM, "sp_event_set malloc() failed");
1490
1491         memset(result, 0, sizeof(struct sp_event_set));
1492
1493         *result_ptr = result;
1494
1495         RETURN_OK();
1496 }
1497
1498 static enum sp_return add_handle(struct sp_event_set *event_set,
1499                 event_handle handle, enum sp_event mask)
1500 {
1501         void *new_handles;
1502         enum sp_event *new_masks;
1503
1504         TRACE("%p, %d, %d", event_set, handle, mask);
1505
1506         if (!(new_handles = realloc(event_set->handles,
1507                         sizeof(event_handle) * (event_set->count + 1))))
1508                 RETURN_ERROR(SP_ERR_MEM, "Handle array realloc() failed");
1509
1510         event_set->handles = new_handles;
1511
1512         if (!(new_masks = realloc(event_set->masks,
1513                         sizeof(enum sp_event) * (event_set->count + 1))))
1514                 RETURN_ERROR(SP_ERR_MEM, "Mask array realloc() failed");
1515
1516         event_set->masks = new_masks;
1517
1518         ((event_handle *) event_set->handles)[event_set->count] = handle;
1519         event_set->masks[event_set->count] = mask;
1520
1521         event_set->count++;
1522
1523         RETURN_OK();
1524 }
1525
1526 SP_API enum sp_return sp_add_port_events(struct sp_event_set *event_set,
1527         const struct sp_port *port, enum sp_event mask)
1528 {
1529         TRACE("%p, %p, %d", event_set, port, mask);
1530
1531         if (!event_set)
1532                 RETURN_ERROR(SP_ERR_ARG, "Null event set");
1533
1534         if (!port)
1535                 RETURN_ERROR(SP_ERR_ARG, "Null port");
1536
1537         if (mask > (SP_EVENT_RX_READY | SP_EVENT_TX_READY | SP_EVENT_ERROR))
1538                 RETURN_ERROR(SP_ERR_ARG, "Invalid event mask");
1539
1540         if (!mask)
1541                 RETURN_OK();
1542
1543 #ifdef _WIN32
1544         enum sp_event handle_mask;
1545         if ((handle_mask = mask & SP_EVENT_TX_READY))
1546                 TRY(add_handle(event_set, port->write_ovl.hEvent, handle_mask));
1547         if ((handle_mask = mask & (SP_EVENT_RX_READY | SP_EVENT_ERROR)))
1548                 TRY(add_handle(event_set, port->wait_ovl.hEvent, handle_mask));
1549 #else
1550         TRY(add_handle(event_set, port->fd, mask));
1551 #endif
1552
1553         RETURN_OK();
1554 }
1555
1556 SP_API void sp_free_event_set(struct sp_event_set *event_set)
1557 {
1558         TRACE("%p", event_set);
1559
1560         if (!event_set) {
1561                 DEBUG("Null event set");
1562                 RETURN();
1563         }
1564
1565         DEBUG("Freeing event set");
1566
1567         if (event_set->handles)
1568                 free(event_set->handles);
1569         if (event_set->masks)
1570                 free(event_set->masks);
1571
1572         free(event_set);
1573
1574         RETURN();
1575 }
1576
1577 SP_API enum sp_return sp_wait(struct sp_event_set *event_set,
1578                               unsigned int timeout_ms)
1579 {
1580         TRACE("%p, %d", event_set, timeout_ms);
1581
1582         if (!event_set)
1583                 RETURN_ERROR(SP_ERR_ARG, "Null event set");
1584
1585 #ifdef _WIN32
1586         if (WaitForMultipleObjects(event_set->count, event_set->handles, FALSE,
1587                         timeout_ms ? timeout_ms : INFINITE) == WAIT_FAILED)
1588                 RETURN_FAIL("WaitForMultipleObjects() failed");
1589
1590         RETURN_OK();
1591 #else
1592         struct timeout timeout;
1593         int result;
1594         struct pollfd *pollfds;
1595         unsigned int i;
1596
1597         if (!(pollfds = malloc(sizeof(struct pollfd) * event_set->count)))
1598                 RETURN_ERROR(SP_ERR_MEM, "pollfds malloc() failed");
1599
1600         for (i = 0; i < event_set->count; i++) {
1601                 pollfds[i].fd = ((int *)event_set->handles)[i];
1602                 pollfds[i].events = 0;
1603                 pollfds[i].revents = 0;
1604                 if (event_set->masks[i] & SP_EVENT_RX_READY)
1605                         pollfds[i].events |= POLLIN;
1606                 if (event_set->masks[i] & SP_EVENT_TX_READY)
1607                         pollfds[i].events |= POLLOUT;
1608                 if (event_set->masks[i] & SP_EVENT_ERROR)
1609                         pollfds[i].events |= POLLERR;
1610         }
1611
1612         timeout_start(&timeout, timeout_ms);
1613         timeout_limit(&timeout, INT_MAX);
1614
1615         /* Loop until an event occurs. */
1616         while (1) {
1617
1618                 if (timeout_check(&timeout)) {
1619                         DEBUG("Wait timed out");
1620                         break;
1621                 }
1622
1623                 result = poll(pollfds, event_set->count, timeout_remaining_ms(&timeout) || -1);
1624
1625                 timeout_update(&timeout);
1626
1627                 if (result < 0) {
1628                         if (errno == EINTR) {
1629                                 DEBUG("poll() call was interrupted, repeating");
1630                                 continue;
1631                         } else {
1632                                 free(pollfds);
1633                                 RETURN_FAIL("poll() failed");
1634                         }
1635                 } else if (result == 0) {
1636                         DEBUG("poll() timed out");
1637                         if (!timeout.overflow)
1638                                 break;
1639                 } else {
1640                         DEBUG("poll() completed");
1641                         break;
1642                 }
1643         }
1644
1645         free(pollfds);
1646         RETURN_OK();
1647 #endif
1648 }
1649
1650 #ifdef USE_TERMIOS_SPEED
1651 static enum sp_return get_baudrate(int fd, int *baudrate)
1652 {
1653         void *data;
1654
1655         TRACE("%d, %p", fd, baudrate);
1656
1657         DEBUG("Getting baud rate");
1658
1659         if (!(data = malloc(get_termios_size())))
1660                 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
1661
1662         if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
1663                 free(data);
1664                 RETURN_FAIL("Getting termios failed");
1665         }
1666
1667         *baudrate = get_termios_speed(data);
1668
1669         free(data);
1670
1671         RETURN_OK();
1672 }
1673
1674 static enum sp_return set_baudrate(int fd, int baudrate)
1675 {
1676         void *data;
1677
1678         TRACE("%d, %d", fd, baudrate);
1679
1680         DEBUG("Getting baud rate");
1681
1682         if (!(data = malloc(get_termios_size())))
1683                 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
1684
1685         if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
1686                 free(data);
1687                 RETURN_FAIL("Getting termios failed");
1688         }
1689
1690         DEBUG("Setting baud rate");
1691
1692         set_termios_speed(data, baudrate);
1693
1694         if (ioctl(fd, get_termios_set_ioctl(), data) < 0) {
1695                 free(data);
1696                 RETURN_FAIL("Setting termios failed");
1697         }
1698
1699         free(data);
1700
1701         RETURN_OK();
1702 }
1703 #endif /* USE_TERMIOS_SPEED */
1704
1705 #ifdef USE_TERMIOX
1706 static enum sp_return get_flow(int fd, struct port_data *data)
1707 {
1708         void *termx;
1709
1710         TRACE("%d, %p", fd, data);
1711
1712         DEBUG("Getting advanced flow control");
1713
1714         if (!(termx = malloc(get_termiox_size())))
1715                 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
1716
1717         if (ioctl(fd, TCGETX, termx) < 0) {
1718                 free(termx);
1719                 RETURN_FAIL("Getting termiox failed");
1720         }
1721
1722         get_termiox_flow(termx, &data->rts_flow, &data->cts_flow,
1723                         &data->dtr_flow, &data->dsr_flow);
1724
1725         free(termx);
1726
1727         RETURN_OK();
1728 }
1729
1730 static enum sp_return set_flow(int fd, struct port_data *data)
1731 {
1732         void *termx;
1733
1734         TRACE("%d, %p", fd, data);
1735
1736         DEBUG("Getting advanced flow control");
1737
1738         if (!(termx = malloc(get_termiox_size())))
1739                 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
1740
1741         if (ioctl(fd, TCGETX, termx) < 0) {
1742                 free(termx);
1743                 RETURN_FAIL("Getting termiox failed");
1744         }
1745
1746         DEBUG("Setting advanced flow control");
1747
1748         set_termiox_flow(termx, data->rts_flow, data->cts_flow,
1749                         data->dtr_flow, data->dsr_flow);
1750
1751         if (ioctl(fd, TCSETX, termx) < 0) {
1752                 free(termx);
1753                 RETURN_FAIL("Setting termiox failed");
1754         }
1755
1756         free(termx);
1757
1758         RETURN_OK();
1759 }
1760 #endif /* USE_TERMIOX */
1761
1762 static enum sp_return get_config(struct sp_port *port, struct port_data *data,
1763         struct sp_port_config *config)
1764 {
1765         unsigned int i;
1766
1767         TRACE("%p, %p, %p", port, data, config);
1768
1769         DEBUG_FMT("Getting configuration for port %s", port->name);
1770
1771 #ifdef _WIN32
1772         if (!GetCommState(port->hdl, &data->dcb))
1773                 RETURN_FAIL("GetCommState() failed");
1774
1775         for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1776                 if (data->dcb.BaudRate == std_baudrates[i].index) {
1777                         config->baudrate = std_baudrates[i].value;
1778                         break;
1779                 }
1780         }
1781
1782         if (i == NUM_STD_BAUDRATES)
1783                 /* BaudRate field can be either an index or a custom baud rate. */
1784                 config->baudrate = data->dcb.BaudRate;
1785
1786         config->bits = data->dcb.ByteSize;
1787
1788         if (data->dcb.fParity)
1789                 switch (data->dcb.Parity) {
1790                 case NOPARITY:
1791                         config->parity = SP_PARITY_NONE;
1792                         break;
1793                 case ODDPARITY:
1794                         config->parity = SP_PARITY_ODD;
1795                         break;
1796                 case EVENPARITY:
1797                         config->parity = SP_PARITY_EVEN;
1798                         break;
1799                 case MARKPARITY:
1800                         config->parity = SP_PARITY_MARK;
1801                         break;
1802                 case SPACEPARITY:
1803                         config->parity = SP_PARITY_SPACE;
1804                         break;
1805                 default:
1806                         config->parity = -1;
1807                 }
1808         else
1809                 config->parity = SP_PARITY_NONE;
1810
1811         switch (data->dcb.StopBits) {
1812         case ONESTOPBIT:
1813                 config->stopbits = 1;
1814                 break;
1815         case TWOSTOPBITS:
1816                 config->stopbits = 2;
1817                 break;
1818         default:
1819                 config->stopbits = -1;
1820         }
1821
1822         switch (data->dcb.fRtsControl) {
1823         case RTS_CONTROL_DISABLE:
1824                 config->rts = SP_RTS_OFF;
1825                 break;
1826         case RTS_CONTROL_ENABLE:
1827                 config->rts = SP_RTS_ON;
1828                 break;
1829         case RTS_CONTROL_HANDSHAKE:
1830                 config->rts = SP_RTS_FLOW_CONTROL;
1831                 break;
1832         default:
1833                 config->rts = -1;
1834         }
1835
1836         config->cts = data->dcb.fOutxCtsFlow ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1837
1838         switch (data->dcb.fDtrControl) {
1839         case DTR_CONTROL_DISABLE:
1840                 config->dtr = SP_DTR_OFF;
1841                 break;
1842         case DTR_CONTROL_ENABLE:
1843                 config->dtr = SP_DTR_ON;
1844                 break;
1845         case DTR_CONTROL_HANDSHAKE:
1846                 config->dtr = SP_DTR_FLOW_CONTROL;
1847                 break;
1848         default:
1849                 config->dtr = -1;
1850         }
1851
1852         config->dsr = data->dcb.fOutxDsrFlow ? SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1853
1854         if (data->dcb.fInX) {
1855                 if (data->dcb.fOutX)
1856                         config->xon_xoff = SP_XONXOFF_INOUT;
1857                 else
1858                         config->xon_xoff = SP_XONXOFF_IN;
1859         } else {
1860                 if (data->dcb.fOutX)
1861                         config->xon_xoff = SP_XONXOFF_OUT;
1862                 else
1863                         config->xon_xoff = SP_XONXOFF_DISABLED;
1864         }
1865
1866 #else // !_WIN32
1867
1868         if (tcgetattr(port->fd, &data->term) < 0)
1869                 RETURN_FAIL("tcgetattr() failed");
1870
1871         if (ioctl(port->fd, TIOCMGET, &data->controlbits) < 0)
1872                 RETURN_FAIL("TIOCMGET ioctl failed");
1873
1874 #ifdef USE_TERMIOX
1875         int ret = get_flow(port->fd, data);
1876
1877         if (ret == SP_ERR_FAIL && errno == EINVAL)
1878                 data->termiox_supported = 0;
1879         else if (ret < 0)
1880                 RETURN_CODEVAL(ret);
1881         else
1882                 data->termiox_supported = 1;
1883 #else
1884         data->termiox_supported = 0;
1885 #endif
1886
1887         for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1888                 if (cfgetispeed(&data->term) == std_baudrates[i].index) {
1889                         config->baudrate = std_baudrates[i].value;
1890                         break;
1891                 }
1892         }
1893
1894         if (i == NUM_STD_BAUDRATES) {
1895 #ifdef __APPLE__
1896                 config->baudrate = (int)data->term.c_ispeed;
1897 #elif defined(USE_TERMIOS_SPEED)
1898                 TRY(get_baudrate(port->fd, &config->baudrate));
1899 #else
1900                 config->baudrate = -1;
1901 #endif
1902         }
1903
1904         switch (data->term.c_cflag & CSIZE) {
1905         case CS8:
1906                 config->bits = 8;
1907                 break;
1908         case CS7:
1909                 config->bits = 7;
1910                 break;
1911         case CS6:
1912                 config->bits = 6;
1913                 break;
1914         case CS5:
1915                 config->bits = 5;
1916                 break;
1917         default:
1918                 config->bits = -1;
1919         }
1920
1921         if (!(data->term.c_cflag & PARENB) && (data->term.c_iflag & IGNPAR))
1922                 config->parity = SP_PARITY_NONE;
1923         else if (!(data->term.c_cflag & PARENB) || (data->term.c_iflag & IGNPAR))
1924                 config->parity = -1;
1925 #ifdef CMSPAR
1926         else if (data->term.c_cflag & CMSPAR)
1927                 config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_MARK : SP_PARITY_SPACE;
1928 #endif
1929         else
1930                 config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_ODD : SP_PARITY_EVEN;
1931
1932         config->stopbits = (data->term.c_cflag & CSTOPB) ? 2 : 1;
1933
1934         if (data->term.c_cflag & CRTSCTS) {
1935                 config->rts = SP_RTS_FLOW_CONTROL;
1936                 config->cts = SP_CTS_FLOW_CONTROL;
1937         } else {
1938                 if (data->termiox_supported && data->rts_flow)
1939                         config->rts = SP_RTS_FLOW_CONTROL;
1940                 else
1941                         config->rts = (data->controlbits & TIOCM_RTS) ? SP_RTS_ON : SP_RTS_OFF;
1942
1943                 config->cts = (data->termiox_supported && data->cts_flow) ?
1944                         SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1945         }
1946
1947         if (data->termiox_supported && data->dtr_flow)
1948                 config->dtr = SP_DTR_FLOW_CONTROL;
1949         else
1950                 config->dtr = (data->controlbits & TIOCM_DTR) ? SP_DTR_ON : SP_DTR_OFF;
1951
1952         config->dsr = (data->termiox_supported && data->dsr_flow) ?
1953                 SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1954
1955         if (data->term.c_iflag & IXOFF) {
1956                 if (data->term.c_iflag & IXON)
1957                         config->xon_xoff = SP_XONXOFF_INOUT;
1958                 else
1959                         config->xon_xoff = SP_XONXOFF_IN;
1960         } else {
1961                 if (data->term.c_iflag & IXON)
1962                         config->xon_xoff = SP_XONXOFF_OUT;
1963                 else
1964                         config->xon_xoff = SP_XONXOFF_DISABLED;
1965         }
1966 #endif
1967
1968         RETURN_OK();
1969 }
1970
1971 static enum sp_return set_config(struct sp_port *port, struct port_data *data,
1972         const struct sp_port_config *config)
1973 {
1974         unsigned int i;
1975 #ifdef __APPLE__
1976         BAUD_TYPE baud_nonstd;
1977
1978         baud_nonstd = B0;
1979 #endif
1980 #ifdef USE_TERMIOS_SPEED
1981         int baud_nonstd = 0;
1982 #endif
1983
1984         TRACE("%p, %p, %p", port, data, config);
1985
1986         DEBUG_FMT("Setting configuration for port %s", port->name);
1987
1988 #ifdef _WIN32
1989
1990         TRY(await_write_completion(port));
1991
1992         if (config->baudrate >= 0) {
1993                 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1994                         if (config->baudrate == std_baudrates[i].value) {
1995                                 data->dcb.BaudRate = std_baudrates[i].index;
1996                                 break;
1997                         }
1998                 }
1999
2000                 if (i == NUM_STD_BAUDRATES)
2001                         data->dcb.BaudRate = config->baudrate;
2002
2003                 /* Allocate write buffer for 50ms of data at baud rate. */
2004                 port->write_buf_size = max(config->baudrate / (8 * 20), 1);
2005                 port->write_buf = realloc(port->write_buf,
2006                                           port->write_buf_size);
2007
2008                 if (!port->write_buf)
2009                         RETURN_ERROR(SP_ERR_MEM, "Allocating write buffer failed");
2010         }
2011
2012         if (config->bits >= 0)
2013                 data->dcb.ByteSize = config->bits;
2014
2015         if (config->parity >= 0) {
2016                 switch (config->parity) {
2017                 case SP_PARITY_NONE:
2018                         data->dcb.Parity = NOPARITY;
2019                         break;
2020                 case SP_PARITY_ODD:
2021                         data->dcb.Parity = ODDPARITY;
2022                         break;
2023                 case SP_PARITY_EVEN:
2024                         data->dcb.Parity = EVENPARITY;
2025                         break;
2026                 case SP_PARITY_MARK:
2027                         data->dcb.Parity = MARKPARITY;
2028                         break;
2029                 case SP_PARITY_SPACE:
2030                         data->dcb.Parity = SPACEPARITY;
2031                         break;
2032                 default:
2033                         RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
2034                 }
2035         }
2036
2037         if (config->stopbits >= 0) {
2038                 switch (config->stopbits) {
2039                 /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
2040                 case 1:
2041                         data->dcb.StopBits = ONESTOPBIT;
2042                         break;
2043                 case 2:
2044                         data->dcb.StopBits = TWOSTOPBITS;
2045                         break;
2046                 default:
2047                         RETURN_ERROR(SP_ERR_ARG, "Invalid stop bit setting");
2048                 }
2049         }
2050
2051         if (config->rts >= 0) {
2052                 switch (config->rts) {
2053                 case SP_RTS_OFF:
2054                         data->dcb.fRtsControl = RTS_CONTROL_DISABLE;
2055                         break;
2056                 case SP_RTS_ON:
2057                         data->dcb.fRtsControl = RTS_CONTROL_ENABLE;
2058                         break;
2059                 case SP_RTS_FLOW_CONTROL:
2060                         data->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
2061                         break;
2062                 default:
2063                         RETURN_ERROR(SP_ERR_ARG, "Invalid RTS setting");
2064                 }
2065         }
2066
2067         if (config->cts >= 0) {
2068                 switch (config->cts) {
2069                 case SP_CTS_IGNORE:
2070                         data->dcb.fOutxCtsFlow = FALSE;
2071                         break;
2072                 case SP_CTS_FLOW_CONTROL:
2073                         data->dcb.fOutxCtsFlow = TRUE;
2074                         break;
2075                 default:
2076                         RETURN_ERROR(SP_ERR_ARG, "Invalid CTS setting");
2077                 }
2078         }
2079
2080         if (config->dtr >= 0) {
2081                 switch (config->dtr) {
2082                 case SP_DTR_OFF:
2083                         data->dcb.fDtrControl = DTR_CONTROL_DISABLE;
2084                         break;
2085                 case SP_DTR_ON:
2086                         data->dcb.fDtrControl = DTR_CONTROL_ENABLE;
2087                         break;
2088                 case SP_DTR_FLOW_CONTROL:
2089                         data->dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
2090                         break;
2091                 default:
2092                         RETURN_ERROR(SP_ERR_ARG, "Invalid DTR setting");
2093                 }
2094         }
2095
2096         if (config->dsr >= 0) {
2097                 switch (config->dsr) {
2098                 case SP_DSR_IGNORE:
2099                         data->dcb.fOutxDsrFlow = FALSE;
2100                         break;
2101                 case SP_DSR_FLOW_CONTROL:
2102                         data->dcb.fOutxDsrFlow = TRUE;
2103                         break;
2104                 default:
2105                         RETURN_ERROR(SP_ERR_ARG, "Invalid DSR setting");
2106                 }
2107         }
2108
2109         if (config->xon_xoff >= 0) {
2110                 switch (config->xon_xoff) {
2111                 case SP_XONXOFF_DISABLED:
2112                         data->dcb.fInX = FALSE;
2113                         data->dcb.fOutX = FALSE;
2114                         break;
2115                 case SP_XONXOFF_IN:
2116                         data->dcb.fInX = TRUE;
2117                         data->dcb.fOutX = FALSE;
2118                         break;
2119                 case SP_XONXOFF_OUT:
2120                         data->dcb.fInX = FALSE;
2121                         data->dcb.fOutX = TRUE;
2122                         break;
2123                 case SP_XONXOFF_INOUT:
2124                         data->dcb.fInX = TRUE;
2125                         data->dcb.fOutX = TRUE;
2126                         break;
2127                 default:
2128                         RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
2129                 }
2130         }
2131
2132         if (!SetCommState(port->hdl, &data->dcb))
2133                 RETURN_FAIL("SetCommState() failed");
2134
2135 #else /* !_WIN32 */
2136
2137         int controlbits;
2138
2139         if (config->baudrate >= 0) {
2140                 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
2141                         if (config->baudrate == std_baudrates[i].value) {
2142                                 if (cfsetospeed(&data->term, std_baudrates[i].index) < 0)
2143                                         RETURN_FAIL("cfsetospeed() failed");
2144
2145                                 if (cfsetispeed(&data->term, std_baudrates[i].index) < 0)
2146                                         RETURN_FAIL("cfsetispeed() failed");
2147                                 break;
2148                         }
2149                 }
2150
2151                 /* Non-standard baud rate */
2152                 if (i == NUM_STD_BAUDRATES) {
2153 #ifdef __APPLE__
2154                         /* Set "dummy" baud rate. */
2155                         if (cfsetspeed(&data->term, B9600) < 0)
2156                                 RETURN_FAIL("cfsetspeed() failed");
2157                         baud_nonstd = config->baudrate;
2158 #elif defined(USE_TERMIOS_SPEED)
2159                         baud_nonstd = 1;
2160 #else
2161                         RETURN_ERROR(SP_ERR_SUPP, "Non-standard baudrate not supported");
2162 #endif
2163                 }
2164         }
2165
2166         if (config->bits >= 0) {
2167                 data->term.c_cflag &= ~CSIZE;
2168                 switch (config->bits) {
2169                 case 8:
2170                         data->term.c_cflag |= CS8;
2171                         break;
2172                 case 7:
2173                         data->term.c_cflag |= CS7;
2174                         break;
2175                 case 6:
2176                         data->term.c_cflag |= CS6;
2177                         break;
2178                 case 5:
2179                         data->term.c_cflag |= CS5;
2180                         break;
2181                 default:
2182                         RETURN_ERROR(SP_ERR_ARG, "Invalid data bits setting");
2183                 }
2184         }
2185
2186         if (config->parity >= 0) {
2187                 data->term.c_iflag &= ~IGNPAR;
2188                 data->term.c_cflag &= ~(PARENB | PARODD);
2189 #ifdef CMSPAR
2190                 data->term.c_cflag &= ~CMSPAR;
2191 #endif
2192                 switch (config->parity) {
2193                 case SP_PARITY_NONE:
2194                         data->term.c_iflag |= IGNPAR;
2195                         break;
2196                 case SP_PARITY_EVEN:
2197                         data->term.c_cflag |= PARENB;
2198                         break;
2199                 case SP_PARITY_ODD:
2200                         data->term.c_cflag |= PARENB | PARODD;
2201                         break;
2202 #ifdef CMSPAR
2203                 case SP_PARITY_MARK:
2204                         data->term.c_cflag |= PARENB | PARODD;
2205                         data->term.c_cflag |= CMSPAR;
2206                         break;
2207                 case SP_PARITY_SPACE:
2208                         data->term.c_cflag |= PARENB;
2209                         data->term.c_cflag |= CMSPAR;
2210                         break;
2211 #else
2212                 case SP_PARITY_MARK:
2213                 case SP_PARITY_SPACE:
2214                         RETURN_ERROR(SP_ERR_SUPP, "Mark/space parity not supported");
2215 #endif
2216                 default:
2217                         RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
2218                 }
2219         }
2220
2221         if (config->stopbits >= 0) {
2222                 data->term.c_cflag &= ~CSTOPB;
2223                 switch (config->stopbits) {
2224                 case 1:
2225                         data->term.c_cflag &= ~CSTOPB;
2226                         break;
2227                 case 2:
2228                         data->term.c_cflag |= CSTOPB;
2229                         break;
2230                 default:
2231                         RETURN_ERROR(SP_ERR_ARG, "Invalid stop bits setting");
2232                 }
2233         }
2234
2235         if (config->rts >= 0 || config->cts >= 0) {
2236                 if (data->termiox_supported) {
2237                         data->rts_flow = data->cts_flow = 0;
2238                         switch (config->rts) {
2239                         case SP_RTS_OFF:
2240                         case SP_RTS_ON:
2241                                 controlbits = TIOCM_RTS;
2242                                 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
2243                                         RETURN_FAIL("Setting RTS signal level failed");
2244                                 break;
2245                         case SP_RTS_FLOW_CONTROL:
2246                                 data->rts_flow = 1;
2247                                 break;
2248                         default:
2249                                 break;
2250                         }
2251                         if (config->cts == SP_CTS_FLOW_CONTROL)
2252                                 data->cts_flow = 1;
2253
2254                         if (data->rts_flow && data->cts_flow)
2255                                 data->term.c_iflag |= CRTSCTS;
2256                         else
2257                                 data->term.c_iflag &= ~CRTSCTS;
2258                 } else {
2259                         /* Asymmetric use of RTS/CTS not supported. */
2260                         if (data->term.c_iflag & CRTSCTS) {
2261                                 /* Flow control can only be disabled for both RTS & CTS together. */
2262                                 if (config->rts >= 0 && config->rts != SP_RTS_FLOW_CONTROL) {
2263                                         if (config->cts != SP_CTS_IGNORE)
2264                                                 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
2265                                 }
2266                                 if (config->cts >= 0 && config->cts != SP_CTS_FLOW_CONTROL) {
2267                                         if (config->rts <= 0 || config->rts == SP_RTS_FLOW_CONTROL)
2268                                                 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
2269                                 }
2270                         } else {
2271                                 /* Flow control can only be enabled for both RTS & CTS together. */
2272                                 if (((config->rts == SP_RTS_FLOW_CONTROL) && (config->cts != SP_CTS_FLOW_CONTROL)) ||
2273                                         ((config->cts == SP_CTS_FLOW_CONTROL) && (config->rts != SP_RTS_FLOW_CONTROL)))
2274                                         RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be enabled together");
2275                         }
2276
2277                         if (config->rts >= 0) {
2278                                 if (config->rts == SP_RTS_FLOW_CONTROL) {
2279                                         data->term.c_iflag |= CRTSCTS;
2280                                 } else {
2281                                         controlbits = TIOCM_RTS;
2282                                         if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC,
2283                                                         &controlbits) < 0)
2284                                                 RETURN_FAIL("Setting RTS signal level failed");
2285                                 }
2286                         }
2287                 }
2288         }
2289
2290         if (config->dtr >= 0 || config->dsr >= 0) {
2291                 if (data->termiox_supported) {
2292                         data->dtr_flow = data->dsr_flow = 0;
2293                         switch (config->dtr) {
2294                         case SP_DTR_OFF:
2295                         case SP_DTR_ON:
2296                                 controlbits = TIOCM_DTR;
2297                                 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
2298                                         RETURN_FAIL("Setting DTR signal level failed");
2299                                 break;
2300                         case SP_DTR_FLOW_CONTROL:
2301                                 data->dtr_flow = 1;
2302                                 break;
2303                         default:
2304                                 break;
2305                         }
2306                         if (config->dsr == SP_DSR_FLOW_CONTROL)
2307                                 data->dsr_flow = 1;
2308                 } else {
2309                         /* DTR/DSR flow control not supported. */
2310                         if (config->dtr == SP_DTR_FLOW_CONTROL || config->dsr == SP_DSR_FLOW_CONTROL)
2311                                 RETURN_ERROR(SP_ERR_SUPP, "DTR/DSR flow control not supported");
2312
2313                         if (config->dtr >= 0) {
2314                                 controlbits = TIOCM_DTR;
2315                                 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC,
2316                                                 &controlbits) < 0)
2317                                         RETURN_FAIL("Setting DTR signal level failed");
2318                         }
2319                 }
2320         }
2321
2322         if (config->xon_xoff >= 0) {
2323                 data->term.c_iflag &= ~(IXON | IXOFF | IXANY);
2324                 switch (config->xon_xoff) {
2325                 case SP_XONXOFF_DISABLED:
2326                         break;
2327                 case SP_XONXOFF_IN:
2328                         data->term.c_iflag |= IXOFF;
2329                         break;
2330                 case SP_XONXOFF_OUT:
2331                         data->term.c_iflag |= IXON | IXANY;
2332                         break;
2333                 case SP_XONXOFF_INOUT:
2334                         data->term.c_iflag |= IXON | IXOFF | IXANY;
2335                         break;
2336                 default:
2337                         RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
2338                 }
2339         }
2340
2341         if (tcsetattr(port->fd, TCSANOW, &data->term) < 0)
2342                 RETURN_FAIL("tcsetattr() failed");
2343
2344 #ifdef __APPLE__
2345         if (baud_nonstd != B0) {
2346                 if (ioctl(port->fd, IOSSIOSPEED, &baud_nonstd) == -1)
2347                         RETURN_FAIL("IOSSIOSPEED ioctl failed");
2348                 /*
2349                  * Set baud rates in data->term to correct, but incompatible
2350                  * with tcsetattr() value, same as delivered by tcgetattr().
2351                  */
2352                 if (cfsetspeed(&data->term, baud_nonstd) < 0)
2353                         RETURN_FAIL("cfsetspeed() failed");
2354         }
2355 #elif defined(__linux__)
2356 #ifdef USE_TERMIOS_SPEED
2357         if (baud_nonstd)
2358                 TRY(set_baudrate(port->fd, config->baudrate));
2359 #endif
2360 #ifdef USE_TERMIOX
2361         if (data->termiox_supported)
2362                 TRY(set_flow(port->fd, data));
2363 #endif
2364 #endif
2365
2366 #endif /* !_WIN32 */
2367
2368         RETURN_OK();
2369 }
2370
2371 SP_API enum sp_return sp_new_config(struct sp_port_config **config_ptr)
2372 {
2373         struct sp_port_config *config;
2374
2375         TRACE("%p", config_ptr);
2376
2377         if (!config_ptr)
2378                 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
2379
2380         *config_ptr = NULL;
2381
2382         if (!(config = malloc(sizeof(struct sp_port_config))))
2383                 RETURN_ERROR(SP_ERR_MEM, "Config malloc failed");
2384
2385         config->baudrate = -1;
2386         config->bits = -1;
2387         config->parity = -1;
2388         config->stopbits = -1;
2389         config->rts = -1;
2390         config->cts = -1;
2391         config->dtr = -1;
2392         config->dsr = -1;
2393
2394         *config_ptr = config;
2395
2396         RETURN_OK();
2397 }
2398
2399 SP_API void sp_free_config(struct sp_port_config *config)
2400 {
2401         TRACE("%p", config);
2402
2403         if (!config)
2404                 DEBUG("Null config");
2405         else
2406                 free(config);
2407
2408         RETURN();
2409 }
2410
2411 SP_API enum sp_return sp_get_config(struct sp_port *port,
2412                                     struct sp_port_config *config)
2413 {
2414         struct port_data data;
2415
2416         TRACE("%p, %p", port, config);
2417
2418         CHECK_OPEN_PORT();
2419
2420         if (!config)
2421                 RETURN_ERROR(SP_ERR_ARG, "Null config");
2422
2423         TRY(get_config(port, &data, config));
2424
2425         RETURN_OK();
2426 }
2427
2428 SP_API enum sp_return sp_set_config(struct sp_port *port,
2429                                     const struct sp_port_config *config)
2430 {
2431         struct port_data data;
2432         struct sp_port_config prev_config;
2433
2434         TRACE("%p, %p", port, config);
2435
2436         CHECK_OPEN_PORT();
2437
2438         if (!config)
2439                 RETURN_ERROR(SP_ERR_ARG, "Null config");
2440
2441         TRY(get_config(port, &data, &prev_config));
2442         TRY(set_config(port, &data, config));
2443
2444         RETURN_OK();
2445 }
2446
2447 #define CREATE_ACCESSORS(x, type) \
2448 SP_API enum sp_return sp_set_##x(struct sp_port *port, type x) { \
2449         struct port_data data; \
2450         struct sp_port_config config; \
2451         TRACE("%p, %d", port, x); \
2452         CHECK_OPEN_PORT(); \
2453         TRY(get_config(port, &data, &config)); \
2454         config.x = x; \
2455         TRY(set_config(port, &data, &config)); \
2456         RETURN_OK(); \
2457 } \
2458 SP_API enum sp_return sp_get_config_##x(const struct sp_port_config *config, \
2459                                         type *x) { \
2460         TRACE("%p, %p", config, x); \
2461         if (!x) \
2462                 RETURN_ERROR(SP_ERR_ARG, "Null result pointer"); \
2463         if (!config) \
2464                 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
2465         *x = config->x; \
2466         RETURN_OK(); \
2467 } \
2468 SP_API enum sp_return sp_set_config_##x(struct sp_port_config *config, \
2469                                         type x) { \
2470         TRACE("%p, %d", config, x); \
2471         if (!config) \
2472                 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
2473         config->x = x; \
2474         RETURN_OK(); \
2475 }
2476
2477 CREATE_ACCESSORS(baudrate, int)
2478 CREATE_ACCESSORS(bits, int)
2479 CREATE_ACCESSORS(parity, enum sp_parity)
2480 CREATE_ACCESSORS(stopbits, int)
2481 CREATE_ACCESSORS(rts, enum sp_rts)
2482 CREATE_ACCESSORS(cts, enum sp_cts)
2483 CREATE_ACCESSORS(dtr, enum sp_dtr)
2484 CREATE_ACCESSORS(dsr, enum sp_dsr)
2485 CREATE_ACCESSORS(xon_xoff, enum sp_xonxoff)
2486
2487 SP_API enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config,
2488                                                 enum sp_flowcontrol flowcontrol)
2489 {
2490         if (!config)
2491                 RETURN_ERROR(SP_ERR_ARG, "Null configuration");
2492
2493         if (flowcontrol > SP_FLOWCONTROL_DTRDSR)
2494                 RETURN_ERROR(SP_ERR_ARG, "Invalid flow control setting");
2495
2496         if (flowcontrol == SP_FLOWCONTROL_XONXOFF)
2497                 config->xon_xoff = SP_XONXOFF_INOUT;
2498         else
2499                 config->xon_xoff = SP_XONXOFF_DISABLED;
2500
2501         if (flowcontrol == SP_FLOWCONTROL_RTSCTS) {
2502                 config->rts = SP_RTS_FLOW_CONTROL;
2503                 config->cts = SP_CTS_FLOW_CONTROL;
2504         } else {
2505                 if (config->rts == SP_RTS_FLOW_CONTROL)
2506                         config->rts = SP_RTS_ON;
2507                 config->cts = SP_CTS_IGNORE;
2508         }
2509
2510         if (flowcontrol == SP_FLOWCONTROL_DTRDSR) {
2511                 config->dtr = SP_DTR_FLOW_CONTROL;
2512                 config->dsr = SP_DSR_FLOW_CONTROL;
2513         } else {
2514                 if (config->dtr == SP_DTR_FLOW_CONTROL)
2515                         config->dtr = SP_DTR_ON;
2516                 config->dsr = SP_DSR_IGNORE;
2517         }
2518
2519         RETURN_OK();
2520 }
2521
2522 SP_API enum sp_return sp_set_flowcontrol(struct sp_port *port,
2523                                          enum sp_flowcontrol flowcontrol)
2524 {
2525         struct port_data data;
2526         struct sp_port_config config;
2527
2528         TRACE("%p, %d", port, flowcontrol);
2529
2530         CHECK_OPEN_PORT();
2531
2532         TRY(get_config(port, &data, &config));
2533
2534         TRY(sp_set_config_flowcontrol(&config, flowcontrol));
2535
2536         TRY(set_config(port, &data, &config));
2537
2538         RETURN_OK();
2539 }
2540
2541 SP_API enum sp_return sp_get_signals(struct sp_port *port,
2542                                      enum sp_signal *signals)
2543 {
2544         TRACE("%p, %p", port, signals);
2545
2546         CHECK_OPEN_PORT();
2547
2548         if (!signals)
2549                 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
2550
2551         DEBUG_FMT("Getting control signals for port %s", port->name);
2552
2553         *signals = 0;
2554 #ifdef _WIN32
2555         DWORD bits;
2556         if (GetCommModemStatus(port->hdl, &bits) == 0)
2557                 RETURN_FAIL("GetCommModemStatus() failed");
2558         if (bits & MS_CTS_ON)
2559                 *signals |= SP_SIG_CTS;
2560         if (bits & MS_DSR_ON)
2561                 *signals |= SP_SIG_DSR;
2562         if (bits & MS_RLSD_ON)
2563                 *signals |= SP_SIG_DCD;
2564         if (bits & MS_RING_ON)
2565                 *signals |= SP_SIG_RI;
2566 #else
2567         int bits;
2568         if (ioctl(port->fd, TIOCMGET, &bits) < 0)
2569                 RETURN_FAIL("TIOCMGET ioctl failed");
2570         if (bits & TIOCM_CTS)
2571                 *signals |= SP_SIG_CTS;
2572         if (bits & TIOCM_DSR)
2573                 *signals |= SP_SIG_DSR;
2574         if (bits & TIOCM_CAR)
2575                 *signals |= SP_SIG_DCD;
2576         if (bits & TIOCM_RNG)
2577                 *signals |= SP_SIG_RI;
2578 #endif
2579         RETURN_OK();
2580 }
2581
2582 SP_API enum sp_return sp_start_break(struct sp_port *port)
2583 {
2584         TRACE("%p", port);
2585
2586         CHECK_OPEN_PORT();
2587 #ifdef _WIN32
2588         if (SetCommBreak(port->hdl) == 0)
2589                 RETURN_FAIL("SetCommBreak() failed");
2590 #else
2591         if (ioctl(port->fd, TIOCSBRK, 1) < 0)
2592                 RETURN_FAIL("TIOCSBRK ioctl failed");
2593 #endif
2594
2595         RETURN_OK();
2596 }
2597
2598 SP_API enum sp_return sp_end_break(struct sp_port *port)
2599 {
2600         TRACE("%p", port);
2601
2602         CHECK_OPEN_PORT();
2603 #ifdef _WIN32
2604         if (ClearCommBreak(port->hdl) == 0)
2605                 RETURN_FAIL("ClearCommBreak() failed");
2606 #else
2607         if (ioctl(port->fd, TIOCCBRK, 1) < 0)
2608                 RETURN_FAIL("TIOCCBRK ioctl failed");
2609 #endif
2610
2611         RETURN_OK();
2612 }
2613
2614 SP_API int sp_last_error_code(void)
2615 {
2616         TRACE_VOID();
2617 #ifdef _WIN32
2618         RETURN_INT(GetLastError());
2619 #else
2620         RETURN_INT(errno);
2621 #endif
2622 }
2623
2624 SP_API char *sp_last_error_message(void)
2625 {
2626         TRACE_VOID();
2627
2628 #ifdef _WIN32
2629         TCHAR *message;
2630         DWORD error = GetLastError();
2631
2632         DWORD length = FormatMessage(
2633                 FORMAT_MESSAGE_ALLOCATE_BUFFER |
2634                 FORMAT_MESSAGE_FROM_SYSTEM |
2635                 FORMAT_MESSAGE_IGNORE_INSERTS,
2636                 NULL,
2637                 error,
2638                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2639                 (LPTSTR) &message,
2640                 0, NULL );
2641
2642         if (length >= 2 && message[length - 2] == '\r')
2643                 message[length - 2] = '\0';
2644
2645         RETURN_STRING(message);
2646 #else
2647         RETURN_STRING(strerror(errno));
2648 #endif
2649 }
2650
2651 SP_API void sp_free_error_message(char *message)
2652 {
2653         TRACE("%s", message);
2654
2655 #ifdef _WIN32
2656         LocalFree(message);
2657 #else
2658         (void)message;
2659 #endif
2660
2661         RETURN();
2662 }
2663
2664 SP_API void sp_set_debug_handler(void (*handler)(const char *format, ...))
2665 {
2666         TRACE("%p", handler);
2667
2668         sp_debug_handler = handler;
2669
2670         RETURN();
2671 }
2672
2673 SP_API void sp_default_debug_handler(const char *format, ...)
2674 {
2675         va_list args;
2676         va_start(args, format);
2677         if (getenv("LIBSERIALPORT_DEBUG")) {
2678                 fputs("sp: ", stderr);
2679                 vfprintf(stderr, format, args);
2680         }
2681         va_end(args);
2682 }
2683
2684 SP_API int sp_get_major_package_version(void)
2685 {
2686         return SP_PACKAGE_VERSION_MAJOR;
2687 }
2688
2689 SP_API int sp_get_minor_package_version(void)
2690 {
2691         return SP_PACKAGE_VERSION_MINOR;
2692 }
2693
2694 SP_API int sp_get_micro_package_version(void)
2695 {
2696         return SP_PACKAGE_VERSION_MICRO;
2697 }
2698
2699 SP_API const char *sp_get_package_version_string(void)
2700 {
2701         return SP_PACKAGE_VERSION_STRING;
2702 }
2703
2704 SP_API int sp_get_current_lib_version(void)
2705 {
2706         return SP_LIB_VERSION_CURRENT;
2707 }
2708
2709 SP_API int sp_get_revision_lib_version(void)
2710 {
2711         return SP_LIB_VERSION_REVISION;
2712 }
2713
2714 SP_API int sp_get_age_lib_version(void)
2715 {
2716         return SP_LIB_VERSION_AGE;
2717 }
2718
2719 SP_API const char *sp_get_lib_version_string(void)
2720 {
2721         return SP_LIB_VERSION_STRING;
2722 }
2723
2724 /** @} */