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>
38 #include <sys/ioctl.h>
41 #include <IOKit/IOKitLib.h>
42 #include <IOKit/serial/IOSerialKeys.h>
43 #include <IOKit/serial/ioss.h>
44 #include <sys/syslimits.h>
48 #include "linux/serial.h"
49 #include "linux_termios.h"
50 #if defined(TCGETX) && defined(TCSETX) && defined(HAVE_TERMIOX)
56 #include "linux_termios.h"
59 #include "libserialport.h"
74 struct sp_port_config {
77 enum sp_parity parity;
83 enum sp_xonxoff xon_xoff;
92 int termiox_supported;
97 /* Standard baud rates. */
99 #define BAUD_TYPE DWORD
100 #define BAUD(n) {CBR_##n, n}
102 #define BAUD_TYPE speed_t
103 #define BAUD(n) {B##n, n}
106 struct std_baudrate {
111 const struct std_baudrate std_baudrates[] = {
114 * The baudrates 50/75/134/150/200/1800/230400/460800 do not seem to
115 * have documented CBR_* macros.
117 BAUD(110), BAUD(300), BAUD(600), BAUD(1200), BAUD(2400), BAUD(4800),
118 BAUD(9600), BAUD(14400), BAUD(19200), BAUD(38400), BAUD(57600),
119 BAUD(115200), BAUD(128000), BAUD(256000),
121 BAUD(50), BAUD(75), BAUD(110), BAUD(134), BAUD(150), BAUD(200),
122 BAUD(300), BAUD(600), BAUD(1200), BAUD(1800), BAUD(2400), BAUD(4800),
123 BAUD(9600), BAUD(19200), BAUD(38400), BAUD(57600), BAUD(115200),
125 #if !defined(__APPLE__) && !defined(__OpenBSD__)
131 void (*sp_debug_handler)(const char *format, ...) = sp_default_debug_handler;
133 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
134 #define NUM_STD_BAUDRATES ARRAY_SIZE(std_baudrates)
136 /* Debug output macros. */
137 #define DEBUG(fmt, ...) do { if (sp_debug_handler) sp_debug_handler(fmt ".\n", ##__VA_ARGS__); } while (0)
138 #define DEBUG_ERROR(err, msg) DEBUG("%s returning " #err ": " msg, __func__)
139 #define DEBUG_FAIL(msg) do { \
140 char *errmsg = sp_last_error_message(); \
141 DEBUG("%s returning SP_ERR_FAIL: " msg ": %s", __func__, errmsg); \
142 sp_free_error_message(errmsg); \
144 #define RETURN() do { DEBUG("%s returning", __func__); return; } while(0)
145 #define RETURN_CODE(x) do { DEBUG("%s returning " #x, __func__); return x; } while (0)
146 #define RETURN_CODEVAL(x) do { \
148 case SP_OK: RETURN_CODE(SP_OK); \
149 case SP_ERR_ARG: RETURN_CODE(SP_ERR_ARG); \
150 case SP_ERR_FAIL: RETURN_CODE(SP_ERR_FAIL); \
151 case SP_ERR_MEM: RETURN_CODE(SP_ERR_MEM); \
152 case SP_ERR_SUPP: RETURN_CODE(SP_ERR_SUPP); \
155 #define RETURN_OK() RETURN_CODE(SP_OK);
156 #define RETURN_ERROR(err, msg) do { DEBUG_ERROR(err, msg); return err; } while (0)
157 #define RETURN_FAIL(msg) do { DEBUG_FAIL(msg); return SP_ERR_FAIL; } while (0)
158 #define RETURN_VALUE(fmt, x) do { DEBUG("%s returning " fmt, __func__, x); return x; } while (0)
159 #define SET_ERROR(val, err, msg) do { DEBUG_ERROR(err, msg); val = err; } while (0)
160 #define SET_FAIL(val, msg) do { DEBUG_FAIL(msg); val = SP_ERR_FAIL; } while (0)
161 #define TRACE(fmt, ...) DEBUG("%s(" fmt ") called", __func__, ##__VA_ARGS__)
163 #define TRY(x) do { int ret = x; if (ret != SP_OK) RETURN_CODEVAL(ret); } while (0)
165 /* Helper functions. */
166 static struct sp_port **list_append(struct sp_port **list, const char *portname);
167 static enum sp_return get_config(struct sp_port *port, struct port_data *data,
168 struct sp_port_config *config);
169 static enum sp_return set_config(struct sp_port *port, struct port_data *data,
170 const struct sp_port_config *config);
172 enum sp_return sp_get_port_by_name(const char *portname, struct sp_port **port_ptr)
174 struct sp_port *port;
177 TRACE("%s, %p", portname, port_ptr);
180 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
185 RETURN_ERROR(SP_ERR_ARG, "Null port name");
187 DEBUG("Building structure for port %s", portname);
189 if (!(port = malloc(sizeof(struct sp_port))))
190 RETURN_ERROR(SP_ERR_MEM, "Port structure malloc failed");
192 len = strlen(portname) + 1;
194 if (!(port->name = malloc(len))) {
196 RETURN_ERROR(SP_ERR_MEM, "Port name malloc failed");
199 memcpy(port->name, portname, len);
202 port->hdl = INVALID_HANDLE_VALUE;
212 char *sp_get_port_name(const struct sp_port *port)
219 RETURN_VALUE("%s", port->name);
222 enum sp_return sp_get_port_handle(const struct sp_port *port, void *result_ptr)
224 TRACE("%p, %p", port, result_ptr);
227 RETURN_ERROR(SP_ERR_ARG, "Null port");
230 HANDLE *handle_ptr = result_ptr;
231 *handle_ptr = port->hdl;
233 int *fd_ptr = result_ptr;
240 enum sp_return sp_copy_port(const struct sp_port *port, struct sp_port **copy_ptr)
242 TRACE("%p, %p", port, copy_ptr);
245 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
250 RETURN_ERROR(SP_ERR_ARG, "Null port");
253 RETURN_ERROR(SP_ERR_ARG, "Null port name");
255 DEBUG("Copying port structure");
257 RETURN_VALUE("%p", sp_get_port_by_name(port->name, copy_ptr));
260 void sp_free_port(struct sp_port *port)
269 DEBUG("Freeing port structure");
279 static struct sp_port **list_append(struct sp_port **list, const char *portname)
284 for (count = 0; list[count]; count++);
285 if (!(tmp = realloc(list, sizeof(struct sp_port *) * (count + 2))))
288 if (sp_get_port_by_name(portname, &list[count]) != SP_OK)
290 list[count + 1] = NULL;
294 sp_free_port_list(list);
298 enum sp_return sp_list_ports(struct sp_port ***list_ptr)
300 struct sp_port **list;
301 int ret = SP_ERR_SUPP;
303 TRACE("%p", list_ptr);
306 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
308 DEBUG("Enumerating ports");
310 if (!(list = malloc(sizeof(struct sp_port **))))
311 RETURN_ERROR(SP_ERR_MEM, "Port list malloc failed");
318 DWORD max_value_len, max_data_size, max_data_len;
319 DWORD value_len, data_size, data_len;
320 DWORD type, index = 0;
326 DEBUG("Opening registry key");
327 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
328 0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS) {
329 SET_FAIL(ret, "RegOpenKeyEx() failed");
332 DEBUG("Querying registry key value and data sizes");
333 if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
334 &max_value_len, &max_data_size, NULL, NULL) != ERROR_SUCCESS) {
335 SET_FAIL(ret, "RegQueryInfoKey() failed");
338 max_data_len = max_data_size / sizeof(TCHAR);
339 if (!(value = malloc((max_value_len + 1) * sizeof(TCHAR)))) {
340 SET_ERROR(ret, SP_ERR_MEM, "registry value malloc failed");
343 if (!(data = malloc((max_data_len + 1) * sizeof(TCHAR)))) {
344 SET_ERROR(ret, SP_ERR_MEM, "registry data malloc failed");
347 DEBUG("Iterating over values");
349 value_len = max_value_len + 1,
350 data_size = max_data_size,
351 RegEnumValue(key, index, value, &value_len,
352 NULL, &type, (LPBYTE)data, &data_size) == ERROR_SUCCESS)
354 data_len = data_size / sizeof(TCHAR);
355 data[data_len] = '\0';
357 name_len = WideCharToMultiByte(CP_ACP, 0, data, -1, NULL, 0, NULL, NULL)
359 name_len = data_len + 1;
361 if (!(name = malloc(name_len))) {
362 SET_ERROR(ret, SP_ERR_MEM, "registry port name malloc failed");
366 WideCharToMultiByte(CP_ACP, 0, data, -1, name, name_len, NULL, NULL);
370 if (type == REG_SZ) {
371 DEBUG("Found port %s", name);
372 if (!(list = list_append(list, name))) {
373 SET_ERROR(ret, SP_ERR_MEM, "list append failed");
389 CFMutableDictionaryRef classes;
398 DEBUG("Getting IOKit master port");
399 if (IOMasterPort(MACH_PORT_NULL, &master) != KERN_SUCCESS) {
400 SET_FAIL(ret, "IOMasterPort() failed");
404 DEBUG("Creating matching dictionary");
405 if (!(classes = IOServiceMatching(kIOSerialBSDServiceValue))) {
406 SET_FAIL(ret, "IOServiceMatching() failed");
410 CFDictionarySetValue(classes,
411 CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes));
413 DEBUG("Getting matching services");
414 if (IOServiceGetMatchingServices(master, classes, &iter) != KERN_SUCCESS) {
415 SET_FAIL(ret, "IOServiceGetMatchingServices() failed");
419 if (!(path = malloc(PATH_MAX))) {
420 SET_ERROR(ret, SP_ERR_MEM, "device path malloc failed");
424 DEBUG("Iterating over results");
425 while ((port = IOIteratorNext(iter))) {
426 cf_path = IORegistryEntryCreateCFProperty(port,
427 CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
429 result = CFStringGetCString(cf_path,
430 path, PATH_MAX, kCFStringEncodingASCII);
433 DEBUG("Found port %s", path);
434 if (!(list = list_append(list, path))) {
435 SET_ERROR(ret, SP_ERR_MEM, "list append failed");
436 IOObjectRelease(port);
441 IOObjectRelease(port);
446 IOObjectRelease(iter);
451 struct udev_enumerate *ud_enumerate;
452 struct udev_list_entry *ud_list;
453 struct udev_list_entry *ud_entry;
455 struct udev_device *ud_dev, *ud_parent;
458 int fd, ioctl_result;
459 struct serial_struct serial_info;
463 DEBUG("Enumerating tty devices");
465 ud_enumerate = udev_enumerate_new(ud);
466 udev_enumerate_add_match_subsystem(ud_enumerate, "tty");
467 udev_enumerate_scan_devices(ud_enumerate);
468 ud_list = udev_enumerate_get_list_entry(ud_enumerate);
469 DEBUG("Iterating over results");
470 udev_list_entry_foreach(ud_entry, ud_list) {
471 path = udev_list_entry_get_name(ud_entry);
472 DEBUG("Found device %s", path);
473 ud_dev = udev_device_new_from_syspath(ud, path);
474 /* If there is no parent device, this is a virtual tty. */
475 ud_parent = udev_device_get_parent(ud_dev);
476 if (ud_parent == NULL) {
477 DEBUG("No parent device, assuming virtual tty");
478 udev_device_unref(ud_dev);
481 name = udev_device_get_devnode(ud_dev);
482 /* The serial8250 driver has a hardcoded number of ports.
483 * The only way to tell which actually exist on a given system
484 * is to try to open them and make an ioctl call. */
485 driver = udev_device_get_driver(ud_parent);
486 if (driver && !strcmp(driver, "serial8250")) {
487 DEBUG("serial8250 device, attempting to open");
488 if ((fd = open(name, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
489 DEBUG("open failed, skipping");
492 ioctl_result = ioctl(fd, TIOCGSERIAL, &serial_info);
494 if (ioctl_result != 0) {
495 DEBUG("ioctl failed, skipping");
498 if (serial_info.type == PORT_UNKNOWN) {
499 DEBUG("port type is unknown, skipping");
503 DEBUG("Found port %s", name);
504 list = list_append(list, name);
506 udev_device_unref(ud_dev);
508 SET_ERROR(ret, SP_ERR_MEM, "list append failed");
513 udev_enumerate_unref(ud_enumerate);
522 DEBUG_ERROR(SP_ERR_SUPP, "Enumeration not supported on this platform.");
525 sp_free_port_list(list);
531 void sp_free_port_list(struct sp_port **list)
542 DEBUG("Freeing port list");
544 for (i = 0; list[i]; i++)
545 sp_free_port(list[i]);
551 #define CHECK_PORT() do { \
553 RETURN_ERROR(SP_ERR_ARG, "Null port"); \
554 if (port->name == NULL) \
555 RETURN_ERROR(SP_ERR_ARG, "Null port name"); \
558 #define CHECK_PORT_HANDLE() do { \
559 if (port->hdl == INVALID_HANDLE_VALUE) \
560 RETURN_ERROR(SP_ERR_ARG, "Invalid port handle"); \
563 #define CHECK_PORT_HANDLE() do { \
565 RETURN_ERROR(SP_ERR_ARG, "Invalid port fd"); \
568 #define CHECK_OPEN_PORT() do { \
570 CHECK_PORT_HANDLE(); \
573 enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
575 struct port_data data;
576 struct sp_port_config config;
579 TRACE("%p, 0x%x", port, flags);
583 if (flags > (SP_MODE_READ | SP_MODE_WRITE | SP_MODE_NONBLOCK))
584 RETURN_ERROR(SP_ERR_ARG, "Invalid flags");
586 DEBUG("Opening port %s", port->name);
588 port->nonblocking = (flags & SP_MODE_NONBLOCK) ? 1 : 0;
591 DWORD desired_access = 0, flags_and_attributes = 0;
592 COMMTIMEOUTS timeouts;
593 char *escaped_port_name;
595 /* Prefix port name with '\\.\' to work with ports above COM9. */
596 if (!(escaped_port_name = malloc(strlen(port->name + 5))))
597 RETURN_ERROR(SP_ERR_MEM, "Escaped port name malloc failed");
598 sprintf(escaped_port_name, "\\\\.\\%s", port->name);
600 /* Map 'flags' to the OS-specific settings. */
601 flags_and_attributes = FILE_ATTRIBUTE_NORMAL;
602 if (flags & SP_MODE_READ)
603 desired_access |= GENERIC_READ;
604 if (flags & SP_MODE_WRITE)
605 desired_access |= GENERIC_WRITE;
606 if (flags & SP_MODE_NONBLOCK)
607 flags_and_attributes |= FILE_FLAG_OVERLAPPED;
609 port->hdl = CreateFile(escaped_port_name, desired_access, 0, 0,
610 OPEN_EXISTING, flags_and_attributes, 0);
612 free(escaped_port_name);
614 if (port->hdl == INVALID_HANDLE_VALUE)
615 RETURN_FAIL("CreateFile() failed");
617 /* All timeouts disabled. */
618 timeouts.ReadIntervalTimeout = 0;
619 timeouts.ReadTotalTimeoutMultiplier = 0;
620 timeouts.ReadTotalTimeoutConstant = 0;
621 timeouts.WriteTotalTimeoutMultiplier = 0;
622 timeouts.WriteTotalTimeoutConstant = 0;
624 if (port->nonblocking) {
625 /* Set read timeout such that all reads return immediately. */
626 timeouts.ReadIntervalTimeout = MAXDWORD;
627 /* Prepare OVERLAPPED structure for non-blocking writes. */
628 memset(&port->write_ovl, 0, sizeof(port->write_ovl));
629 if (!(port->write_ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) {
631 RETURN_FAIL("CreateEvent() failed");
633 port->writing = FALSE;
636 if (SetCommTimeouts(port->hdl, &timeouts) == 0) {
638 RETURN_FAIL("SetCommTimeouts() failed");
643 /* Map 'flags' to the OS-specific settings. */
644 if (flags & (SP_MODE_READ | SP_MODE_WRITE))
645 flags_local |= O_RDWR;
646 else if (flags & SP_MODE_READ)
647 flags_local |= O_RDONLY;
648 else if (flags & SP_MODE_WRITE)
649 flags_local |= O_WRONLY;
650 if (flags & SP_MODE_NONBLOCK)
651 flags_local |= O_NONBLOCK;
653 if ((port->fd = open(port->name, flags_local)) < 0)
654 RETURN_FAIL("open() failed");
657 ret = get_config(port, &data, &config);
664 /* Set sane port settings. */
666 data.dcb.fBinary = TRUE;
667 data.dcb.fDsrSensitivity = FALSE;
668 data.dcb.fErrorChar = FALSE;
669 data.dcb.fNull = FALSE;
670 data.dcb.fAbortOnError = TRUE;
672 /* Turn off all fancy termios tricks, give us a raw channel. */
673 data.term.c_iflag &= ~(IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR | IGNCR | ICRNL | IMAXBEL);
675 data.term.c_iflag &= ~IUCLC;
677 data.term.c_oflag &= ~(OPOST | ONLCR | OCRNL | ONOCR | ONLRET);
679 data.term.c_oflag &= ~OLCUC;
682 data.term.c_oflag &= ~NLDLY;
685 data.term.c_oflag &= ~CRDLY;
688 data.term.c_oflag &= ~TABDLY;
691 data.term.c_oflag &= ~BSDLY;
694 data.term.c_oflag &= ~VTDLY;
697 data.term.c_oflag &= ~FFDLY;
700 data.term.c_oflag &= ~OFILL;
702 data.term.c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN);
703 data.term.c_cc[VMIN] = 0;
704 data.term.c_cc[VTIME] = 0;
706 /* Ignore modem status lines; enable receiver; leave control lines alone on close. */
707 data.term.c_cflag |= (CLOCAL | CREAD | HUPCL);
710 ret = set_config(port, &data, &config);
720 enum sp_return sp_close(struct sp_port *port)
726 DEBUG("Closing port %s", port->name);
729 /* Returns non-zero upon success, 0 upon failure. */
730 if (CloseHandle(port->hdl) == 0)
731 RETURN_FAIL("CloseHandle() failed");
732 port->hdl = INVALID_HANDLE_VALUE;
733 if (port->nonblocking) {
734 /* Close event handle created for overlapped writes. */
735 if (CloseHandle(port->write_ovl.hEvent) == 0)
736 RETURN_FAIL("CloseHandle() failed");
739 /* Returns 0 upon success, -1 upon failure. */
740 if (close(port->fd) == -1)
741 RETURN_FAIL("close() failed");
748 enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers)
750 TRACE("%p, 0x%x", port, buffers);
754 if (buffers > SP_BUF_BOTH)
755 RETURN_ERROR(SP_ERR_ARG, "Invalid buffer selection");
757 const char *buffer_names[] = {"no", "input", "output", "both"};
759 DEBUG("Flushing %s buffers on port %s", buffer_names[buffers], port->name);
763 if (buffers & SP_BUF_INPUT)
764 flags |= PURGE_RXCLEAR;
765 if (buffers & SP_BUF_OUTPUT)
766 flags |= PURGE_TXCLEAR;
768 /* Returns non-zero upon success, 0 upon failure. */
769 if (PurgeComm(port->hdl, flags) == 0)
770 RETURN_FAIL("PurgeComm() failed");
773 if (buffers & SP_BUF_BOTH)
775 else if (buffers & SP_BUF_INPUT)
777 else if (buffers & SP_BUF_OUTPUT)
780 /* Returns 0 upon success, -1 upon failure. */
781 if (tcflush(port->fd, flags) < 0)
782 RETURN_FAIL("tcflush() failed");
787 enum sp_return sp_drain(struct sp_port *port)
793 DEBUG("Draining port %s", port->name);
796 /* Returns non-zero upon success, 0 upon failure. */
797 if (FlushFileBuffers(port->hdl) == 0)
798 RETURN_FAIL("FlushFileBuffers() failed");
800 /* Returns 0 upon success, -1 upon failure. */
801 if (tcdrain(port->fd) < 0)
802 RETURN_FAIL("tcdrain() failed");
808 enum sp_return sp_write(struct sp_port *port, const void *buf, size_t count)
810 TRACE("%p, %p, %d", port, buf, count);
815 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
817 DEBUG("Writing up to %d bytes to port %s", count, port->name);
820 RETURN_VALUE("0", 0);
824 BYTE *ptr = (BYTE *) buf;
826 if (port->nonblocking) {
827 /* Non-blocking write. */
829 /* Check whether previous write is complete. */
831 if (HasOverlappedIoCompleted(&port->write_ovl)) {
832 DEBUG("Previous write completed");
835 DEBUG("Previous write not complete");
836 /* Can't take a new write until the previous one finishes. */
837 RETURN_VALUE("0", 0);
841 /* Keep writing data until the OS has to actually start an async IO for it.
842 * At that point we know the buffer is full. */
843 while (written < count)
845 /* Copy first byte of user buffer. */
846 port->pending_byte = *ptr++;
848 /* Start asynchronous write. */
849 if (WriteFile(port->hdl, &port->pending_byte, 1, NULL, &port->write_ovl) == 0) {
850 if (GetLastError() == ERROR_IO_PENDING) {
851 DEBUG("Asynchronous write started");
853 RETURN_VALUE("%d", ++written);
855 /* Actual failure of some kind. */
856 RETURN_FAIL("WriteFile() failed");
859 DEBUG("Single byte written immediately.");
864 DEBUG("All bytes written immediately.");
867 /* Blocking write. */
868 if (WriteFile(port->hdl, buf, count, &written, NULL) == 0) {
869 RETURN_FAIL("WriteFile() failed");
873 RETURN_VALUE("%d", written);
875 /* Returns the number of bytes written, or -1 upon failure. */
876 ssize_t written = write(port->fd, buf, count);
879 RETURN_FAIL("write() failed");
881 RETURN_VALUE("%d", written);
885 enum sp_return sp_read(struct sp_port *port, void *buf, size_t count)
887 TRACE("%p, %p, %d", port, buf, count);
892 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
894 DEBUG("Reading up to %d bytes from port %s", count, port->name);
897 DWORD bytes_read = 0;
899 /* Returns non-zero upon success, 0 upon failure. */
900 if (ReadFile(port->hdl, buf, count, &bytes_read, NULL) == 0)
901 RETURN_FAIL("ReadFile() failed");
902 RETURN_VALUE("%d", bytes_read);
906 /* Returns the number of bytes read, or -1 upon failure. */
907 if ((bytes_read = read(port->fd, buf, count)) < 0) {
908 if (port->nonblocking && errno == EAGAIN)
909 /* Port is opened in nonblocking mode and there are no bytes available. */
912 /* This is an actual failure. */
913 RETURN_FAIL("read() failed");
915 RETURN_VALUE("%d", bytes_read);
920 static enum sp_return get_baudrate(int fd, int *baudrate)
924 TRACE("%d, %p", fd, baudrate);
926 DEBUG("Getting baud rate");
928 if (!(data = malloc(get_termios_size())))
929 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
931 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
933 RETURN_FAIL("getting termios failed");
936 *baudrate = get_termios_speed(data);
943 static enum sp_return set_baudrate(int fd, int baudrate)
947 TRACE("%d, %d", fd, baudrate);
949 DEBUG("Getting baud rate");
951 if (!(data = malloc(get_termios_size())))
952 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
954 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
956 RETURN_FAIL("getting termios failed");
959 DEBUG("Setting baud rate");
961 set_termios_speed(data, baudrate);
963 if (ioctl(fd, get_termios_set_ioctl(), data) < 0) {
965 RETURN_FAIL("setting termios failed");
974 static enum sp_return get_flow(int fd, int *flow)
978 TRACE("%d, %p", fd, flow);
980 DEBUG("Getting advanced flow control");
982 if (!(data = malloc(get_termiox_size())))
983 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
985 if (ioctl(fd, TCGETX, data) < 0) {
987 RETURN_FAIL("getting termiox failed");
990 *flow = get_termiox_flow(data);
997 static enum sp_return set_flow(int fd, int flow)
1001 TRACE("%d, %d", fd, flow);
1003 DEBUG("Getting advanced flow control");
1005 if (!(data = malloc(get_termiox_size())))
1006 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
1008 if (ioctl(fd, TCGETX, data) < 0) {
1010 RETURN_FAIL("getting termiox failed");
1013 DEBUG("Setting advanced flow control");
1015 set_termiox_flow(data, flow);
1017 if (ioctl(fd, TCSETX, data) < 0) {
1019 RETURN_FAIL("setting termiox failed");
1026 #endif /* USE_TERMIOX */
1027 #endif /* __linux__ */
1029 static enum sp_return get_config(struct sp_port *port, struct port_data *data,
1030 struct sp_port_config *config)
1034 TRACE("%p, %p, %p", port, data, config);
1036 DEBUG("Getting configuration for port %s", port->name);
1039 if (!GetCommState(port->hdl, &data->dcb))
1040 RETURN_FAIL("GetCommState() failed");
1042 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1043 if (data->dcb.BaudRate == std_baudrates[i].index) {
1044 config->baudrate = std_baudrates[i].value;
1049 if (i == NUM_STD_BAUDRATES)
1050 /* BaudRate field can be either an index or a custom baud rate. */
1051 config->baudrate = data->dcb.BaudRate;
1053 config->bits = data->dcb.ByteSize;
1055 if (data->dcb.fParity)
1056 switch (data->dcb.Parity) {
1058 config->parity = SP_PARITY_NONE;
1061 config->parity = SP_PARITY_ODD;
1064 config->parity = SP_PARITY_EVEN;
1067 config->parity = SP_PARITY_MARK;
1070 config->parity = SP_PARITY_SPACE;
1073 config->parity = -1;
1076 config->parity = SP_PARITY_NONE;
1078 switch (data->dcb.StopBits) {
1080 config->stopbits = 1;
1083 config->stopbits = 2;
1086 config->stopbits = -1;
1089 switch (data->dcb.fRtsControl) {
1090 case RTS_CONTROL_DISABLE:
1091 config->rts = SP_RTS_OFF;
1093 case RTS_CONTROL_ENABLE:
1094 config->rts = SP_RTS_ON;
1096 case RTS_CONTROL_HANDSHAKE:
1097 config->rts = SP_RTS_FLOW_CONTROL;
1103 config->cts = data->dcb.fOutxCtsFlow ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1105 switch (data->dcb.fDtrControl) {
1106 case DTR_CONTROL_DISABLE:
1107 config->dtr = SP_DTR_OFF;
1109 case DTR_CONTROL_ENABLE:
1110 config->dtr = SP_DTR_ON;
1112 case DTR_CONTROL_HANDSHAKE:
1113 config->dtr = SP_DTR_FLOW_CONTROL;
1119 config->dsr = data->dcb.fOutxDsrFlow ? SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1121 if (data->dcb.fInX) {
1122 if (data->dcb.fOutX)
1123 config->xon_xoff = SP_XONXOFF_INOUT;
1125 config->xon_xoff = SP_XONXOFF_IN;
1127 if (data->dcb.fOutX)
1128 config->xon_xoff = SP_XONXOFF_OUT;
1130 config->xon_xoff = SP_XONXOFF_DISABLED;
1135 if (tcgetattr(port->fd, &data->term) < 0)
1136 RETURN_FAIL("tcgetattr() failed");
1138 if (ioctl(port->fd, TIOCMGET, &data->controlbits) < 0)
1139 RETURN_FAIL("TIOCMGET ioctl failed");
1142 int ret = get_flow(port->fd, &data->flow);
1144 if (ret == SP_ERR_FAIL && errno == EINVAL)
1145 data->termiox_supported = 0;
1147 RETURN_CODEVAL(ret);
1149 data->termiox_supported = 1;
1151 data->termiox_supported = 0;
1154 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1155 if (cfgetispeed(&data->term) == std_baudrates[i].index) {
1156 config->baudrate = std_baudrates[i].value;
1161 if (i == NUM_STD_BAUDRATES) {
1163 config->baudrate = (int)data->term.c_ispeed;
1164 #elif defined(__linux__)
1165 TRY(get_baudrate(port->fd, &config->baudrate));
1167 config->baudrate = -1;
1171 switch (data->term.c_cflag & CSIZE) {
1188 if (!(data->term.c_cflag & PARENB) && (data->term.c_iflag & IGNPAR))
1189 config->parity = SP_PARITY_NONE;
1190 else if (!(data->term.c_cflag & PARENB) || (data->term.c_iflag & IGNPAR))
1191 config->parity = -1;
1193 else if (data->term.c_cflag & CMSPAR)
1194 config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_MARK : SP_PARITY_SPACE;
1197 config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_ODD : SP_PARITY_EVEN;
1199 config->stopbits = (data->term.c_cflag & CSTOPB) ? 2 : 1;
1201 if (data->term.c_cflag & CRTSCTS) {
1202 config->rts = SP_RTS_FLOW_CONTROL;
1203 config->cts = SP_CTS_FLOW_CONTROL;
1205 if (data->termiox_supported && data->flow & RTS_FLOW)
1206 config->rts = SP_RTS_FLOW_CONTROL;
1208 config->rts = (data->controlbits & TIOCM_RTS) ? SP_RTS_ON : SP_RTS_OFF;
1210 config->cts = (data->termiox_supported && data->flow & CTS_FLOW) ?
1211 SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1214 if (data->termiox_supported && data->flow & DTR_FLOW)
1215 config->dtr = SP_DTR_FLOW_CONTROL;
1217 config->dtr = (data->controlbits & TIOCM_DTR) ? SP_DTR_ON : SP_DTR_OFF;
1219 config->dsr = (data->termiox_supported && data->flow & DSR_FLOW) ?
1220 SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1222 if (data->term.c_iflag & IXOFF) {
1223 if (data->term.c_iflag & IXON)
1224 config->xon_xoff = SP_XONXOFF_INOUT;
1226 config->xon_xoff = SP_XONXOFF_IN;
1228 if (data->term.c_iflag & IXON)
1229 config->xon_xoff = SP_XONXOFF_OUT;
1231 config->xon_xoff = SP_XONXOFF_DISABLED;
1238 static enum sp_return set_config(struct sp_port *port, struct port_data *data,
1239 const struct sp_port_config *config)
1243 BAUD_TYPE baud_nonstd;
1248 int baud_nonstd = 0;
1251 TRACE("%p, %p, %p", port, data, config);
1253 DEBUG("Setting configuration for port %s", port->name);
1256 if (config->baudrate >= 0) {
1257 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1258 if (config->baudrate == std_baudrates[i].value) {
1259 data->dcb.BaudRate = std_baudrates[i].index;
1264 if (i == NUM_STD_BAUDRATES)
1265 data->dcb.BaudRate = config->baudrate;
1268 if (config->bits >= 0)
1269 data->dcb.ByteSize = config->bits;
1271 if (config->parity >= 0) {
1272 switch (config->parity) {
1273 /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
1274 case SP_PARITY_NONE:
1275 data->dcb.Parity = NOPARITY;
1278 data->dcb.Parity = ODDPARITY;
1280 case SP_PARITY_EVEN:
1281 data->dcb.Parity = EVENPARITY;
1283 case SP_PARITY_MARK:
1284 data->dcb.Parity = MARKPARITY;
1286 case SP_PARITY_SPACE:
1287 data->dcb.Parity = SPACEPARITY;
1290 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1294 if (config->stopbits >= 0) {
1295 switch (config->stopbits) {
1296 /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
1298 data->dcb.StopBits = ONESTOPBIT;
1301 data->dcb.StopBits = TWOSTOPBITS;
1304 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bit setting");
1308 if (config->rts >= 0) {
1309 switch (config->rts) {
1311 data->dcb.fRtsControl = RTS_CONTROL_DISABLE;
1314 data->dcb.fRtsControl = RTS_CONTROL_ENABLE;
1316 case SP_RTS_FLOW_CONTROL:
1317 data->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
1320 RETURN_ERROR(SP_ERR_ARG, "Invalid RTS setting");
1324 if (config->cts >= 0) {
1325 switch (config->cts) {
1327 data->dcb.fOutxCtsFlow = FALSE;
1329 case SP_CTS_FLOW_CONTROL:
1330 data->dcb.fOutxCtsFlow = TRUE;
1333 RETURN_ERROR(SP_ERR_ARG, "Invalid CTS setting");
1337 if (config->dtr >= 0) {
1338 switch (config->dtr) {
1340 data->dcb.fDtrControl = DTR_CONTROL_DISABLE;
1343 data->dcb.fDtrControl = DTR_CONTROL_ENABLE;
1345 case SP_DTR_FLOW_CONTROL:
1346 data->dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
1349 RETURN_ERROR(SP_ERR_ARG, "Invalid DTR setting");
1353 if (config->dsr >= 0) {
1354 switch (config->dsr) {
1356 data->dcb.fOutxDsrFlow = FALSE;
1358 case SP_DSR_FLOW_CONTROL:
1359 data->dcb.fOutxDsrFlow = TRUE;
1362 RETURN_ERROR(SP_ERR_ARG, "Invalid DSR setting");
1366 if (config->xon_xoff >= 0) {
1367 switch (config->xon_xoff) {
1368 case SP_XONXOFF_DISABLED:
1369 data->dcb.fInX = FALSE;
1370 data->dcb.fOutX = FALSE;
1373 data->dcb.fInX = TRUE;
1374 data->dcb.fOutX = FALSE;
1376 case SP_XONXOFF_OUT:
1377 data->dcb.fInX = FALSE;
1378 data->dcb.fOutX = TRUE;
1380 case SP_XONXOFF_INOUT:
1381 data->dcb.fInX = TRUE;
1382 data->dcb.fOutX = TRUE;
1385 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1389 if (!SetCommState(port->hdl, &data->dcb))
1390 RETURN_FAIL("SetCommState() failed");
1396 if (config->baudrate >= 0) {
1397 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1398 if (config->baudrate == std_baudrates[i].value) {
1399 if (cfsetospeed(&data->term, std_baudrates[i].index) < 0)
1400 RETURN_FAIL("cfsetospeed() failed");
1402 if (cfsetispeed(&data->term, std_baudrates[i].index) < 0)
1403 RETURN_FAIL("cfsetispeed() failed");
1408 /* Non-standard baud rate */
1409 if (i == NUM_STD_BAUDRATES) {
1411 /* Set "dummy" baud rate. */
1412 if (cfsetspeed(&data->term, B9600) < 0)
1413 RETURN_FAIL("cfsetspeed() failed");
1414 baud_nonstd = config->baudrate;
1415 #elif defined(__linux__)
1418 RETURN_ERROR(SP_ERR_SUPP, "Non-standard baudrate not supported");
1423 if (config->bits >= 0) {
1424 data->term.c_cflag &= ~CSIZE;
1425 switch (config->bits) {
1427 data->term.c_cflag |= CS8;
1430 data->term.c_cflag |= CS7;
1433 data->term.c_cflag |= CS6;
1436 data->term.c_cflag |= CS5;
1439 RETURN_ERROR(SP_ERR_ARG, "Invalid data bits setting");
1443 if (config->parity >= 0) {
1444 data->term.c_iflag &= ~IGNPAR;
1445 data->term.c_cflag &= ~(PARENB | PARODD);
1447 data->term.c_cflag &= ~CMSPAR;
1449 switch (config->parity) {
1450 case SP_PARITY_NONE:
1451 data->term.c_iflag |= IGNPAR;
1453 case SP_PARITY_EVEN:
1454 data->term.c_cflag |= PARENB;
1457 data->term.c_cflag |= PARENB | PARODD;
1459 case SP_PARITY_MARK:
1460 data->term.c_cflag |= PARENB | PARODD;
1462 data->term.c_cflag |= CMSPAR;
1465 case SP_PARITY_SPACE:
1466 data->term.c_cflag |= PARENB;
1468 data->term.c_cflag |= CMSPAR;
1472 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1476 if (config->stopbits >= 0) {
1477 data->term.c_cflag &= ~CSTOPB;
1478 switch (config->stopbits) {
1480 data->term.c_cflag &= ~CSTOPB;
1483 data->term.c_cflag |= CSTOPB;
1486 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bits setting");
1490 if (config->rts >= 0 || config->cts >= 0) {
1491 if (data->termiox_supported) {
1492 data->flow &= ~(RTS_FLOW | CTS_FLOW);
1493 switch (config->rts) {
1496 controlbits = TIOCM_RTS;
1497 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1498 RETURN_FAIL("Setting RTS signal level failed");
1500 case SP_RTS_FLOW_CONTROL:
1501 data->flow |= RTS_FLOW;
1506 if (config->cts == SP_CTS_FLOW_CONTROL)
1507 data->flow |= CTS_FLOW;
1509 if (data->flow & (RTS_FLOW | CTS_FLOW))
1510 data->term.c_iflag |= CRTSCTS;
1512 data->term.c_iflag &= ~CRTSCTS;
1514 /* Asymmetric use of RTS/CTS not supported. */
1515 if (data->term.c_iflag & CRTSCTS) {
1516 /* Flow control can only be disabled for both RTS & CTS together. */
1517 if (config->rts >= 0 && config->rts != SP_RTS_FLOW_CONTROL) {
1518 if (config->cts != SP_CTS_IGNORE)
1519 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1521 if (config->cts >= 0 && config->cts != SP_CTS_FLOW_CONTROL) {
1522 if (config->rts <= 0 || config->rts == SP_RTS_FLOW_CONTROL)
1523 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1526 /* Flow control can only be enabled for both RTS & CTS together. */
1527 if (((config->rts == SP_RTS_FLOW_CONTROL) && (config->cts != SP_CTS_FLOW_CONTROL)) ||
1528 ((config->cts == SP_CTS_FLOW_CONTROL) && (config->rts != SP_RTS_FLOW_CONTROL)))
1529 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be enabled together");
1532 if (config->rts >= 0) {
1533 if (config->rts == SP_RTS_FLOW_CONTROL) {
1534 data->term.c_iflag |= CRTSCTS;
1536 controlbits = TIOCM_RTS;
1537 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC,
1539 RETURN_FAIL("Setting RTS signal level failed");
1545 if (config->dtr >= 0 || config->dsr >= 0) {
1546 if (data->termiox_supported) {
1547 data->flow &= ~(DTR_FLOW | DSR_FLOW);
1548 switch (config->dtr) {
1551 controlbits = TIOCM_DTR;
1552 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1553 RETURN_FAIL("Setting DTR signal level failed");
1555 case SP_DTR_FLOW_CONTROL:
1556 data->flow |= DTR_FLOW;
1561 if (config->dsr == SP_DSR_FLOW_CONTROL)
1562 data->flow |= DSR_FLOW;
1564 /* DTR/DSR flow control not supported. */
1565 if (config->dtr == SP_DTR_FLOW_CONTROL || config->dsr == SP_DSR_FLOW_CONTROL)
1566 RETURN_ERROR(SP_ERR_SUPP, "DTR/DSR flow control not supported");
1568 if (config->dtr >= 0) {
1569 controlbits = TIOCM_DTR;
1570 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC,
1572 RETURN_FAIL("Setting DTR signal level failed");
1577 if (config->xon_xoff >= 0) {
1578 data->term.c_iflag &= ~(IXON | IXOFF | IXANY);
1579 switch (config->xon_xoff) {
1580 case SP_XONXOFF_DISABLED:
1583 data->term.c_iflag |= IXOFF;
1585 case SP_XONXOFF_OUT:
1586 data->term.c_iflag |= IXON | IXANY;
1588 case SP_XONXOFF_INOUT:
1589 data->term.c_iflag |= IXON | IXOFF | IXANY;
1592 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1596 if (tcsetattr(port->fd, TCSANOW, &data->term) < 0)
1597 RETURN_FAIL("tcsetattr() failed");
1600 if (baud_nonstd != B0) {
1601 if (ioctl(port->fd, IOSSIOSPEED, &baud_nonstd) == -1)
1602 RETURN_FAIL("IOSSIOSPEED ioctl failed");
1603 /* Set baud rates in data->term to correct, but incompatible
1604 * with tcsetattr() value, same as delivered by tcgetattr(). */
1605 if (cfsetspeed(&data->term, baud_nonstd) < 0)
1606 RETURN_FAIL("cfsetspeed() failed");
1608 #elif defined(__linux__)
1610 TRY(set_baudrate(port->fd, config->baudrate));
1612 if (data->termiox_supported)
1613 TRY(set_flow(port->fd, data->flow));
1617 #endif /* !_WIN32 */
1622 enum sp_return sp_new_config(struct sp_port_config **config_ptr)
1624 struct sp_port_config *config;
1626 TRACE("%p", config_ptr);
1629 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
1633 if (!(config = malloc(sizeof(struct sp_port_config))))
1634 RETURN_ERROR(SP_ERR_MEM, "config malloc failed");
1636 config->baudrate = -1;
1638 config->parity = -1;
1639 config->stopbits = -1;
1645 *config_ptr = config;
1650 void sp_free_config(struct sp_port_config *config)
1652 TRACE("%p", config);
1655 DEBUG("Null config");
1662 enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config)
1664 struct port_data data;
1666 TRACE("%p, %p", port, config);
1671 RETURN_ERROR(SP_ERR_ARG, "Null config");
1673 TRY(get_config(port, &data, config));
1678 enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config)
1680 struct port_data data;
1681 struct sp_port_config prev_config;
1683 TRACE("%p, %p", port, config);
1688 RETURN_ERROR(SP_ERR_ARG, "Null config");
1690 TRY(get_config(port, &data, &prev_config));
1691 TRY(set_config(port, &data, config));
1696 #define CREATE_ACCESSORS(x, type) \
1697 enum sp_return sp_set_##x(struct sp_port *port, type x) { \
1698 struct port_data data; \
1699 struct sp_port_config config; \
1700 TRACE("%p, %d", port, x); \
1701 CHECK_OPEN_PORT(); \
1702 TRY(get_config(port, &data, &config)); \
1704 TRY(set_config(port, &data, &config)); \
1707 enum sp_return sp_get_config_##x(const struct sp_port_config *config, type *x) { \
1708 TRACE("%p, %p", config, x); \
1710 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
1714 enum sp_return sp_set_config_##x(struct sp_port_config *config, type x) { \
1715 TRACE("%p, %d", config, x); \
1717 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
1722 CREATE_ACCESSORS(baudrate, int)
1723 CREATE_ACCESSORS(bits, int)
1724 CREATE_ACCESSORS(parity, enum sp_parity)
1725 CREATE_ACCESSORS(stopbits, int)
1726 CREATE_ACCESSORS(rts, enum sp_rts)
1727 CREATE_ACCESSORS(cts, enum sp_cts)
1728 CREATE_ACCESSORS(dtr, enum sp_dtr)
1729 CREATE_ACCESSORS(dsr, enum sp_dsr)
1730 CREATE_ACCESSORS(xon_xoff, enum sp_xonxoff)
1732 enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol)
1735 RETURN_ERROR(SP_ERR_ARG, "Null configuration");
1737 if (flowcontrol > SP_FLOWCONTROL_DTRDSR)
1738 RETURN_ERROR(SP_ERR_ARG, "Invalid flow control setting");
1740 if (flowcontrol == SP_FLOWCONTROL_XONXOFF)
1741 config->xon_xoff = SP_XONXOFF_INOUT;
1743 config->xon_xoff = SP_XONXOFF_DISABLED;
1745 if (flowcontrol == SP_FLOWCONTROL_RTSCTS) {
1746 config->rts = SP_RTS_FLOW_CONTROL;
1747 config->cts = SP_CTS_FLOW_CONTROL;
1749 if (config->rts == SP_RTS_FLOW_CONTROL)
1750 config->rts = SP_RTS_ON;
1751 config->cts = SP_CTS_IGNORE;
1754 if (flowcontrol == SP_FLOWCONTROL_DTRDSR) {
1755 config->dtr = SP_DTR_FLOW_CONTROL;
1756 config->dsr = SP_DSR_FLOW_CONTROL;
1758 if (config->dtr == SP_DTR_FLOW_CONTROL)
1759 config->dtr = SP_DTR_ON;
1760 config->dsr = SP_DSR_IGNORE;
1766 enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol)
1768 struct port_data data;
1769 struct sp_port_config config;
1771 TRACE("%p, %d", port, flowcontrol);
1775 TRY(get_config(port, &data, &config));
1777 TRY(sp_set_config_flowcontrol(&config, flowcontrol));
1779 TRY(set_config(port, &data, &config));
1784 enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signals)
1786 TRACE("%p, %p", port, signals);
1791 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
1793 DEBUG("Getting control signals for port %s", port->name);
1798 if (GetCommModemStatus(port->hdl, &bits) == 0)
1799 RETURN_FAIL("GetCommModemStatus() failed");
1800 if (bits & MS_CTS_ON)
1801 *signals |= SP_SIG_CTS;
1802 if (bits & MS_DSR_ON)
1803 *signals |= SP_SIG_DSR;
1804 if (bits & MS_RLSD_ON)
1805 *signals |= SP_SIG_DCD;
1806 if (bits & MS_RING_ON)
1807 *signals |= SP_SIG_RI;
1810 if (ioctl(port->fd, TIOCMGET, &bits) < 0)
1811 RETURN_FAIL("TIOCMGET ioctl failed");
1812 if (bits & TIOCM_CTS)
1813 *signals |= SP_SIG_CTS;
1814 if (bits & TIOCM_DSR)
1815 *signals |= SP_SIG_DSR;
1816 if (bits & TIOCM_CAR)
1817 *signals |= SP_SIG_DCD;
1818 if (bits & TIOCM_RNG)
1819 *signals |= SP_SIG_RI;
1824 enum sp_return sp_start_break(struct sp_port *port)
1830 if (SetCommBreak(port->hdl) == 0)
1831 RETURN_FAIL("SetCommBreak() failed");
1833 if (ioctl(port->fd, TIOCSBRK, 1) < 0)
1834 RETURN_FAIL("TIOCSBRK ioctl failed");
1840 enum sp_return sp_end_break(struct sp_port *port)
1846 if (ClearCommBreak(port->hdl) == 0)
1847 RETURN_FAIL("ClearCommBreak() failed");
1849 if (ioctl(port->fd, TIOCCBRK, 1) < 0)
1850 RETURN_FAIL("TIOCCBRK ioctl failed");
1856 int sp_last_error_code(void)
1860 RETURN_VALUE("%d", GetLastError());
1862 RETURN_VALUE("%d", errno);
1866 char *sp_last_error_message(void)
1872 DWORD error = GetLastError();
1875 FORMAT_MESSAGE_ALLOCATE_BUFFER |
1876 FORMAT_MESSAGE_FROM_SYSTEM |
1877 FORMAT_MESSAGE_IGNORE_INSERTS,
1880 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1884 RETURN_VALUE("%s", message);
1886 RETURN_VALUE("%s", strerror(errno));
1890 void sp_free_error_message(char *message)
1892 TRACE("%s", message);
1903 void sp_set_debug_handler(void (*handler)(const char *format, ...))
1905 TRACE("%p", handler);
1907 sp_debug_handler = handler;
1912 void sp_default_debug_handler(const char *format, ...)
1915 va_start(args, format);
1916 if (getenv("LIBSERIALPORT_DEBUG")) {
1917 fputs("sp: ", stderr);
1918 vfprintf(stderr, format, args);