2 * This file is part of the libserialport project.
4 * Copyright (C) 2010-2012 Bert Vermeulen <bert@biot.com>
5 * Copyright (C) 2010-2012 Uwe Hermann <uwe@hermann-uwe.de>
6 * Copyright (C) 2013 Martin Ling <martin-libserialport@earth.li>
7 * Copyright (C) 2013 Matthias Heidbrink <m-sigrok@heidbrink.biz>
9 * This program is free software: you can redistribute it and/or modify
10 * it under the terms of the GNU Lesser General Public License as
11 * published by the Free Software Foundation, either version 3 of the
12 * License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU Lesser General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <sys/types.h>
39 #include <sys/ioctl.h>
44 #include <IOKit/IOKitLib.h>
45 #include <IOKit/serial/IOSerialKeys.h>
46 #include <IOKit/serial/ioss.h>
47 #include <sys/syslimits.h>
51 #include "linux/serial.h"
52 #include "linux_termios.h"
53 #if defined(TCGETX) && defined(TCSETX) && defined(HAVE_TERMIOX)
59 #include "linux_termios.h"
62 #include "libserialport.h"
68 COMMTIMEOUTS timeouts;
78 struct sp_port_config {
81 enum sp_parity parity;
87 enum sp_xonxoff xon_xoff;
96 int termiox_supported;
101 /* Standard baud rates. */
103 #define BAUD_TYPE DWORD
104 #define BAUD(n) {CBR_##n, n}
106 #define BAUD_TYPE speed_t
107 #define BAUD(n) {B##n, n}
110 struct std_baudrate {
115 const struct std_baudrate std_baudrates[] = {
118 * The baudrates 50/75/134/150/200/1800/230400/460800 do not seem to
119 * have documented CBR_* macros.
121 BAUD(110), BAUD(300), BAUD(600), BAUD(1200), BAUD(2400), BAUD(4800),
122 BAUD(9600), BAUD(14400), BAUD(19200), BAUD(38400), BAUD(57600),
123 BAUD(115200), BAUD(128000), BAUD(256000),
125 BAUD(50), BAUD(75), BAUD(110), BAUD(134), BAUD(150), BAUD(200),
126 BAUD(300), BAUD(600), BAUD(1200), BAUD(1800), BAUD(2400), BAUD(4800),
127 BAUD(9600), BAUD(19200), BAUD(38400), BAUD(57600), BAUD(115200),
129 #if !defined(__APPLE__) && !defined(__OpenBSD__)
135 void (*sp_debug_handler)(const char *format, ...) = sp_default_debug_handler;
137 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
138 #define NUM_STD_BAUDRATES ARRAY_SIZE(std_baudrates)
140 /* Debug output macros. */
141 #define DEBUG(fmt, ...) do { if (sp_debug_handler) sp_debug_handler(fmt ".\n", ##__VA_ARGS__); } while (0)
142 #define DEBUG_ERROR(err, msg) DEBUG("%s returning " #err ": " msg, __func__)
143 #define DEBUG_FAIL(msg) do { \
144 char *errmsg = sp_last_error_message(); \
145 DEBUG("%s returning SP_ERR_FAIL: " msg ": %s", __func__, errmsg); \
146 sp_free_error_message(errmsg); \
148 #define RETURN() do { DEBUG("%s returning", __func__); return; } while(0)
149 #define RETURN_CODE(x) do { DEBUG("%s returning " #x, __func__); return x; } while (0)
150 #define RETURN_CODEVAL(x) do { \
152 case SP_OK: RETURN_CODE(SP_OK); \
153 case SP_ERR_ARG: RETURN_CODE(SP_ERR_ARG); \
154 case SP_ERR_FAIL: RETURN_CODE(SP_ERR_FAIL); \
155 case SP_ERR_MEM: RETURN_CODE(SP_ERR_MEM); \
156 case SP_ERR_SUPP: RETURN_CODE(SP_ERR_SUPP); \
159 #define RETURN_OK() RETURN_CODE(SP_OK);
160 #define RETURN_ERROR(err, msg) do { DEBUG_ERROR(err, msg); return err; } while (0)
161 #define RETURN_FAIL(msg) do { DEBUG_FAIL(msg); return SP_ERR_FAIL; } while (0)
162 #define RETURN_VALUE(fmt, x) do { DEBUG("%s returning " fmt, __func__, x); return x; } while (0)
163 #define SET_ERROR(val, err, msg) do { DEBUG_ERROR(err, msg); val = err; } while (0)
164 #define SET_FAIL(val, msg) do { DEBUG_FAIL(msg); val = SP_ERR_FAIL; } while (0)
165 #define TRACE(fmt, ...) DEBUG("%s(" fmt ") called", __func__, ##__VA_ARGS__)
167 #define TRY(x) do { int ret = x; if (ret != SP_OK) RETURN_CODEVAL(ret); } while (0)
169 /* Helper functions. */
170 static struct sp_port **list_append(struct sp_port **list, const char *portname);
171 static enum sp_return get_config(struct sp_port *port, struct port_data *data,
172 struct sp_port_config *config);
173 static enum sp_return set_config(struct sp_port *port, struct port_data *data,
174 const struct sp_port_config *config);
176 enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_ptr)
178 struct sp_port *port;
181 TRACE("%s, %p", portname, port_ptr);
184 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
189 RETURN_ERROR(SP_ERR_ARG, "Null port name");
191 DEBUG("Building structure for port %s", portname);
193 if (!(port = malloc(sizeof(struct sp_port))))
194 RETURN_ERROR(SP_ERR_MEM, "Port structure malloc failed");
196 len = strlen(portname) + 1;
198 if (!(port->name = malloc(len))) {
200 RETURN_ERROR(SP_ERR_MEM, "Port name malloc failed");
203 memcpy(port->name, portname, len);
206 port->hdl = INVALID_HANDLE_VALUE;
216 char *sp_get_port_name(const struct sp_port *port)
223 RETURN_VALUE("%s", port->name);
226 enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr)
228 TRACE("%p, %p", port, result_ptr);
231 RETURN_ERROR(SP_ERR_ARG, "Null port");
234 HANDLE *handle_ptr = result_ptr;
235 *handle_ptr = port->hdl;
237 int *fd_ptr = result_ptr;
244 enum sp_return sp_copy_port(const struct sp_port *port, struct sp_port **copy_ptr)
246 TRACE("%p, %p", port, copy_ptr);
249 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
254 RETURN_ERROR(SP_ERR_ARG, "Null port");
257 RETURN_ERROR(SP_ERR_ARG, "Null port name");
259 DEBUG("Copying port structure");
261 RETURN_VALUE("%p", sp_get_port_by_name(port->name, copy_ptr));
264 void sp_free_port(struct sp_port *port)
273 DEBUG("Freeing port structure");
283 static struct sp_port **list_append(struct sp_port **list, const char *portname)
288 for (count = 0; list[count]; count++);
289 if (!(tmp = realloc(list, sizeof(struct sp_port *) * (count + 2))))
292 if (sp_get_port_by_name(portname, &list[count]) != SP_OK)
294 list[count + 1] = NULL;
298 sp_free_port_list(list);
302 enum sp_return sp_list_ports(struct sp_port ***list_ptr)
304 struct sp_port **list;
305 int ret = SP_ERR_SUPP;
307 TRACE("%p", list_ptr);
310 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
312 DEBUG("Enumerating ports");
314 if (!(list = malloc(sizeof(struct sp_port **))))
315 RETURN_ERROR(SP_ERR_MEM, "Port list malloc failed");
322 DWORD max_value_len, max_data_size, max_data_len;
323 DWORD value_len, data_size, data_len;
324 DWORD type, index = 0;
330 DEBUG("Opening registry key");
331 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
332 0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS) {
333 SET_FAIL(ret, "RegOpenKeyEx() failed");
336 DEBUG("Querying registry key value and data sizes");
337 if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
338 &max_value_len, &max_data_size, NULL, NULL) != ERROR_SUCCESS) {
339 SET_FAIL(ret, "RegQueryInfoKey() failed");
342 max_data_len = max_data_size / sizeof(TCHAR);
343 if (!(value = malloc((max_value_len + 1) * sizeof(TCHAR)))) {
344 SET_ERROR(ret, SP_ERR_MEM, "registry value malloc failed");
347 if (!(data = malloc((max_data_len + 1) * sizeof(TCHAR)))) {
348 SET_ERROR(ret, SP_ERR_MEM, "registry data malloc failed");
351 DEBUG("Iterating over values");
353 value_len = max_value_len + 1,
354 data_size = max_data_size,
355 RegEnumValue(key, index, value, &value_len,
356 NULL, &type, (LPBYTE)data, &data_size) == ERROR_SUCCESS)
358 data_len = data_size / sizeof(TCHAR);
359 data[data_len] = '\0';
361 name_len = WideCharToMultiByte(CP_ACP, 0, data, -1, NULL, 0, NULL, NULL)
363 name_len = data_len + 1;
365 if (!(name = malloc(name_len))) {
366 SET_ERROR(ret, SP_ERR_MEM, "registry port name malloc failed");
370 WideCharToMultiByte(CP_ACP, 0, data, -1, name, name_len, NULL, NULL);
374 if (type == REG_SZ) {
375 DEBUG("Found port %s", name);
376 if (!(list = list_append(list, name))) {
377 SET_ERROR(ret, SP_ERR_MEM, "list append failed");
393 CFMutableDictionaryRef classes;
402 DEBUG("Getting IOKit master port");
403 if (IOMasterPort(MACH_PORT_NULL, &master) != KERN_SUCCESS) {
404 SET_FAIL(ret, "IOMasterPort() failed");
408 DEBUG("Creating matching dictionary");
409 if (!(classes = IOServiceMatching(kIOSerialBSDServiceValue))) {
410 SET_FAIL(ret, "IOServiceMatching() failed");
414 CFDictionarySetValue(classes,
415 CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes));
417 DEBUG("Getting matching services");
418 if (IOServiceGetMatchingServices(master, classes, &iter) != KERN_SUCCESS) {
419 SET_FAIL(ret, "IOServiceGetMatchingServices() failed");
423 if (!(path = malloc(PATH_MAX))) {
424 SET_ERROR(ret, SP_ERR_MEM, "device path malloc failed");
428 DEBUG("Iterating over results");
429 while ((port = IOIteratorNext(iter))) {
430 cf_path = IORegistryEntryCreateCFProperty(port,
431 CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
433 result = CFStringGetCString(cf_path,
434 path, PATH_MAX, kCFStringEncodingASCII);
437 DEBUG("Found port %s", path);
438 if (!(list = list_append(list, path))) {
439 SET_ERROR(ret, SP_ERR_MEM, "list append failed");
440 IOObjectRelease(port);
445 IOObjectRelease(port);
450 IOObjectRelease(iter);
455 struct udev_enumerate *ud_enumerate;
456 struct udev_list_entry *ud_list;
457 struct udev_list_entry *ud_entry;
459 struct udev_device *ud_dev, *ud_parent;
462 int fd, ioctl_result;
463 struct serial_struct serial_info;
467 DEBUG("Enumerating tty devices");
469 ud_enumerate = udev_enumerate_new(ud);
470 udev_enumerate_add_match_subsystem(ud_enumerate, "tty");
471 udev_enumerate_scan_devices(ud_enumerate);
472 ud_list = udev_enumerate_get_list_entry(ud_enumerate);
473 DEBUG("Iterating over results");
474 udev_list_entry_foreach(ud_entry, ud_list) {
475 path = udev_list_entry_get_name(ud_entry);
476 DEBUG("Found device %s", path);
477 ud_dev = udev_device_new_from_syspath(ud, path);
478 /* If there is no parent device, this is a virtual tty. */
479 ud_parent = udev_device_get_parent(ud_dev);
480 if (ud_parent == NULL) {
481 DEBUG("No parent device, assuming virtual tty");
482 udev_device_unref(ud_dev);
485 name = udev_device_get_devnode(ud_dev);
486 /* The serial8250 driver has a hardcoded number of ports.
487 * The only way to tell which actually exist on a given system
488 * is to try to open them and make an ioctl call. */
489 driver = udev_device_get_driver(ud_parent);
490 if (driver && !strcmp(driver, "serial8250")) {
491 DEBUG("serial8250 device, attempting to open");
492 if ((fd = open(name, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
493 DEBUG("open failed, skipping");
496 ioctl_result = ioctl(fd, TIOCGSERIAL, &serial_info);
498 if (ioctl_result != 0) {
499 DEBUG("ioctl failed, skipping");
502 if (serial_info.type == PORT_UNKNOWN) {
503 DEBUG("port type is unknown, skipping");
507 DEBUG("Found port %s", name);
508 list = list_append(list, name);
510 udev_device_unref(ud_dev);
512 SET_ERROR(ret, SP_ERR_MEM, "list append failed");
517 udev_enumerate_unref(ud_enumerate);
526 DEBUG_ERROR(SP_ERR_SUPP, "Enumeration not supported on this platform.");
529 sp_free_port_list(list);
535 void sp_free_port_list(struct sp_port **list)
546 DEBUG("Freeing port list");
548 for (i = 0; list[i]; i++)
549 sp_free_port(list[i]);
555 #define CHECK_PORT() do { \
557 RETURN_ERROR(SP_ERR_ARG, "Null port"); \
558 if (port->name == NULL) \
559 RETURN_ERROR(SP_ERR_ARG, "Null port name"); \
562 #define CHECK_PORT_HANDLE() do { \
563 if (port->hdl == INVALID_HANDLE_VALUE) \
564 RETURN_ERROR(SP_ERR_ARG, "Invalid port handle"); \
567 #define CHECK_PORT_HANDLE() do { \
569 RETURN_ERROR(SP_ERR_ARG, "Invalid port fd"); \
572 #define CHECK_OPEN_PORT() do { \
574 CHECK_PORT_HANDLE(); \
577 enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
579 struct port_data data;
580 struct sp_port_config config;
583 TRACE("%p, 0x%x", port, flags);
587 if (flags > (SP_MODE_READ | SP_MODE_WRITE))
588 RETURN_ERROR(SP_ERR_ARG, "Invalid flags");
590 DEBUG("Opening port %s", port->name);
593 DWORD desired_access = 0, flags_and_attributes = 0;
594 char *escaped_port_name;
596 /* Prefix port name with '\\.\' to work with ports above COM9. */
597 if (!(escaped_port_name = malloc(strlen(port->name + 5))))
598 RETURN_ERROR(SP_ERR_MEM, "Escaped port name malloc failed");
599 sprintf(escaped_port_name, "\\\\.\\%s", port->name);
601 /* Map 'flags' to the OS-specific settings. */
602 flags_and_attributes = FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED;
603 if (flags & SP_MODE_READ)
604 desired_access |= GENERIC_READ;
605 if (flags & SP_MODE_WRITE)
606 desired_access |= GENERIC_WRITE;
608 port->hdl = CreateFile(escaped_port_name, desired_access, 0, 0,
609 OPEN_EXISTING, flags_and_attributes, 0);
611 free(escaped_port_name);
613 if (port->hdl == INVALID_HANDLE_VALUE)
614 RETURN_FAIL("port CreateFile() failed");
616 /* All timeouts initially disabled. */
617 port->timeouts.ReadIntervalTimeout = 0;
618 port->timeouts.ReadTotalTimeoutMultiplier = 0;
619 port->timeouts.ReadTotalTimeoutConstant = 0;
620 port->timeouts.WriteTotalTimeoutMultiplier = 0;
621 port->timeouts.WriteTotalTimeoutConstant = 0;
623 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0) {
625 RETURN_FAIL("SetCommTimeouts() failed");
628 /* Prepare OVERLAPPED structures. */
629 memset(&port->read_ovl, 0, sizeof(port->read_ovl));
630 memset(&port->write_ovl, 0, sizeof(port->write_ovl));
631 port->read_ovl.hEvent = INVALID_HANDLE_VALUE;
632 port->write_ovl.hEvent = INVALID_HANDLE_VALUE;
633 if ((port->read_ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == INVALID_HANDLE_VALUE) {
635 RETURN_FAIL("read event CreateEvent() failed");
637 if ((port->write_ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == INVALID_HANDLE_VALUE) {
639 RETURN_FAIL("write event CreateEvent() failed");
642 port->writing = FALSE;
645 int flags_local = O_NONBLOCK | O_NOCTTY;
647 /* Map 'flags' to the OS-specific settings. */
648 if (flags & (SP_MODE_READ | SP_MODE_WRITE))
649 flags_local |= O_RDWR;
650 else if (flags & SP_MODE_READ)
651 flags_local |= O_RDONLY;
652 else if (flags & SP_MODE_WRITE)
653 flags_local |= O_WRONLY;
655 if ((port->fd = open(port->name, flags_local)) < 0)
656 RETURN_FAIL("open() failed");
659 ret = get_config(port, &data, &config);
666 /* Set sane port settings. */
668 data.dcb.fBinary = TRUE;
669 data.dcb.fDsrSensitivity = FALSE;
670 data.dcb.fErrorChar = FALSE;
671 data.dcb.fNull = FALSE;
672 data.dcb.fAbortOnError = TRUE;
674 /* Turn off all fancy termios tricks, give us a raw channel. */
675 data.term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IMAXBEL);
677 data.term.c_iflag &= ~IUCLC;
679 data.term.c_oflag &= ~(OPOST | ONLCR | OCRNL | ONOCR | ONLRET);
681 data.term.c_oflag &= ~OLCUC;
684 data.term.c_oflag &= ~NLDLY;
687 data.term.c_oflag &= ~CRDLY;
690 data.term.c_oflag &= ~TABDLY;
693 data.term.c_oflag &= ~BSDLY;
696 data.term.c_oflag &= ~VTDLY;
699 data.term.c_oflag &= ~FFDLY;
702 data.term.c_oflag &= ~OFILL;
704 data.term.c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN);
705 data.term.c_cc[VMIN] = 0;
706 data.term.c_cc[VTIME] = 0;
708 /* Ignore modem status lines; enable receiver; leave control lines alone on close. */
709 data.term.c_cflag |= (CLOCAL | CREAD | HUPCL);
712 ret = set_config(port, &data, &config);
722 enum sp_return sp_close(struct sp_port *port)
728 DEBUG("Closing port %s", port->name);
731 /* Returns non-zero upon success, 0 upon failure. */
732 if (CloseHandle(port->hdl) == 0)
733 RETURN_FAIL("port CloseHandle() failed");
734 port->hdl = INVALID_HANDLE_VALUE;
735 /* Close event handle created for overlapped reads. */
736 if (port->read_ovl.hEvent != INVALID_HANDLE_VALUE && CloseHandle(port->read_ovl.hEvent) == 0)
737 RETURN_FAIL("read event CloseHandle() failed");
738 /* Close event handle created for overlapped writes. */
739 if (port->write_ovl.hEvent != INVALID_HANDLE_VALUE && CloseHandle(port->write_ovl.hEvent) == 0)
740 RETURN_FAIL("write event CloseHandle() failed");
742 /* Returns 0 upon success, -1 upon failure. */
743 if (close(port->fd) == -1)
744 RETURN_FAIL("close() failed");
751 enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers)
753 TRACE("%p, 0x%x", port, buffers);
757 if (buffers > SP_BUF_BOTH)
758 RETURN_ERROR(SP_ERR_ARG, "Invalid buffer selection");
760 const char *buffer_names[] = {"no", "input", "output", "both"};
762 DEBUG("Flushing %s buffers on port %s", buffer_names[buffers], port->name);
766 if (buffers & SP_BUF_INPUT)
767 flags |= PURGE_RXCLEAR;
768 if (buffers & SP_BUF_OUTPUT)
769 flags |= PURGE_TXCLEAR;
771 /* Returns non-zero upon success, 0 upon failure. */
772 if (PurgeComm(port->hdl, flags) == 0)
773 RETURN_FAIL("PurgeComm() failed");
776 if (buffers & SP_BUF_BOTH)
778 else if (buffers & SP_BUF_INPUT)
780 else if (buffers & SP_BUF_OUTPUT)
783 /* Returns 0 upon success, -1 upon failure. */
784 if (tcflush(port->fd, flags) < 0)
785 RETURN_FAIL("tcflush() failed");
790 enum sp_return sp_drain(struct sp_port *port)
796 DEBUG("Draining port %s", port->name);
799 /* Returns non-zero upon success, 0 upon failure. */
800 if (FlushFileBuffers(port->hdl) == 0)
801 RETURN_FAIL("FlushFileBuffers() failed");
806 result = tcdrain(port->fd);
808 if (errno == EINTR) {
809 DEBUG("tcdrain() was interrupted");
812 RETURN_FAIL("tcdrain() failed");
821 enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t count, unsigned int timeout)
823 TRACE("%p, %p, %d, %d", port, buf, count, timeout);
828 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
831 DEBUG("Writing %d bytes to port %s, timeout %d ms", count, port->name, timeout);
833 DEBUG("Writing %d bytes to port %s, no timeout", count, port->name);
836 RETURN_VALUE("0", 0);
839 DWORD bytes_written = 0;
842 /* Wait for previous non-blocking write to complete, if any. */
844 DEBUG("Waiting for previous write to complete");
845 result = GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE);
848 RETURN_FAIL("Previous write failed to complete");
849 DEBUG("Previous write completed");
853 port->timeouts.WriteTotalTimeoutConstant = timeout;
854 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
855 RETURN_FAIL("SetCommTimeouts() failed");
858 if (WriteFile(port->hdl, buf, count, NULL, &port->write_ovl) == 0) {
859 if (GetLastError() == ERROR_IO_PENDING) {
860 DEBUG("Waiting for write to complete");
861 GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE);
862 DEBUG("Write completed, %d/%d bytes written", bytes_written, count);
863 RETURN_VALUE("%d", bytes_written);
865 RETURN_FAIL("WriteFile() failed");
868 DEBUG("Write completed immediately");
869 RETURN_VALUE("%d", count);
872 size_t bytes_written = 0;
873 unsigned char *ptr = (unsigned char *) buf;
874 struct timeval start, delta, now, end = {0, 0};
879 /* Get time at start of operation. */
880 gettimeofday(&start, NULL);
881 /* Define duration of timeout. */
882 delta.tv_sec = timeout / 1000;
883 delta.tv_usec = (timeout % 1000) * 1000;
884 /* Calculate time at which we should give up. */
885 timeradd(&start, &delta, &end);
888 /* Loop until we have written the requested number of bytes. */
889 while (bytes_written < count)
891 /* Wait until space is available. */
893 FD_SET(port->fd, &fds);
895 gettimeofday(&now, NULL);
896 if (timercmp(&now, &end, >)) {
897 DEBUG("write timed out");
898 RETURN_VALUE("%d", bytes_written);
900 timersub(&end, &now, &delta);
902 result = select(port->fd + 1, NULL, &fds, NULL, timeout ? &delta : NULL);
904 if (errno == EINTR) {
905 DEBUG("select() call was interrupted, repeating");
908 RETURN_FAIL("select() failed");
910 } else if (result == 0) {
911 DEBUG("write timed out");
912 RETURN_VALUE("%d", bytes_written);
916 result = write(port->fd, ptr, count - bytes_written);
920 /* This shouldn't happen because we did a select() first, but handle anyway. */
923 /* This is an actual failure. */
924 RETURN_FAIL("write() failed");
927 bytes_written += result;
931 RETURN_VALUE("%d", bytes_written);
935 enum sp_return sp_nonblocking_write(struct sp_port *port, const void *buf, size_t count)
937 TRACE("%p, %p, %d", port, buf, count);
942 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
944 DEBUG("Writing up to %d bytes to port %s", count, port->name);
947 RETURN_VALUE("0", 0);
951 BYTE *ptr = (BYTE *) buf;
953 /* Check whether previous write is complete. */
955 if (HasOverlappedIoCompleted(&port->write_ovl)) {
956 DEBUG("Previous write completed");
959 DEBUG("Previous write not complete");
960 /* Can't take a new write until the previous one finishes. */
961 RETURN_VALUE("0", 0);
966 port->timeouts.WriteTotalTimeoutConstant = 0;
967 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
968 RETURN_FAIL("SetCommTimeouts() failed");
970 /* Keep writing data until the OS has to actually start an async IO for it.
971 * At that point we know the buffer is full. */
972 while (written < count)
974 /* Copy first byte of user buffer. */
975 port->pending_byte = *ptr++;
977 /* Start asynchronous write. */
978 if (WriteFile(port->hdl, &port->pending_byte, 1, NULL, &port->write_ovl) == 0) {
979 if (GetLastError() == ERROR_IO_PENDING) {
980 DEBUG("Asynchronous write started");
982 RETURN_VALUE("%d", ++written);
984 /* Actual failure of some kind. */
985 RETURN_FAIL("WriteFile() failed");
988 DEBUG("Single byte written immediately.");
993 DEBUG("All bytes written immediately.");
995 RETURN_VALUE("%d", written);
997 /* Returns the number of bytes written, or -1 upon failure. */
998 ssize_t written = write(port->fd, buf, count);
1001 RETURN_FAIL("write() failed");
1003 RETURN_VALUE("%d", written);
1007 enum sp_return sp_blocking_read(struct sp_port *port, void *buf, size_t count, unsigned int timeout)
1009 TRACE("%p, %p, %d, %d", port, buf, count, timeout);
1014 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
1017 DEBUG("Reading %d bytes from port %s, timeout %d ms", count, port->name, timeout);
1019 DEBUG("Reading %d bytes from port %s, no timeout", count, port->name);
1022 RETURN_VALUE("0", 0);
1025 DWORD bytes_read = 0;
1028 port->timeouts.ReadIntervalTimeout = 0;
1029 port->timeouts.ReadTotalTimeoutConstant = timeout;
1030 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
1031 RETURN_FAIL("SetCommTimeouts() failed");
1034 if (ReadFile(port->hdl, buf, count, NULL, &port->read_ovl) == 0) {
1035 if (GetLastError() == ERROR_IO_PENDING) {
1036 DEBUG("Waiting for read to complete");
1037 GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE);
1038 DEBUG("Read completed, %d/%d bytes read", bytes_read, count);
1039 RETURN_VALUE("%d", bytes_read);
1041 RETURN_FAIL("ReadFile() failed");
1044 DEBUG("Read completed immediately");
1045 RETURN_VALUE("%d", count);
1048 size_t bytes_read = 0;
1049 unsigned char *ptr = (unsigned char *) buf;
1050 struct timeval start, delta, now, end = {0, 0};
1055 /* Get time at start of operation. */
1056 gettimeofday(&start, NULL);
1057 /* Define duration of timeout. */
1058 delta.tv_sec = timeout / 1000;
1059 delta.tv_usec = (timeout % 1000) * 1000;
1060 /* Calculate time at which we should give up. */
1061 timeradd(&start, &delta, &end);
1064 /* Loop until we have the requested number of bytes. */
1065 while (bytes_read < count)
1067 /* Wait until data is available. */
1069 FD_SET(port->fd, &fds);
1071 gettimeofday(&now, NULL);
1072 if (timercmp(&now, &end, >))
1073 /* Timeout has expired. */
1074 RETURN_VALUE("%d", bytes_read);
1075 timersub(&end, &now, &delta);
1077 result = select(port->fd + 1, &fds, NULL, NULL, timeout ? &delta : NULL);
1079 if (errno == EINTR) {
1080 DEBUG("select() call was interrupted, repeating");
1083 RETURN_FAIL("select() failed");
1085 } else if (result == 0) {
1086 DEBUG("read timed out");
1087 RETURN_VALUE("%d", bytes_read);
1091 result = read(port->fd, ptr, count - bytes_read);
1094 if (errno == EAGAIN)
1095 /* This shouldn't happen because we did a select() first, but handle anyway. */
1098 /* This is an actual failure. */
1099 RETURN_FAIL("read() failed");
1102 bytes_read += result;
1106 RETURN_VALUE("%d", bytes_read);
1110 enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, size_t count)
1112 TRACE("%p, %p, %d", port, buf, count);
1117 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
1119 DEBUG("Reading up to %d bytes from port %s", count, port->name);
1125 port->timeouts.ReadIntervalTimeout = MAXDWORD;
1126 port->timeouts.ReadTotalTimeoutConstant = 0;
1127 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
1128 RETURN_FAIL("SetCommTimeouts() failed");
1131 if (ReadFile(port->hdl, buf, count, NULL, &port->read_ovl) == 0)
1132 RETURN_FAIL("ReadFile() failed");
1134 /* Get number of bytes read. */
1135 GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE);
1137 RETURN_VALUE("%d", bytes_read);
1141 /* Returns the number of bytes read, or -1 upon failure. */
1142 if ((bytes_read = read(port->fd, buf, count)) < 0) {
1143 if (errno == EAGAIN)
1144 /* No bytes available. */
1147 /* This is an actual failure. */
1148 RETURN_FAIL("read() failed");
1150 RETURN_VALUE("%d", bytes_read);
1154 enum sp_return sp_input_waiting(struct sp_port *port)
1160 DEBUG("Checking input bytes waiting on port %s", port->name);
1166 if (ClearCommError(port->hdl, &errors, &comstat) == 0)
1167 RETURN_FAIL("ClearComError() failed");
1168 RETURN_VALUE("%d", comstat.cbInQue);
1171 if (ioctl(port->fd, TIOCINQ, &bytes_waiting) < 0)
1172 RETURN_FAIL("TIOCINQ ioctl failed");
1173 RETURN_VALUE("%d", bytes_waiting);
1177 enum sp_return sp_output_waiting(struct sp_port *port)
1183 DEBUG("Checking output bytes waiting on port %s", port->name);
1189 if (ClearCommError(port->hdl, &errors, &comstat) == 0)
1190 RETURN_FAIL("ClearComError() failed");
1191 RETURN_VALUE("%d", comstat.cbOutQue);
1194 if (ioctl(port->fd, TIOCOUTQ, &bytes_waiting) < 0)
1195 RETURN_FAIL("TIOCOUTQ ioctl failed");
1196 RETURN_VALUE("%d", bytes_waiting);
1201 static enum sp_return get_baudrate(int fd, int *baudrate)
1205 TRACE("%d, %p", fd, baudrate);
1207 DEBUG("Getting baud rate");
1209 if (!(data = malloc(get_termios_size())))
1210 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
1212 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
1214 RETURN_FAIL("getting termios failed");
1217 *baudrate = get_termios_speed(data);
1224 static enum sp_return set_baudrate(int fd, int baudrate)
1228 TRACE("%d, %d", fd, baudrate);
1230 DEBUG("Getting baud rate");
1232 if (!(data = malloc(get_termios_size())))
1233 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
1235 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
1237 RETURN_FAIL("getting termios failed");
1240 DEBUG("Setting baud rate");
1242 set_termios_speed(data, baudrate);
1244 if (ioctl(fd, get_termios_set_ioctl(), data) < 0) {
1246 RETURN_FAIL("setting termios failed");
1255 static enum sp_return get_flow(int fd, int *flow)
1259 TRACE("%d, %p", fd, flow);
1261 DEBUG("Getting advanced flow control");
1263 if (!(data = malloc(get_termiox_size())))
1264 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
1266 if (ioctl(fd, TCGETX, data) < 0) {
1268 RETURN_FAIL("getting termiox failed");
1271 *flow = get_termiox_flow(data);
1278 static enum sp_return set_flow(int fd, int flow)
1282 TRACE("%d, %d", fd, flow);
1284 DEBUG("Getting advanced flow control");
1286 if (!(data = malloc(get_termiox_size())))
1287 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
1289 if (ioctl(fd, TCGETX, data) < 0) {
1291 RETURN_FAIL("getting termiox failed");
1294 DEBUG("Setting advanced flow control");
1296 set_termiox_flow(data, flow);
1298 if (ioctl(fd, TCSETX, data) < 0) {
1300 RETURN_FAIL("setting termiox failed");
1307 #endif /* USE_TERMIOX */
1308 #endif /* __linux__ */
1310 static enum sp_return get_config(struct sp_port *port, struct port_data *data,
1311 struct sp_port_config *config)
1315 TRACE("%p, %p, %p", port, data, config);
1317 DEBUG("Getting configuration for port %s", port->name);
1320 if (!GetCommState(port->hdl, &data->dcb))
1321 RETURN_FAIL("GetCommState() failed");
1323 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1324 if (data->dcb.BaudRate == std_baudrates[i].index) {
1325 config->baudrate = std_baudrates[i].value;
1330 if (i == NUM_STD_BAUDRATES)
1331 /* BaudRate field can be either an index or a custom baud rate. */
1332 config->baudrate = data->dcb.BaudRate;
1334 config->bits = data->dcb.ByteSize;
1336 if (data->dcb.fParity)
1337 switch (data->dcb.Parity) {
1339 config->parity = SP_PARITY_NONE;
1342 config->parity = SP_PARITY_ODD;
1345 config->parity = SP_PARITY_EVEN;
1348 config->parity = SP_PARITY_MARK;
1351 config->parity = SP_PARITY_SPACE;
1354 config->parity = -1;
1357 config->parity = SP_PARITY_NONE;
1359 switch (data->dcb.StopBits) {
1361 config->stopbits = 1;
1364 config->stopbits = 2;
1367 config->stopbits = -1;
1370 switch (data->dcb.fRtsControl) {
1371 case RTS_CONTROL_DISABLE:
1372 config->rts = SP_RTS_OFF;
1374 case RTS_CONTROL_ENABLE:
1375 config->rts = SP_RTS_ON;
1377 case RTS_CONTROL_HANDSHAKE:
1378 config->rts = SP_RTS_FLOW_CONTROL;
1384 config->cts = data->dcb.fOutxCtsFlow ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1386 switch (data->dcb.fDtrControl) {
1387 case DTR_CONTROL_DISABLE:
1388 config->dtr = SP_DTR_OFF;
1390 case DTR_CONTROL_ENABLE:
1391 config->dtr = SP_DTR_ON;
1393 case DTR_CONTROL_HANDSHAKE:
1394 config->dtr = SP_DTR_FLOW_CONTROL;
1400 config->dsr = data->dcb.fOutxDsrFlow ? SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1402 if (data->dcb.fInX) {
1403 if (data->dcb.fOutX)
1404 config->xon_xoff = SP_XONXOFF_INOUT;
1406 config->xon_xoff = SP_XONXOFF_IN;
1408 if (data->dcb.fOutX)
1409 config->xon_xoff = SP_XONXOFF_OUT;
1411 config->xon_xoff = SP_XONXOFF_DISABLED;
1416 if (tcgetattr(port->fd, &data->term) < 0)
1417 RETURN_FAIL("tcgetattr() failed");
1419 if (ioctl(port->fd, TIOCMGET, &data->controlbits) < 0)
1420 RETURN_FAIL("TIOCMGET ioctl failed");
1423 int ret = get_flow(port->fd, &data->flow);
1425 if (ret == SP_ERR_FAIL && errno == EINVAL)
1426 data->termiox_supported = 0;
1428 RETURN_CODEVAL(ret);
1430 data->termiox_supported = 1;
1432 data->termiox_supported = 0;
1435 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1436 if (cfgetispeed(&data->term) == std_baudrates[i].index) {
1437 config->baudrate = std_baudrates[i].value;
1442 if (i == NUM_STD_BAUDRATES) {
1444 config->baudrate = (int)data->term.c_ispeed;
1445 #elif defined(__linux__)
1446 TRY(get_baudrate(port->fd, &config->baudrate));
1448 config->baudrate = -1;
1452 switch (data->term.c_cflag & CSIZE) {
1469 if (!(data->term.c_cflag & PARENB) && (data->term.c_iflag & IGNPAR))
1470 config->parity = SP_PARITY_NONE;
1471 else if (!(data->term.c_cflag & PARENB) || (data->term.c_iflag & IGNPAR))
1472 config->parity = -1;
1474 else if (data->term.c_cflag & CMSPAR)
1475 config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_MARK : SP_PARITY_SPACE;
1478 config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_ODD : SP_PARITY_EVEN;
1480 config->stopbits = (data->term.c_cflag & CSTOPB) ? 2 : 1;
1482 if (data->term.c_cflag & CRTSCTS) {
1483 config->rts = SP_RTS_FLOW_CONTROL;
1484 config->cts = SP_CTS_FLOW_CONTROL;
1486 if (data->termiox_supported && data->flow & RTS_FLOW)
1487 config->rts = SP_RTS_FLOW_CONTROL;
1489 config->rts = (data->controlbits & TIOCM_RTS) ? SP_RTS_ON : SP_RTS_OFF;
1491 config->cts = (data->termiox_supported && data->flow & CTS_FLOW) ?
1492 SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1495 if (data->termiox_supported && data->flow & DTR_FLOW)
1496 config->dtr = SP_DTR_FLOW_CONTROL;
1498 config->dtr = (data->controlbits & TIOCM_DTR) ? SP_DTR_ON : SP_DTR_OFF;
1500 config->dsr = (data->termiox_supported && data->flow & DSR_FLOW) ?
1501 SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1503 if (data->term.c_iflag & IXOFF) {
1504 if (data->term.c_iflag & IXON)
1505 config->xon_xoff = SP_XONXOFF_INOUT;
1507 config->xon_xoff = SP_XONXOFF_IN;
1509 if (data->term.c_iflag & IXON)
1510 config->xon_xoff = SP_XONXOFF_OUT;
1512 config->xon_xoff = SP_XONXOFF_DISABLED;
1519 static enum sp_return set_config(struct sp_port *port, struct port_data *data,
1520 const struct sp_port_config *config)
1524 BAUD_TYPE baud_nonstd;
1529 int baud_nonstd = 0;
1532 TRACE("%p, %p, %p", port, data, config);
1534 DEBUG("Setting configuration for port %s", port->name);
1537 if (config->baudrate >= 0) {
1538 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1539 if (config->baudrate == std_baudrates[i].value) {
1540 data->dcb.BaudRate = std_baudrates[i].index;
1545 if (i == NUM_STD_BAUDRATES)
1546 data->dcb.BaudRate = config->baudrate;
1549 if (config->bits >= 0)
1550 data->dcb.ByteSize = config->bits;
1552 if (config->parity >= 0) {
1553 switch (config->parity) {
1554 /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
1555 case SP_PARITY_NONE:
1556 data->dcb.Parity = NOPARITY;
1559 data->dcb.Parity = ODDPARITY;
1561 case SP_PARITY_EVEN:
1562 data->dcb.Parity = EVENPARITY;
1564 case SP_PARITY_MARK:
1565 data->dcb.Parity = MARKPARITY;
1567 case SP_PARITY_SPACE:
1568 data->dcb.Parity = SPACEPARITY;
1571 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1575 if (config->stopbits >= 0) {
1576 switch (config->stopbits) {
1577 /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
1579 data->dcb.StopBits = ONESTOPBIT;
1582 data->dcb.StopBits = TWOSTOPBITS;
1585 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bit setting");
1589 if (config->rts >= 0) {
1590 switch (config->rts) {
1592 data->dcb.fRtsControl = RTS_CONTROL_DISABLE;
1595 data->dcb.fRtsControl = RTS_CONTROL_ENABLE;
1597 case SP_RTS_FLOW_CONTROL:
1598 data->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
1601 RETURN_ERROR(SP_ERR_ARG, "Invalid RTS setting");
1605 if (config->cts >= 0) {
1606 switch (config->cts) {
1608 data->dcb.fOutxCtsFlow = FALSE;
1610 case SP_CTS_FLOW_CONTROL:
1611 data->dcb.fOutxCtsFlow = TRUE;
1614 RETURN_ERROR(SP_ERR_ARG, "Invalid CTS setting");
1618 if (config->dtr >= 0) {
1619 switch (config->dtr) {
1621 data->dcb.fDtrControl = DTR_CONTROL_DISABLE;
1624 data->dcb.fDtrControl = DTR_CONTROL_ENABLE;
1626 case SP_DTR_FLOW_CONTROL:
1627 data->dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
1630 RETURN_ERROR(SP_ERR_ARG, "Invalid DTR setting");
1634 if (config->dsr >= 0) {
1635 switch (config->dsr) {
1637 data->dcb.fOutxDsrFlow = FALSE;
1639 case SP_DSR_FLOW_CONTROL:
1640 data->dcb.fOutxDsrFlow = TRUE;
1643 RETURN_ERROR(SP_ERR_ARG, "Invalid DSR setting");
1647 if (config->xon_xoff >= 0) {
1648 switch (config->xon_xoff) {
1649 case SP_XONXOFF_DISABLED:
1650 data->dcb.fInX = FALSE;
1651 data->dcb.fOutX = FALSE;
1654 data->dcb.fInX = TRUE;
1655 data->dcb.fOutX = FALSE;
1657 case SP_XONXOFF_OUT:
1658 data->dcb.fInX = FALSE;
1659 data->dcb.fOutX = TRUE;
1661 case SP_XONXOFF_INOUT:
1662 data->dcb.fInX = TRUE;
1663 data->dcb.fOutX = TRUE;
1666 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1670 if (!SetCommState(port->hdl, &data->dcb))
1671 RETURN_FAIL("SetCommState() failed");
1677 if (config->baudrate >= 0) {
1678 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1679 if (config->baudrate == std_baudrates[i].value) {
1680 if (cfsetospeed(&data->term, std_baudrates[i].index) < 0)
1681 RETURN_FAIL("cfsetospeed() failed");
1683 if (cfsetispeed(&data->term, std_baudrates[i].index) < 0)
1684 RETURN_FAIL("cfsetispeed() failed");
1689 /* Non-standard baud rate */
1690 if (i == NUM_STD_BAUDRATES) {
1692 /* Set "dummy" baud rate. */
1693 if (cfsetspeed(&data->term, B9600) < 0)
1694 RETURN_FAIL("cfsetspeed() failed");
1695 baud_nonstd = config->baudrate;
1696 #elif defined(__linux__)
1699 RETURN_ERROR(SP_ERR_SUPP, "Non-standard baudrate not supported");
1704 if (config->bits >= 0) {
1705 data->term.c_cflag &= ~CSIZE;
1706 switch (config->bits) {
1708 data->term.c_cflag |= CS8;
1711 data->term.c_cflag |= CS7;
1714 data->term.c_cflag |= CS6;
1717 data->term.c_cflag |= CS5;
1720 RETURN_ERROR(SP_ERR_ARG, "Invalid data bits setting");
1724 if (config->parity >= 0) {
1725 data->term.c_iflag &= ~IGNPAR;
1726 data->term.c_cflag &= ~(PARENB | PARODD);
1728 data->term.c_cflag &= ~CMSPAR;
1730 switch (config->parity) {
1731 case SP_PARITY_NONE:
1732 data->term.c_iflag |= IGNPAR;
1734 case SP_PARITY_EVEN:
1735 data->term.c_cflag |= PARENB;
1738 data->term.c_cflag |= PARENB | PARODD;
1741 case SP_PARITY_MARK:
1742 data->term.c_cflag |= PARENB | PARODD;
1743 data->term.c_cflag |= CMSPAR;
1745 case SP_PARITY_SPACE:
1746 data->term.c_cflag |= PARENB;
1747 data->term.c_cflag |= CMSPAR;
1750 case SP_PARITY_MARK:
1751 case SP_PARITY_SPACE:
1752 RETURN_ERROR(SP_ERR_SUPP, "Mark/space parity not supported");
1755 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1759 if (config->stopbits >= 0) {
1760 data->term.c_cflag &= ~CSTOPB;
1761 switch (config->stopbits) {
1763 data->term.c_cflag &= ~CSTOPB;
1766 data->term.c_cflag |= CSTOPB;
1769 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bits setting");
1773 if (config->rts >= 0 || config->cts >= 0) {
1774 if (data->termiox_supported) {
1775 data->flow &= ~(RTS_FLOW | CTS_FLOW);
1776 switch (config->rts) {
1779 controlbits = TIOCM_RTS;
1780 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1781 RETURN_FAIL("Setting RTS signal level failed");
1783 case SP_RTS_FLOW_CONTROL:
1784 data->flow |= RTS_FLOW;
1789 if (config->cts == SP_CTS_FLOW_CONTROL)
1790 data->flow |= CTS_FLOW;
1792 if (data->flow & (RTS_FLOW | CTS_FLOW))
1793 data->term.c_iflag |= CRTSCTS;
1795 data->term.c_iflag &= ~CRTSCTS;
1797 /* Asymmetric use of RTS/CTS not supported. */
1798 if (data->term.c_iflag & CRTSCTS) {
1799 /* Flow control can only be disabled for both RTS & CTS together. */
1800 if (config->rts >= 0 && config->rts != SP_RTS_FLOW_CONTROL) {
1801 if (config->cts != SP_CTS_IGNORE)
1802 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1804 if (config->cts >= 0 && config->cts != SP_CTS_FLOW_CONTROL) {
1805 if (config->rts <= 0 || config->rts == SP_RTS_FLOW_CONTROL)
1806 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1809 /* Flow control can only be enabled for both RTS & CTS together. */
1810 if (((config->rts == SP_RTS_FLOW_CONTROL) && (config->cts != SP_CTS_FLOW_CONTROL)) ||
1811 ((config->cts == SP_CTS_FLOW_CONTROL) && (config->rts != SP_RTS_FLOW_CONTROL)))
1812 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be enabled together");
1815 if (config->rts >= 0) {
1816 if (config->rts == SP_RTS_FLOW_CONTROL) {
1817 data->term.c_iflag |= CRTSCTS;
1819 controlbits = TIOCM_RTS;
1820 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC,
1822 RETURN_FAIL("Setting RTS signal level failed");
1828 if (config->dtr >= 0 || config->dsr >= 0) {
1829 if (data->termiox_supported) {
1830 data->flow &= ~(DTR_FLOW | DSR_FLOW);
1831 switch (config->dtr) {
1834 controlbits = TIOCM_DTR;
1835 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1836 RETURN_FAIL("Setting DTR signal level failed");
1838 case SP_DTR_FLOW_CONTROL:
1839 data->flow |= DTR_FLOW;
1844 if (config->dsr == SP_DSR_FLOW_CONTROL)
1845 data->flow |= DSR_FLOW;
1847 /* DTR/DSR flow control not supported. */
1848 if (config->dtr == SP_DTR_FLOW_CONTROL || config->dsr == SP_DSR_FLOW_CONTROL)
1849 RETURN_ERROR(SP_ERR_SUPP, "DTR/DSR flow control not supported");
1851 if (config->dtr >= 0) {
1852 controlbits = TIOCM_DTR;
1853 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC,
1855 RETURN_FAIL("Setting DTR signal level failed");
1860 if (config->xon_xoff >= 0) {
1861 data->term.c_iflag &= ~(IXON | IXOFF | IXANY);
1862 switch (config->xon_xoff) {
1863 case SP_XONXOFF_DISABLED:
1866 data->term.c_iflag |= IXOFF;
1868 case SP_XONXOFF_OUT:
1869 data->term.c_iflag |= IXON | IXANY;
1871 case SP_XONXOFF_INOUT:
1872 data->term.c_iflag |= IXON | IXOFF | IXANY;
1875 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1879 if (tcsetattr(port->fd, TCSANOW, &data->term) < 0)
1880 RETURN_FAIL("tcsetattr() failed");
1883 if (baud_nonstd != B0) {
1884 if (ioctl(port->fd, IOSSIOSPEED, &baud_nonstd) == -1)
1885 RETURN_FAIL("IOSSIOSPEED ioctl failed");
1886 /* Set baud rates in data->term to correct, but incompatible
1887 * with tcsetattr() value, same as delivered by tcgetattr(). */
1888 if (cfsetspeed(&data->term, baud_nonstd) < 0)
1889 RETURN_FAIL("cfsetspeed() failed");
1891 #elif defined(__linux__)
1893 TRY(set_baudrate(port->fd, config->baudrate));
1895 if (data->termiox_supported)
1896 TRY(set_flow(port->fd, data->flow));
1900 #endif /* !_WIN32 */
1905 enum sp_return sp_new_config(struct sp_port_config **config_ptr)
1907 struct sp_port_config *config;
1909 TRACE("%p", config_ptr);
1912 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
1916 if (!(config = malloc(sizeof(struct sp_port_config))))
1917 RETURN_ERROR(SP_ERR_MEM, "config malloc failed");
1919 config->baudrate = -1;
1921 config->parity = -1;
1922 config->stopbits = -1;
1928 *config_ptr = config;
1933 void sp_free_config(struct sp_port_config *config)
1935 TRACE("%p", config);
1938 DEBUG("Null config");
1945 enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config)
1947 struct port_data data;
1949 TRACE("%p, %p", port, config);
1954 RETURN_ERROR(SP_ERR_ARG, "Null config");
1956 TRY(get_config(port, &data, config));
1961 enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config)
1963 struct port_data data;
1964 struct sp_port_config prev_config;
1966 TRACE("%p, %p", port, config);
1971 RETURN_ERROR(SP_ERR_ARG, "Null config");
1973 TRY(get_config(port, &data, &prev_config));
1974 TRY(set_config(port, &data, config));
1979 #define CREATE_ACCESSORS(x, type) \
1980 enum sp_return sp_set_##x(struct sp_port *port, type x) { \
1981 struct port_data data; \
1982 struct sp_port_config config; \
1983 TRACE("%p, %d", port, x); \
1984 CHECK_OPEN_PORT(); \
1985 TRY(get_config(port, &data, &config)); \
1987 TRY(set_config(port, &data, &config)); \
1990 enum sp_return sp_get_config_##x(const struct sp_port_config *config, type *x) { \
1991 TRACE("%p, %p", config, x); \
1993 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
1997 enum sp_return sp_set_config_##x(struct sp_port_config *config, type x) { \
1998 TRACE("%p, %d", config, x); \
2000 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
2005 CREATE_ACCESSORS(baudrate, int)
2006 CREATE_ACCESSORS(bits, int)
2007 CREATE_ACCESSORS(parity, enum sp_parity)
2008 CREATE_ACCESSORS(stopbits, int)
2009 CREATE_ACCESSORS(rts, enum sp_rts)
2010 CREATE_ACCESSORS(cts, enum sp_cts)
2011 CREATE_ACCESSORS(dtr, enum sp_dtr)
2012 CREATE_ACCESSORS(dsr, enum sp_dsr)
2013 CREATE_ACCESSORS(xon_xoff, enum sp_xonxoff)
2015 enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol)
2018 RETURN_ERROR(SP_ERR_ARG, "Null configuration");
2020 if (flowcontrol > SP_FLOWCONTROL_DTRDSR)
2021 RETURN_ERROR(SP_ERR_ARG, "Invalid flow control setting");
2023 if (flowcontrol == SP_FLOWCONTROL_XONXOFF)
2024 config->xon_xoff = SP_XONXOFF_INOUT;
2026 config->xon_xoff = SP_XONXOFF_DISABLED;
2028 if (flowcontrol == SP_FLOWCONTROL_RTSCTS) {
2029 config->rts = SP_RTS_FLOW_CONTROL;
2030 config->cts = SP_CTS_FLOW_CONTROL;
2032 if (config->rts == SP_RTS_FLOW_CONTROL)
2033 config->rts = SP_RTS_ON;
2034 config->cts = SP_CTS_IGNORE;
2037 if (flowcontrol == SP_FLOWCONTROL_DTRDSR) {
2038 config->dtr = SP_DTR_FLOW_CONTROL;
2039 config->dsr = SP_DSR_FLOW_CONTROL;
2041 if (config->dtr == SP_DTR_FLOW_CONTROL)
2042 config->dtr = SP_DTR_ON;
2043 config->dsr = SP_DSR_IGNORE;
2049 enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol)
2051 struct port_data data;
2052 struct sp_port_config config;
2054 TRACE("%p, %d", port, flowcontrol);
2058 TRY(get_config(port, &data, &config));
2060 TRY(sp_set_config_flowcontrol(&config, flowcontrol));
2062 TRY(set_config(port, &data, &config));
2067 enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signals)
2069 TRACE("%p, %p", port, signals);
2074 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
2076 DEBUG("Getting control signals for port %s", port->name);
2081 if (GetCommModemStatus(port->hdl, &bits) == 0)
2082 RETURN_FAIL("GetCommModemStatus() failed");
2083 if (bits & MS_CTS_ON)
2084 *signals |= SP_SIG_CTS;
2085 if (bits & MS_DSR_ON)
2086 *signals |= SP_SIG_DSR;
2087 if (bits & MS_RLSD_ON)
2088 *signals |= SP_SIG_DCD;
2089 if (bits & MS_RING_ON)
2090 *signals |= SP_SIG_RI;
2093 if (ioctl(port->fd, TIOCMGET, &bits) < 0)
2094 RETURN_FAIL("TIOCMGET ioctl failed");
2095 if (bits & TIOCM_CTS)
2096 *signals |= SP_SIG_CTS;
2097 if (bits & TIOCM_DSR)
2098 *signals |= SP_SIG_DSR;
2099 if (bits & TIOCM_CAR)
2100 *signals |= SP_SIG_DCD;
2101 if (bits & TIOCM_RNG)
2102 *signals |= SP_SIG_RI;
2107 enum sp_return sp_start_break(struct sp_port *port)
2113 if (SetCommBreak(port->hdl) == 0)
2114 RETURN_FAIL("SetCommBreak() failed");
2116 if (ioctl(port->fd, TIOCSBRK, 1) < 0)
2117 RETURN_FAIL("TIOCSBRK ioctl failed");
2123 enum sp_return sp_end_break(struct sp_port *port)
2129 if (ClearCommBreak(port->hdl) == 0)
2130 RETURN_FAIL("ClearCommBreak() failed");
2132 if (ioctl(port->fd, TIOCCBRK, 1) < 0)
2133 RETURN_FAIL("TIOCCBRK ioctl failed");
2139 int sp_last_error_code(void)
2143 RETURN_VALUE("%d", GetLastError());
2145 RETURN_VALUE("%d", errno);
2149 char *sp_last_error_message(void)
2155 DWORD error = GetLastError();
2158 FORMAT_MESSAGE_ALLOCATE_BUFFER |
2159 FORMAT_MESSAGE_FROM_SYSTEM |
2160 FORMAT_MESSAGE_IGNORE_INSERTS,
2163 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2167 RETURN_VALUE("%s", message);
2169 RETURN_VALUE("%s", strerror(errno));
2173 void sp_free_error_message(char *message)
2175 TRACE("%s", message);
2186 void sp_set_debug_handler(void (*handler)(const char *format, ...))
2188 TRACE("%p", handler);
2190 sp_debug_handler = handler;
2195 void sp_default_debug_handler(const char *format, ...)
2198 va_start(args, format);
2199 if (getenv("LIBSERIALPORT_DEBUG")) {
2200 fputs("sp: ", stderr);
2201 vfprintf(stderr, format, args);