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);
1135 static enum sp_return get_baudrate(int fd, int *baudrate)
1139 TRACE("%d, %p", fd, baudrate);
1141 DEBUG("Getting baud rate");
1143 if (!(data = malloc(get_termios_size())))
1144 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
1146 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
1148 RETURN_FAIL("getting termios failed");
1151 *baudrate = get_termios_speed(data);
1158 static enum sp_return set_baudrate(int fd, int baudrate)
1162 TRACE("%d, %d", fd, baudrate);
1164 DEBUG("Getting baud rate");
1166 if (!(data = malloc(get_termios_size())))
1167 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
1169 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
1171 RETURN_FAIL("getting termios failed");
1174 DEBUG("Setting baud rate");
1176 set_termios_speed(data, baudrate);
1178 if (ioctl(fd, get_termios_set_ioctl(), data) < 0) {
1180 RETURN_FAIL("setting termios failed");
1189 static enum sp_return get_flow(int fd, int *flow)
1193 TRACE("%d, %p", fd, flow);
1195 DEBUG("Getting advanced flow control");
1197 if (!(data = malloc(get_termiox_size())))
1198 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
1200 if (ioctl(fd, TCGETX, data) < 0) {
1202 RETURN_FAIL("getting termiox failed");
1205 *flow = get_termiox_flow(data);
1212 static enum sp_return set_flow(int fd, int flow)
1216 TRACE("%d, %d", fd, flow);
1218 DEBUG("Getting advanced flow control");
1220 if (!(data = malloc(get_termiox_size())))
1221 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
1223 if (ioctl(fd, TCGETX, data) < 0) {
1225 RETURN_FAIL("getting termiox failed");
1228 DEBUG("Setting advanced flow control");
1230 set_termiox_flow(data, flow);
1232 if (ioctl(fd, TCSETX, data) < 0) {
1234 RETURN_FAIL("setting termiox failed");
1241 #endif /* USE_TERMIOX */
1242 #endif /* __linux__ */
1244 static enum sp_return get_config(struct sp_port *port, struct port_data *data,
1245 struct sp_port_config *config)
1249 TRACE("%p, %p, %p", port, data, config);
1251 DEBUG("Getting configuration for port %s", port->name);
1254 if (!GetCommState(port->hdl, &data->dcb))
1255 RETURN_FAIL("GetCommState() failed");
1257 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1258 if (data->dcb.BaudRate == std_baudrates[i].index) {
1259 config->baudrate = std_baudrates[i].value;
1264 if (i == NUM_STD_BAUDRATES)
1265 /* BaudRate field can be either an index or a custom baud rate. */
1266 config->baudrate = data->dcb.BaudRate;
1268 config->bits = data->dcb.ByteSize;
1270 if (data->dcb.fParity)
1271 switch (data->dcb.Parity) {
1273 config->parity = SP_PARITY_NONE;
1276 config->parity = SP_PARITY_ODD;
1279 config->parity = SP_PARITY_EVEN;
1282 config->parity = SP_PARITY_MARK;
1285 config->parity = SP_PARITY_SPACE;
1288 config->parity = -1;
1291 config->parity = SP_PARITY_NONE;
1293 switch (data->dcb.StopBits) {
1295 config->stopbits = 1;
1298 config->stopbits = 2;
1301 config->stopbits = -1;
1304 switch (data->dcb.fRtsControl) {
1305 case RTS_CONTROL_DISABLE:
1306 config->rts = SP_RTS_OFF;
1308 case RTS_CONTROL_ENABLE:
1309 config->rts = SP_RTS_ON;
1311 case RTS_CONTROL_HANDSHAKE:
1312 config->rts = SP_RTS_FLOW_CONTROL;
1318 config->cts = data->dcb.fOutxCtsFlow ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1320 switch (data->dcb.fDtrControl) {
1321 case DTR_CONTROL_DISABLE:
1322 config->dtr = SP_DTR_OFF;
1324 case DTR_CONTROL_ENABLE:
1325 config->dtr = SP_DTR_ON;
1327 case DTR_CONTROL_HANDSHAKE:
1328 config->dtr = SP_DTR_FLOW_CONTROL;
1334 config->dsr = data->dcb.fOutxDsrFlow ? SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1336 if (data->dcb.fInX) {
1337 if (data->dcb.fOutX)
1338 config->xon_xoff = SP_XONXOFF_INOUT;
1340 config->xon_xoff = SP_XONXOFF_IN;
1342 if (data->dcb.fOutX)
1343 config->xon_xoff = SP_XONXOFF_OUT;
1345 config->xon_xoff = SP_XONXOFF_DISABLED;
1350 if (tcgetattr(port->fd, &data->term) < 0)
1351 RETURN_FAIL("tcgetattr() failed");
1353 if (ioctl(port->fd, TIOCMGET, &data->controlbits) < 0)
1354 RETURN_FAIL("TIOCMGET ioctl failed");
1357 int ret = get_flow(port->fd, &data->flow);
1359 if (ret == SP_ERR_FAIL && errno == EINVAL)
1360 data->termiox_supported = 0;
1362 RETURN_CODEVAL(ret);
1364 data->termiox_supported = 1;
1366 data->termiox_supported = 0;
1369 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1370 if (cfgetispeed(&data->term) == std_baudrates[i].index) {
1371 config->baudrate = std_baudrates[i].value;
1376 if (i == NUM_STD_BAUDRATES) {
1378 config->baudrate = (int)data->term.c_ispeed;
1379 #elif defined(__linux__)
1380 TRY(get_baudrate(port->fd, &config->baudrate));
1382 config->baudrate = -1;
1386 switch (data->term.c_cflag & CSIZE) {
1403 if (!(data->term.c_cflag & PARENB) && (data->term.c_iflag & IGNPAR))
1404 config->parity = SP_PARITY_NONE;
1405 else if (!(data->term.c_cflag & PARENB) || (data->term.c_iflag & IGNPAR))
1406 config->parity = -1;
1408 else if (data->term.c_cflag & CMSPAR)
1409 config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_MARK : SP_PARITY_SPACE;
1412 config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_ODD : SP_PARITY_EVEN;
1414 config->stopbits = (data->term.c_cflag & CSTOPB) ? 2 : 1;
1416 if (data->term.c_cflag & CRTSCTS) {
1417 config->rts = SP_RTS_FLOW_CONTROL;
1418 config->cts = SP_CTS_FLOW_CONTROL;
1420 if (data->termiox_supported && data->flow & RTS_FLOW)
1421 config->rts = SP_RTS_FLOW_CONTROL;
1423 config->rts = (data->controlbits & TIOCM_RTS) ? SP_RTS_ON : SP_RTS_OFF;
1425 config->cts = (data->termiox_supported && data->flow & CTS_FLOW) ?
1426 SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1429 if (data->termiox_supported && data->flow & DTR_FLOW)
1430 config->dtr = SP_DTR_FLOW_CONTROL;
1432 config->dtr = (data->controlbits & TIOCM_DTR) ? SP_DTR_ON : SP_DTR_OFF;
1434 config->dsr = (data->termiox_supported && data->flow & DSR_FLOW) ?
1435 SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1437 if (data->term.c_iflag & IXOFF) {
1438 if (data->term.c_iflag & IXON)
1439 config->xon_xoff = SP_XONXOFF_INOUT;
1441 config->xon_xoff = SP_XONXOFF_IN;
1443 if (data->term.c_iflag & IXON)
1444 config->xon_xoff = SP_XONXOFF_OUT;
1446 config->xon_xoff = SP_XONXOFF_DISABLED;
1453 static enum sp_return set_config(struct sp_port *port, struct port_data *data,
1454 const struct sp_port_config *config)
1458 BAUD_TYPE baud_nonstd;
1463 int baud_nonstd = 0;
1466 TRACE("%p, %p, %p", port, data, config);
1468 DEBUG("Setting configuration for port %s", port->name);
1471 if (config->baudrate >= 0) {
1472 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1473 if (config->baudrate == std_baudrates[i].value) {
1474 data->dcb.BaudRate = std_baudrates[i].index;
1479 if (i == NUM_STD_BAUDRATES)
1480 data->dcb.BaudRate = config->baudrate;
1483 if (config->bits >= 0)
1484 data->dcb.ByteSize = config->bits;
1486 if (config->parity >= 0) {
1487 switch (config->parity) {
1488 /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
1489 case SP_PARITY_NONE:
1490 data->dcb.Parity = NOPARITY;
1493 data->dcb.Parity = ODDPARITY;
1495 case SP_PARITY_EVEN:
1496 data->dcb.Parity = EVENPARITY;
1498 case SP_PARITY_MARK:
1499 data->dcb.Parity = MARKPARITY;
1501 case SP_PARITY_SPACE:
1502 data->dcb.Parity = SPACEPARITY;
1505 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1509 if (config->stopbits >= 0) {
1510 switch (config->stopbits) {
1511 /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
1513 data->dcb.StopBits = ONESTOPBIT;
1516 data->dcb.StopBits = TWOSTOPBITS;
1519 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bit setting");
1523 if (config->rts >= 0) {
1524 switch (config->rts) {
1526 data->dcb.fRtsControl = RTS_CONTROL_DISABLE;
1529 data->dcb.fRtsControl = RTS_CONTROL_ENABLE;
1531 case SP_RTS_FLOW_CONTROL:
1532 data->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
1535 RETURN_ERROR(SP_ERR_ARG, "Invalid RTS setting");
1539 if (config->cts >= 0) {
1540 switch (config->cts) {
1542 data->dcb.fOutxCtsFlow = FALSE;
1544 case SP_CTS_FLOW_CONTROL:
1545 data->dcb.fOutxCtsFlow = TRUE;
1548 RETURN_ERROR(SP_ERR_ARG, "Invalid CTS setting");
1552 if (config->dtr >= 0) {
1553 switch (config->dtr) {
1555 data->dcb.fDtrControl = DTR_CONTROL_DISABLE;
1558 data->dcb.fDtrControl = DTR_CONTROL_ENABLE;
1560 case SP_DTR_FLOW_CONTROL:
1561 data->dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
1564 RETURN_ERROR(SP_ERR_ARG, "Invalid DTR setting");
1568 if (config->dsr >= 0) {
1569 switch (config->dsr) {
1571 data->dcb.fOutxDsrFlow = FALSE;
1573 case SP_DSR_FLOW_CONTROL:
1574 data->dcb.fOutxDsrFlow = TRUE;
1577 RETURN_ERROR(SP_ERR_ARG, "Invalid DSR setting");
1581 if (config->xon_xoff >= 0) {
1582 switch (config->xon_xoff) {
1583 case SP_XONXOFF_DISABLED:
1584 data->dcb.fInX = FALSE;
1585 data->dcb.fOutX = FALSE;
1588 data->dcb.fInX = TRUE;
1589 data->dcb.fOutX = FALSE;
1591 case SP_XONXOFF_OUT:
1592 data->dcb.fInX = FALSE;
1593 data->dcb.fOutX = TRUE;
1595 case SP_XONXOFF_INOUT:
1596 data->dcb.fInX = TRUE;
1597 data->dcb.fOutX = TRUE;
1600 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1604 if (!SetCommState(port->hdl, &data->dcb))
1605 RETURN_FAIL("SetCommState() failed");
1611 if (config->baudrate >= 0) {
1612 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1613 if (config->baudrate == std_baudrates[i].value) {
1614 if (cfsetospeed(&data->term, std_baudrates[i].index) < 0)
1615 RETURN_FAIL("cfsetospeed() failed");
1617 if (cfsetispeed(&data->term, std_baudrates[i].index) < 0)
1618 RETURN_FAIL("cfsetispeed() failed");
1623 /* Non-standard baud rate */
1624 if (i == NUM_STD_BAUDRATES) {
1626 /* Set "dummy" baud rate. */
1627 if (cfsetspeed(&data->term, B9600) < 0)
1628 RETURN_FAIL("cfsetspeed() failed");
1629 baud_nonstd = config->baudrate;
1630 #elif defined(__linux__)
1633 RETURN_ERROR(SP_ERR_SUPP, "Non-standard baudrate not supported");
1638 if (config->bits >= 0) {
1639 data->term.c_cflag &= ~CSIZE;
1640 switch (config->bits) {
1642 data->term.c_cflag |= CS8;
1645 data->term.c_cflag |= CS7;
1648 data->term.c_cflag |= CS6;
1651 data->term.c_cflag |= CS5;
1654 RETURN_ERROR(SP_ERR_ARG, "Invalid data bits setting");
1658 if (config->parity >= 0) {
1659 data->term.c_iflag &= ~IGNPAR;
1660 data->term.c_cflag &= ~(PARENB | PARODD);
1662 data->term.c_cflag &= ~CMSPAR;
1664 switch (config->parity) {
1665 case SP_PARITY_NONE:
1666 data->term.c_iflag |= IGNPAR;
1668 case SP_PARITY_EVEN:
1669 data->term.c_cflag |= PARENB;
1672 data->term.c_cflag |= PARENB | PARODD;
1675 case SP_PARITY_MARK:
1676 data->term.c_cflag |= PARENB | PARODD;
1677 data->term.c_cflag |= CMSPAR;
1679 case SP_PARITY_SPACE:
1680 data->term.c_cflag |= PARENB;
1681 data->term.c_cflag |= CMSPAR;
1684 case SP_PARITY_MARK:
1685 case SP_PARITY_SPACE:
1686 RETURN_ERROR(SP_ERR_SUPP, "Mark/space parity not supported");
1689 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1693 if (config->stopbits >= 0) {
1694 data->term.c_cflag &= ~CSTOPB;
1695 switch (config->stopbits) {
1697 data->term.c_cflag &= ~CSTOPB;
1700 data->term.c_cflag |= CSTOPB;
1703 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bits setting");
1707 if (config->rts >= 0 || config->cts >= 0) {
1708 if (data->termiox_supported) {
1709 data->flow &= ~(RTS_FLOW | CTS_FLOW);
1710 switch (config->rts) {
1713 controlbits = TIOCM_RTS;
1714 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1715 RETURN_FAIL("Setting RTS signal level failed");
1717 case SP_RTS_FLOW_CONTROL:
1718 data->flow |= RTS_FLOW;
1723 if (config->cts == SP_CTS_FLOW_CONTROL)
1724 data->flow |= CTS_FLOW;
1726 if (data->flow & (RTS_FLOW | CTS_FLOW))
1727 data->term.c_iflag |= CRTSCTS;
1729 data->term.c_iflag &= ~CRTSCTS;
1731 /* Asymmetric use of RTS/CTS not supported. */
1732 if (data->term.c_iflag & CRTSCTS) {
1733 /* Flow control can only be disabled for both RTS & CTS together. */
1734 if (config->rts >= 0 && config->rts != SP_RTS_FLOW_CONTROL) {
1735 if (config->cts != SP_CTS_IGNORE)
1736 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1738 if (config->cts >= 0 && config->cts != SP_CTS_FLOW_CONTROL) {
1739 if (config->rts <= 0 || config->rts == SP_RTS_FLOW_CONTROL)
1740 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1743 /* Flow control can only be enabled for both RTS & CTS together. */
1744 if (((config->rts == SP_RTS_FLOW_CONTROL) && (config->cts != SP_CTS_FLOW_CONTROL)) ||
1745 ((config->cts == SP_CTS_FLOW_CONTROL) && (config->rts != SP_RTS_FLOW_CONTROL)))
1746 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be enabled together");
1749 if (config->rts >= 0) {
1750 if (config->rts == SP_RTS_FLOW_CONTROL) {
1751 data->term.c_iflag |= CRTSCTS;
1753 controlbits = TIOCM_RTS;
1754 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC,
1756 RETURN_FAIL("Setting RTS signal level failed");
1762 if (config->dtr >= 0 || config->dsr >= 0) {
1763 if (data->termiox_supported) {
1764 data->flow &= ~(DTR_FLOW | DSR_FLOW);
1765 switch (config->dtr) {
1768 controlbits = TIOCM_DTR;
1769 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1770 RETURN_FAIL("Setting DTR signal level failed");
1772 case SP_DTR_FLOW_CONTROL:
1773 data->flow |= DTR_FLOW;
1778 if (config->dsr == SP_DSR_FLOW_CONTROL)
1779 data->flow |= DSR_FLOW;
1781 /* DTR/DSR flow control not supported. */
1782 if (config->dtr == SP_DTR_FLOW_CONTROL || config->dsr == SP_DSR_FLOW_CONTROL)
1783 RETURN_ERROR(SP_ERR_SUPP, "DTR/DSR flow control not supported");
1785 if (config->dtr >= 0) {
1786 controlbits = TIOCM_DTR;
1787 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC,
1789 RETURN_FAIL("Setting DTR signal level failed");
1794 if (config->xon_xoff >= 0) {
1795 data->term.c_iflag &= ~(IXON | IXOFF | IXANY);
1796 switch (config->xon_xoff) {
1797 case SP_XONXOFF_DISABLED:
1800 data->term.c_iflag |= IXOFF;
1802 case SP_XONXOFF_OUT:
1803 data->term.c_iflag |= IXON | IXANY;
1805 case SP_XONXOFF_INOUT:
1806 data->term.c_iflag |= IXON | IXOFF | IXANY;
1809 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1813 if (tcsetattr(port->fd, TCSANOW, &data->term) < 0)
1814 RETURN_FAIL("tcsetattr() failed");
1817 if (baud_nonstd != B0) {
1818 if (ioctl(port->fd, IOSSIOSPEED, &baud_nonstd) == -1)
1819 RETURN_FAIL("IOSSIOSPEED ioctl failed");
1820 /* Set baud rates in data->term to correct, but incompatible
1821 * with tcsetattr() value, same as delivered by tcgetattr(). */
1822 if (cfsetspeed(&data->term, baud_nonstd) < 0)
1823 RETURN_FAIL("cfsetspeed() failed");
1825 #elif defined(__linux__)
1827 TRY(set_baudrate(port->fd, config->baudrate));
1829 if (data->termiox_supported)
1830 TRY(set_flow(port->fd, data->flow));
1834 #endif /* !_WIN32 */
1839 enum sp_return sp_new_config(struct sp_port_config **config_ptr)
1841 struct sp_port_config *config;
1843 TRACE("%p", config_ptr);
1846 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
1850 if (!(config = malloc(sizeof(struct sp_port_config))))
1851 RETURN_ERROR(SP_ERR_MEM, "config malloc failed");
1853 config->baudrate = -1;
1855 config->parity = -1;
1856 config->stopbits = -1;
1862 *config_ptr = config;
1867 void sp_free_config(struct sp_port_config *config)
1869 TRACE("%p", config);
1872 DEBUG("Null config");
1879 enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config)
1881 struct port_data data;
1883 TRACE("%p, %p", port, config);
1888 RETURN_ERROR(SP_ERR_ARG, "Null config");
1890 TRY(get_config(port, &data, config));
1895 enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config)
1897 struct port_data data;
1898 struct sp_port_config prev_config;
1900 TRACE("%p, %p", port, config);
1905 RETURN_ERROR(SP_ERR_ARG, "Null config");
1907 TRY(get_config(port, &data, &prev_config));
1908 TRY(set_config(port, &data, config));
1913 #define CREATE_ACCESSORS(x, type) \
1914 enum sp_return sp_set_##x(struct sp_port *port, type x) { \
1915 struct port_data data; \
1916 struct sp_port_config config; \
1917 TRACE("%p, %d", port, x); \
1918 CHECK_OPEN_PORT(); \
1919 TRY(get_config(port, &data, &config)); \
1921 TRY(set_config(port, &data, &config)); \
1924 enum sp_return sp_get_config_##x(const struct sp_port_config *config, type *x) { \
1925 TRACE("%p, %p", config, x); \
1927 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
1931 enum sp_return sp_set_config_##x(struct sp_port_config *config, type x) { \
1932 TRACE("%p, %d", config, x); \
1934 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
1939 CREATE_ACCESSORS(baudrate, int)
1940 CREATE_ACCESSORS(bits, int)
1941 CREATE_ACCESSORS(parity, enum sp_parity)
1942 CREATE_ACCESSORS(stopbits, int)
1943 CREATE_ACCESSORS(rts, enum sp_rts)
1944 CREATE_ACCESSORS(cts, enum sp_cts)
1945 CREATE_ACCESSORS(dtr, enum sp_dtr)
1946 CREATE_ACCESSORS(dsr, enum sp_dsr)
1947 CREATE_ACCESSORS(xon_xoff, enum sp_xonxoff)
1949 enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol)
1952 RETURN_ERROR(SP_ERR_ARG, "Null configuration");
1954 if (flowcontrol > SP_FLOWCONTROL_DTRDSR)
1955 RETURN_ERROR(SP_ERR_ARG, "Invalid flow control setting");
1957 if (flowcontrol == SP_FLOWCONTROL_XONXOFF)
1958 config->xon_xoff = SP_XONXOFF_INOUT;
1960 config->xon_xoff = SP_XONXOFF_DISABLED;
1962 if (flowcontrol == SP_FLOWCONTROL_RTSCTS) {
1963 config->rts = SP_RTS_FLOW_CONTROL;
1964 config->cts = SP_CTS_FLOW_CONTROL;
1966 if (config->rts == SP_RTS_FLOW_CONTROL)
1967 config->rts = SP_RTS_ON;
1968 config->cts = SP_CTS_IGNORE;
1971 if (flowcontrol == SP_FLOWCONTROL_DTRDSR) {
1972 config->dtr = SP_DTR_FLOW_CONTROL;
1973 config->dsr = SP_DSR_FLOW_CONTROL;
1975 if (config->dtr == SP_DTR_FLOW_CONTROL)
1976 config->dtr = SP_DTR_ON;
1977 config->dsr = SP_DSR_IGNORE;
1983 enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol)
1985 struct port_data data;
1986 struct sp_port_config config;
1988 TRACE("%p, %d", port, flowcontrol);
1992 TRY(get_config(port, &data, &config));
1994 TRY(sp_set_config_flowcontrol(&config, flowcontrol));
1996 TRY(set_config(port, &data, &config));
2001 enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signals)
2003 TRACE("%p, %p", port, signals);
2008 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
2010 DEBUG("Getting control signals for port %s", port->name);
2015 if (GetCommModemStatus(port->hdl, &bits) == 0)
2016 RETURN_FAIL("GetCommModemStatus() failed");
2017 if (bits & MS_CTS_ON)
2018 *signals |= SP_SIG_CTS;
2019 if (bits & MS_DSR_ON)
2020 *signals |= SP_SIG_DSR;
2021 if (bits & MS_RLSD_ON)
2022 *signals |= SP_SIG_DCD;
2023 if (bits & MS_RING_ON)
2024 *signals |= SP_SIG_RI;
2027 if (ioctl(port->fd, TIOCMGET, &bits) < 0)
2028 RETURN_FAIL("TIOCMGET ioctl failed");
2029 if (bits & TIOCM_CTS)
2030 *signals |= SP_SIG_CTS;
2031 if (bits & TIOCM_DSR)
2032 *signals |= SP_SIG_DSR;
2033 if (bits & TIOCM_CAR)
2034 *signals |= SP_SIG_DCD;
2035 if (bits & TIOCM_RNG)
2036 *signals |= SP_SIG_RI;
2041 enum sp_return sp_start_break(struct sp_port *port)
2047 if (SetCommBreak(port->hdl) == 0)
2048 RETURN_FAIL("SetCommBreak() failed");
2050 if (ioctl(port->fd, TIOCSBRK, 1) < 0)
2051 RETURN_FAIL("TIOCSBRK ioctl failed");
2057 enum sp_return sp_end_break(struct sp_port *port)
2063 if (ClearCommBreak(port->hdl) == 0)
2064 RETURN_FAIL("ClearCommBreak() failed");
2066 if (ioctl(port->fd, TIOCCBRK, 1) < 0)
2067 RETURN_FAIL("TIOCCBRK ioctl failed");
2073 int sp_last_error_code(void)
2077 RETURN_VALUE("%d", GetLastError());
2079 RETURN_VALUE("%d", errno);
2083 char *sp_last_error_message(void)
2089 DWORD error = GetLastError();
2092 FORMAT_MESSAGE_ALLOCATE_BUFFER |
2093 FORMAT_MESSAGE_FROM_SYSTEM |
2094 FORMAT_MESSAGE_IGNORE_INSERTS,
2097 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
2101 RETURN_VALUE("%s", message);
2103 RETURN_VALUE("%s", strerror(errno));
2107 void sp_free_error_message(char *message)
2109 TRACE("%s", message);
2120 void sp_set_debug_handler(void (*handler)(const char *format, ...))
2122 TRACE("%p", handler);
2124 sp_debug_handler = handler;
2129 void sp_default_debug_handler(const char *format, ...)
2132 va_start(args, format);
2133 if (getenv("LIBSERIALPORT_DEBUG")) {
2134 fputs("sp: ", stderr);
2135 vfprintf(stderr, format, args);