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