]> sigrok.org Git - libserialport.git/blame - serialport.c
Update documentation.
[libserialport.git] / serialport.c
CommitLineData
74510d4b
ML
1/*
2 * This file is part of the libserialport project.
3 *
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 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Lesser General Public License as
10 * published by the Free Software Foundation, either version 3 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
22#include <string.h>
23#include <sys/types.h>
24#include <sys/stat.h>
25#include <fcntl.h>
26#include <unistd.h>
3b63f34d
ML
27#include <stdlib.h>
28#include <errno.h>
74510d4b
ML
29#ifdef _WIN32
30#include <windows.h>
3b63f34d 31#include <tchar.h>
74510d4b 32#else
74510d4b
ML
33#include <termios.h>
34#include <sys/ioctl.h>
35#endif
3b63f34d 36#ifdef __APPLE__
1ebf4347
ML
37#include <IOKit/IOKitLib.h>
38#include <IOKit/serial/IOSerialKeys.h>
39#include <sys/syslimits.h>
3b63f34d
ML
40#endif
41#ifdef __linux__
42#include "libudev.h"
4b97c9fc 43#include "linux/serial.h"
3b63f34d 44#endif
74510d4b
ML
45
46#include "serialport.h"
47
77f262c4 48int sp_get_port_by_name(const char *portname, struct sp_port **port_ptr)
d54e9004
ML
49{
50 struct sp_port *port;
5919c913 51 int len;
d54e9004 52
77f262c4
ML
53 *port_ptr = NULL;
54
d4babed2 55 if (!portname)
77f262c4 56 return SP_ERR_ARG;
d4babed2 57
d54e9004 58 if (!(port = malloc(sizeof(struct sp_port))))
77f262c4 59 return SP_ERR_MEM;
d54e9004 60
5919c913
ML
61 len = strlen(portname) + 1;
62
d54e9004
ML
63 if (!(port->name = malloc(len)))
64 {
65 free(port);
77f262c4 66 return SP_ERR_MEM;
d54e9004
ML
67 }
68
69 memcpy(port->name, portname, len);
70
77f262c4
ML
71 *port_ptr = port;
72
73 return SP_OK;
d54e9004
ML
74}
75
e3b2f7a4
ML
76void sp_free_port(struct sp_port *port)
77{
78 if (!port)
79 return;
80
81 if (port->name)
82 free(port->name);
83
84 free(port);
85}
86
5919c913 87static struct sp_port **sp_list_append(struct sp_port **list, const char *portname)
3b63f34d
ML
88{
89 void *tmp;
90 unsigned int count;
91 for (count = 0; list[count]; count++);
d54e9004 92 if (!(tmp = realloc(list, sizeof(struct sp_port *) * (count + 2))))
3b63f34d
ML
93 goto fail;
94 list = tmp;
77f262c4 95 if (sp_get_port_by_name(portname, &list[count]) != SP_OK)
3b63f34d 96 goto fail;
db2794ce 97 list[count + 1] = NULL;
3b63f34d
ML
98 return list;
99fail:
100 sp_free_port_list(list);
101 return NULL;
102}
103
68ab64cc
ML
104/**
105 * List the serial ports available on the system.
106 *
107 * @return A null-terminated array of port name strings.
108 */
77f262c4 109int sp_list_ports(struct sp_port ***list_ptr)
3b63f34d 110{
d54e9004 111 struct sp_port **list;
77f262c4 112 int ret = SP_OK;
24c1a4bb 113
d54e9004 114 if (!(list = malloc(sizeof(struct sp_port **))))
77f262c4 115 return SP_ERR_MEM;;
24c1a4bb
ML
116
117 list[0] = NULL;
3b63f34d
ML
118
119#ifdef _WIN32
120 HKEY key;
bdfb5b8c
ML
121 TCHAR *value, *data;
122 DWORD max_value_len, max_data_size, max_data_len;
123 DWORD value_len, data_size, data_len;
3b63f34d 124 DWORD type, index = 0;
8b532d9c
ML
125 char *name;
126 int name_len;
3b63f34d
ML
127
128 if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("HARDWARE\\DEVICEMAP\\SERIALCOMM"),
129 0, KEY_QUERY_VALUE, &key) != ERROR_SUCCESS)
77f262c4
ML
130 {
131 ret = SP_ERR_FAIL;
132 goto out_done;
133 }
3b63f34d 134 if (RegQueryInfoKey(key, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
bdfb5b8c 135 &max_value_len, &max_data_size, NULL, NULL) != ERROR_SUCCESS)
77f262c4
ML
136 {
137 ret = SP_ERR_FAIL;
3b63f34d 138 goto out_close;
77f262c4 139 }
3b63f34d 140 max_data_len = max_data_size / sizeof(TCHAR);
bdfb5b8c 141 if (!(value = malloc((max_value_len + 1) * sizeof(TCHAR))))
77f262c4
ML
142 {
143 ret = SP_ERR_MEM;
3b63f34d 144 goto out_close;
77f262c4 145 }
3b63f34d 146 if (!(data = malloc((max_data_len + 1) * sizeof(TCHAR))))
77f262c4
ML
147 {
148 ret = SP_ERR_MEM;
bdfb5b8c 149 goto out_free_value;
77f262c4 150 }
3b63f34d 151 while (
bdfb5b8c 152 value_len = max_value_len,
3b63f34d 153 data_size = max_data_size,
bdfb5b8c 154 RegEnumValue(key, index, value, &value_len,
3b63f34d
ML
155 NULL, &type, (LPBYTE)data, &data_size) == ERROR_SUCCESS)
156 {
157 data_len = data_size / sizeof(TCHAR);
158 data[data_len] = '\0';
8b532d9c
ML
159#ifdef UNICODE
160 name_len = WideCharToMultiByte(CP_ACP, 0, data, -1, NULL, 0, NULL, NULL)
161#else
162 name_len = data_len + 1;
163#endif
164 if (!(name = malloc(name_len)))
77f262c4
ML
165 {
166 ret = SP_ERR_MEM;
8b532d9c 167 goto out;
77f262c4 168 }
8b532d9c
ML
169#ifdef UNICODE
170 WideCharToMultiByte(CP_ACP, 0, data, -1, name, name_len, NULL, NULL);
171#else
172 strcpy(name, data);
173#endif
77f262c4
ML
174 if (type == REG_SZ && !(list = sp_list_append(list, name)))
175 {
176 ret = SP_ERR_MEM;
177 goto out;
178 }
3b63f34d
ML
179 index++;
180 }
181out:
182 free(data);
bdfb5b8c
ML
183out_free_value:
184 free(value);
3b63f34d
ML
185out_close:
186 RegCloseKey(key);
77f262c4 187out_done:
3b63f34d
ML
188#endif
189#ifdef __APPLE__
190 mach_port_t master;
191 CFMutableDictionaryRef classes;
192 io_iterator_t iter;
193 char *path;
194 io_object_t port;
195 CFTypeRef cf_path;
196 Boolean result;
197
198 if (IOMasterPort(MACH_PORT_NULL, &master) != KERN_SUCCESS)
77f262c4
ML
199 {
200 ret = SP_ERR_FAIL;
201 goto out_done;
202 }
3b63f34d
ML
203
204 if (!(classes = IOServiceMatching(kIOSerialBSDServiceValue)))
77f262c4
ML
205 {
206 ret = SP_ERR_FAIL;
207 goto out_done;
208 }
3b63f34d
ML
209
210 CFDictionarySetValue(classes,
211 CFSTR(kIOSerialBSDTypeKey), CFSTR(kIOSerialBSDAllTypes));
212
213 if (!(IOServiceGetMatchingServices(master, classes, &iter)))
77f262c4
ML
214 {
215 ret = SP_ERR_FAIL;
216 goto out_done;
217 }
3b63f34d
ML
218
219 if (!(path = malloc(PATH_MAX)))
77f262c4
ML
220 {
221 ret = SP_ERR_MEM;
3b63f34d 222 goto out_release;
77f262c4 223 }
3b63f34d 224
1ebf4347 225 while ((port = IOIteratorNext(iter))) {
3b63f34d
ML
226 cf_path = IORegistryEntryCreateCFProperty(port,
227 CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0);
228 if (cf_path) {
229 result = CFStringGetCString(cf_path,
230 path, PATH_MAX, kCFStringEncodingASCII);
231 CFRelease(cf_path);
77f262c4
ML
232 if (result && !(list = sp_list_append(list, path)))
233 {
234 ret = SP_ERR_MEM;
235 IOObjectRelease(port);
236 goto out;
237 }
3b63f34d
ML
238 }
239 IOObjectRelease(port);
240 }
3b63f34d
ML
241out:
242 free(path);
243out_release:
244 IOObjectRelease(iter);
77f262c4 245out_done:
3b63f34d
ML
246#endif
247#ifdef __linux__
248 struct udev *ud;
249 struct udev_enumerate *ud_enumerate;
250 struct udev_list_entry *ud_list;
251 struct udev_list_entry *ud_entry;
252 const char *path;
08fe0bdb 253 struct udev_device *ud_dev, *ud_parent;
3b63f34d 254 const char *name;
4b97c9fc
ML
255 const char *driver;
256 int fd, ioctl_result;
257 struct serial_struct serial_info;
3b63f34d
ML
258
259 ud = udev_new();
260 ud_enumerate = udev_enumerate_new(ud);
261 udev_enumerate_add_match_subsystem(ud_enumerate, "tty");
262 udev_enumerate_scan_devices(ud_enumerate);
263 ud_list = udev_enumerate_get_list_entry(ud_enumerate);
3b63f34d
ML
264 udev_list_entry_foreach(ud_entry, ud_list)
265 {
266 path = udev_list_entry_get_name(ud_entry);
267 ud_dev = udev_device_new_from_syspath(ud, path);
08fe0bdb
ML
268 /* If there is no parent device, this is a virtual tty. */
269 ud_parent = udev_device_get_parent(ud_dev);
270 if (ud_parent == NULL)
271 {
272 udev_device_unref(ud_dev);
273 continue;
274 }
3b63f34d 275 name = udev_device_get_devnode(ud_dev);
4b97c9fc
ML
276 /* The serial8250 driver has a hardcoded number of ports.
277 * The only way to tell which actually exist on a given system
278 * is to try to open them and make an ioctl call. */
279 driver = udev_device_get_driver(ud_parent);
280 if (driver && !strcmp(driver, "serial8250"))
281 {
282 if ((fd = open(name, O_RDWR | O_NONBLOCK | O_NOCTTY)) < 0)
283 goto skip;
284 ioctl_result = ioctl(fd, TIOCGSERIAL, &serial_info);
285 close(fd);
286 if (ioctl_result != 0)
287 goto skip;
288 if (serial_info.type == PORT_UNKNOWN)
289 goto skip;
290 }
5919c913 291 list = sp_list_append(list, name);
4b97c9fc 292skip:
3b63f34d
ML
293 udev_device_unref(ud_dev);
294 if (!list)
77f262c4
ML
295 {
296 ret = SP_ERR_MEM;
3b63f34d 297 goto out;
77f262c4 298 }
3b63f34d
ML
299 }
300out:
301 udev_enumerate_unref(ud_enumerate);
302 udev_unref(ud);
3b63f34d 303#endif
77f262c4
ML
304
305 if (ret == SP_OK)
306 {
307 *list_ptr = list;
308 }
309 else
310 {
311 if (list)
312 sp_free_port_list(list);
313
314 *list_ptr = NULL;
315 }
316
317 return ret;
3b63f34d
ML
318}
319
68ab64cc
ML
320/**
321 * Free a port list returned by sp_list_ports.
322 */
d54e9004 323void sp_free_port_list(struct sp_port **list)
3b63f34d
ML
324{
325 unsigned int i;
326 for (i = 0; list[i]; i++)
e3b2f7a4 327 sp_free_port(list[i]);
3b63f34d
ML
328 free(list);
329}
330
74510d4b
ML
331static int sp_validate_port(struct sp_port *port)
332{
333 if (port == NULL)
334 return 0;
335#ifdef _WIN32
336 if (port->hdl == INVALID_HANDLE_VALUE)
337 return 0;
338#else
339 if (port->fd < 0)
340 return 0;
341#endif
342 return 1;
343}
344
345#define CHECK_PORT() do { if (!sp_validate_port(port)) return SP_ERR_ARG; } while (0)
346
347/**
348 * Open the specified serial port.
349 *
350 * @param port Pointer to empty port structure allocated by caller.
351 * @param portname Name of port to open.
352 * @param flags Flags to use when opening the serial port. Possible flags
353 * are: SP_MODE_RDWR, SP_MODE_RDONLY, SP_MODE_NONBLOCK.
354 *
355 * @return SP_OK on success, SP_ERR_FAIL on failure,
356 * or SP_ERR_ARG if an invalid port or name is passed.
357 */
d54e9004 358int sp_open(struct sp_port *port, int flags)
74510d4b
ML
359{
360 if (!port)
361 return SP_ERR_ARG;
362
74510d4b
ML
363#ifdef _WIN32
364 DWORD desired_access = 0, flags_and_attributes = 0;
365 /* Map 'flags' to the OS-specific settings. */
366 desired_access |= GENERIC_READ;
367 flags_and_attributes = FILE_ATTRIBUTE_NORMAL;
368 if (flags & SP_MODE_RDWR)
369 desired_access |= GENERIC_WRITE;
370 if (flags & SP_MODE_NONBLOCK)
371 flags_and_attributes |= FILE_FLAG_OVERLAPPED;
372
373 port->hdl = CreateFile(port->name, desired_access, 0, 0,
374 OPEN_EXISTING, flags_and_attributes, 0);
375 if (port->hdl == INVALID_HANDLE_VALUE)
376 return SP_ERR_FAIL;
377#else
378 int flags_local = 0;
379 /* Map 'flags' to the OS-specific settings. */
380 if (flags & SP_MODE_RDWR)
381 flags_local |= O_RDWR;
382 if (flags & SP_MODE_RDONLY)
383 flags_local |= O_RDONLY;
384 if (flags & SP_MODE_NONBLOCK)
385 flags_local |= O_NONBLOCK;
386
387 if ((port->fd = open(port->name, flags_local)) < 0)
388 return SP_ERR_FAIL;
389#endif
390
391 return SP_OK;
392}
393
394/**
395 * Close the specified serial port.
396 *
397 * @param port Pointer to port structure.
398 *
399 * @return SP_OK on success, SP_ERR_FAIL on failure,
400 * or SP_ERR_ARG if an invalid port is passed.
401 */
402int sp_close(struct sp_port *port)
403{
404 CHECK_PORT();
405
406#ifdef _WIN32
407 /* Returns non-zero upon success, 0 upon failure. */
408 if (CloseHandle(port->hdl) == 0)
409 return SP_ERR_FAIL;
410#else
411 /* Returns 0 upon success, -1 upon failure. */
412 if (close(port->fd) == -1)
413 return SP_ERR_FAIL;
414#endif
415
416 return SP_OK;
417}
418
419/**
420 * Flush serial port buffers.
421 *
422 * @param port Pointer to port structure.
423 *
424 * @return SP_OK on success, SP_ERR_FAIL on failure,
425 * or SP_ERR_ARG if an invalid port is passed.
426 */
427int sp_flush(struct sp_port *port)
428{
429 CHECK_PORT();
430
431#ifdef _WIN32
432 /* Returns non-zero upon success, 0 upon failure. */
433 if (PurgeComm(port->hdl, PURGE_RXCLEAR | PURGE_TXCLEAR) == 0)
434 return SP_ERR_FAIL;
435#else
436 /* Returns 0 upon success, -1 upon failure. */
437 if (tcflush(port->fd, TCIOFLUSH) < 0)
438 return SP_ERR_FAIL;
439#endif
440 return SP_OK;
441}
442
443/**
444 * Write a number of bytes to the specified serial port.
445 *
446 * @param port Pointer to port structure.
447 * @param buf Buffer containing the bytes to write.
448 * @param count Number of bytes to write.
449 *
450 * @return The number of bytes written, SP_ERR_FAIL on failure,
451 * or SP_ERR_ARG if an invalid port is passed.
452 */
453int sp_write(struct sp_port *port, const void *buf, size_t count)
454{
455 CHECK_PORT();
456
457 if (!buf)
458 return SP_ERR_ARG;
459
460#ifdef _WIN32
461 DWORD written = 0;
462 /* Returns non-zero upon success, 0 upon failure. */
463 if (WriteFile(port->hdl, buf, count, &written, NULL) == 0)
464 return SP_ERR_FAIL;
465 return written;
466#else
467 /* Returns the number of bytes written, or -1 upon failure. */
468 ssize_t written = write(port->fd, buf, count);
469 if (written < 0)
470 return SP_ERR_FAIL;
471 else
472 return written;;
473#endif
474}
475
476/**
477 * Read a number of bytes from the specified serial port.
478 *
479 * @param port Pointer to port structure.
480 * @param buf Buffer where to store the bytes that are read.
481 * @param count The number of bytes to read.
482 *
483 * @return The number of bytes read, SP_ERR_FAIL on failure,
484 * or SP_ERR_ARG if an invalid port is passed.
485 */
486int sp_read(struct sp_port *port, void *buf, size_t count)
487{
488 CHECK_PORT();
489
490 if (!buf)
491 return SP_ERR_ARG;
492
493#ifdef _WIN32
494 DWORD bytes_read = 0;
495 /* Returns non-zero upon success, 0 upon failure. */
496 if (ReadFile(port->hdl, buf, count, &bytes_read, NULL) == 0)
497 return SP_ERR_FAIL;
498 return bytes_read;
499#else
500 ssize_t bytes_read;
501 /* Returns the number of bytes read, or -1 upon failure. */
502 if ((bytes_read = read(port->fd, buf, count)) < 0)
503 return SP_ERR_FAIL;
504 return bytes_read;
505#endif
506}
507
508/**
509 * Set serial parameters for the specified serial port.
510 *
511 * @param port Pointer to port structure.
512 * @param baudrate The baudrate to set.
513 * @param bits The number of data bits to use.
514 * @param parity The parity setting to use (0 = none, 1 = even, 2 = odd).
515 * @param stopbits The number of stop bits to use (1 or 2).
516 * @param flowcontrol The flow control settings to use (0 = none, 1 = RTS/CTS,
517 * 2 = XON/XOFF).
518 *
519 * @return The number of bytes read, SP_ERR_FAIL on failure,
520 * or SP_ERR_ARG if an invalid argument is passed.
521 */
522int sp_set_params(struct sp_port *port, int baudrate,
523 int bits, int parity, int stopbits,
524 int flowcontrol, int rts, int dtr)
525{
526 CHECK_PORT();
527
528#ifdef _WIN32
529 DCB dcb;
530
531 if (!GetCommState(port->hdl, &dcb))
532 return SP_ERR_FAIL;
533
534 switch (baudrate) {
535 /*
536 * The baudrates 50/75/134/150/200/1800/230400/460800 do not seem to
537 * have documented CBR_* macros.
538 */
539 case 110:
540 dcb.BaudRate = CBR_110;
541 break;
542 case 300:
543 dcb.BaudRate = CBR_300;
544 break;
545 case 600:
546 dcb.BaudRate = CBR_600;
547 break;
548 case 1200:
549 dcb.BaudRate = CBR_1200;
550 break;
551 case 2400:
552 dcb.BaudRate = CBR_2400;
553 break;
554 case 4800:
555 dcb.BaudRate = CBR_4800;
556 break;
557 case 9600:
558 dcb.BaudRate = CBR_9600;
559 break;
560 case 14400:
561 dcb.BaudRate = CBR_14400; /* Not available on Unix? */
562 break;
563 case 19200:
564 dcb.BaudRate = CBR_19200;
565 break;
566 case 38400:
567 dcb.BaudRate = CBR_38400;
568 break;
569 case 57600:
570 dcb.BaudRate = CBR_57600;
571 break;
572 case 115200:
573 dcb.BaudRate = CBR_115200;
574 break;
575 case 128000:
576 dcb.BaudRate = CBR_128000; /* Not available on Unix? */
577 break;
578 case 256000:
579 dcb.BaudRate = CBR_256000; /* Not available on Unix? */
580 break;
581 default:
582 return SP_ERR_ARG;
583 }
584
585 switch (stopbits) {
586 /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
587 case 1:
588 dcb.StopBits = ONESTOPBIT;
589 break;
590 case 2:
591 dcb.StopBits = TWOSTOPBITS;
592 break;
593 default:
594 return SP_ERR_ARG;
595 }
596
597 switch (parity) {
598 /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
599 case SP_PARITY_NONE:
600 dcb.Parity = NOPARITY;
601 break;
602 case SP_PARITY_EVEN:
603 dcb.Parity = EVENPARITY;
604 break;
605 case SP_PARITY_ODD:
606 dcb.Parity = ODDPARITY;
607 break;
608 default:
609 return SP_ERR_ARG;
610 }
611
612 if (rts != -1) {
613 if (rts)
614 dcb.fRtsControl = RTS_CONTROL_ENABLE;
615 else
616 dcb.fRtsControl = RTS_CONTROL_DISABLE;
617 }
618
619 if (dtr != -1) {
620 if (dtr)
621 dcb.fDtrControl = DTR_CONTROL_ENABLE;
622 else
623 dcb.fDtrControl = DTR_CONTROL_DISABLE;
624 }
625
626 if (!SetCommState(port->hdl, &dcb))
627 return SP_ERR_FAIL;
628#else
629 struct termios term;
630 speed_t baud;
631 int controlbits;
632
633 if (tcgetattr(port->fd, &term) < 0)
634 return SP_ERR_FAIL;
635
636 switch (baudrate) {
637 case 50:
638 baud = B50;
639 break;
640 case 75:
641 baud = B75;
642 break;
643 case 110:
644 baud = B110;
645 break;
646 case 134:
647 baud = B134;
648 break;
649 case 150:
650 baud = B150;
651 break;
652 case 200:
653 baud = B200;
654 break;
655 case 300:
656 baud = B300;
657 break;
658 case 600:
659 baud = B600;
660 break;
661 case 1200:
662 baud = B1200;
663 break;
664 case 1800:
665 baud = B1800;
666 break;
667 case 2400:
668 baud = B2400;
669 break;
670 case 4800:
671 baud = B4800;
672 break;
673 case 9600:
674 baud = B9600;
675 break;
676 case 19200:
677 baud = B19200;
678 break;
679 case 38400:
680 baud = B38400;
681 break;
682 case 57600:
683 baud = B57600;
684 break;
685 case 115200:
686 baud = B115200;
687 break;
688 case 230400:
689 baud = B230400;
690 break;
691#if !defined(__APPLE__) && !defined(__OpenBSD__)
692 case 460800:
693 baud = B460800;
694 break;
695#endif
696 default:
697 return SP_ERR_ARG;
698 }
699
700 if (cfsetospeed(&term, baud) < 0)
701 return SP_ERR_FAIL;
702
703 if (cfsetispeed(&term, baud) < 0)
704 return SP_ERR_FAIL;
705
706 term.c_cflag &= ~CSIZE;
707 switch (bits) {
708 case 8:
709 term.c_cflag |= CS8;
710 break;
711 case 7:
712 term.c_cflag |= CS7;
713 break;
714 default:
715 return SP_ERR_ARG;
716 }
717
718 term.c_cflag &= ~CSTOPB;
719 switch (stopbits) {
720 case 1:
721 term.c_cflag &= ~CSTOPB;
722 break;
723 case 2:
724 term.c_cflag |= CSTOPB;
725 break;
726 default:
727 return SP_ERR_ARG;
728 }
729
8683177b 730 term.c_iflag &= ~(IXON | IXOFF | IXANY);
74510d4b
ML
731 term.c_cflag &= ~CRTSCTS;
732 switch (flowcontrol) {
733 case 0:
734 /* No flow control. */
735 break;
736 case 1:
737 term.c_cflag |= CRTSCTS;
738 break;
739 case 2:
8683177b 740 term.c_iflag |= IXON | IXOFF | IXANY;
74510d4b
ML
741 break;
742 default:
743 return SP_ERR_ARG;
744 }
745
746 term.c_iflag &= ~IGNPAR;
8683177b 747 term.c_cflag &= ~(PARENB | PARODD);
74510d4b
ML
748 switch (parity) {
749 case SP_PARITY_NONE:
750 term.c_iflag |= IGNPAR;
751 break;
752 case SP_PARITY_EVEN:
753 term.c_cflag |= PARENB;
754 break;
755 case SP_PARITY_ODD:
756 term.c_cflag |= PARENB | PARODD;
757 break;
758 default:
759 return SP_ERR_ARG;
760 }
761
762 /* Turn off all serial port cooking. */
763 term.c_iflag &= ~(ISTRIP | INLCR | ICRNL);
764 term.c_oflag &= ~(ONLCR | OCRNL | ONOCR);
765#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
766 term.c_oflag &= ~OFILL;
767#endif
768
769 /* Disable canonical mode, and don't echo input characters. */
770 term.c_lflag &= ~(ICANON | ECHO);
771
8683177b
ML
772 /* Ignore modem status lines; enable receiver */
773 term.c_cflag |= (CLOCAL | CREAD);
774
74510d4b
ML
775 /* Write the configured settings. */
776 if (tcsetattr(port->fd, TCSADRAIN, &term) < 0)
777 return SP_ERR_FAIL;
778
779 if (rts != -1) {
780 controlbits = TIOCM_RTS;
781 if (ioctl(port->fd, rts ? TIOCMBIS : TIOCMBIC,
782 &controlbits) < 0)
783 return SP_ERR_FAIL;
784 }
785
786 if (dtr != -1) {
787 controlbits = TIOCM_DTR;
788 if (ioctl(port->fd, dtr ? TIOCMBIS : TIOCMBIC,
789 &controlbits) < 0)
790 return SP_ERR_FAIL;
791 }
792#endif
793
794 return SP_OK;
795}
796
797/**
798 * Get error code for failed operation.
799 *
800 * In order to obtain the correct result, this function should be called
801 * straight after the failure, before executing any other system operations.
802 *
803 * @return The system's numeric code for the error that caused the last
804 * operation to fail.
805 */
806int sp_last_error_code(void)
807{
808#ifdef _WIN32
809 return GetLastError();
810#else
811 return errno;
812#endif
813}
814
815/**
816 * Get error message for failed operation.
817 *
818 * In order to obtain the correct result, this function should be called
819 * straight after the failure, before executing other system operations.
820 *
821 * @return The system's message for the error that caused the last
822 * operation to fail. This string may be allocated by the function,
823 * and can be freed after use by calling sp_free_error_message.
824 */
825char *sp_last_error_message(void)
826{
827#ifdef _WIN32
828 LPVOID message;
829 DWORD error = GetLastError();
830
831 FormatMessage(
832 FORMAT_MESSAGE_ALLOCATE_BUFFER |
833 FORMAT_MESSAGE_FROM_SYSTEM |
834 FORMAT_MESSAGE_IGNORE_INSERTS,
835 NULL,
836 error,
837 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
838 (LPTSTR) &message,
839 0, NULL );
840
841 return message;
842#else
843 return strerror(errno);
844#endif
845}
846
847/**
848 * Free error message.
849 *
850 * This function can be used to free a string returned by the
851 * sp_last_error_message function.
852 */
853void sp_free_error_message(char *message)
854{
855#ifdef _WIN32
856 LocalFree(message);
64eec30d
ML
857#else
858 (void)message;
74510d4b
ML
859#endif
860}