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->write_buf = NULL;
631 port->writing = FALSE;
634 if (SetCommTimeouts(port->hdl, &timeouts) == 0) {
636 RETURN_FAIL("SetCommTimeouts() failed");
640 struct port_data data;
641 struct sp_port_config config;
644 /* Map 'flags' to the OS-specific settings. */
645 if (flags & (SP_MODE_READ | SP_MODE_WRITE))
646 flags_local |= O_RDWR;
647 else if (flags & SP_MODE_READ)
648 flags_local |= O_RDONLY;
649 else if (flags & SP_MODE_WRITE)
650 flags_local |= O_WRONLY;
651 if (flags & SP_MODE_NONBLOCK)
652 flags_local |= O_NONBLOCK;
654 if ((port->fd = open(port->name, flags_local)) < 0)
655 RETURN_FAIL("open() failed");
657 ret = get_config(port, &data, &config);
664 /* Turn off all serial port cooking. */
665 data.term.c_iflag &= ~(ISTRIP | INLCR | ICRNL);
666 data.term.c_oflag &= ~(ONLCR | OCRNL | ONOCR);
667 #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
668 data.term.c_oflag &= ~OFILL;
670 /* Disable canonical mode, and don't echo input characters. */
671 data.term.c_lflag &= ~(ICANON | ECHO);
673 /* Ignore modem status lines; enable receiver */
674 data.term.c_cflag |= (CLOCAL | CREAD);
676 ret = set_config(port, &data, &config);
687 enum sp_return sp_close(struct sp_port *port)
693 DEBUG("Closing port %s", port->name);
696 /* Returns non-zero upon success, 0 upon failure. */
697 if (CloseHandle(port->hdl) == 0)
698 RETURN_FAIL("CloseHandle() failed");
699 port->hdl = INVALID_HANDLE_VALUE;
700 if (port->nonblocking) {
702 /* Write should have been stopped by closing the port, so safe to free buffer. */
703 free(port->write_buf);
704 /* Close event handle created for overlapped writes. */
705 if (CloseHandle(port->write_ovl.hEvent) == 0)
706 RETURN_FAIL("CloseHandle() failed");
709 /* Returns 0 upon success, -1 upon failure. */
710 if (close(port->fd) == -1)
711 RETURN_FAIL("close() failed");
718 enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers)
720 TRACE("%p, %x", port, buffers);
724 if (buffers > SP_BUF_BOTH)
725 RETURN_ERROR(SP_ERR_ARG, "Invalid buffer selection");
727 const char *buffer_names[] = {"no", "input", "output", "both"};
729 DEBUG("Flushing %s buffers on port %s", buffer_names[buffers], port->name);
733 if (buffers & SP_BUF_INPUT)
734 flags |= PURGE_RXCLEAR;
735 if (buffers & SP_BUF_OUTPUT)
736 flags |= PURGE_TXCLEAR;
738 /* Returns non-zero upon success, 0 upon failure. */
739 if (PurgeComm(port->hdl, flags) == 0)
740 RETURN_FAIL("PurgeComm() failed");
743 if (buffers & SP_BUF_BOTH)
745 else if (buffers & SP_BUF_INPUT)
747 else if (buffers & SP_BUF_OUTPUT)
750 /* Returns 0 upon success, -1 upon failure. */
751 if (tcflush(port->fd, flags) < 0)
752 RETURN_FAIL("tcflush() failed");
757 enum sp_return sp_drain(struct sp_port *port)
763 DEBUG("Draining port %s", port->name);
766 /* Returns non-zero upon success, 0 upon failure. */
767 if (FlushFileBuffers(port->hdl) == 0)
768 RETURN_FAIL("FlushFileBuffers() failed");
770 /* Returns 0 upon success, -1 upon failure. */
771 if (tcdrain(port->fd) < 0)
772 RETURN_FAIL("tcdrain() failed");
778 enum sp_return sp_write(struct sp_port *port, const void *buf, size_t count)
780 TRACE("%p, %p, %d", port, buf, count);
785 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
787 DEBUG("Writing up to %d bytes to port %s", count, port->name);
790 RETURN_VALUE("0", 0);
795 if (port->nonblocking) {
796 /* Non-blocking write. */
798 /* Check whether previous write is complete. */
800 if (HasOverlappedIoCompleted(&port->write_ovl)) {
801 DEBUG("Previous write completed");
803 free(port->write_buf);
804 port->write_buf = NULL;
806 DEBUG("Previous write not complete");
807 /* Can't take a new write until the previous one finishes. */
808 RETURN_VALUE("0", 0);
812 /* Copy user buffer. */
813 if (!(port->write_buf = malloc(count)))
814 RETURN_ERROR(SP_ERR_MEM, "buffer copy malloc failed");
815 memcpy(port->write_buf, buf, count);
817 /* Start asynchronous write. */
818 if (WriteFile(port->hdl, buf, count, NULL, &port->write_ovl) == 0) {
819 if (GetLastError() == ERROR_IO_PENDING) {
820 DEBUG("Asynchronous write started");
822 RETURN_VALUE("%d", count);
824 free(port->write_buf);
825 port->write_buf = NULL;
826 /* Actual failure of some kind. */
827 RETURN_FAIL("WriteFile() failed");
830 DEBUG("Write completed immediately");
831 free(port->write_buf);
832 port->write_buf = NULL;
833 RETURN_VALUE("%d", count);
836 /* Blocking write. */
837 if (WriteFile(port->hdl, buf, count, &written, NULL) == 0) {
838 RETURN_FAIL("WriteFile() failed");
842 RETURN_VALUE("%d", written);
844 /* Returns the number of bytes written, or -1 upon failure. */
845 ssize_t written = write(port->fd, buf, count);
848 RETURN_FAIL("write() failed");
850 RETURN_VALUE("%d", written);
854 enum sp_return sp_read(struct sp_port *port, void *buf, size_t count)
856 TRACE("%p, %p, %d", port, buf, count);
861 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
863 DEBUG("Reading up to %d bytes from port %s", count, port->name);
866 DWORD bytes_read = 0;
868 /* Returns non-zero upon success, 0 upon failure. */
869 if (ReadFile(port->hdl, buf, count, &bytes_read, NULL) == 0)
870 RETURN_FAIL("ReadFile() failed");
871 RETURN_VALUE("%d", bytes_read);
875 /* Returns the number of bytes read, or -1 upon failure. */
876 if ((bytes_read = read(port->fd, buf, count)) < 0) {
877 if (port->nonblocking && errno == EAGAIN)
878 /* Port is opened in nonblocking mode and there are no bytes available. */
881 /* This is an actual failure. */
882 RETURN_FAIL("read() failed");
884 RETURN_VALUE("%d", bytes_read);
889 static enum sp_return get_baudrate(int fd, int *baudrate)
893 TRACE("%d, %p", fd, baudrate);
895 DEBUG("Getting baud rate");
897 if (!(data = malloc(get_termios_size())))
898 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
900 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
902 RETURN_FAIL("getting termios failed");
905 *baudrate = get_termios_speed(data);
912 static enum sp_return set_baudrate(int fd, int baudrate)
916 TRACE("%d, %d", fd, baudrate);
918 DEBUG("Getting baud rate");
920 if (!(data = malloc(get_termios_size())))
921 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
923 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
925 RETURN_FAIL("getting termios failed");
928 DEBUG("Setting baud rate");
930 set_termios_speed(data, baudrate);
932 if (ioctl(fd, get_termios_set_ioctl(), data) < 0) {
934 RETURN_FAIL("setting termios failed");
943 static enum sp_return get_flow(int fd, int *flow)
947 TRACE("%d, %p", fd, flow);
949 DEBUG("Getting advanced flow control");
951 if (!(data = malloc(get_termiox_size())))
952 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
954 if (ioctl(fd, TCGETX, data) < 0) {
956 RETURN_FAIL("getting termiox failed");
959 *flow = get_termiox_flow(data);
966 static enum sp_return set_flow(int fd, int flow)
970 TRACE("%d, %d", fd, flow);
972 DEBUG("Getting advanced flow control");
974 if (!(data = malloc(get_termiox_size())))
975 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
977 if (ioctl(fd, TCGETX, data) < 0) {
979 RETURN_FAIL("getting termiox failed");
982 DEBUG("Setting advanced flow control");
984 set_termiox_flow(data, flow);
986 if (ioctl(fd, TCSETX, data) < 0) {
988 RETURN_FAIL("setting termiox failed");
995 #endif /* USE_TERMIOX */
996 #endif /* __linux__ */
998 static enum sp_return get_config(struct sp_port *port, struct port_data *data,
999 struct sp_port_config *config)
1003 TRACE("%p, %p, %p", port, data, config);
1005 DEBUG("Getting configuration for port %s", port->name);
1008 if (!GetCommState(port->hdl, &data->dcb))
1009 RETURN_FAIL("GetCommState() failed");
1011 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1012 if (data->dcb.BaudRate == std_baudrates[i].index) {
1013 config->baudrate = std_baudrates[i].value;
1018 if (i == NUM_STD_BAUDRATES)
1019 /* BaudRate field can be either an index or a custom baud rate. */
1020 config->baudrate = data->dcb.BaudRate;
1022 config->bits = data->dcb.ByteSize;
1024 if (data->dcb.fParity)
1025 switch (data->dcb.Parity) {
1027 config->parity = SP_PARITY_NONE;
1030 config->parity = SP_PARITY_EVEN;
1033 config->parity = SP_PARITY_ODD;
1036 config->parity = -1;
1039 config->parity = SP_PARITY_NONE;
1041 switch (data->dcb.StopBits) {
1043 config->stopbits = 1;
1046 config->stopbits = 2;
1049 config->stopbits = -1;
1052 switch (data->dcb.fRtsControl) {
1053 case RTS_CONTROL_DISABLE:
1054 config->rts = SP_RTS_OFF;
1056 case RTS_CONTROL_ENABLE:
1057 config->rts = SP_RTS_ON;
1059 case RTS_CONTROL_HANDSHAKE:
1060 config->rts = SP_RTS_FLOW_CONTROL;
1066 config->cts = data->dcb.fOutxCtsFlow ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1068 switch (data->dcb.fDtrControl) {
1069 case DTR_CONTROL_DISABLE:
1070 config->dtr = SP_DTR_OFF;
1072 case DTR_CONTROL_ENABLE:
1073 config->dtr = SP_DTR_ON;
1075 case DTR_CONTROL_HANDSHAKE:
1076 config->dtr = SP_DTR_FLOW_CONTROL;
1082 config->dsr = data->dcb.fOutxDsrFlow ? SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1084 if (data->dcb.fInX) {
1085 if (data->dcb.fOutX)
1086 config->xon_xoff = SP_XONXOFF_INOUT;
1088 config->xon_xoff = SP_XONXOFF_IN;
1090 if (data->dcb.fOutX)
1091 config->xon_xoff = SP_XONXOFF_OUT;
1093 config->xon_xoff = SP_XONXOFF_DISABLED;
1098 if (tcgetattr(port->fd, &data->term) < 0)
1099 RETURN_FAIL("tcgetattr() failed");
1101 if (ioctl(port->fd, TIOCMGET, &data->controlbits) < 0)
1102 RETURN_FAIL("TIOCMGET ioctl failed");
1105 int ret = get_flow(port->fd, &data->flow);
1107 if (ret == SP_ERR_FAIL && errno == EINVAL)
1108 data->termiox_supported = 0;
1110 RETURN_CODEVAL(ret);
1112 data->termiox_supported = 1;
1114 data->termiox_supported = 0;
1117 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1118 if (cfgetispeed(&data->term) == std_baudrates[i].index) {
1119 config->baudrate = std_baudrates[i].value;
1124 if (i == NUM_STD_BAUDRATES) {
1126 config->baudrate = (int)data->term.c_ispeed;
1127 #elif defined(__linux__)
1128 TRY(get_baudrate(port->fd, &config->baudrate));
1130 config->baudrate = -1;
1134 switch (data->term.c_cflag & CSIZE) {
1151 if (!(data->term.c_cflag & PARENB) && (data->term.c_iflag & IGNPAR))
1152 config->parity = SP_PARITY_NONE;
1153 else if (!(data->term.c_cflag & PARENB) || (data->term.c_iflag & IGNPAR))
1154 config->parity = -1;
1156 config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_ODD : SP_PARITY_EVEN;
1158 config->stopbits = (data->term.c_cflag & CSTOPB) ? 2 : 1;
1160 if (data->term.c_cflag & CRTSCTS) {
1161 config->rts = SP_RTS_FLOW_CONTROL;
1162 config->cts = SP_CTS_FLOW_CONTROL;
1164 if (data->termiox_supported && data->flow & RTS_FLOW)
1165 config->rts = SP_RTS_FLOW_CONTROL;
1167 config->rts = (data->controlbits & TIOCM_RTS) ? SP_RTS_ON : SP_RTS_OFF;
1169 config->cts = (data->termiox_supported && data->flow & CTS_FLOW) ?
1170 SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1173 if (data->termiox_supported && data->flow & DTR_FLOW)
1174 config->dtr = SP_DTR_FLOW_CONTROL;
1176 config->dtr = (data->controlbits & TIOCM_DTR) ? SP_DTR_ON : SP_DTR_OFF;
1178 config->dsr = (data->termiox_supported && data->flow & DSR_FLOW) ?
1179 SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1181 if (data->term.c_iflag & IXOFF) {
1182 if (data->term.c_iflag & IXON)
1183 config->xon_xoff = SP_XONXOFF_INOUT;
1185 config->xon_xoff = SP_XONXOFF_IN;
1187 if (data->term.c_iflag & IXON)
1188 config->xon_xoff = SP_XONXOFF_OUT;
1190 config->xon_xoff = SP_XONXOFF_DISABLED;
1197 static enum sp_return set_config(struct sp_port *port, struct port_data *data,
1198 const struct sp_port_config *config)
1202 BAUD_TYPE baud_nonstd;
1207 int baud_nonstd = 0;
1210 TRACE("%p, %p, %p", port, data, config);
1212 DEBUG("Setting configuration for port %s", port->name);
1215 if (config->baudrate >= 0) {
1216 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1217 if (config->baudrate == std_baudrates[i].value) {
1218 data->dcb.BaudRate = std_baudrates[i].index;
1223 if (i == NUM_STD_BAUDRATES)
1224 data->dcb.BaudRate = config->baudrate;
1227 if (config->bits >= 0)
1228 data->dcb.ByteSize = config->bits;
1230 if (config->parity >= 0) {
1231 switch (config->parity) {
1232 /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
1233 case SP_PARITY_NONE:
1234 data->dcb.Parity = NOPARITY;
1236 case SP_PARITY_EVEN:
1237 data->dcb.Parity = EVENPARITY;
1240 data->dcb.Parity = ODDPARITY;
1243 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1247 if (config->stopbits >= 0) {
1248 switch (config->stopbits) {
1249 /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
1251 data->dcb.StopBits = ONESTOPBIT;
1254 data->dcb.StopBits = TWOSTOPBITS;
1257 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bit setting");
1261 if (config->rts >= 0) {
1262 switch (config->rts) {
1264 data->dcb.fRtsControl = RTS_CONTROL_DISABLE;
1267 data->dcb.fRtsControl = RTS_CONTROL_ENABLE;
1269 case SP_RTS_FLOW_CONTROL:
1270 data->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
1273 RETURN_ERROR(SP_ERR_ARG, "Invalid RTS setting");
1277 if (config->cts >= 0) {
1278 switch (config->cts) {
1280 data->dcb.fOutxCtsFlow = FALSE;
1282 case SP_CTS_FLOW_CONTROL:
1283 data->dcb.fOutxCtsFlow = TRUE;
1286 RETURN_ERROR(SP_ERR_ARG, "Invalid CTS setting");
1290 if (config->dtr >= 0) {
1291 switch (config->dtr) {
1293 data->dcb.fDtrControl = DTR_CONTROL_DISABLE;
1296 data->dcb.fDtrControl = DTR_CONTROL_ENABLE;
1298 case SP_DTR_FLOW_CONTROL:
1299 data->dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
1302 RETURN_ERROR(SP_ERR_ARG, "Invalid DTR setting");
1306 if (config->dsr >= 0) {
1307 switch (config->dsr) {
1309 data->dcb.fOutxDsrFlow = FALSE;
1311 case SP_DSR_FLOW_CONTROL:
1312 data->dcb.fOutxDsrFlow = TRUE;
1315 RETURN_ERROR(SP_ERR_ARG, "Invalid DSR setting");
1319 if (config->xon_xoff >= 0) {
1320 switch (config->xon_xoff) {
1321 case SP_XONXOFF_DISABLED:
1322 data->dcb.fInX = FALSE;
1323 data->dcb.fOutX = FALSE;
1326 data->dcb.fInX = TRUE;
1327 data->dcb.fOutX = FALSE;
1329 case SP_XONXOFF_OUT:
1330 data->dcb.fInX = FALSE;
1331 data->dcb.fOutX = TRUE;
1333 case SP_XONXOFF_INOUT:
1334 data->dcb.fInX = TRUE;
1335 data->dcb.fOutX = TRUE;
1338 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1342 if (!SetCommState(port->hdl, &data->dcb))
1343 RETURN_FAIL("SetCommState() failed");
1349 if (config->baudrate >= 0) {
1350 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1351 if (config->baudrate == std_baudrates[i].value) {
1352 if (cfsetospeed(&data->term, std_baudrates[i].index) < 0)
1353 RETURN_FAIL("cfsetospeed() failed");
1355 if (cfsetispeed(&data->term, std_baudrates[i].index) < 0)
1356 RETURN_FAIL("cfsetispeed() failed");
1361 /* Non-standard baud rate */
1362 if (i == NUM_STD_BAUDRATES) {
1364 /* Set "dummy" baud rate. */
1365 if (cfsetspeed(&data->term, B9600) < 0)
1366 RETURN_FAIL("cfsetspeed() failed");
1367 baud_nonstd = config->baudrate;
1368 #elif defined(__linux__)
1371 RETURN_ERROR(SP_ERR_SUPP, "Non-standard baudrate not supported");
1376 if (config->bits >= 0) {
1377 data->term.c_cflag &= ~CSIZE;
1378 switch (config->bits) {
1380 data->term.c_cflag |= CS8;
1383 data->term.c_cflag |= CS7;
1386 data->term.c_cflag |= CS6;
1389 data->term.c_cflag |= CS5;
1392 RETURN_ERROR(SP_ERR_ARG, "Invalid data bits setting");
1396 if (config->parity >= 0) {
1397 data->term.c_iflag &= ~IGNPAR;
1398 data->term.c_cflag &= ~(PARENB | PARODD);
1399 switch (config->parity) {
1400 case SP_PARITY_NONE:
1401 data->term.c_iflag |= IGNPAR;
1403 case SP_PARITY_EVEN:
1404 data->term.c_cflag |= PARENB;
1407 data->term.c_cflag |= PARENB | PARODD;
1410 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1414 if (config->stopbits >= 0) {
1415 data->term.c_cflag &= ~CSTOPB;
1416 switch (config->stopbits) {
1418 data->term.c_cflag &= ~CSTOPB;
1421 data->term.c_cflag |= CSTOPB;
1424 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bits setting");
1428 if (config->rts >= 0 || config->cts >= 0) {
1429 if (data->termiox_supported) {
1430 data->flow &= ~(RTS_FLOW | CTS_FLOW);
1431 switch (config->rts) {
1434 controlbits = TIOCM_RTS;
1435 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1436 RETURN_FAIL("Setting RTS signal level failed");
1438 case SP_RTS_FLOW_CONTROL:
1439 data->flow |= RTS_FLOW;
1444 if (config->cts == SP_CTS_FLOW_CONTROL)
1445 data->flow |= CTS_FLOW;
1447 if (data->flow & (RTS_FLOW | CTS_FLOW))
1448 data->term.c_iflag |= CRTSCTS;
1450 data->term.c_iflag &= ~CRTSCTS;
1452 /* Asymmetric use of RTS/CTS not supported. */
1453 if (data->term.c_iflag & CRTSCTS) {
1454 /* Flow control can only be disabled for both RTS & CTS together. */
1455 if (config->rts >= 0 && config->rts != SP_RTS_FLOW_CONTROL) {
1456 if (config->cts != SP_CTS_IGNORE)
1457 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1459 if (config->cts >= 0 && config->cts != SP_CTS_FLOW_CONTROL) {
1460 if (config->rts <= 0 || config->rts == SP_RTS_FLOW_CONTROL)
1461 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1464 /* Flow control can only be enabled for both RTS & CTS together. */
1465 if (((config->rts == SP_RTS_FLOW_CONTROL) && (config->cts != SP_CTS_FLOW_CONTROL)) ||
1466 ((config->cts == SP_CTS_FLOW_CONTROL) && (config->rts != SP_RTS_FLOW_CONTROL)))
1467 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be enabled together");
1470 if (config->rts >= 0) {
1471 if (config->rts == SP_RTS_FLOW_CONTROL) {
1472 data->term.c_iflag |= CRTSCTS;
1474 controlbits = TIOCM_RTS;
1475 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC,
1477 RETURN_FAIL("Setting RTS signal level failed");
1483 if (config->dtr >= 0 || config->dsr >= 0) {
1484 if (data->termiox_supported) {
1485 data->flow &= ~(DTR_FLOW | DSR_FLOW);
1486 switch (config->dtr) {
1489 controlbits = TIOCM_DTR;
1490 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1491 RETURN_FAIL("Setting DTR signal level failed");
1493 case SP_DTR_FLOW_CONTROL:
1494 data->flow |= DTR_FLOW;
1499 if (config->dsr == SP_DSR_FLOW_CONTROL)
1500 data->flow |= DSR_FLOW;
1502 /* DTR/DSR flow control not supported. */
1503 if (config->dtr == SP_DTR_FLOW_CONTROL || config->dsr == SP_DSR_FLOW_CONTROL)
1504 RETURN_ERROR(SP_ERR_SUPP, "DTR/DSR flow control not supported");
1506 if (config->dtr >= 0) {
1507 controlbits = TIOCM_DTR;
1508 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC,
1510 RETURN_FAIL("Setting DTR signal level failed");
1515 if (config->xon_xoff >= 0) {
1516 data->term.c_iflag &= ~(IXON | IXOFF | IXANY);
1517 switch (config->xon_xoff) {
1518 case SP_XONXOFF_DISABLED:
1521 data->term.c_iflag |= IXOFF;
1523 case SP_XONXOFF_OUT:
1524 data->term.c_iflag |= IXON | IXANY;
1526 case SP_XONXOFF_INOUT:
1527 data->term.c_iflag |= IXON | IXOFF | IXANY;
1530 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1534 if (tcsetattr(port->fd, TCSADRAIN, &data->term) < 0)
1535 RETURN_FAIL("tcsetattr() failed");
1538 if (baud_nonstd != B0) {
1539 if (ioctl(port->fd, IOSSIOSPEED, &baud_nonstd) == -1)
1540 RETURN_FAIL("IOSSIOSPEED ioctl failed");
1541 /* Set baud rates in data->term to correct, but incompatible
1542 * with tcsetattr() value, same as delivered by tcgetattr(). */
1543 if (cfsetspeed(&data->term, baud_nonstd) < 0)
1544 RETURN_FAIL("cfsetspeed() failed");
1546 #elif defined(__linux__)
1548 TRY(set_baudrate(port->fd, config->baudrate));
1550 if (data->termiox_supported)
1551 TRY(set_flow(port->fd, data->flow));
1555 #endif /* !_WIN32 */
1560 enum sp_return sp_new_config(struct sp_port_config **config_ptr)
1562 TRACE("%p", config_ptr);
1563 struct sp_port_config *config;
1566 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
1570 if (!(config = malloc(sizeof(struct sp_port_config))))
1571 RETURN_ERROR(SP_ERR_MEM, "config malloc failed");
1573 config->baudrate = -1;
1575 config->parity = -1;
1576 config->stopbits = -1;
1582 *config_ptr = config;
1587 void sp_free_config(struct sp_port_config *config)
1589 TRACE("%p", config);
1592 DEBUG("Null config");
1599 enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config)
1601 struct port_data data;
1603 TRACE("%p, %p", port, config);
1608 RETURN_ERROR(SP_ERR_ARG, "Null config");
1610 TRY(get_config(port, &data, config));
1615 enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config)
1617 struct port_data data;
1618 struct sp_port_config prev_config;
1620 TRACE("%p, %p", port, config);
1625 RETURN_ERROR(SP_ERR_ARG, "Null config");
1627 TRY(get_config(port, &data, &prev_config));
1628 TRY(set_config(port, &data, config));
1633 #define CREATE_ACCESSORS(x, type) \
1634 enum sp_return sp_set_##x(struct sp_port *port, type x) { \
1635 struct port_data data; \
1636 struct sp_port_config config; \
1637 TRACE("%p, %d", port, x); \
1638 CHECK_OPEN_PORT(); \
1639 TRY(get_config(port, &data, &config)); \
1641 TRY(set_config(port, &data, &config)); \
1644 enum sp_return sp_get_config_##x(const struct sp_port_config *config, type *x) { \
1645 TRACE("%p", config); \
1647 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
1651 enum sp_return sp_set_config_##x(struct sp_port_config *config, type x) { \
1652 TRACE("%p, %d", config, x); \
1654 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
1659 CREATE_ACCESSORS(baudrate, int)
1660 CREATE_ACCESSORS(bits, int)
1661 CREATE_ACCESSORS(parity, enum sp_parity)
1662 CREATE_ACCESSORS(stopbits, int)
1663 CREATE_ACCESSORS(rts, enum sp_rts)
1664 CREATE_ACCESSORS(cts, enum sp_cts)
1665 CREATE_ACCESSORS(dtr, enum sp_dtr)
1666 CREATE_ACCESSORS(dsr, enum sp_dsr)
1667 CREATE_ACCESSORS(xon_xoff, enum sp_xonxoff)
1669 enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol)
1672 RETURN_ERROR(SP_ERR_ARG, "Null configuration");
1674 if (flowcontrol > SP_FLOWCONTROL_DTRDSR)
1675 RETURN_ERROR(SP_ERR_ARG, "Invalid flow control setting");
1677 if (flowcontrol == SP_FLOWCONTROL_XONXOFF)
1678 config->xon_xoff = SP_XONXOFF_INOUT;
1680 config->xon_xoff = SP_XONXOFF_DISABLED;
1682 if (flowcontrol == SP_FLOWCONTROL_RTSCTS) {
1683 config->rts = SP_RTS_FLOW_CONTROL;
1684 config->cts = SP_CTS_FLOW_CONTROL;
1686 if (config->rts == SP_RTS_FLOW_CONTROL)
1687 config->rts = SP_RTS_ON;
1688 config->cts = SP_CTS_IGNORE;
1691 if (flowcontrol == SP_FLOWCONTROL_DTRDSR) {
1692 config->dtr = SP_DTR_FLOW_CONTROL;
1693 config->dsr = SP_DSR_FLOW_CONTROL;
1695 if (config->dtr == SP_DTR_FLOW_CONTROL)
1696 config->dtr = SP_DTR_ON;
1697 config->dsr = SP_DSR_IGNORE;
1703 enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol)
1705 struct port_data data;
1706 struct sp_port_config config;
1708 TRACE("%p, %d", port, flowcontrol);
1712 TRY(get_config(port, &data, &config));
1714 TRY(sp_set_config_flowcontrol(&config, flowcontrol));
1716 TRY(set_config(port, &data, &config));
1721 enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signals)
1723 TRACE("%p, %p", port, signals);
1728 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
1730 DEBUG("Getting control signals for port %s", port->name);
1735 if (GetCommModemStatus(port->hdl, &bits) == 0)
1736 RETURN_FAIL("GetCommModemStatus() failed");
1737 if (bits & MS_CTS_ON)
1738 *signals |= SP_SIG_CTS;
1739 if (bits & MS_DSR_ON)
1740 *signals |= SP_SIG_DSR;
1741 if (bits & MS_RLSD_ON)
1742 *signals |= SP_SIG_DCD;
1743 if (bits & MS_RING_ON)
1744 *signals |= SP_SIG_RI;
1747 if (ioctl(port->fd, TIOCMGET, &bits) < 0)
1748 RETURN_FAIL("TIOCMGET ioctl failed");
1749 if (bits & TIOCM_CTS)
1750 *signals |= SP_SIG_CTS;
1751 if (bits & TIOCM_DSR)
1752 *signals |= SP_SIG_DSR;
1753 if (bits & TIOCM_CAR)
1754 *signals |= SP_SIG_DCD;
1755 if (bits & TIOCM_RNG)
1756 *signals |= SP_SIG_RI;
1761 enum sp_return sp_start_break(struct sp_port *port)
1767 if (SetCommBreak(port->hdl) == 0)
1768 RETURN_FAIL("SetCommBreak() failed");
1770 if (ioctl(port->fd, TIOCSBRK, 1) < 0)
1771 RETURN_FAIL("TIOCSBRK ioctl failed");
1777 enum sp_return sp_end_break(struct sp_port *port)
1783 if (ClearCommBreak(port->hdl) == 0)
1784 RETURN_FAIL("ClearCommBreak() failed");
1786 if (ioctl(port->fd, TIOCCBRK, 1) < 0)
1787 RETURN_FAIL("TIOCCBRK ioctl failed");
1793 int sp_last_error_code(void)
1797 RETURN_VALUE("%d", GetLastError());
1799 RETURN_VALUE("%d", errno);
1803 char *sp_last_error_message(void)
1809 DWORD error = GetLastError();
1812 FORMAT_MESSAGE_ALLOCATE_BUFFER |
1813 FORMAT_MESSAGE_FROM_SYSTEM |
1814 FORMAT_MESSAGE_IGNORE_INSERTS,
1817 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1821 RETURN_VALUE("%s", message);
1823 RETURN_VALUE("%s", strerror(errno));
1827 void sp_free_error_message(char *message)
1829 TRACE("%s", message);
1840 void sp_set_debug_handler(void (*handler)(const char *format, ...))
1842 TRACE("%p", handler);
1844 sp_debug_handler = handler;
1849 void sp_default_debug_handler(const char *format, ...)
1852 va_start(args, format);
1853 if (getenv("LIBSERIALPORT_DEBUG")) {
1854 fputs("libserialport: ", stderr);
1855 vfprintf(stderr, format, args);