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");
803 /* Returns 0 upon success, -1 upon failure. */
804 if (tcdrain(port->fd) < 0)
805 RETURN_FAIL("tcdrain() failed");
811 enum sp_return sp_blocking_write(struct sp_port *port, const void *buf, size_t count, unsigned int timeout)
813 TRACE("%p, %p, %d, %d", port, buf, count, timeout);
818 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
821 DEBUG("Writing %d bytes to port %s, timeout %d ms", count, port->name, timeout);
823 DEBUG("Writing %d bytes to port %s, no timeout", count, port->name);
826 RETURN_VALUE("0", 0);
829 DWORD bytes_written = 0;
832 /* Wait for previous non-blocking write to complete, if any. */
834 DEBUG("Waiting for previous write to complete");
835 result = GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE);
838 RETURN_FAIL("Previous write failed to complete");
839 DEBUG("Previous write completed");
843 port->timeouts.WriteTotalTimeoutConstant = timeout;
844 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
845 RETURN_FAIL("SetCommTimeouts() failed");
848 if (WriteFile(port->hdl, buf, count, NULL, &port->write_ovl) == 0) {
849 if (GetLastError() == ERROR_IO_PENDING) {
850 DEBUG("Waiting for write to complete");
851 GetOverlappedResult(port->hdl, &port->write_ovl, &bytes_written, TRUE);
852 DEBUG("Write completed, %d/%d bytes written", bytes_written, count);
853 RETURN_VALUE("%d", bytes_written);
855 RETURN_FAIL("WriteFile() failed");
858 DEBUG("Write completed immediately");
859 RETURN_VALUE("%d", count);
862 size_t bytes_written = 0;
863 unsigned char *ptr = (unsigned char *) buf;
864 struct timeval start, delta, now, end = {0, 0};
869 /* Get time at start of operation. */
870 gettimeofday(&start, NULL);
871 /* Define duration of timeout. */
872 delta.tv_sec = timeout / 1000;
873 delta.tv_usec = timeout % 1000;
874 /* Calculate time at which we should give up. */
875 timeradd(&start, &delta, &end);
878 /* Loop until we have written the requested number of bytes. */
879 while (bytes_written < count)
881 /* Wait until space is available. */
883 FD_SET(port->fd, &fds);
885 gettimeofday(&now, NULL);
886 if (timercmp(&now, &end, >)) {
887 DEBUG("write timed out");
888 RETURN_VALUE("%d", bytes_written);
890 timersub(&end, &now, &delta);
892 result = select(port->fd + 1, NULL, &fds, NULL, timeout ? &delta : NULL);
894 RETURN_FAIL("select() failed");
896 DEBUG("write timed out");
897 RETURN_VALUE("%d", bytes_written);
901 result = write(port->fd, ptr, count - bytes_written);
905 /* This shouldn't happen because we did a select() first, but handle anyway. */
908 /* This is an actual failure. */
909 RETURN_FAIL("write() failed");
912 bytes_written += result;
916 RETURN_VALUE("%d", bytes_written);
920 enum sp_return sp_nonblocking_write(struct sp_port *port, const void *buf, size_t count)
922 TRACE("%p, %p, %d", port, buf, count);
927 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
929 DEBUG("Writing up to %d bytes to port %s", count, port->name);
932 RETURN_VALUE("0", 0);
936 BYTE *ptr = (BYTE *) buf;
938 /* Check whether previous write is complete. */
940 if (HasOverlappedIoCompleted(&port->write_ovl)) {
941 DEBUG("Previous write completed");
944 DEBUG("Previous write not complete");
945 /* Can't take a new write until the previous one finishes. */
946 RETURN_VALUE("0", 0);
951 port->timeouts.WriteTotalTimeoutConstant = 0;
952 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
953 RETURN_FAIL("SetCommTimeouts() failed");
955 /* Keep writing data until the OS has to actually start an async IO for it.
956 * At that point we know the buffer is full. */
957 while (written < count)
959 /* Copy first byte of user buffer. */
960 port->pending_byte = *ptr++;
962 /* Start asynchronous write. */
963 if (WriteFile(port->hdl, &port->pending_byte, 1, NULL, &port->write_ovl) == 0) {
964 if (GetLastError() == ERROR_IO_PENDING) {
965 DEBUG("Asynchronous write started");
967 RETURN_VALUE("%d", ++written);
969 /* Actual failure of some kind. */
970 RETURN_FAIL("WriteFile() failed");
973 DEBUG("Single byte written immediately.");
978 DEBUG("All bytes written immediately.");
980 RETURN_VALUE("%d", written);
982 /* Returns the number of bytes written, or -1 upon failure. */
983 ssize_t written = write(port->fd, buf, count);
986 RETURN_FAIL("write() failed");
988 RETURN_VALUE("%d", written);
992 enum sp_return sp_blocking_read(struct sp_port *port, void *buf, size_t count, unsigned int timeout)
994 TRACE("%p, %p, %d, %d", port, buf, count, timeout);
999 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
1002 DEBUG("Reading %d bytes from port %s, timeout %d ms", count, port->name, timeout);
1004 DEBUG("Reading %d bytes from port %s, no timeout", count, port->name);
1007 RETURN_VALUE("0", 0);
1010 DWORD bytes_read = 0;
1013 port->timeouts.ReadIntervalTimeout = 0;
1014 port->timeouts.ReadTotalTimeoutConstant = timeout;
1015 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
1016 RETURN_FAIL("SetCommTimeouts() failed");
1019 if (ReadFile(port->hdl, buf, count, NULL, &port->read_ovl) == 0) {
1020 if (GetLastError() == ERROR_IO_PENDING) {
1021 DEBUG("Waiting for read to complete");
1022 GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE);
1023 DEBUG("Read completed, %d/%d bytes read", bytes_read, count);
1024 RETURN_VALUE("%d", bytes_read);
1026 RETURN_FAIL("ReadFile() failed");
1029 DEBUG("Read completed immediately");
1030 RETURN_VALUE("%d", count);
1033 size_t bytes_read = 0;
1034 unsigned char *ptr = (unsigned char *) buf;
1035 struct timeval start, delta, now, end = {0, 0};
1040 /* Get time at start of operation. */
1041 gettimeofday(&start, NULL);
1042 /* Define duration of timeout. */
1043 delta.tv_sec = timeout / 1000;
1044 delta.tv_usec = timeout % 1000;
1045 /* Calculate time at which we should give up. */
1046 timeradd(&start, &delta, &end);
1049 /* Loop until we have the requested number of bytes. */
1050 while (bytes_read < count)
1052 /* Wait until data is available. */
1054 FD_SET(port->fd, &fds);
1056 gettimeofday(&now, NULL);
1057 if (timercmp(&now, &end, >))
1058 /* Timeout has expired. */
1059 RETURN_VALUE("%d", bytes_read);
1060 timersub(&end, &now, &delta);
1062 result = select(port->fd + 1, &fds, NULL, NULL, timeout ? &delta : NULL);
1064 RETURN_FAIL("select() failed");
1066 DEBUG("read timed out");
1067 RETURN_VALUE("%d", bytes_read);
1071 result = read(port->fd, ptr, count - bytes_read);
1074 if (errno == EAGAIN)
1075 /* This shouldn't happen because we did a select() first, but handle anyway. */
1078 /* This is an actual failure. */
1079 RETURN_FAIL("read() failed");
1082 bytes_read += result;
1086 RETURN_VALUE("%d", bytes_read);
1090 enum sp_return sp_nonblocking_read(struct sp_port *port, void *buf, size_t count)
1092 TRACE("%p, %p, %d", port, buf, count);
1097 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
1099 DEBUG("Reading up to %d bytes from port %s", count, port->name);
1105 port->timeouts.ReadIntervalTimeout = MAXDWORD;
1106 port->timeouts.ReadTotalTimeoutConstant = 0;
1107 if (SetCommTimeouts(port->hdl, &port->timeouts) == 0)
1108 RETURN_FAIL("SetCommTimeouts() failed");
1111 if (ReadFile(port->hdl, buf, count, NULL, &port->read_ovl) == 0)
1112 RETURN_FAIL("ReadFile() failed");
1114 /* Get number of bytes read. */
1115 GetOverlappedResult(port->hdl, &port->read_ovl, &bytes_read, TRUE);
1117 RETURN_VALUE("%d", bytes_read);
1121 /* Returns the number of bytes read, or -1 upon failure. */
1122 if ((bytes_read = read(port->fd, buf, count)) < 0) {
1123 if (errno == EAGAIN)
1124 /* No bytes available. */
1127 /* This is an actual failure. */
1128 RETURN_FAIL("read() failed");
1130 RETURN_VALUE("%d", bytes_read);
1134 enum sp_return sp_input_waiting(struct sp_port *port)
1140 DEBUG("Checking input bytes waiting on port %s", port->name);
1146 if (ClearCommError(port->hdl, &errors, &comstat) == 0)
1147 RETURN_FAIL("ClearComError() failed");
1148 RETURN_VALUE("%d", comstat.cbInQue);
1151 if (ioctl(port->fd, TIOCINQ, &bytes_waiting) < 0)
1152 RETURN_FAIL("TIOCINQ ioctl failed");
1153 RETURN_VALUE("%d", bytes_waiting);
1157 enum sp_return sp_output_waiting(struct sp_port *port)
1163 DEBUG("Checking output bytes waiting on port %s", port->name);
1169 if (ClearCommError(port->hdl, &errors, &comstat) == 0)
1170 RETURN_FAIL("ClearComError() failed");
1171 RETURN_VALUE("%d", comstat.cbOutQue);
1174 if (ioctl(port->fd, TIOCOUTQ, &bytes_waiting) < 0)
1175 RETURN_FAIL("TIOCOUTQ ioctl failed");
1176 RETURN_VALUE("%d", bytes_waiting);
1181 static enum sp_return get_baudrate(int fd, int *baudrate)
1185 TRACE("%d, %p", fd, baudrate);
1187 DEBUG("Getting baud rate");
1189 if (!(data = malloc(get_termios_size())))
1190 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
1192 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
1194 RETURN_FAIL("getting termios failed");
1197 *baudrate = get_termios_speed(data);
1204 static enum sp_return set_baudrate(int fd, int baudrate)
1208 TRACE("%d, %d", fd, baudrate);
1210 DEBUG("Getting baud rate");
1212 if (!(data = malloc(get_termios_size())))
1213 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
1215 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
1217 RETURN_FAIL("getting termios failed");
1220 DEBUG("Setting baud rate");
1222 set_termios_speed(data, baudrate);
1224 if (ioctl(fd, get_termios_set_ioctl(), data) < 0) {
1226 RETURN_FAIL("setting termios failed");
1235 static enum sp_return get_flow(int fd, int *flow)
1239 TRACE("%d, %p", fd, flow);
1241 DEBUG("Getting advanced flow control");
1243 if (!(data = malloc(get_termiox_size())))
1244 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
1246 if (ioctl(fd, TCGETX, data) < 0) {
1248 RETURN_FAIL("getting termiox failed");
1251 *flow = get_termiox_flow(data);
1258 static enum sp_return set_flow(int fd, int flow)
1262 TRACE("%d, %d", fd, flow);
1264 DEBUG("Getting advanced flow control");
1266 if (!(data = malloc(get_termiox_size())))
1267 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
1269 if (ioctl(fd, TCGETX, data) < 0) {
1271 RETURN_FAIL("getting termiox failed");
1274 DEBUG("Setting advanced flow control");
1276 set_termiox_flow(data, flow);
1278 if (ioctl(fd, TCSETX, data) < 0) {
1280 RETURN_FAIL("setting termiox failed");
1287 #endif /* USE_TERMIOX */
1288 #endif /* __linux__ */
1290 static enum sp_return get_config(struct sp_port *port, struct port_data *data,
1291 struct sp_port_config *config)
1295 TRACE("%p, %p, %p", port, data, config);
1297 DEBUG("Getting configuration for port %s", port->name);
1300 if (!GetCommState(port->hdl, &data->dcb))
1301 RETURN_FAIL("GetCommState() failed");
1303 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1304 if (data->dcb.BaudRate == std_baudrates[i].index) {
1305 config->baudrate = std_baudrates[i].value;
1310 if (i == NUM_STD_BAUDRATES)
1311 /* BaudRate field can be either an index or a custom baud rate. */
1312 config->baudrate = data->dcb.BaudRate;
1314 config->bits = data->dcb.ByteSize;
1316 if (data->dcb.fParity)
1317 switch (data->dcb.Parity) {
1319 config->parity = SP_PARITY_NONE;
1322 config->parity = SP_PARITY_ODD;
1325 config->parity = SP_PARITY_EVEN;
1328 config->parity = SP_PARITY_MARK;
1331 config->parity = SP_PARITY_SPACE;
1334 config->parity = -1;
1337 config->parity = SP_PARITY_NONE;
1339 switch (data->dcb.StopBits) {
1341 config->stopbits = 1;
1344 config->stopbits = 2;
1347 config->stopbits = -1;
1350 switch (data->dcb.fRtsControl) {
1351 case RTS_CONTROL_DISABLE:
1352 config->rts = SP_RTS_OFF;
1354 case RTS_CONTROL_ENABLE:
1355 config->rts = SP_RTS_ON;
1357 case RTS_CONTROL_HANDSHAKE:
1358 config->rts = SP_RTS_FLOW_CONTROL;
1364 config->cts = data->dcb.fOutxCtsFlow ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1366 switch (data->dcb.fDtrControl) {
1367 case DTR_CONTROL_DISABLE:
1368 config->dtr = SP_DTR_OFF;
1370 case DTR_CONTROL_ENABLE:
1371 config->dtr = SP_DTR_ON;
1373 case DTR_CONTROL_HANDSHAKE:
1374 config->dtr = SP_DTR_FLOW_CONTROL;
1380 config->dsr = data->dcb.fOutxDsrFlow ? SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1382 if (data->dcb.fInX) {
1383 if (data->dcb.fOutX)
1384 config->xon_xoff = SP_XONXOFF_INOUT;
1386 config->xon_xoff = SP_XONXOFF_IN;
1388 if (data->dcb.fOutX)
1389 config->xon_xoff = SP_XONXOFF_OUT;
1391 config->xon_xoff = SP_XONXOFF_DISABLED;
1396 if (tcgetattr(port->fd, &data->term) < 0)
1397 RETURN_FAIL("tcgetattr() failed");
1399 if (ioctl(port->fd, TIOCMGET, &data->controlbits) < 0)
1400 RETURN_FAIL("TIOCMGET ioctl failed");
1403 int ret = get_flow(port->fd, &data->flow);
1405 if (ret == SP_ERR_FAIL && errno == EINVAL)
1406 data->termiox_supported = 0;
1408 RETURN_CODEVAL(ret);
1410 data->termiox_supported = 1;
1412 data->termiox_supported = 0;
1415 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1416 if (cfgetispeed(&data->term) == std_baudrates[i].index) {
1417 config->baudrate = std_baudrates[i].value;
1422 if (i == NUM_STD_BAUDRATES) {
1424 config->baudrate = (int)data->term.c_ispeed;
1425 #elif defined(__linux__)
1426 TRY(get_baudrate(port->fd, &config->baudrate));
1428 config->baudrate = -1;
1432 switch (data->term.c_cflag & CSIZE) {
1449 if (!(data->term.c_cflag & PARENB) && (data->term.c_iflag & IGNPAR))
1450 config->parity = SP_PARITY_NONE;
1451 else if (!(data->term.c_cflag & PARENB) || (data->term.c_iflag & IGNPAR))
1452 config->parity = -1;
1454 else if (data->term.c_cflag & CMSPAR)
1455 config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_MARK : SP_PARITY_SPACE;
1458 config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_ODD : SP_PARITY_EVEN;
1460 config->stopbits = (data->term.c_cflag & CSTOPB) ? 2 : 1;
1462 if (data->term.c_cflag & CRTSCTS) {
1463 config->rts = SP_RTS_FLOW_CONTROL;
1464 config->cts = SP_CTS_FLOW_CONTROL;
1466 if (data->termiox_supported && data->flow & RTS_FLOW)
1467 config->rts = SP_RTS_FLOW_CONTROL;
1469 config->rts = (data->controlbits & TIOCM_RTS) ? SP_RTS_ON : SP_RTS_OFF;
1471 config->cts = (data->termiox_supported && data->flow & CTS_FLOW) ?
1472 SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1475 if (data->termiox_supported && data->flow & DTR_FLOW)
1476 config->dtr = SP_DTR_FLOW_CONTROL;
1478 config->dtr = (data->controlbits & TIOCM_DTR) ? SP_DTR_ON : SP_DTR_OFF;
1480 config->dsr = (data->termiox_supported && data->flow & DSR_FLOW) ?
1481 SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1483 if (data->term.c_iflag & IXOFF) {
1484 if (data->term.c_iflag & IXON)
1485 config->xon_xoff = SP_XONXOFF_INOUT;
1487 config->xon_xoff = SP_XONXOFF_IN;
1489 if (data->term.c_iflag & IXON)
1490 config->xon_xoff = SP_XONXOFF_OUT;
1492 config->xon_xoff = SP_XONXOFF_DISABLED;
1499 static enum sp_return set_config(struct sp_port *port, struct port_data *data,
1500 const struct sp_port_config *config)
1504 BAUD_TYPE baud_nonstd;
1509 int baud_nonstd = 0;
1512 TRACE("%p, %p, %p", port, data, config);
1514 DEBUG("Setting configuration for port %s", port->name);
1517 if (config->baudrate >= 0) {
1518 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1519 if (config->baudrate == std_baudrates[i].value) {
1520 data->dcb.BaudRate = std_baudrates[i].index;
1525 if (i == NUM_STD_BAUDRATES)
1526 data->dcb.BaudRate = config->baudrate;
1529 if (config->bits >= 0)
1530 data->dcb.ByteSize = config->bits;
1532 if (config->parity >= 0) {
1533 switch (config->parity) {
1534 /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
1535 case SP_PARITY_NONE:
1536 data->dcb.Parity = NOPARITY;
1539 data->dcb.Parity = ODDPARITY;
1541 case SP_PARITY_EVEN:
1542 data->dcb.Parity = EVENPARITY;
1544 case SP_PARITY_MARK:
1545 data->dcb.Parity = MARKPARITY;
1547 case SP_PARITY_SPACE:
1548 data->dcb.Parity = SPACEPARITY;
1551 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1555 if (config->stopbits >= 0) {
1556 switch (config->stopbits) {
1557 /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
1559 data->dcb.StopBits = ONESTOPBIT;
1562 data->dcb.StopBits = TWOSTOPBITS;
1565 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bit setting");
1569 if (config->rts >= 0) {
1570 switch (config->rts) {
1572 data->dcb.fRtsControl = RTS_CONTROL_DISABLE;
1575 data->dcb.fRtsControl = RTS_CONTROL_ENABLE;
1577 case SP_RTS_FLOW_CONTROL:
1578 data->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
1581 RETURN_ERROR(SP_ERR_ARG, "Invalid RTS setting");
1585 if (config->cts >= 0) {
1586 switch (config->cts) {
1588 data->dcb.fOutxCtsFlow = FALSE;
1590 case SP_CTS_FLOW_CONTROL:
1591 data->dcb.fOutxCtsFlow = TRUE;
1594 RETURN_ERROR(SP_ERR_ARG, "Invalid CTS setting");
1598 if (config->dtr >= 0) {
1599 switch (config->dtr) {
1601 data->dcb.fDtrControl = DTR_CONTROL_DISABLE;
1604 data->dcb.fDtrControl = DTR_CONTROL_ENABLE;
1606 case SP_DTR_FLOW_CONTROL:
1607 data->dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
1610 RETURN_ERROR(SP_ERR_ARG, "Invalid DTR setting");
1614 if (config->dsr >= 0) {
1615 switch (config->dsr) {
1617 data->dcb.fOutxDsrFlow = FALSE;
1619 case SP_DSR_FLOW_CONTROL:
1620 data->dcb.fOutxDsrFlow = TRUE;
1623 RETURN_ERROR(SP_ERR_ARG, "Invalid DSR setting");
1627 if (config->xon_xoff >= 0) {
1628 switch (config->xon_xoff) {
1629 case SP_XONXOFF_DISABLED:
1630 data->dcb.fInX = FALSE;
1631 data->dcb.fOutX = FALSE;
1634 data->dcb.fInX = TRUE;
1635 data->dcb.fOutX = FALSE;
1637 case SP_XONXOFF_OUT:
1638 data->dcb.fInX = FALSE;
1639 data->dcb.fOutX = TRUE;
1641 case SP_XONXOFF_INOUT:
1642 data->dcb.fInX = TRUE;
1643 data->dcb.fOutX = TRUE;
1646 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1650 if (!SetCommState(port->hdl, &data->dcb))
1651 RETURN_FAIL("SetCommState() failed");
1657 if (config->baudrate >= 0) {
1658 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1659 if (config->baudrate == std_baudrates[i].value) {
1660 if (cfsetospeed(&data->term, std_baudrates[i].index) < 0)
1661 RETURN_FAIL("cfsetospeed() failed");
1663 if (cfsetispeed(&data->term, std_baudrates[i].index) < 0)
1664 RETURN_FAIL("cfsetispeed() failed");
1669 /* Non-standard baud rate */
1670 if (i == NUM_STD_BAUDRATES) {
1672 /* Set "dummy" baud rate. */
1673 if (cfsetspeed(&data->term, B9600) < 0)
1674 RETURN_FAIL("cfsetspeed() failed");
1675 baud_nonstd = config->baudrate;
1676 #elif defined(__linux__)
1679 RETURN_ERROR(SP_ERR_SUPP, "Non-standard baudrate not supported");
1684 if (config->bits >= 0) {
1685 data->term.c_cflag &= ~CSIZE;
1686 switch (config->bits) {
1688 data->term.c_cflag |= CS8;
1691 data->term.c_cflag |= CS7;
1694 data->term.c_cflag |= CS6;
1697 data->term.c_cflag |= CS5;
1700 RETURN_ERROR(SP_ERR_ARG, "Invalid data bits setting");
1704 if (config->parity >= 0) {
1705 data->term.c_iflag &= ~IGNPAR;
1706 data->term.c_cflag &= ~(PARENB | PARODD);
1708 data->term.c_cflag &= ~CMSPAR;
1710 switch (config->parity) {
1711 case SP_PARITY_NONE:
1712 data->term.c_iflag |= IGNPAR;
1714 case SP_PARITY_EVEN:
1715 data->term.c_cflag |= PARENB;
1718 data->term.c_cflag |= PARENB | PARODD;
1721 case SP_PARITY_MARK:
1722 data->term.c_cflag |= PARENB | PARODD;
1723 data->term.c_cflag |= CMSPAR;
1725 case SP_PARITY_SPACE:
1726 data->term.c_cflag |= PARENB;
1727 data->term.c_cflag |= CMSPAR;
1730 case SP_PARITY_MARK:
1731 case SP_PARITY_SPACE:
1732 RETURN_ERROR(SP_ERR_SUPP, "Mark/space parity not supported");
1735 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1739 if (config->stopbits >= 0) {
1740 data->term.c_cflag &= ~CSTOPB;
1741 switch (config->stopbits) {
1743 data->term.c_cflag &= ~CSTOPB;
1746 data->term.c_cflag |= CSTOPB;
1749 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bits setting");
1753 if (config->rts >= 0 || config->cts >= 0) {
1754 if (data->termiox_supported) {
1755 data->flow &= ~(RTS_FLOW | CTS_FLOW);
1756 switch (config->rts) {
1759 controlbits = TIOCM_RTS;
1760 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1761 RETURN_FAIL("Setting RTS signal level failed");
1763 case SP_RTS_FLOW_CONTROL:
1764 data->flow |= RTS_FLOW;
1769 if (config->cts == SP_CTS_FLOW_CONTROL)
1770 data->flow |= CTS_FLOW;
1772 if (data->flow & (RTS_FLOW | CTS_FLOW))
1773 data->term.c_iflag |= CRTSCTS;
1775 data->term.c_iflag &= ~CRTSCTS;
1777 /* Asymmetric use of RTS/CTS not supported. */
1778 if (data->term.c_iflag & CRTSCTS) {
1779 /* Flow control can only be disabled for both RTS & CTS together. */
1780 if (config->rts >= 0 && config->rts != SP_RTS_FLOW_CONTROL) {
1781 if (config->cts != SP_CTS_IGNORE)
1782 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1784 if (config->cts >= 0 && config->cts != SP_CTS_FLOW_CONTROL) {
1785 if (config->rts <= 0 || config->rts == SP_RTS_FLOW_CONTROL)
1786 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1789 /* Flow control can only be enabled for both RTS & CTS together. */
1790 if (((config->rts == SP_RTS_FLOW_CONTROL) && (config->cts != SP_CTS_FLOW_CONTROL)) ||
1791 ((config->cts == SP_CTS_FLOW_CONTROL) && (config->rts != SP_RTS_FLOW_CONTROL)))
1792 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be enabled together");
1795 if (config->rts >= 0) {
1796 if (config->rts == SP_RTS_FLOW_CONTROL) {
1797 data->term.c_iflag |= CRTSCTS;
1799 controlbits = TIOCM_RTS;
1800 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC,
1802 RETURN_FAIL("Setting RTS signal level failed");
1808 if (config->dtr >= 0 || config->dsr >= 0) {
1809 if (data->termiox_supported) {
1810 data->flow &= ~(DTR_FLOW | DSR_FLOW);
1811 switch (config->dtr) {
1814 controlbits = TIOCM_DTR;
1815 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1816 RETURN_FAIL("Setting DTR signal level failed");
1818 case SP_DTR_FLOW_CONTROL:
1819 data->flow |= DTR_FLOW;
1824 if (config->dsr == SP_DSR_FLOW_CONTROL)
1825 data->flow |= DSR_FLOW;
1827 /* DTR/DSR flow control not supported. */
1828 if (config->dtr == SP_DTR_FLOW_CONTROL || config->dsr == SP_DSR_FLOW_CONTROL)
1829 RETURN_ERROR(SP_ERR_SUPP, "DTR/DSR flow control not supported");
1831 if (config->dtr >= 0) {
1832 controlbits = TIOCM_DTR;
1833 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC,
1835 RETURN_FAIL("Setting DTR signal level failed");
1840 if (config->xon_xoff >= 0) {
1841 data->term.c_iflag &= ~(IXON | IXOFF | IXANY);
1842 switch (config->xon_xoff) {
1843 case SP_XONXOFF_DISABLED:
1846 data->term.c_iflag |= IXOFF;
1848 case SP_XONXOFF_OUT:
1849 data->term.c_iflag |= IXON | IXANY;
1851 case SP_XONXOFF_INOUT:
1852 data->term.c_iflag |= IXON | IXOFF | IXANY;
1855 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1859 if (tcsetattr(port->fd, TCSANOW, &data->term) < 0)
1860 RETURN_FAIL("tcsetattr() failed");
1863 if (baud_nonstd != B0) {
1864 if (ioctl(port->fd, IOSSIOSPEED, &baud_nonstd) == -1)
1865 RETURN_FAIL("IOSSIOSPEED ioctl failed");
1866 /* Set baud rates in data->term to correct, but incompatible
1867 * with tcsetattr() value, same as delivered by tcgetattr(). */
1868 if (cfsetspeed(&data->term, baud_nonstd) < 0)
1869 RETURN_FAIL("cfsetspeed() failed");
1871 #elif defined(__linux__)
1873 TRY(set_baudrate(port->fd, config->baudrate));
1875 if (data->termiox_supported)
1876 TRY(set_flow(port->fd, data->flow));
1880 #endif /* !_WIN32 */
1885 enum sp_return sp_new_config(struct sp_port_config **config_ptr)
1887 struct sp_port_config *config;
1889 TRACE("%p", config_ptr);
1892 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
1896 if (!(config = malloc(sizeof(struct sp_port_config))))
1897 RETURN_ERROR(SP_ERR_MEM, "config malloc failed");
1899 config->baudrate = -1;
1901 config->parity = -1;
1902 config->stopbits = -1;
1908 *config_ptr = config;
1913 void sp_free_config(struct sp_port_config *config)
1915 TRACE("%p", config);
1918 DEBUG("Null config");
1925 enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config)
1927 struct port_data data;
1929 TRACE("%p, %p", port, config);
1934 RETURN_ERROR(SP_ERR_ARG, "Null config");
1936 TRY(get_config(port, &data, config));
1941 enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config)
1943 struct port_data data;
1944 struct sp_port_config prev_config;
1946 TRACE("%p, %p", port, config);
1951 RETURN_ERROR(SP_ERR_ARG, "Null config");
1953 TRY(get_config(port, &data, &prev_config));
1954 TRY(set_config(port, &data, config));
1959 #define CREATE_ACCESSORS(x, type) \
1960 enum sp_return sp_set_##x(struct sp_port *port, type x) { \
1961 struct port_data data; \
1962 struct sp_port_config config; \
1963 TRACE("%p, %d", port, x); \
1964 CHECK_OPEN_PORT(); \
1965 TRY(get_config(port, &data, &config)); \
1967 TRY(set_config(port, &data, &config)); \
1970 enum sp_return sp_get_config_##x(const struct sp_port_config *config, type *x) { \
1971 TRACE("%p, %p", config, x); \
1973 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
1977 enum sp_return sp_set_config_##x(struct sp_port_config *config, type x) { \
1978 TRACE("%p, %d", config, x); \
1980 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
1985 CREATE_ACCESSORS(baudrate, int)
1986 CREATE_ACCESSORS(bits, int)
1987 CREATE_ACCESSORS(parity, enum sp_parity)
1988 CREATE_ACCESSORS(stopbits, int)
1989 CREATE_ACCESSORS(rts, enum sp_rts)
1990 CREATE_ACCESSORS(cts, enum sp_cts)
1991 CREATE_ACCESSORS(dtr, enum sp_dtr)
1992 CREATE_ACCESSORS(dsr, enum sp_dsr)
1993 CREATE_ACCESSORS(xon_xoff, enum sp_xonxoff)
1995 enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol)
1998 RETURN_ERROR(SP_ERR_ARG, "Null configuration");
2000 if (flowcontrol > SP_FLOWCONTROL_DTRDSR)
2001 RETURN_ERROR(SP_ERR_ARG, "Invalid flow control setting");
2003 if (flowcontrol == SP_FLOWCONTROL_XONXOFF)
2004 config->xon_xoff = SP_XONXOFF_INOUT;
2006 config->xon_xoff = SP_XONXOFF_DISABLED;
2008 if (flowcontrol == SP_FLOWCONTROL_RTSCTS) {
2009 config->rts = SP_RTS_FLOW_CONTROL;
2010 config->cts = SP_CTS_FLOW_CONTROL;
2012 if (config->rts == SP_RTS_FLOW_CONTROL)
2013 config->rts = SP_RTS_ON;
2014 config->cts = SP_CTS_IGNORE;
2017 if (flowcontrol == SP_FLOWCONTROL_DTRDSR) {
2018 config->dtr = SP_DTR_FLOW_CONTROL;
2019 config->dsr = SP_DSR_FLOW_CONTROL;
2021 if (config->dtr == SP_DTR_FLOW_CONTROL)
2022 config->dtr = SP_DTR_ON;
2023 config->dsr = SP_DSR_IGNORE;
2029 enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol)
2031 struct port_data data;
2032 struct sp_port_config config;
2034 TRACE("%p, %d", port, flowcontrol);
2038 TRY(get_config(port, &data, &config));
2040 TRY(sp_set_config_flowcontrol(&config, flowcontrol));
2042 TRY(set_config(port, &data, &config));
2047 enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signals)
2049 TRACE("%p, %p", port, signals);
2054 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
2056 DEBUG("Getting control signals for port %s", port->name);
2061 if (GetCommModemStatus(port->hdl, &bits) == 0)
2062 RETURN_FAIL("GetCommModemStatus() failed");
2063 if (bits & MS_CTS_ON)
2064 *signals |= SP_SIG_CTS;
2065 if (bits & MS_DSR_ON)
2066 *signals |= SP_SIG_DSR;
2067 if (bits & MS_RLSD_ON)
2068 *signals |= SP_SIG_DCD;
2069 if (bits & MS_RING_ON)
2070 *signals |= SP_SIG_RI;
2073 if (ioctl(port->fd, TIOCMGET, &bits) < 0)
2074 RETURN_FAIL("TIOCMGET ioctl failed");
2075 if (bits & TIOCM_CTS)
2076 *signals |= SP_SIG_CTS;
2077 if (bits & TIOCM_DSR)
2078 *signals |= SP_SIG_DSR;
2079 if (bits & TIOCM_CAR)
2080 *signals |= SP_SIG_DCD;
2081 if (bits & TIOCM_RNG)
2082 *signals |= SP_SIG_RI;
2087 enum sp_return sp_start_break(struct sp_port *port)
2093 if (SetCommBreak(port->hdl) == 0)
2094 RETURN_FAIL("SetCommBreak() failed");
2096 if (ioctl(port->fd, TIOCSBRK, 1) < 0)
2097 RETURN_FAIL("TIOCSBRK ioctl failed");
2103 enum sp_return sp_end_break(struct sp_port *port)
2109 if (ClearCommBreak(port->hdl) == 0)
2110 RETURN_FAIL("ClearCommBreak() failed");
2112 if (ioctl(port->fd, TIOCCBRK, 1) < 0)
2113 RETURN_FAIL("TIOCCBRK ioctl failed");
2119 int sp_last_error_code(void)
2123 RETURN_VALUE("%d", GetLastError());
2125 RETURN_VALUE("%d", errno);
2129 char *sp_last_error_message(void)
2135 DWORD error = GetLastError();
2138 FORMAT_MESSAGE_ALLOCATE_BUFFER |
2139 FORMAT_MESSAGE_FROM_SYSTEM |
2140 FORMAT_MESSAGE_IGNORE_INSERTS,
2143 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2147 RETURN_VALUE("%s", message);
2149 RETURN_VALUE("%s", strerror(errno));
2153 void sp_free_error_message(char *message)
2155 TRACE("%s", message);
2166 void sp_set_debug_handler(void (*handler)(const char *format, ...))
2168 TRACE("%p", handler);
2170 sp_debug_handler = handler;
2175 void sp_default_debug_handler(const char *format, ...)
2178 va_start(args, format);
2179 if (getenv("LIBSERIALPORT_DEBUG")) {
2180 fputs("sp: ", stderr);
2181 vfprintf(stderr, format, args);