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 fancy termios tricks, give us a raw channel. */
664 data.term.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL|IUCLC|IMAXBEL);
665 data.term.c_oflag &= ~(OPOST|OLCUC|ONLCR|OCRNL|ONOCR|ONLRET|NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY);
667 data.term.c_oflag &= ~OFILL;
669 data.term.c_lflag &= ~(ISIG|ICANON|ECHO|IEXTEN);
670 data.term.c_cc[VMIN] = 0;
671 data.term.c_cc[VTIME] = 0;
673 /* Ignore modem status lines; enable receiver; leave control lines alone on close. */
674 data.term.c_cflag |= (CLOCAL | CREAD | HUPCL);
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) {
701 /* Close event handle created for overlapped writes. */
702 if (CloseHandle(port->write_ovl.hEvent) == 0)
703 RETURN_FAIL("CloseHandle() failed");
706 /* Returns 0 upon success, -1 upon failure. */
707 if (close(port->fd) == -1)
708 RETURN_FAIL("close() failed");
715 enum sp_return sp_flush(struct sp_port *port, enum sp_buffer buffers)
717 TRACE("%p, %x", port, buffers);
721 if (buffers > SP_BUF_BOTH)
722 RETURN_ERROR(SP_ERR_ARG, "Invalid buffer selection");
724 const char *buffer_names[] = {"no", "input", "output", "both"};
726 DEBUG("Flushing %s buffers on port %s", buffer_names[buffers], port->name);
730 if (buffers & SP_BUF_INPUT)
731 flags |= PURGE_RXCLEAR;
732 if (buffers & SP_BUF_OUTPUT)
733 flags |= PURGE_TXCLEAR;
735 /* Returns non-zero upon success, 0 upon failure. */
736 if (PurgeComm(port->hdl, flags) == 0)
737 RETURN_FAIL("PurgeComm() failed");
740 if (buffers & SP_BUF_BOTH)
742 else if (buffers & SP_BUF_INPUT)
744 else if (buffers & SP_BUF_OUTPUT)
747 /* Returns 0 upon success, -1 upon failure. */
748 if (tcflush(port->fd, flags) < 0)
749 RETURN_FAIL("tcflush() failed");
754 enum sp_return sp_drain(struct sp_port *port)
760 DEBUG("Draining port %s", port->name);
763 /* Returns non-zero upon success, 0 upon failure. */
764 if (FlushFileBuffers(port->hdl) == 0)
765 RETURN_FAIL("FlushFileBuffers() failed");
767 /* Returns 0 upon success, -1 upon failure. */
768 if (tcdrain(port->fd) < 0)
769 RETURN_FAIL("tcdrain() failed");
775 enum sp_return sp_write(struct sp_port *port, const void *buf, size_t count)
777 TRACE("%p, %p, %d", port, buf, count);
782 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
784 DEBUG("Writing up to %d bytes to port %s", count, port->name);
787 RETURN_VALUE("0", 0);
791 BYTE *ptr = (BYTE *) buf;
793 if (port->nonblocking) {
794 /* Non-blocking write. */
796 /* Check whether previous write is complete. */
798 if (HasOverlappedIoCompleted(&port->write_ovl)) {
799 DEBUG("Previous write completed");
802 DEBUG("Previous write not complete");
803 /* Can't take a new write until the previous one finishes. */
804 RETURN_VALUE("0", 0);
808 /* Keep writing data until the OS has to actually start an async IO for it.
809 * At that point we know the buffer is full. */
810 while (written < count)
812 /* Copy first byte of user buffer. */
813 port->pending_byte = *ptr++;
815 /* Start asynchronous write. */
816 if (WriteFile(port->hdl, &port->pending_byte, 1, NULL, &port->write_ovl) == 0) {
817 if (GetLastError() == ERROR_IO_PENDING) {
818 DEBUG("Asynchronous write started");
820 RETURN_VALUE("%d", ++written);
822 /* Actual failure of some kind. */
823 RETURN_FAIL("WriteFile() failed");
826 DEBUG("Single byte written immediately.");
831 DEBUG("All bytes written immediately.");
834 /* Blocking write. */
835 if (WriteFile(port->hdl, buf, count, &written, NULL) == 0) {
836 RETURN_FAIL("WriteFile() failed");
840 RETURN_VALUE("%d", written);
842 /* Returns the number of bytes written, or -1 upon failure. */
843 ssize_t written = write(port->fd, buf, count);
846 RETURN_FAIL("write() failed");
848 RETURN_VALUE("%d", written);
852 enum sp_return sp_read(struct sp_port *port, void *buf, size_t count)
854 TRACE("%p, %p, %d", port, buf, count);
859 RETURN_ERROR(SP_ERR_ARG, "Null buffer");
861 DEBUG("Reading up to %d bytes from port %s", count, port->name);
864 DWORD bytes_read = 0;
866 /* Returns non-zero upon success, 0 upon failure. */
867 if (ReadFile(port->hdl, buf, count, &bytes_read, NULL) == 0)
868 RETURN_FAIL("ReadFile() failed");
869 RETURN_VALUE("%d", bytes_read);
873 /* Returns the number of bytes read, or -1 upon failure. */
874 if ((bytes_read = read(port->fd, buf, count)) < 0) {
875 if (port->nonblocking && errno == EAGAIN)
876 /* Port is opened in nonblocking mode and there are no bytes available. */
879 /* This is an actual failure. */
880 RETURN_FAIL("read() failed");
882 RETURN_VALUE("%d", bytes_read);
887 static enum sp_return get_baudrate(int fd, int *baudrate)
891 TRACE("%d, %p", fd, baudrate);
893 DEBUG("Getting baud rate");
895 if (!(data = malloc(get_termios_size())))
896 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
898 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
900 RETURN_FAIL("getting termios failed");
903 *baudrate = get_termios_speed(data);
910 static enum sp_return set_baudrate(int fd, int baudrate)
914 TRACE("%d, %d", fd, baudrate);
916 DEBUG("Getting baud rate");
918 if (!(data = malloc(get_termios_size())))
919 RETURN_ERROR(SP_ERR_MEM, "termios malloc failed");
921 if (ioctl(fd, get_termios_get_ioctl(), data) < 0) {
923 RETURN_FAIL("getting termios failed");
926 DEBUG("Setting baud rate");
928 set_termios_speed(data, baudrate);
930 if (ioctl(fd, get_termios_set_ioctl(), data) < 0) {
932 RETURN_FAIL("setting termios failed");
941 static enum sp_return get_flow(int fd, int *flow)
945 TRACE("%d, %p", fd, flow);
947 DEBUG("Getting advanced flow control");
949 if (!(data = malloc(get_termiox_size())))
950 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
952 if (ioctl(fd, TCGETX, data) < 0) {
954 RETURN_FAIL("getting termiox failed");
957 *flow = get_termiox_flow(data);
964 static enum sp_return set_flow(int fd, int flow)
968 TRACE("%d, %d", fd, flow);
970 DEBUG("Getting advanced flow control");
972 if (!(data = malloc(get_termiox_size())))
973 RETURN_ERROR(SP_ERR_MEM, "termiox malloc failed");
975 if (ioctl(fd, TCGETX, data) < 0) {
977 RETURN_FAIL("getting termiox failed");
980 DEBUG("Setting advanced flow control");
982 set_termiox_flow(data, flow);
984 if (ioctl(fd, TCSETX, data) < 0) {
986 RETURN_FAIL("setting termiox failed");
993 #endif /* USE_TERMIOX */
994 #endif /* __linux__ */
996 static enum sp_return get_config(struct sp_port *port, struct port_data *data,
997 struct sp_port_config *config)
1001 TRACE("%p, %p, %p", port, data, config);
1003 DEBUG("Getting configuration for port %s", port->name);
1006 if (!GetCommState(port->hdl, &data->dcb))
1007 RETURN_FAIL("GetCommState() failed");
1009 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1010 if (data->dcb.BaudRate == std_baudrates[i].index) {
1011 config->baudrate = std_baudrates[i].value;
1016 if (i == NUM_STD_BAUDRATES)
1017 /* BaudRate field can be either an index or a custom baud rate. */
1018 config->baudrate = data->dcb.BaudRate;
1020 config->bits = data->dcb.ByteSize;
1022 if (data->dcb.fParity)
1023 switch (data->dcb.Parity) {
1025 config->parity = SP_PARITY_NONE;
1028 config->parity = SP_PARITY_EVEN;
1031 config->parity = SP_PARITY_ODD;
1034 config->parity = -1;
1037 config->parity = SP_PARITY_NONE;
1039 switch (data->dcb.StopBits) {
1041 config->stopbits = 1;
1044 config->stopbits = 2;
1047 config->stopbits = -1;
1050 switch (data->dcb.fRtsControl) {
1051 case RTS_CONTROL_DISABLE:
1052 config->rts = SP_RTS_OFF;
1054 case RTS_CONTROL_ENABLE:
1055 config->rts = SP_RTS_ON;
1057 case RTS_CONTROL_HANDSHAKE:
1058 config->rts = SP_RTS_FLOW_CONTROL;
1064 config->cts = data->dcb.fOutxCtsFlow ? SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1066 switch (data->dcb.fDtrControl) {
1067 case DTR_CONTROL_DISABLE:
1068 config->dtr = SP_DTR_OFF;
1070 case DTR_CONTROL_ENABLE:
1071 config->dtr = SP_DTR_ON;
1073 case DTR_CONTROL_HANDSHAKE:
1074 config->dtr = SP_DTR_FLOW_CONTROL;
1080 config->dsr = data->dcb.fOutxDsrFlow ? SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1082 if (data->dcb.fInX) {
1083 if (data->dcb.fOutX)
1084 config->xon_xoff = SP_XONXOFF_INOUT;
1086 config->xon_xoff = SP_XONXOFF_IN;
1088 if (data->dcb.fOutX)
1089 config->xon_xoff = SP_XONXOFF_OUT;
1091 config->xon_xoff = SP_XONXOFF_DISABLED;
1096 if (tcgetattr(port->fd, &data->term) < 0)
1097 RETURN_FAIL("tcgetattr() failed");
1099 if (ioctl(port->fd, TIOCMGET, &data->controlbits) < 0)
1100 RETURN_FAIL("TIOCMGET ioctl failed");
1103 int ret = get_flow(port->fd, &data->flow);
1105 if (ret == SP_ERR_FAIL && errno == EINVAL)
1106 data->termiox_supported = 0;
1108 RETURN_CODEVAL(ret);
1110 data->termiox_supported = 1;
1112 data->termiox_supported = 0;
1115 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1116 if (cfgetispeed(&data->term) == std_baudrates[i].index) {
1117 config->baudrate = std_baudrates[i].value;
1122 if (i == NUM_STD_BAUDRATES) {
1124 config->baudrate = (int)data->term.c_ispeed;
1125 #elif defined(__linux__)
1126 TRY(get_baudrate(port->fd, &config->baudrate));
1128 config->baudrate = -1;
1132 switch (data->term.c_cflag & CSIZE) {
1149 if (!(data->term.c_cflag & PARENB) && (data->term.c_iflag & IGNPAR))
1150 config->parity = SP_PARITY_NONE;
1151 else if (!(data->term.c_cflag & PARENB) || (data->term.c_iflag & IGNPAR))
1152 config->parity = -1;
1154 config->parity = (data->term.c_cflag & PARODD) ? SP_PARITY_ODD : SP_PARITY_EVEN;
1156 config->stopbits = (data->term.c_cflag & CSTOPB) ? 2 : 1;
1158 if (data->term.c_cflag & CRTSCTS) {
1159 config->rts = SP_RTS_FLOW_CONTROL;
1160 config->cts = SP_CTS_FLOW_CONTROL;
1162 if (data->termiox_supported && data->flow & RTS_FLOW)
1163 config->rts = SP_RTS_FLOW_CONTROL;
1165 config->rts = (data->controlbits & TIOCM_RTS) ? SP_RTS_ON : SP_RTS_OFF;
1167 config->cts = (data->termiox_supported && data->flow & CTS_FLOW) ?
1168 SP_CTS_FLOW_CONTROL : SP_CTS_IGNORE;
1171 if (data->termiox_supported && data->flow & DTR_FLOW)
1172 config->dtr = SP_DTR_FLOW_CONTROL;
1174 config->dtr = (data->controlbits & TIOCM_DTR) ? SP_DTR_ON : SP_DTR_OFF;
1176 config->dsr = (data->termiox_supported && data->flow & DSR_FLOW) ?
1177 SP_DSR_FLOW_CONTROL : SP_DSR_IGNORE;
1179 if (data->term.c_iflag & IXOFF) {
1180 if (data->term.c_iflag & IXON)
1181 config->xon_xoff = SP_XONXOFF_INOUT;
1183 config->xon_xoff = SP_XONXOFF_IN;
1185 if (data->term.c_iflag & IXON)
1186 config->xon_xoff = SP_XONXOFF_OUT;
1188 config->xon_xoff = SP_XONXOFF_DISABLED;
1195 static enum sp_return set_config(struct sp_port *port, struct port_data *data,
1196 const struct sp_port_config *config)
1200 BAUD_TYPE baud_nonstd;
1205 int baud_nonstd = 0;
1208 TRACE("%p, %p, %p", port, data, config);
1210 DEBUG("Setting configuration for port %s", port->name);
1213 if (config->baudrate >= 0) {
1214 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1215 if (config->baudrate == std_baudrates[i].value) {
1216 data->dcb.BaudRate = std_baudrates[i].index;
1221 if (i == NUM_STD_BAUDRATES)
1222 data->dcb.BaudRate = config->baudrate;
1225 if (config->bits >= 0)
1226 data->dcb.ByteSize = config->bits;
1228 if (config->parity >= 0) {
1229 switch (config->parity) {
1230 /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
1231 case SP_PARITY_NONE:
1232 data->dcb.Parity = NOPARITY;
1234 case SP_PARITY_EVEN:
1235 data->dcb.Parity = EVENPARITY;
1238 data->dcb.Parity = ODDPARITY;
1241 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1245 if (config->stopbits >= 0) {
1246 switch (config->stopbits) {
1247 /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
1249 data->dcb.StopBits = ONESTOPBIT;
1252 data->dcb.StopBits = TWOSTOPBITS;
1255 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bit setting");
1259 if (config->rts >= 0) {
1260 switch (config->rts) {
1262 data->dcb.fRtsControl = RTS_CONTROL_DISABLE;
1265 data->dcb.fRtsControl = RTS_CONTROL_ENABLE;
1267 case SP_RTS_FLOW_CONTROL:
1268 data->dcb.fRtsControl = RTS_CONTROL_HANDSHAKE;
1271 RETURN_ERROR(SP_ERR_ARG, "Invalid RTS setting");
1275 if (config->cts >= 0) {
1276 switch (config->cts) {
1278 data->dcb.fOutxCtsFlow = FALSE;
1280 case SP_CTS_FLOW_CONTROL:
1281 data->dcb.fOutxCtsFlow = TRUE;
1284 RETURN_ERROR(SP_ERR_ARG, "Invalid CTS setting");
1288 if (config->dtr >= 0) {
1289 switch (config->dtr) {
1291 data->dcb.fDtrControl = DTR_CONTROL_DISABLE;
1294 data->dcb.fDtrControl = DTR_CONTROL_ENABLE;
1296 case SP_DTR_FLOW_CONTROL:
1297 data->dcb.fDtrControl = DTR_CONTROL_HANDSHAKE;
1300 RETURN_ERROR(SP_ERR_ARG, "Invalid DTR setting");
1304 if (config->dsr >= 0) {
1305 switch (config->dsr) {
1307 data->dcb.fOutxDsrFlow = FALSE;
1309 case SP_DSR_FLOW_CONTROL:
1310 data->dcb.fOutxDsrFlow = TRUE;
1313 RETURN_ERROR(SP_ERR_ARG, "Invalid DSR setting");
1317 if (config->xon_xoff >= 0) {
1318 switch (config->xon_xoff) {
1319 case SP_XONXOFF_DISABLED:
1320 data->dcb.fInX = FALSE;
1321 data->dcb.fOutX = FALSE;
1324 data->dcb.fInX = TRUE;
1325 data->dcb.fOutX = FALSE;
1327 case SP_XONXOFF_OUT:
1328 data->dcb.fInX = FALSE;
1329 data->dcb.fOutX = TRUE;
1331 case SP_XONXOFF_INOUT:
1332 data->dcb.fInX = TRUE;
1333 data->dcb.fOutX = TRUE;
1336 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1340 if (!SetCommState(port->hdl, &data->dcb))
1341 RETURN_FAIL("SetCommState() failed");
1347 if (config->baudrate >= 0) {
1348 for (i = 0; i < NUM_STD_BAUDRATES; i++) {
1349 if (config->baudrate == std_baudrates[i].value) {
1350 if (cfsetospeed(&data->term, std_baudrates[i].index) < 0)
1351 RETURN_FAIL("cfsetospeed() failed");
1353 if (cfsetispeed(&data->term, std_baudrates[i].index) < 0)
1354 RETURN_FAIL("cfsetispeed() failed");
1359 /* Non-standard baud rate */
1360 if (i == NUM_STD_BAUDRATES) {
1362 /* Set "dummy" baud rate. */
1363 if (cfsetspeed(&data->term, B9600) < 0)
1364 RETURN_FAIL("cfsetspeed() failed");
1365 baud_nonstd = config->baudrate;
1366 #elif defined(__linux__)
1369 RETURN_ERROR(SP_ERR_SUPP, "Non-standard baudrate not supported");
1374 if (config->bits >= 0) {
1375 data->term.c_cflag &= ~CSIZE;
1376 switch (config->bits) {
1378 data->term.c_cflag |= CS8;
1381 data->term.c_cflag |= CS7;
1384 data->term.c_cflag |= CS6;
1387 data->term.c_cflag |= CS5;
1390 RETURN_ERROR(SP_ERR_ARG, "Invalid data bits setting");
1394 if (config->parity >= 0) {
1395 data->term.c_iflag &= ~IGNPAR;
1396 data->term.c_cflag &= ~(PARENB | PARODD);
1397 switch (config->parity) {
1398 case SP_PARITY_NONE:
1399 data->term.c_iflag |= IGNPAR;
1401 case SP_PARITY_EVEN:
1402 data->term.c_cflag |= PARENB;
1405 data->term.c_cflag |= PARENB | PARODD;
1408 RETURN_ERROR(SP_ERR_ARG, "Invalid parity setting");
1412 if (config->stopbits >= 0) {
1413 data->term.c_cflag &= ~CSTOPB;
1414 switch (config->stopbits) {
1416 data->term.c_cflag &= ~CSTOPB;
1419 data->term.c_cflag |= CSTOPB;
1422 RETURN_ERROR(SP_ERR_ARG, "Invalid stop bits setting");
1426 if (config->rts >= 0 || config->cts >= 0) {
1427 if (data->termiox_supported) {
1428 data->flow &= ~(RTS_FLOW | CTS_FLOW);
1429 switch (config->rts) {
1432 controlbits = TIOCM_RTS;
1433 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1434 RETURN_FAIL("Setting RTS signal level failed");
1436 case SP_RTS_FLOW_CONTROL:
1437 data->flow |= RTS_FLOW;
1442 if (config->cts == SP_CTS_FLOW_CONTROL)
1443 data->flow |= CTS_FLOW;
1445 if (data->flow & (RTS_FLOW | CTS_FLOW))
1446 data->term.c_iflag |= CRTSCTS;
1448 data->term.c_iflag &= ~CRTSCTS;
1450 /* Asymmetric use of RTS/CTS not supported. */
1451 if (data->term.c_iflag & CRTSCTS) {
1452 /* Flow control can only be disabled for both RTS & CTS together. */
1453 if (config->rts >= 0 && config->rts != SP_RTS_FLOW_CONTROL) {
1454 if (config->cts != SP_CTS_IGNORE)
1455 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1457 if (config->cts >= 0 && config->cts != SP_CTS_FLOW_CONTROL) {
1458 if (config->rts <= 0 || config->rts == SP_RTS_FLOW_CONTROL)
1459 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be disabled together");
1462 /* Flow control can only be enabled for both RTS & CTS together. */
1463 if (((config->rts == SP_RTS_FLOW_CONTROL) && (config->cts != SP_CTS_FLOW_CONTROL)) ||
1464 ((config->cts == SP_CTS_FLOW_CONTROL) && (config->rts != SP_RTS_FLOW_CONTROL)))
1465 RETURN_ERROR(SP_ERR_SUPP, "RTS & CTS flow control must be enabled together");
1468 if (config->rts >= 0) {
1469 if (config->rts == SP_RTS_FLOW_CONTROL) {
1470 data->term.c_iflag |= CRTSCTS;
1472 controlbits = TIOCM_RTS;
1473 if (ioctl(port->fd, config->rts == SP_RTS_ON ? TIOCMBIS : TIOCMBIC,
1475 RETURN_FAIL("Setting RTS signal level failed");
1481 if (config->dtr >= 0 || config->dsr >= 0) {
1482 if (data->termiox_supported) {
1483 data->flow &= ~(DTR_FLOW | DSR_FLOW);
1484 switch (config->dtr) {
1487 controlbits = TIOCM_DTR;
1488 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC, &controlbits) < 0)
1489 RETURN_FAIL("Setting DTR signal level failed");
1491 case SP_DTR_FLOW_CONTROL:
1492 data->flow |= DTR_FLOW;
1497 if (config->dsr == SP_DSR_FLOW_CONTROL)
1498 data->flow |= DSR_FLOW;
1500 /* DTR/DSR flow control not supported. */
1501 if (config->dtr == SP_DTR_FLOW_CONTROL || config->dsr == SP_DSR_FLOW_CONTROL)
1502 RETURN_ERROR(SP_ERR_SUPP, "DTR/DSR flow control not supported");
1504 if (config->dtr >= 0) {
1505 controlbits = TIOCM_DTR;
1506 if (ioctl(port->fd, config->dtr == SP_DTR_ON ? TIOCMBIS : TIOCMBIC,
1508 RETURN_FAIL("Setting DTR signal level failed");
1513 if (config->xon_xoff >= 0) {
1514 data->term.c_iflag &= ~(IXON | IXOFF | IXANY);
1515 switch (config->xon_xoff) {
1516 case SP_XONXOFF_DISABLED:
1519 data->term.c_iflag |= IXOFF;
1521 case SP_XONXOFF_OUT:
1522 data->term.c_iflag |= IXON | IXANY;
1524 case SP_XONXOFF_INOUT:
1525 data->term.c_iflag |= IXON | IXOFF | IXANY;
1528 RETURN_ERROR(SP_ERR_ARG, "Invalid XON/XOFF setting");
1532 if (tcsetattr(port->fd, TCSADRAIN, &data->term) < 0)
1533 RETURN_FAIL("tcsetattr() failed");
1536 if (baud_nonstd != B0) {
1537 if (ioctl(port->fd, IOSSIOSPEED, &baud_nonstd) == -1)
1538 RETURN_FAIL("IOSSIOSPEED ioctl failed");
1539 /* Set baud rates in data->term to correct, but incompatible
1540 * with tcsetattr() value, same as delivered by tcgetattr(). */
1541 if (cfsetspeed(&data->term, baud_nonstd) < 0)
1542 RETURN_FAIL("cfsetspeed() failed");
1544 #elif defined(__linux__)
1546 TRY(set_baudrate(port->fd, config->baudrate));
1548 if (data->termiox_supported)
1549 TRY(set_flow(port->fd, data->flow));
1553 #endif /* !_WIN32 */
1558 enum sp_return sp_new_config(struct sp_port_config **config_ptr)
1560 TRACE("%p", config_ptr);
1561 struct sp_port_config *config;
1564 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
1568 if (!(config = malloc(sizeof(struct sp_port_config))))
1569 RETURN_ERROR(SP_ERR_MEM, "config malloc failed");
1571 config->baudrate = -1;
1573 config->parity = -1;
1574 config->stopbits = -1;
1580 *config_ptr = config;
1585 void sp_free_config(struct sp_port_config *config)
1587 TRACE("%p", config);
1590 DEBUG("Null config");
1597 enum sp_return sp_get_config(struct sp_port *port, struct sp_port_config *config)
1599 struct port_data data;
1601 TRACE("%p, %p", port, config);
1606 RETURN_ERROR(SP_ERR_ARG, "Null config");
1608 TRY(get_config(port, &data, config));
1613 enum sp_return sp_set_config(struct sp_port *port, const struct sp_port_config *config)
1615 struct port_data data;
1616 struct sp_port_config prev_config;
1618 TRACE("%p, %p", port, config);
1623 RETURN_ERROR(SP_ERR_ARG, "Null config");
1625 TRY(get_config(port, &data, &prev_config));
1626 TRY(set_config(port, &data, config));
1631 #define CREATE_ACCESSORS(x, type) \
1632 enum sp_return sp_set_##x(struct sp_port *port, type x) { \
1633 struct port_data data; \
1634 struct sp_port_config config; \
1635 TRACE("%p, %d", port, x); \
1636 CHECK_OPEN_PORT(); \
1637 TRY(get_config(port, &data, &config)); \
1639 TRY(set_config(port, &data, &config)); \
1642 enum sp_return sp_get_config_##x(const struct sp_port_config *config, type *x) { \
1643 TRACE("%p", config); \
1645 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
1649 enum sp_return sp_set_config_##x(struct sp_port_config *config, type x) { \
1650 TRACE("%p, %d", config, x); \
1652 RETURN_ERROR(SP_ERR_ARG, "Null config"); \
1657 CREATE_ACCESSORS(baudrate, int)
1658 CREATE_ACCESSORS(bits, int)
1659 CREATE_ACCESSORS(parity, enum sp_parity)
1660 CREATE_ACCESSORS(stopbits, int)
1661 CREATE_ACCESSORS(rts, enum sp_rts)
1662 CREATE_ACCESSORS(cts, enum sp_cts)
1663 CREATE_ACCESSORS(dtr, enum sp_dtr)
1664 CREATE_ACCESSORS(dsr, enum sp_dsr)
1665 CREATE_ACCESSORS(xon_xoff, enum sp_xonxoff)
1667 enum sp_return sp_set_config_flowcontrol(struct sp_port_config *config, enum sp_flowcontrol flowcontrol)
1670 RETURN_ERROR(SP_ERR_ARG, "Null configuration");
1672 if (flowcontrol > SP_FLOWCONTROL_DTRDSR)
1673 RETURN_ERROR(SP_ERR_ARG, "Invalid flow control setting");
1675 if (flowcontrol == SP_FLOWCONTROL_XONXOFF)
1676 config->xon_xoff = SP_XONXOFF_INOUT;
1678 config->xon_xoff = SP_XONXOFF_DISABLED;
1680 if (flowcontrol == SP_FLOWCONTROL_RTSCTS) {
1681 config->rts = SP_RTS_FLOW_CONTROL;
1682 config->cts = SP_CTS_FLOW_CONTROL;
1684 if (config->rts == SP_RTS_FLOW_CONTROL)
1685 config->rts = SP_RTS_ON;
1686 config->cts = SP_CTS_IGNORE;
1689 if (flowcontrol == SP_FLOWCONTROL_DTRDSR) {
1690 config->dtr = SP_DTR_FLOW_CONTROL;
1691 config->dsr = SP_DSR_FLOW_CONTROL;
1693 if (config->dtr == SP_DTR_FLOW_CONTROL)
1694 config->dtr = SP_DTR_ON;
1695 config->dsr = SP_DSR_IGNORE;
1701 enum sp_return sp_set_flowcontrol(struct sp_port *port, enum sp_flowcontrol flowcontrol)
1703 struct port_data data;
1704 struct sp_port_config config;
1706 TRACE("%p, %d", port, flowcontrol);
1710 TRY(get_config(port, &data, &config));
1712 TRY(sp_set_config_flowcontrol(&config, flowcontrol));
1714 TRY(set_config(port, &data, &config));
1719 enum sp_return sp_get_signals(struct sp_port *port, enum sp_signal *signals)
1721 TRACE("%p, %p", port, signals);
1726 RETURN_ERROR(SP_ERR_ARG, "Null result pointer");
1728 DEBUG("Getting control signals for port %s", port->name);
1733 if (GetCommModemStatus(port->hdl, &bits) == 0)
1734 RETURN_FAIL("GetCommModemStatus() failed");
1735 if (bits & MS_CTS_ON)
1736 *signals |= SP_SIG_CTS;
1737 if (bits & MS_DSR_ON)
1738 *signals |= SP_SIG_DSR;
1739 if (bits & MS_RLSD_ON)
1740 *signals |= SP_SIG_DCD;
1741 if (bits & MS_RING_ON)
1742 *signals |= SP_SIG_RI;
1745 if (ioctl(port->fd, TIOCMGET, &bits) < 0)
1746 RETURN_FAIL("TIOCMGET ioctl failed");
1747 if (bits & TIOCM_CTS)
1748 *signals |= SP_SIG_CTS;
1749 if (bits & TIOCM_DSR)
1750 *signals |= SP_SIG_DSR;
1751 if (bits & TIOCM_CAR)
1752 *signals |= SP_SIG_DCD;
1753 if (bits & TIOCM_RNG)
1754 *signals |= SP_SIG_RI;
1759 enum sp_return sp_start_break(struct sp_port *port)
1765 if (SetCommBreak(port->hdl) == 0)
1766 RETURN_FAIL("SetCommBreak() failed");
1768 if (ioctl(port->fd, TIOCSBRK, 1) < 0)
1769 RETURN_FAIL("TIOCSBRK ioctl failed");
1775 enum sp_return sp_end_break(struct sp_port *port)
1781 if (ClearCommBreak(port->hdl) == 0)
1782 RETURN_FAIL("ClearCommBreak() failed");
1784 if (ioctl(port->fd, TIOCCBRK, 1) < 0)
1785 RETURN_FAIL("TIOCCBRK ioctl failed");
1791 int sp_last_error_code(void)
1795 RETURN_VALUE("%d", GetLastError());
1797 RETURN_VALUE("%d", errno);
1801 char *sp_last_error_message(void)
1807 DWORD error = GetLastError();
1810 FORMAT_MESSAGE_ALLOCATE_BUFFER |
1811 FORMAT_MESSAGE_FROM_SYSTEM |
1812 FORMAT_MESSAGE_IGNORE_INSERTS,
1815 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
1819 RETURN_VALUE("%s", message);
1821 RETURN_VALUE("%s", strerror(errno));
1825 void sp_free_error_message(char *message)
1827 TRACE("%s", message);
1838 void sp_set_debug_handler(void (*handler)(const char *format, ...))
1840 TRACE("%p", handler);
1842 sp_debug_handler = handler;
1847 void sp_default_debug_handler(const char *format, ...)
1850 va_start(args, format);
1851 if (getenv("LIBSERIALPORT_DEBUG")) {
1852 fputs("libserialport: ", stderr);
1853 vfprintf(stderr, format, args);