]> sigrok.org Git - libserialport.git/blob - serialport.c
Avoid unused variable warning on non-Windows platforms.
[libserialport.git] / serialport.c
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>
27 #ifdef _WIN32
28 #include <windows.h>
29 #else
30 #include <termios.h>
31 #include <sys/ioctl.h>
32 #endif
33 #include <stdlib.h>
34 #include <errno.h>
35
36 #include "serialport.h"
37
38 static int sp_validate_port(struct sp_port *port)
39 {
40         if (port == NULL)
41                 return 0;
42 #ifdef _WIN32
43         if (port->hdl == INVALID_HANDLE_VALUE)
44                 return 0;
45 #else
46         if (port->fd < 0)
47                 return 0;
48 #endif
49         return 1;
50 }
51
52 #define CHECK_PORT() do { if (!sp_validate_port(port)) return SP_ERR_ARG; } while (0)
53
54 /**
55  * Open the specified serial port.
56  *
57  * @param port Pointer to empty port structure allocated by caller.
58  * @param portname Name of port to open.
59  * @param flags Flags to use when opening the serial port. Possible flags
60  *              are: SP_MODE_RDWR, SP_MODE_RDONLY, SP_MODE_NONBLOCK.
61  *
62  * @return SP_OK on success, SP_ERR_FAIL on failure,
63  *         or SP_ERR_ARG if an invalid port or name is passed.
64  */
65 int sp_open(struct sp_port *port, char *portname, int flags)
66 {
67         if (!port)
68                 return SP_ERR_ARG;
69
70         if (!portname)
71                 return SP_ERR_ARG;
72
73         port->name = portname;
74
75 #ifdef _WIN32
76         DWORD desired_access = 0, flags_and_attributes = 0;
77         /* Map 'flags' to the OS-specific settings. */
78         desired_access |= GENERIC_READ;
79         flags_and_attributes = FILE_ATTRIBUTE_NORMAL;
80         if (flags & SP_MODE_RDWR)
81                 desired_access |= GENERIC_WRITE;
82         if (flags & SP_MODE_NONBLOCK)
83                 flags_and_attributes |= FILE_FLAG_OVERLAPPED;
84
85         port->hdl = CreateFile(port->name, desired_access, 0, 0,
86                          OPEN_EXISTING, flags_and_attributes, 0);
87         if (port->hdl == INVALID_HANDLE_VALUE)
88                 return SP_ERR_FAIL;
89 #else
90         int flags_local = 0;
91         /* Map 'flags' to the OS-specific settings. */
92         if (flags & SP_MODE_RDWR)
93                 flags_local |= O_RDWR;
94         if (flags & SP_MODE_RDONLY)
95                 flags_local |= O_RDONLY;
96         if (flags & SP_MODE_NONBLOCK)
97                 flags_local |= O_NONBLOCK;
98
99         if ((port->fd = open(port->name, flags_local)) < 0)
100                 return SP_ERR_FAIL;
101 #endif
102
103         return SP_OK;
104 }
105
106 /**
107  * Close the specified serial port.
108  *
109  * @param port Pointer to port structure.
110  *
111  * @return SP_OK on success, SP_ERR_FAIL on failure,
112  *         or SP_ERR_ARG if an invalid port is passed.
113  */
114 int sp_close(struct sp_port *port)
115 {
116         CHECK_PORT();
117
118 #ifdef _WIN32
119         /* Returns non-zero upon success, 0 upon failure. */
120         if (CloseHandle(port->hdl) == 0)
121                 return SP_ERR_FAIL;
122 #else
123         /* Returns 0 upon success, -1 upon failure. */
124         if (close(port->fd) == -1)
125                 return SP_ERR_FAIL;
126 #endif
127
128         return SP_OK;
129 }
130
131 /**
132  * Flush serial port buffers.
133  *
134  * @param port Pointer to port structure.
135  *
136  * @return SP_OK on success, SP_ERR_FAIL on failure,
137  *         or SP_ERR_ARG if an invalid port is passed.
138  */
139 int sp_flush(struct sp_port *port)
140 {
141         CHECK_PORT();
142
143 #ifdef _WIN32
144         /* Returns non-zero upon success, 0 upon failure. */
145         if (PurgeComm(port->hdl, PURGE_RXCLEAR | PURGE_TXCLEAR) == 0)
146                 return SP_ERR_FAIL;
147 #else
148         /* Returns 0 upon success, -1 upon failure. */
149         if (tcflush(port->fd, TCIOFLUSH) < 0)
150                 return SP_ERR_FAIL;
151 #endif
152         return SP_OK;
153 }
154
155 /**
156  * Write a number of bytes to the specified serial port.
157  *
158  * @param port Pointer to port structure.
159  * @param buf Buffer containing the bytes to write.
160  * @param count Number of bytes to write.
161  *
162  * @return The number of bytes written, SP_ERR_FAIL on failure,
163  *         or SP_ERR_ARG if an invalid port is passed.
164  */
165 int sp_write(struct sp_port *port, const void *buf, size_t count)
166 {
167         CHECK_PORT();
168
169         if (!buf)
170                 return SP_ERR_ARG;
171
172 #ifdef _WIN32
173         DWORD written = 0;
174         /* Returns non-zero upon success, 0 upon failure. */
175         if (WriteFile(port->hdl, buf, count, &written, NULL) == 0)
176                 return SP_ERR_FAIL;
177         return written;
178 #else
179         /* Returns the number of bytes written, or -1 upon failure. */
180         ssize_t written = write(port->fd, buf, count);
181         if (written < 0)
182                 return SP_ERR_FAIL;
183         else
184                 return written;;
185 #endif
186 }
187
188 /**
189  * Read a number of bytes from the specified serial port.
190  *
191  * @param port Pointer to port structure.
192  * @param buf Buffer where to store the bytes that are read.
193  * @param count The number of bytes to read.
194  *
195  * @return The number of bytes read, SP_ERR_FAIL on failure,
196  *         or SP_ERR_ARG if an invalid port is passed.
197  */
198 int sp_read(struct sp_port *port, void *buf, size_t count)
199 {
200         CHECK_PORT();
201
202         if (!buf)
203                 return SP_ERR_ARG;
204
205 #ifdef _WIN32
206         DWORD bytes_read = 0;
207         /* Returns non-zero upon success, 0 upon failure. */
208         if (ReadFile(port->hdl, buf, count, &bytes_read, NULL) == 0)
209                 return SP_ERR_FAIL;
210         return bytes_read;
211 #else
212         ssize_t bytes_read;
213         /* Returns the number of bytes read, or -1 upon failure. */
214         if ((bytes_read = read(port->fd, buf, count)) < 0)
215                 return SP_ERR_FAIL;
216         return bytes_read;
217 #endif
218 }
219
220 /**
221  * Set serial parameters for the specified serial port.
222  *
223  * @param port Pointer to port structure.
224  * @param baudrate The baudrate to set.
225  * @param bits The number of data bits to use.
226  * @param parity The parity setting to use (0 = none, 1 = even, 2 = odd).
227  * @param stopbits The number of stop bits to use (1 or 2).
228  * @param flowcontrol The flow control settings to use (0 = none, 1 = RTS/CTS,
229  *                    2 = XON/XOFF).
230  *
231  * @return The number of bytes read, SP_ERR_FAIL on failure,
232  *         or SP_ERR_ARG if an invalid argument is passed.
233  */
234 int sp_set_params(struct sp_port *port, int baudrate,
235                               int bits, int parity, int stopbits,
236                               int flowcontrol, int rts, int dtr)
237 {
238         CHECK_PORT();
239
240 #ifdef _WIN32
241         DCB dcb;
242
243         if (!GetCommState(port->hdl, &dcb))
244                 return SP_ERR_FAIL;
245
246         switch (baudrate) {
247         /*
248          * The baudrates 50/75/134/150/200/1800/230400/460800 do not seem to
249          * have documented CBR_* macros.
250          */
251         case 110:
252                 dcb.BaudRate = CBR_110;
253                 break;
254         case 300:
255                 dcb.BaudRate = CBR_300;
256                 break;
257         case 600:
258                 dcb.BaudRate = CBR_600;
259                 break;
260         case 1200:
261                 dcb.BaudRate = CBR_1200;
262                 break;
263         case 2400:
264                 dcb.BaudRate = CBR_2400;
265                 break;
266         case 4800:
267                 dcb.BaudRate = CBR_4800;
268                 break;
269         case 9600:
270                 dcb.BaudRate = CBR_9600;
271                 break;
272         case 14400:
273                 dcb.BaudRate = CBR_14400; /* Not available on Unix? */
274                 break;
275         case 19200:
276                 dcb.BaudRate = CBR_19200;
277                 break;
278         case 38400:
279                 dcb.BaudRate = CBR_38400;
280                 break;
281         case 57600:
282                 dcb.BaudRate = CBR_57600;
283                 break;
284         case 115200:
285                 dcb.BaudRate = CBR_115200;
286                 break;
287         case 128000:
288                 dcb.BaudRate = CBR_128000; /* Not available on Unix? */
289                 break;
290         case 256000:
291                 dcb.BaudRate = CBR_256000; /* Not available on Unix? */
292                 break;
293         default:
294                 return SP_ERR_ARG;
295         }
296
297         switch (stopbits) {
298         /* Note: There's also ONE5STOPBITS == 1.5 (unneeded so far). */
299         case 1:
300                 dcb.StopBits = ONESTOPBIT;
301                 break;
302         case 2:
303                 dcb.StopBits = TWOSTOPBITS;
304                 break;
305         default:
306                 return SP_ERR_ARG;
307         }
308
309         switch (parity) {
310         /* Note: There's also SPACEPARITY, MARKPARITY (unneeded so far). */
311         case SP_PARITY_NONE:
312                 dcb.Parity = NOPARITY;
313                 break;
314         case SP_PARITY_EVEN:
315                 dcb.Parity = EVENPARITY;
316                 break;
317         case SP_PARITY_ODD:
318                 dcb.Parity = ODDPARITY;
319                 break;
320         default:
321                 return SP_ERR_ARG;
322         }
323
324         if (rts != -1) {
325                 if (rts)
326                         dcb.fRtsControl = RTS_CONTROL_ENABLE;
327                 else
328                         dcb.fRtsControl = RTS_CONTROL_DISABLE;
329         }
330
331         if (dtr != -1) {
332                 if (dtr)
333                         dcb.fDtrControl = DTR_CONTROL_ENABLE;
334                 else
335                         dcb.fDtrControl = DTR_CONTROL_DISABLE;
336         }
337
338         if (!SetCommState(port->hdl, &dcb))
339                 return SP_ERR_FAIL;
340 #else
341         struct termios term;
342         speed_t baud;
343         int controlbits;
344
345         if (tcgetattr(port->fd, &term) < 0)
346                 return SP_ERR_FAIL;
347
348         switch (baudrate) {
349         case 50:
350                 baud = B50;
351                 break;
352         case 75:
353                 baud = B75;
354                 break;
355         case 110:
356                 baud = B110;
357                 break;
358         case 134:
359                 baud = B134;
360                 break;
361         case 150:
362                 baud = B150;
363                 break;
364         case 200:
365                 baud = B200;
366                 break;
367         case 300:
368                 baud = B300;
369                 break;
370         case 600:
371                 baud = B600;
372                 break;
373         case 1200:
374                 baud = B1200;
375                 break;
376         case 1800:
377                 baud = B1800;
378                 break;
379         case 2400:
380                 baud = B2400;
381                 break;
382         case 4800:
383                 baud = B4800;
384                 break;
385         case 9600:
386                 baud = B9600;
387                 break;
388         case 19200:
389                 baud = B19200;
390                 break;
391         case 38400:
392                 baud = B38400;
393                 break;
394         case 57600:
395                 baud = B57600;
396                 break;
397         case 115200:
398                 baud = B115200;
399                 break;
400         case 230400:
401                 baud = B230400;
402                 break;
403 #if !defined(__APPLE__) && !defined(__OpenBSD__)
404         case 460800:
405                 baud = B460800;
406                 break;
407 #endif
408         default:
409                 return SP_ERR_ARG;
410         }
411
412         if (cfsetospeed(&term, baud) < 0)
413                 return SP_ERR_FAIL;
414
415         if (cfsetispeed(&term, baud) < 0)
416                 return SP_ERR_FAIL;
417
418         term.c_cflag &= ~CSIZE;
419         switch (bits) {
420         case 8:
421                 term.c_cflag |= CS8;
422                 break;
423         case 7:
424                 term.c_cflag |= CS7;
425                 break;
426         default:
427                 return SP_ERR_ARG;
428         }
429
430         term.c_cflag &= ~CSTOPB;
431         switch (stopbits) {
432         case 1:
433                 term.c_cflag &= ~CSTOPB;
434                 break;
435         case 2:
436                 term.c_cflag |= CSTOPB;
437                 break;
438         default:
439                 return SP_ERR_ARG;
440         }
441
442         term.c_iflag &= ~(IXON | IXOFF);
443         term.c_cflag &= ~CRTSCTS;
444         switch (flowcontrol) {
445         case 0:
446                 /* No flow control. */
447                 break;
448         case 1:
449                 term.c_cflag |= CRTSCTS;
450                 break;
451         case 2:
452                 term.c_iflag |= IXON | IXOFF;
453                 break;
454         default:
455                 return SP_ERR_ARG;
456         }
457
458         term.c_iflag &= ~IGNPAR;
459         term.c_cflag &= ~(PARODD | PARENB);
460         switch (parity) {
461         case SP_PARITY_NONE:
462                 term.c_iflag |= IGNPAR;
463                 break;
464         case SP_PARITY_EVEN:
465                 term.c_cflag |= PARENB;
466                 break;
467         case SP_PARITY_ODD:
468                 term.c_cflag |= PARENB | PARODD;
469                 break;
470         default:
471                 return SP_ERR_ARG;
472         }
473
474         /* Turn off all serial port cooking. */
475         term.c_iflag &= ~(ISTRIP | INLCR | ICRNL);
476         term.c_oflag &= ~(ONLCR | OCRNL | ONOCR);
477 #if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
478         term.c_oflag &= ~OFILL;
479 #endif
480
481         /* Disable canonical mode, and don't echo input characters. */
482         term.c_lflag &= ~(ICANON | ECHO);
483
484         /* Write the configured settings. */
485         if (tcsetattr(port->fd, TCSADRAIN, &term) < 0)
486                 return SP_ERR_FAIL;
487
488         if (rts != -1) {
489                 controlbits = TIOCM_RTS;
490                 if (ioctl(port->fd, rts ? TIOCMBIS : TIOCMBIC,
491                                 &controlbits) < 0)
492                         return SP_ERR_FAIL;
493         }
494
495         if (dtr != -1) {
496                 controlbits = TIOCM_DTR;
497                 if (ioctl(port->fd, dtr ? TIOCMBIS : TIOCMBIC,
498                                 &controlbits) < 0)
499                         return SP_ERR_FAIL;
500         }
501 #endif
502
503         return SP_OK;
504 }
505
506 /**
507  * Get error code for failed operation.
508  *
509  * In order to obtain the correct result, this function should be called
510  * straight after the failure, before executing any other system operations.
511  *
512  * @return The system's numeric code for the error that caused the last
513  *         operation to fail.
514  */
515 int sp_last_error_code(void)
516 {
517 #ifdef _WIN32
518         return GetLastError();
519 #else
520         return errno;
521 #endif
522 }
523
524 /**
525  * Get error message for failed operation.
526  *
527  * In order to obtain the correct result, this function should be called
528  * straight after the failure, before executing other system operations.
529  *
530  * @return The system's message for the error that caused the last
531  *         operation to fail. This string may be allocated by the function,
532  *         and can be freed after use by calling sp_free_error_message.
533  */
534 char *sp_last_error_message(void)
535 {
536 #ifdef _WIN32
537         LPVOID message;
538         DWORD error = GetLastError();
539
540         FormatMessage(
541                 FORMAT_MESSAGE_ALLOCATE_BUFFER |
542                 FORMAT_MESSAGE_FROM_SYSTEM |
543                 FORMAT_MESSAGE_IGNORE_INSERTS,
544                 NULL,
545                 error,
546                 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
547                 (LPTSTR) &message,
548                 0, NULL );
549
550         return message;
551 #else
552         return strerror(errno);
553 #endif
554 }
555
556 /**
557  * Free error message.
558  *
559  * This function can be used to free a string returned by the
560  * sp_last_error_message function.
561  */
562 void sp_free_error_message(char *message)
563 {
564 #ifdef _WIN32
565         LocalFree(message);
566 #else
567         (void)message;
568 #endif
569 }