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)
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)
270 DEBUG("Freeing port structure");
280 static struct sp_port **list_append(struct sp_port **list, const char *portname)
285 for (count = 0; list[count]; count++);
286 if (!(tmp = realloc(list, sizeof(struct sp_port *) * (count + 2))))
289 if (sp_get_port_by_name(portname, &list[count]) != SP_OK)
291 list[count + 1] = NULL;
295 sp_free_port_list(list);
299 enum sp_return sp_list_ports(struct sp_port ***list_ptr)
301 struct sp_port **list;
302 int ret = SP_ERR_SUPP;
304 TRACE("%p", list_ptr);
307 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
309 DEBUG("Enumerating ports");
311 if (!(list = malloc(sizeof(struct sp_port **))))
312 RETURN_ERROR(SP_ERR_MEM, "Port list malloc failed");
319 DWORD max_value_len, max_data_size, max_data_len;
320 DWORD value_len, data_size, data_len;
321 DWORD type, index = 0;
327 DEBUG("Opening registry key");
328 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
329 0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS) {
330 SET_FAIL(ret, "RegOpenKeyEx() failed");
333 DEBUG("Querying registry key value and data sizes");
334 if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
335 &max_value_len, &max_data_size, NULL, NULL) != ERROR_SUCCESS) {
336 SET_FAIL(ret, "RegQueryInfoKey() failed");
339 max_data_len = max_data_size / sizeof(TCHAR);
340 if (!(value = malloc((max_value_len + 1) * sizeof(TCHAR)))) {
341 SET_ERROR(ret, SP_ERR_MEM, "registry value malloc failed");
344 if (!(data = malloc((max_data_len + 1) * sizeof(TCHAR)))) {
345 SET_ERROR(ret, SP_ERR_MEM, "registry data malloc failed");
348 DEBUG("Iterating over values");
350 value_len = max_value_len + 1,
351 data_size = max_data_size,
352 RegEnumValue(key, index, value, &value_len,
353 NULL, &type, (LPBYTE)data, &data_size) == ERROR_SUCCESS)
355 data_len = data_size / sizeof(TCHAR);
356 data[data_len] = '\0';
358 name_len = WideCharToMultiByte(CP_ACP, 0, data, -1, NULL, 0, NULL, NULL)
360 name_len = data_len + 1;
362 if (!(name = malloc(name_len))) {
363 SET_ERROR(ret, SP_ERR_MEM, "registry port name malloc failed");
367 WideCharToMultiByte(CP_ACP, 0, data, -1, name, name_len, NULL, NULL);
371 if (type == REG_SZ) {
372 DEBUG("Found port %s", name);
373 if (!(list = list_append(list, name))) {
374 SET_ERROR(ret, SP_ERR_MEM, "list append failed");
390 CFMutableDictionaryRef classes;
399 DEBUG("Getting IOKit master port");
400 if (IOMasterPort(MACH_PORT_NULL, &master) != KERN_SUCCESS) {
401 SET_FAIL(ret, "IOMasterPort() failed");
405 DEBUG("Creating matching dictionary");
406 if (!(classes = IOServiceMatching(kIOSerialBSDServiceValue))) {
407 SET_FAIL(ret, "IOServiceMatching() failed");
411 CFDictionarySetValue(classes,
412 CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes));
414 DEBUG("Getting matching services");
415 if (IOServiceGetMatchingServices(master, classes, &iter) != KERN_SUCCESS) {
416 SET_FAIL(ret, "IOServiceGetMatchingServices() failed");
420 if (!(path = malloc(PATH_MAX))) {
421 SET_ERROR(ret, SP_ERR_MEM, "device path malloc failed");
425 DEBUG("Iterating over results");
426 while ((port = IOIteratorNext(iter))) {
427 cf_path = IORegistryEntryCreateCFProperty(port,
428 CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
430 result = CFStringGetCString(cf_path,
431 path, PATH_MAX, kCFStringEncodingASCII);
434 DEBUG("Found port %s", path);
435 if (!(list = list_append(list, path))) {
436 SET_ERROR(ret, SP_ERR_MEM, "list append failed");
437 IOObjectRelease(port);
442 IOObjectRelease(port);
447 IOObjectRelease(iter);
452 struct udev_enumerate *ud_enumerate;
453 struct udev_list_entry *ud_list;
454 struct udev_list_entry *ud_entry;
456 struct udev_device *ud_dev, *ud_parent;
459 int fd, ioctl_result;
460 struct serial_struct serial_info;
464 DEBUG("Enumerating tty devices");
466 ud_enumerate = udev_enumerate_new(ud);
467 udev_enumerate_add_match_subsystem(ud_enumerate, "tty");
468 udev_enumerate_scan_devices(ud_enumerate);
469 ud_list = udev_enumerate_get_list_entry(ud_enumerate);
470 DEBUG("Iterating over results");
471 udev_list_entry_foreach(ud_entry, ud_list) {
472 path = udev_list_entry_get_name(ud_entry);
473 DEBUG("Found device %s", path);
474 ud_dev = udev_device_new_from_syspath(ud, path);
475 /* If there is no parent device, this is a virtual tty. */
476 ud_parent = udev_device_get_parent(ud_dev);
477 if (ud_parent == NULL) {
478 DEBUG("No parent device, assuming virtual tty");
479 udev_device_unref(ud_dev);
482 name = udev_device_get_devnode(ud_dev);
483 /* The serial8250 driver has a hardcoded number of ports.
484 * The only way to tell which actually exist on a given system
485 * is to try to open them and make an ioctl call. */
486 driver = udev_device_get_driver(ud_parent);
487 if (driver && !strcmp(driver, "serial8250")) {
488 DEBUG("serial8250 device, attempting to open");
489 if ((fd = open(name, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0) {
490 DEBUG("open failed, skipping");
493 ioctl_result = ioctl(fd, TIOCGSERIAL, &serial_info);
495 if (ioctl_result != 0) {
496 DEBUG("ioctl failed, skipping");
499 if (serial_info.type == PORT_UNKNOWN) {
500 DEBUG("port type is unknown, skipping");
504 DEBUG("Found port %s", name);
505 list = list_append(list, name);
507 udev_device_unref(ud_dev);
509 SET_ERROR(ret, SP_ERR_MEM, "list append failed");
514 udev_enumerate_unref(ud_enumerate);
523 DEBUG_ERROR(SP_ERR_SUPP, "Enumeration not supported on this platform.");
526 sp_free_port_list(list);
532 void sp_free_port_list(struct sp_port **list)
543 DEBUG("Freeing port list");
545 for (i = 0; list[i]; i++)
546 sp_free_port(list[i]);
552 #define CHECK_PORT() do { \
554 RETURN_ERROR(SP_ERR_ARG, "Null port"); \
555 if (port->name == NULL) \
556 RETURN_ERROR(SP_ERR_ARG, "Null port name"); \
559 #define CHECK_PORT_HANDLE() do { \
560 if (port->hdl == INVALID_HANDLE_VALUE) \
561 RETURN_ERROR(SP_ERR_ARG, "Invalid port handle"); \
564 #define CHECK_PORT_HANDLE() do { \
566 RETURN_ERROR(SP_ERR_ARG, "Invalid port fd"); \
569 #define CHECK_OPEN_PORT() do { \
571 CHECK_PORT_HANDLE(); \
574 enum sp_return sp_open(struct sp_port *port, enum sp_mode flags)
576 TRACE("%p, %x", port, flags);
580 if (flags > (SP_MODE_READ | SP_MODE_WRITE | SP_MODE_NONBLOCK))
581 RETURN_ERROR(SP_ERR_ARG, "Invalid flags");
583 DEBUG("Opening port %s", port->name);
585 port->nonblocking = (flags & SP_MODE_NONBLOCK) ? 1 : 0;
588 DWORD desired_access = 0, flags_and_attributes = 0;
589 COMMTIMEOUTS timeouts;
590 char *escaped_port_name;
592 /* Prefix port name with '\\.\' to work with ports above COM9. */
593 if (!(escaped_port_name = malloc(strlen(port->name + 5))))
594 RETURN_ERROR(SP_ERR_MEM, "Escaped port name malloc failed");
595 sprintf(escaped_port_name, "\\\\.\\%s", port->name);
597 /* Map 'flags' to the OS-specific settings. */
598 flags_and_attributes = FILE_ATTRIBUTE_NORMAL;
599 if (flags & SP_MODE_READ)
600 desired_access |= GENERIC_READ;
601 if (flags & SP_MODE_WRITE)
602 desired_access |= GENERIC_WRITE;
603 if (flags & SP_MODE_NONBLOCK)
604 flags_and_attributes |= FILE_FLAG_OVERLAPPED;
606 port->hdl = CreateFile(escaped_port_name, desired_access, 0, 0,
607 OPEN_EXISTING, flags_and_attributes, 0);
609 free(escaped_port_name);
611 if (port->hdl == INVALID_HANDLE_VALUE)
612 RETURN_FAIL("CreateFile() failed");
614 /* All timeouts disabled. */
615 timeouts.ReadIntervalTimeout = 0;
616 timeouts.ReadTotalTimeoutMultiplier = 0;
617 timeouts.ReadTotalTimeoutConstant = 0;
618 timeouts.WriteTotalTimeoutMultiplier = 0;
619 timeouts.WriteTotalTimeoutConstant = 0;
621 if (port->nonblocking) {
622 /* Set read timeout such that all reads return immediately. */
623 timeouts.ReadIntervalTimeout = MAXDWORD;
624 /* Prepare OVERLAPPED structure for non-blocking writes. */
625 memset(&port->write_ovl, 0, sizeof(port->write_ovl));
626 if (!(port->write_ovl.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL))) {
628 RETURN_FAIL("CreateEvent() failed");
630 port->writing = FALSE;
633 if (SetCommTimeouts(port->hdl, &timeouts) == 0) {
635 RETURN_FAIL("SetCommTimeouts() failed");
639 struct port_data data;
640 struct sp_port_config config;
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");
656 ret = get_config(port, &data, &config);
663 /* Turn off all serial port cooking. */
664 data.term.c_iflag &= ~(ISTRIP | INLCR | ICRNL);
665 data.term.c_oflag &= ~(ONLCR | OCRNL | ONOCR);
666 #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
667 data.term.c_oflag &= ~OFILL;
669 /* Disable canonical mode, and don't echo input characters. */
670 data.term.c_lflag &= ~(ICANON | ECHO);
672 /* Ignore modem status lines; enable receiver */
673 data.term.c_cflag |= (CLOCAL | CREAD);
675 ret = set_config(port, &data, &config);
686 enum sp_return sp_close(struct sp_port *port)
692 DEBUG("Closing port %s", port->name);
695 /* Returns non-zero upon success, 0 upon failure. */
696 if (CloseHandle(port->hdl) == 0)
697 RETURN_FAIL("CloseHandle() failed");
698 port->hdl = INVALID_HANDLE_VALUE;
699 if (port->nonblocking) {
700 /* Close event handle created for overlapped writes. */
701 if (CloseHandle(port->write_ovl.hEvent) == 0)
702 RETURN_FAIL("CloseHandle() failed");
705 /* Returns 0 upon success, -1 upon failure. */
706 if (close(port->fd) == -1)
707 RETURN_FAIL("close() failed");
714 enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers)
716 TRACE("%p, %x", port, buffers);
720 if (buffers > SP_BUF_BOTH)
721 RETURN_ERROR(SP_ERR_ARG, "Invalid buffer selection");
723 const char *buffer_names[] = {"no", "input", "output", "both"};
725 DEBUG("Flushing %s buffers on port %s", buffer_names[buffers], port->name);
729 if (buffers & SP_BUF_INPUT)
730 flags |= PURGE_RXCLEAR;
731 if (buffers & SP_BUF_OUTPUT)
732 flags |= PURGE_TXCLEAR;
734 /* Returns non-zero upon success, 0 upon failure. */
735 if (PurgeComm(port->hdl, flags) == 0)
736 RETURN_FAIL("PurgeComm() failed");
739 if (buffers & SP_BUF_BOTH)
741 else if (buffers & SP_BUF_INPUT)
743 else if (buffers & SP_BUF_OUTPUT)
746 /* Returns 0 upon success, -1 upon failure. */
747 if (tcflush(port->fd, flags) < 0)
748 RETURN_FAIL("tcflush() failed");
753 enum sp_return sp_drain(struct sp_port *port)
759 DEBUG("Draining port %s", port->name);
762 /* Returns non-zero upon success, 0 upon failure. */
763 if (FlushFileBuffers(port->hdl) == 0)
764 RETURN_FAIL("FlushFileBuffers() failed");
766 /* Returns 0 upon success, -1 upon failure. */
767 if (tcdrain(port->fd) < 0)
768 RETURN_FAIL("tcdrain() failed");
774 enum sp_return sp_write(struct sp_port *port, const void *buf, size_t count)
776 TRACE("%p, %p, %d", port, buf, count);
781 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
783 DEBUG("Writing up to %d bytes to port %s", count, port->name);
786 RETURN_VALUE("0", 0);
790 BYTE *ptr = (BYTE *) buf;
792 if (port->nonblocking) {
793 /* Non-blocking write. */
795 /* Check whether previous write is complete. */
797 if (HasOverlappedIoCompleted(&port->write_ovl)) {
798 DEBUG("Previous write completed");
801 DEBUG("Previous write not complete");
802 /* Can't take a new write until the previous one finishes. */
803 RETURN_VALUE("0", 0);
807 /* Keep writing data until the OS has to actually start an async IO for it.
808 * At that point we know the buffer is full. */
809 while (written < count)
811 /* Copy first byte of user buffer. */
812 port->pending_byte = *ptr++;
814 /* Start asynchronous write. */
815 if (WriteFile(port->hdl, &port->pending_byte, 1, NULL, &port->write_ovl) == 0) {
816 if (GetLastError() == ERROR_IO_PENDING) {
817 DEBUG("Asynchronous write started");
819 RETURN_VALUE("%d", ++written);
821 /* Actual failure of some kind. */
822 RETURN_FAIL("WriteFile() failed");
825 DEBUG("Single byte written immediately.");
830 DEBUG("All bytes written immediately.");
833 /* Blocking write. */
834 if (WriteFile(port->hdl, buf, count, &written, NULL) == 0) {
835 RETURN_FAIL("WriteFile() failed");
839 RETURN_VALUE("%d", written);
841 /* Returns the number of bytes written, or -1 upon failure. */
842 ssize_t written = write(port->fd, buf, count);
845 RETURN_FAIL("write() failed");
847 RETURN_VALUE("%d", written);
851 enum sp_return sp_read(struct sp_port *port, void *buf, size_t count)
853 TRACE("%p, %p, %d", port, buf, count);
858 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
860 DEBUG("Reading up to %d bytes from port %s", count, port->name);
863 DWORD bytes_read = 0;
865 /* Returns non-zero upon success, 0 upon failure. */
866 if (ReadFile(port->hdl, buf, count, &bytes_read, NULL) == 0)
867 RETURN_FAIL("ReadFile() failed");
868 RETURN_VALUE("%d", bytes_read);
872 /* Returns the number of bytes read, or -1 upon failure. */
873 if ((bytes_read = read(port->fd, buf, count)) < 0) {
874 if (port->nonblocking && errno == EAGAIN)
875 /* Port is opened in nonblocking mode and there are no bytes available. */
878 /* This is an actual failure. */
879 RETURN_FAIL("read() failed");
881 RETURN_VALUE("%d", bytes_read);
886 static enum sp_return get_baudrate(int fd, int *baudrate)
890 TRACE("%d, %p", fd, baudrate);
892 DEBUG("Getting baud rate");
894 if (!(data = malloc(get_termios_size())))
895 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
897 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
899 RETURN_FAIL("getting termios failed");
902 *baudrate = get_termios_speed(data);
909 static enum sp_return set_baudrate(int fd, int baudrate)
913 TRACE("%d, %d", fd, baudrate);
915 DEBUG("Getting baud rate");
917 if (!(data = malloc(get_termios_size())))
918 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
920 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
922 RETURN_FAIL("getting termios failed");
925 DEBUG("Setting baud rate");
927 set_termios_speed(data, baudrate);
929 if (ioctl(fd, get_termios_set_ioctl(), data) < 0) {
931 RETURN_FAIL("setting termios failed");
940 static enum sp_return get_flow(int fd, int *flow)
944 TRACE("%d, %p", fd, flow);
946 DEBUG("Getting advanced flow control");
948 if (!(data = malloc(get_termiox_size())))
949 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
951 if (ioctl(fd, TCGETX, data) < 0) {
953 RETURN_FAIL("getting termiox failed");
956 *flow = get_termiox_flow(data);
963 static enum sp_return set_flow(int fd, int flow)
967 TRACE("%d, %d", fd, flow);
969 DEBUG("Getting advanced flow control");
971 if (!(data = malloc(get_termiox_size())))
972 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
974 if (ioctl(fd, TCGETX, data) < 0) {
976 RETURN_FAIL("getting termiox failed");
979 DEBUG("Setting advanced flow control");
981 set_termiox_flow(data, flow);
983 if (ioctl(fd, TCSETX, data) < 0) {
985 RETURN_FAIL("setting termiox failed");
992 #endif /* USE_TERMIOX */
993 #endif /* __linux__ */
995 static enum sp_return get_config(struct sp_port *port, struct port_data *data,
996 struct sp_port_config *config)
1000 TRACE("%p, %p, %p", port, data, config);
1002 DEBUG("Getting configuration for port %s", port->name);
1005 if (!GetCommState(port->hdl, &data->dcb))
1006 RETURN_FAIL("GetCommState() failed");
1008 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1009 if (data->dcb.BaudRate == std_baudrates[i].index) {
1010 config->baudrate = std_baudrates[i].value;
1015 if (i == NUM_STD_BAUDRATES)
1016 /* BaudRate field can be either an index or a custom baud rate. */
1017 config->baudrate = data->dcb.BaudRate;
1019 config->bits = data->dcb.ByteSize;
1021 if (data->dcb.fParity)
1022 switch (data->dcb.Parity) {
1024 config->parity = SP_PARITY_NONE;
1027 config->parity = SP_PARITY_EVEN;
1030 config->parity = SP_PARITY_ODD;
1033 config->parity = -1;
1036 config->parity = SP_PARITY_NONE;
1038 switch (data->dcb.StopBits) {
1040 config->stopbits = 1;
1043 config->stopbits = 2;
1046 config->stopbits = -1;
1049 switch (data->dcb.fRtsControl) {
1050 case RTS_CONTROL_DISABLE:
1051 config->rts = SP_RTS_OFF;
1053 case RTS_CONTROL_ENABLE:
1054 config->rts = SP_RTS_ON;
1056 case RTS_CONTROL_HANDSHAKE:
1057 config->rts = SP_RTS_FLOW_CONTROL;
1063 config->cts = data->dcb.fOutxCtsFlow ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1065 switch (data->dcb.fDtrControl) {
1066 case DTR_CONTROL_DISABLE:
1067 config->dtr = SP_DTR_OFF;
1069 case DTR_CONTROL_ENABLE:
1070 config->dtr = SP_DTR_ON;
1072 case DTR_CONTROL_HANDSHAKE:
1073 config->dtr = SP_DTR_FLOW_CONTROL;
1079 config->dsr = data->dcb.fOutxDsrFlow ? SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1081 if (data->dcb.fInX) {
1082 if (data->dcb.fOutX)
1083 config->xon_xoff = SP_XONXOFF_INOUT;
1085 config->xon_xoff = SP_XONXOFF_IN;
1087 if (data->dcb.fOutX)
1088 config->xon_xoff = SP_XONXOFF_OUT;
1090 config->xon_xoff = SP_XONXOFF_DISABLED;
1095 if (tcgetattr(port->fd, &data->term) < 0)
1096 RETURN_FAIL("tcgetattr() failed");
1098 if (ioctl(port->fd, TIOCMGET, &data->controlbits) < 0)
1099 RETURN_FAIL("TIOCMGET ioctl failed");
1102 int ret = get_flow(port->fd, &data->flow);
1104 if (ret == SP_ERR_FAIL && errno == EINVAL)
1105 data->termiox_supported = 0;
1107 RETURN_CODEVAL(ret);
1109 data->termiox_supported = 1;
1111 data->termiox_supported = 0;
1114 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1115 if (cfgetispeed(&data->term) == std_baudrates[i].index) {
1116 config->baudrate = std_baudrates[i].value;
1121 if (i == NUM_STD_BAUDRATES) {
1123 config->baudrate = (int)data->term.c_ispeed;
1124 #elif defined(__linux__)
1125 TRY(get_baudrate(port->fd, &config->baudrate));
1127 config->baudrate = -1;
1131 switch (data->term.c_cflag & CSIZE) {
1148 if (!(data->term.c_cflag & PARENB) && (data->term.c_iflag & IGNPAR))
1149 config->parity = SP_PARITY_NONE;
1150 else if (!(data->term.c_cflag & PARENB) || (data->term.c_iflag & IGNPAR))
1151 config->parity = -1;
1153 config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_ODD : SP_PARITY_EVEN;
1155 config->stopbits = (data->term.c_cflag & CSTOPB) ? 2 : 1;
1157 if (data->term.c_cflag & CRTSCTS) {
1158 config->rts = SP_RTS_FLOW_CONTROL;
1159 config->cts = SP_CTS_FLOW_CONTROL;
1161 if (data->termiox_supported && data->flow & RTS_FLOW)
1162 config->rts = SP_RTS_FLOW_CONTROL;
1164 config->rts = (data->controlbits & TIOCM_RTS) ? SP_RTS_ON : SP_RTS_OFF;
1166 config->cts = (data->termiox_supported && data->flow & CTS_FLOW) ?
1167 SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1170 if (data->termiox_supported && data->flow & DTR_FLOW)
1171 config->dtr = SP_DTR_FLOW_CONTROL;
1173 config->dtr = (data->controlbits & TIOCM_DTR) ? SP_DTR_ON : SP_DTR_OFF;
1175 config->dsr = (data->termiox_supported && data->flow & DSR_FLOW) ?
1176 SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1178 if (data->term.c_iflag & IXOFF) {
1179 if (data->term.c_iflag & IXON)
1180 config->xon_xoff = SP_XONXOFF_INOUT;
1182 config->xon_xoff = SP_XONXOFF_IN;
1184 if (data->term.c_iflag & IXON)
1185 config->xon_xoff = SP_XONXOFF_OUT;
1187 config->xon_xoff = SP_XONXOFF_DISABLED;
1194 static enum sp_return set_config(struct sp_port *port, struct port_data *data,
1195 const struct sp_port_config *config)
1199 BAUD_TYPE baud_nonstd;
1204 int baud_nonstd = 0;
1207 TRACE("%p, %p, %p", port, data, config);
1209 DEBUG("Setting configuration for port %s", port->name);
1212 if (config->baudrate >= 0) {
1213 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1214 if (config->baudrate == std_baudrates[i].value) {
1215 data->dcb.BaudRate = std_baudrates[i].index;
1220 if (i == NUM_STD_BAUDRATES)
1221 data->dcb.BaudRate = config->baudrate;
1224 if (config->bits >= 0)
1225 data->dcb.ByteSize = config->bits;
1227 if (config->parity >= 0) {
1228 switch (config->parity) {
1229 /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
1230 case SP_PARITY_NONE:
1231 data->dcb.Parity = NOPARITY;
1233 case SP_PARITY_EVEN:
1234 data->dcb.Parity = EVENPARITY;
1237 data->dcb.Parity = ODDPARITY;
1240 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1244 if (config->stopbits >= 0) {
1245 switch (config->stopbits) {
1246 /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
1248 data->dcb.StopBits = ONESTOPBIT;
1251 data->dcb.StopBits = TWOSTOPBITS;
1254 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bit setting");
1258 if (config->rts >= 0) {
1259 switch (config->rts) {
1261 data->dcb.fRtsControl = RTS_CONTROL_DISABLE;
1264 data->dcb.fRtsControl = RTS_CONTROL_ENABLE;
1266 case SP_RTS_FLOW_CONTROL:
1267 data->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
1270 RETURN_ERROR(SP_ERR_ARG, "Invalid RTS setting");
1274 if (config->cts >= 0) {
1275 switch (config->cts) {
1277 data->dcb.fOutxCtsFlow = FALSE;
1279 case SP_CTS_FLOW_CONTROL:
1280 data->dcb.fOutxCtsFlow = TRUE;
1283 RETURN_ERROR(SP_ERR_ARG, "Invalid CTS setting");
1287 if (config->dtr >= 0) {
1288 switch (config->dtr) {
1290 data->dcb.fDtrControl = DTR_CONTROL_DISABLE;
1293 data->dcb.fDtrControl = DTR_CONTROL_ENABLE;
1295 case SP_DTR_FLOW_CONTROL:
1296 data->dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
1299 RETURN_ERROR(SP_ERR_ARG, "Invalid DTR setting");
1303 if (config->dsr >= 0) {
1304 switch (config->dsr) {
1306 data->dcb.fOutxDsrFlow = FALSE;
1308 case SP_DSR_FLOW_CONTROL:
1309 data->dcb.fOutxDsrFlow = TRUE;
1312 RETURN_ERROR(SP_ERR_ARG, "Invalid DSR setting");
1316 if (config->xon_xoff >= 0) {
1317 switch (config->xon_xoff) {
1318 case SP_XONXOFF_DISABLED:
1319 data->dcb.fInX = FALSE;
1320 data->dcb.fOutX = FALSE;
1323 data->dcb.fInX = TRUE;
1324 data->dcb.fOutX = FALSE;
1326 case SP_XONXOFF_OUT:
1327 data->dcb.fInX = FALSE;
1328 data->dcb.fOutX = TRUE;
1330 case SP_XONXOFF_INOUT:
1331 data->dcb.fInX = TRUE;
1332 data->dcb.fOutX = TRUE;
1335 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1339 if (!SetCommState(port->hdl, &data->dcb))
1340 RETURN_FAIL("SetCommState() failed");
1346 if (config->baudrate >= 0) {
1347 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1348 if (config->baudrate == std_baudrates[i].value) {
1349 if (cfsetospeed(&data->term, std_baudrates[i].index) < 0)
1350 RETURN_FAIL("cfsetospeed() failed");
1352 if (cfsetispeed(&data->term, std_baudrates[i].index) < 0)
1353 RETURN_FAIL("cfsetispeed() failed");
1358 /* Non-standard baud rate */
1359 if (i == NUM_STD_BAUDRATES) {
1361 /* Set "dummy" baud rate. */
1362 if (cfsetspeed(&data->term, B9600) < 0)
1363 RETURN_FAIL("cfsetspeed() failed");
1364 baud_nonstd = config->baudrate;
1365 #elif defined(__linux__)
1368 RETURN_ERROR(SP_ERR_SUPP, "Non-standard baudrate not supported");
1373 if (config->bits >= 0) {
1374 data->term.c_cflag &= ~CSIZE;
1375 switch (config->bits) {
1377 data->term.c_cflag |= CS8;
1380 data->term.c_cflag |= CS7;
1383 data->term.c_cflag |= CS6;
1386 data->term.c_cflag |= CS5;
1389 RETURN_ERROR(SP_ERR_ARG, "Invalid data bits setting");
1393 if (config->parity >= 0) {
1394 data->term.c_iflag &= ~IGNPAR;
1395 data->term.c_cflag &= ~(PARENB | PARODD);
1396 switch (config->parity) {
1397 case SP_PARITY_NONE:
1398 data->term.c_iflag |= IGNPAR;
1400 case SP_PARITY_EVEN:
1401 data->term.c_cflag |= PARENB;
1404 data->term.c_cflag |= PARENB | PARODD;
1407 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1411 if (config->stopbits >= 0) {
1412 data->term.c_cflag &= ~CSTOPB;
1413 switch (config->stopbits) {
1415 data->term.c_cflag &= ~CSTOPB;
1418 data->term.c_cflag |= CSTOPB;
1421 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bits setting");
1425 if (config->rts >= 0 || config->cts >= 0) {
1426 if (data->termiox_supported) {
1427 data->flow &= ~(RTS_FLOW | CTS_FLOW);
1428 switch (config->rts) {
1431 controlbits = TIOCM_RTS;
1432 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1433 RETURN_FAIL("Setting RTS signal level failed");
1435 case SP_RTS_FLOW_CONTROL:
1436 data->flow |= RTS_FLOW;
1441 if (config->cts == SP_CTS_FLOW_CONTROL)
1442 data->flow |= CTS_FLOW;
1444 if (data->flow & (RTS_FLOW | CTS_FLOW))
1445 data->term.c_iflag |= CRTSCTS;
1447 data->term.c_iflag &= ~CRTSCTS;
1449 /* Asymmetric use of RTS/CTS not supported. */
1450 if (data->term.c_iflag & CRTSCTS) {
1451 /* Flow control can only be disabled for both RTS & CTS together. */
1452 if (config->rts >= 0 && config->rts != SP_RTS_FLOW_CONTROL) {
1453 if (config->cts != SP_CTS_IGNORE)
1454 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1456 if (config->cts >= 0 && config->cts != SP_CTS_FLOW_CONTROL) {
1457 if (config->rts <= 0 || config->rts == SP_RTS_FLOW_CONTROL)
1458 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1461 /* Flow control can only be enabled for both RTS & CTS together. */
1462 if (((config->rts == SP_RTS_FLOW_CONTROL) && (config->cts != SP_CTS_FLOW_CONTROL)) ||
1463 ((config->cts == SP_CTS_FLOW_CONTROL) && (config->rts != SP_RTS_FLOW_CONTROL)))
1464 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be enabled together");
1467 if (config->rts >= 0) {
1468 if (config->rts == SP_RTS_FLOW_CONTROL) {
1469 data->term.c_iflag |= CRTSCTS;
1471 controlbits = TIOCM_RTS;
1472 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC,
1474 RETURN_FAIL("Setting RTS signal level failed");
1480 if (config->dtr >= 0 || config->dsr >= 0) {
1481 if (data->termiox_supported) {
1482 data->flow &= ~(DTR_FLOW | DSR_FLOW);
1483 switch (config->dtr) {
1486 controlbits = TIOCM_DTR;
1487 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1488 RETURN_FAIL("Setting DTR signal level failed");
1490 case SP_DTR_FLOW_CONTROL:
1491 data->flow |= DTR_FLOW;
1496 if (config->dsr == SP_DSR_FLOW_CONTROL)
1497 data->flow |= DSR_FLOW;
1499 /* DTR/DSR flow control not supported. */
1500 if (config->dtr == SP_DTR_FLOW_CONTROL || config->dsr == SP_DSR_FLOW_CONTROL)
1501 RETURN_ERROR(SP_ERR_SUPP, "DTR/DSR flow control not supported");
1503 if (config->dtr >= 0) {
1504 controlbits = TIOCM_DTR;
1505 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC,
1507 RETURN_FAIL("Setting DTR signal level failed");
1512 if (config->xon_xoff >= 0) {
1513 data->term.c_iflag &= ~(IXON | IXOFF | IXANY);
1514 switch (config->xon_xoff) {
1515 case SP_XONXOFF_DISABLED:
1518 data->term.c_iflag |= IXOFF;
1520 case SP_XONXOFF_OUT:
1521 data->term.c_iflag |= IXON | IXANY;
1523 case SP_XONXOFF_INOUT:
1524 data->term.c_iflag |= IXON | IXOFF | IXANY;
1527 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1531 if (tcsetattr(port->fd, TCSADRAIN, &data->term) < 0)
1532 RETURN_FAIL("tcsetattr() failed");
1535 if (baud_nonstd != B0) {
1536 if (ioctl(port->fd, IOSSIOSPEED, &baud_nonstd) == -1)
1537 RETURN_FAIL("IOSSIOSPEED ioctl failed");
1538 /* Set baud rates in data->term to correct, but incompatible
1539 * with tcsetattr() value, same as delivered by tcgetattr(). */
1540 if (cfsetspeed(&data->term, baud_nonstd) < 0)
1541 RETURN_FAIL("cfsetspeed() failed");
1543 #elif defined(__linux__)
1545 TRY(set_baudrate(port->fd, config->baudrate));
1547 if (data->termiox_supported)
1548 TRY(set_flow(port->fd, data->flow));
1552 #endif /* !_WIN32 */
1557 enum sp_return sp_new_config(struct sp_port_config **config_ptr)
1559 TRACE("%p", config_ptr);
1560 struct sp_port_config *config;
1563 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
1567 if (!(config = malloc(sizeof(struct sp_port_config))))
1568 RETURN_ERROR(SP_ERR_MEM, "config malloc failed");
1570 config->baudrate = -1;
1572 config->parity = -1;
1573 config->stopbits = -1;
1579 *config_ptr = config;
1584 void sp_free_config(struct sp_port_config *config)
1586 TRACE("%p", config);
1589 DEBUG("Null config");
1596 enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config)
1598 struct port_data data;
1600 TRACE("%p, %p", port, config);
1605 RETURN_ERROR(SP_ERR_ARG, "Null config");
1607 TRY(get_config(port, &data, config));
1612 enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config)
1614 struct port_data data;
1615 struct sp_port_config prev_config;
1617 TRACE("%p, %p", port, config);
1622 RETURN_ERROR(SP_ERR_ARG, "Null config");
1624 TRY(get_config(port, &data, &prev_config));
1625 TRY(set_config(port, &data, config));
1630 #define CREATE_ACCESSORS(x, type) \
1631 enum sp_return sp_set_##x(struct sp_port *port, type x) { \
1632 struct port_data data; \
1633 struct sp_port_config config; \
1634 TRACE("%p, %d", port, x); \
1635 CHECK_OPEN_PORT(); \
1636 TRY(get_config(port, &data, &config)); \
1638 TRY(set_config(port, &data, &config)); \
1641 enum sp_return sp_get_config_##x(const struct sp_port_config *config, type *x) { \
1642 TRACE("%p", config); \
1644 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
1648 enum sp_return sp_set_config_##x(struct sp_port_config *config, type x) { \
1649 TRACE("%p, %d", config, x); \
1651 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
1656 CREATE_ACCESSORS(baudrate, int)
1657 CREATE_ACCESSORS(bits, int)
1658 CREATE_ACCESSORS(parity, enum sp_parity)
1659 CREATE_ACCESSORS(stopbits, int)
1660 CREATE_ACCESSORS(rts, enum sp_rts)
1661 CREATE_ACCESSORS(cts, enum sp_cts)
1662 CREATE_ACCESSORS(dtr, enum sp_dtr)
1663 CREATE_ACCESSORS(dsr, enum sp_dsr)
1664 CREATE_ACCESSORS(xon_xoff, enum sp_xonxoff)
1666 enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol)
1669 RETURN_ERROR(SP_ERR_ARG, "Null configuration");
1671 if (flowcontrol > SP_FLOWCONTROL_DTRDSR)
1672 RETURN_ERROR(SP_ERR_ARG, "Invalid flow control setting");
1674 if (flowcontrol == SP_FLOWCONTROL_XONXOFF)
1675 config->xon_xoff = SP_XONXOFF_INOUT;
1677 config->xon_xoff = SP_XONXOFF_DISABLED;
1679 if (flowcontrol == SP_FLOWCONTROL_RTSCTS) {
1680 config->rts = SP_RTS_FLOW_CONTROL;
1681 config->cts = SP_CTS_FLOW_CONTROL;
1683 if (config->rts == SP_RTS_FLOW_CONTROL)
1684 config->rts = SP_RTS_ON;
1685 config->cts = SP_CTS_IGNORE;
1688 if (flowcontrol == SP_FLOWCONTROL_DTRDSR) {
1689 config->dtr = SP_DTR_FLOW_CONTROL;
1690 config->dsr = SP_DSR_FLOW_CONTROL;
1692 if (config->dtr == SP_DTR_FLOW_CONTROL)
1693 config->dtr = SP_DTR_ON;
1694 config->dsr = SP_DSR_IGNORE;
1700 enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol)
1702 struct port_data data;
1703 struct sp_port_config config;
1705 TRACE("%p, %d", port, flowcontrol);
1709 TRY(get_config(port, &data, &config));
1711 TRY(sp_set_config_flowcontrol(&config, flowcontrol));
1713 TRY(set_config(port, &data, &config));
1718 enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signals)
1720 TRACE("%p, %p", port, signals);
1725 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
1727 DEBUG("Getting control signals for port %s", port->name);
1732 if (GetCommModemStatus(port->hdl, &bits) == 0)
1733 RETURN_FAIL("GetCommModemStatus() failed");
1734 if (bits & MS_CTS_ON)
1735 *signals |= SP_SIG_CTS;
1736 if (bits & MS_DSR_ON)
1737 *signals |= SP_SIG_DSR;
1738 if (bits & MS_RLSD_ON)
1739 *signals |= SP_SIG_DCD;
1740 if (bits & MS_RING_ON)
1741 *signals |= SP_SIG_RI;
1744 if (ioctl(port->fd, TIOCMGET, &bits) < 0)
1745 RETURN_FAIL("TIOCMGET ioctl failed");
1746 if (bits & TIOCM_CTS)
1747 *signals |= SP_SIG_CTS;
1748 if (bits & TIOCM_DSR)
1749 *signals |= SP_SIG_DSR;
1750 if (bits & TIOCM_CAR)
1751 *signals |= SP_SIG_DCD;
1752 if (bits & TIOCM_RNG)
1753 *signals |= SP_SIG_RI;
1758 enum sp_return sp_start_break(struct sp_port *port)
1764 if (SetCommBreak(port->hdl) == 0)
1765 RETURN_FAIL("SetCommBreak() failed");
1767 if (ioctl(port->fd, TIOCSBRK, 1) < 0)
1768 RETURN_FAIL("TIOCSBRK ioctl failed");
1774 enum sp_return sp_end_break(struct sp_port *port)
1780 if (ClearCommBreak(port->hdl) == 0)
1781 RETURN_FAIL("ClearCommBreak() failed");
1783 if (ioctl(port->fd, TIOCCBRK, 1) < 0)
1784 RETURN_FAIL("TIOCCBRK ioctl failed");
1790 int sp_last_error_code(void)
1794 RETURN_VALUE("%d", GetLastError());
1796 RETURN_VALUE("%d", errno);
1800 char *sp_last_error_message(void)
1806 DWORD error = GetLastError();
1809 FORMAT_MESSAGE_ALLOCATE_BUFFER |
1810 FORMAT_MESSAGE_FROM_SYSTEM |
1811 FORMAT_MESSAGE_IGNORE_INSERTS,
1814 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1818 RETURN_VALUE("%s", message);
1820 RETURN_VALUE("%s", strerror(errno));
1824 void sp_free_error_message(char *message)
1826 TRACE("%s", message);
1837 void sp_set_debug_handler(void (*handler)(const char *format, ...))
1839 TRACE("%p", handler);
1841 sp_debug_handler = handler;
1846 void sp_default_debug_handler(const char *format, ...)
1849 va_start(args, format);
1850 if (getenv("LIBSERIALPORT_DEBUG")) {
1851 fputs("libserialport: ", stderr);
1852 vfprintf(stderr, format, args);