Visual Servoing Platform version 3.5.0
vpSerial.cpp
1/****************************************************************************
2 *
3 * ViSP, open source Visual Servoing Platform software.
4 * Copyright (C) 2005 - 2019 by Inria. All rights reserved.
5 *
6 * This software is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 * See the file LICENSE.txt at the root directory of this source
11 * distribution for additional information about the GNU GPL.
12 *
13 * For using ViSP with software that can not be combined with the GNU
14 * GPL, please contact Inria about acquiring a ViSP Professional
15 * Edition License.
16 *
17 * See http://visp.inria.fr for more information.
18 *
19 * This software was developed at:
20 * Inria Rennes - Bretagne Atlantique
21 * Campus Universitaire de Beaulieu
22 * 35042 Rennes Cedex
23 * France
24 *
25 * If you have questions regarding the use of this file, please contact
26 * Inria at visp@inria.fr
27 *
28 * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
29 * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30 *
31 * Description:
32 * Serial communication.
33 *
34 * Authors:
35 * Fabien Spindler
36 *
37 *****************************************************************************/
38
39#include <visp3/core/vpConfig.h>
40
41#if !defined(_WIN32)
42
43#include <fcntl.h>
44#include <stdio.h>
45#include <stdlib.h>
46#include <string.h>
47#include <sys/stat.h>
48#include <sys/types.h>
49#include <sys/ioctl.h>
50#include <termios.h>
51#include <unistd.h>
52#include <errno.h>
53
54#include <visp3/core/vpSerial.h>
55#include <visp3/core/vpException.h>
56
57#ifndef TIOCINQ
58# ifdef FIONREAD
59# define TIOCINQ FIONREAD
60# else
61# define TIOCINQ 0x541B
62# endif
63#endif
64
100vpSerial::vpSerial(const std::string &port, unsigned long baudrate,
101 bytesize_t bytesize, parity_t parity, stopbits_t stopbits,
102 flowcontrol_t flowcontrol)
103 : m_port(port), m_fd(-1), m_is_open(false), m_xonxoff(false), m_rtscts(false),
104 m_baudrate(baudrate), m_parity(parity),
105 m_bytesize(bytesize), m_stopbits(stopbits), m_flowcontrol(flowcontrol)
106{
107 if (m_port.empty () == false)
108 open();
109}
110
115{
116 close();
117}
118
123void vpSerial::setBaudrate(const unsigned long baudrate)
124{
125 m_baudrate = baudrate;
126}
127
133{
134 m_bytesize = bytesize;
135}
136
142{
143 m_flowcontrol = flowcontrol;
144}
145
150void vpSerial::setParity(const parity_t &parity)
151{
152 m_parity = parity;
153}
154
160{
161 m_stopbits = stopbits;
162}
163
181void vpSerial::setPort(const std::string &port)
182{
183 m_port = port;
184}
185
190{
191 if (!m_is_open) {
192 return 0;
193 }
194 int count = 0;
195 if (-1 == ioctl (m_fd, TIOCINQ, &count)) {
196 throw(vpException(vpException::fatalError, "Cannot check is serial port data available"));
197 } else {
198 return count;
199 }
200}
201
207{
208 if (m_is_open == true) {
209 if (m_fd != -1) {
210 int ret;
211 ret = ::close (m_fd);
212 if (ret == 0) {
213 m_fd = -1;
214 } else {
215 throw(vpException(vpException::fatalError, "Cannot close serial port"));
216 }
217 }
218 m_is_open = false;
219 }
220}
221
250{
251 if (m_port.empty ()) {
252 throw(vpException(vpException::fatalError, "Serial port empty"));
253 }
254 if (m_is_open == true) {
255 throw(vpException(vpException::fatalError, "Serial port already open"));
256 }
257
258 m_fd = ::open (m_port.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
259
260 if (m_fd == -1) {
261 switch (errno) {
262 case EINTR:
263 // Try again because this is a recoverable error.
264 open();
265 return;
266 case ENFILE:
267 case EMFILE:
268 throw(vpException(vpException::fatalError, "Serial port has to many handles open"));
269 default:
270 throw(vpException(vpException::fatalError, "Serial port opening error"));
271 }
272 }
273
274 configure();
275 m_is_open = true;
276}
277
284bool vpSerial::read(char *c, long timeout_s)
285{
286 if (m_is_open == false) {
287 throw(vpException(vpException::fatalError, "Serial port not opened"));
288 }
289
290 fd_set readfds; /* list of fds for select to listen to */
291 struct timeval timeout = {timeout_s, 0}; // seconde, micro-sec
292
293 FD_ZERO(&readfds);
294 FD_SET(static_cast<unsigned int>(m_fd), &readfds);
295
296 int ret = select(FD_SETSIZE, &readfds, (fd_set *)NULL, (fd_set *)NULL, &timeout);
297
298 if (ret < 0) {
299 throw(vpException(vpException::fatalError, "Serial i/o exception"));
300 }
301 else if (ret == 0) {
302 // Timeout occured
303 return false;
304 }
305 else {
306 ssize_t n = ::read(m_fd, c, 1); // read one character at a time
307 if (n != 1)
308 return false;
309 }
310 return true;
311}
312
318std::string vpSerial::readline(const std::string &eol)
319{
320 char c;
321 size_t read_so_far = 0;
322 size_t eol_len = eol.length ();
323 std::string line;
324
325 while(true) {
326 size_t bytes_read = this->read(&c, 1);
327 read_so_far += bytes_read;
328 if (bytes_read == 0) {
329 break; // Timeout occured on reading 1 byte
330 }
331 line.append(&c, 1);
332 if (std::string(line, line.size() - eol_len, eol_len) == eol) {
333 break; // EOL found
334 }
335 }
336 return line;
337}
338
343void vpSerial::write(const std::string &s)
344{
345 if (m_is_open == false) {
346 throw(vpException(vpException::fatalError, "Serial port not opened"));
347 }
348
349 ssize_t r = ::write(m_fd, s.c_str(), s.size());
350 if (r != (ssize_t)(s.size())) {
351 throw(vpException(vpException::fatalError, "Serial port write error"));
352 }
353}
354
355void vpSerial::configure()
356{
357 if (m_fd == -1) {
358 throw(vpException(vpException::fatalError, "Serial port not opened"));
359 }
360
361 struct termios options;
362
363 if (tcgetattr(m_fd, &options) == -1) {
364 ::close(m_fd);
365 throw vpException(vpException::fatalError, "Cannot get serial configuration");
366 }
367
368 // set up raw mode / no echo / binary
369 options.c_cflag |= (tcflag_t) (CLOCAL | CREAD);
370 options.c_lflag &= (tcflag_t) ~(ICANON | ECHO | ECHOE | ECHOK | ECHONL |
371 ISIG | IEXTEN); //|ECHOPRT
372
373 options.c_oflag &= (tcflag_t) ~(OPOST);
374 options.c_iflag &= (tcflag_t) ~(INLCR | IGNCR | ICRNL | IGNBRK);
375
376#ifdef IUCLC
377 options.c_iflag &= (tcflag_t) ~IUCLC;
378#endif
379#ifdef PARMRK
380 options.c_iflag &= (tcflag_t) ~PARMRK;
381#endif
382
383 speed_t baudrate;
384 switch(m_baudrate) {
385#ifdef B0
386 case 0: baudrate = B0; break;
387#endif
388#ifdef B50
389 case 50: baudrate = B50; break;
390#endif
391#ifdef B75
392 case 75: baudrate = B75; break;
393#endif
394#ifdef B110
395 case 110: baudrate = B110; break;
396#endif
397#ifdef B134
398 case 134: baudrate = B134; break;
399#endif
400#ifdef B150
401 case 150: baudrate = B150; break;
402#endif
403#ifdef B200
404 case 200: baudrate = B200; break;
405#endif
406#ifdef B300
407 case 300: baudrate = B300; break;
408#endif
409#ifdef B600
410 case 600: baudrate = B600; break;
411#endif
412#ifdef B1200
413 case 1200: baudrate = B1200; break;
414#endif
415#ifdef B1800
416 case 1800: baudrate = B1800; break;
417#endif
418#ifdef B2400
419 case 2400: baudrate = B2400; break;
420#endif
421#ifdef B4800
422 case 4800: baudrate = B4800; break;
423#endif
424#ifdef B9600
425 case 9600: baudrate = B9600; break;
426#endif
427#ifdef B14400
428 case 14400: baudrate = B14400; break;
429#endif
430#ifdef B19200
431 case 19200: baudrate = B19200; break;
432#endif
433#ifdef B38400
434 case 38400: baudrate = B38400; break;
435#endif
436#ifdef B57600
437 case 57600: baudrate = B57600; break;
438#endif
439#ifdef B115200
440 case 115200: baudrate = B115200; break;
441#endif
442#ifdef B230400
443 case 230400: baudrate = B230400; break;
444#endif
445#ifdef B460800
446 case 460800: baudrate = B460800; break;
447#endif
448#ifdef B500000
449 case 500000: baudrate = B500000; break;
450#endif
451#ifdef B576000
452 case 576000: baudrate = B576000; break;
453#endif
454#ifdef B921600
455 case 921600: baudrate = B921600; break;
456#endif
457#ifdef B1000000
458 case 1000000: baudrate = B1000000; break;
459#endif
460#ifdef B1152000
461 case 1152000: baudrate = B1152000; break;
462#endif
463#ifdef B1500000
464 case 1500000: baudrate = B1500000; break;
465#endif
466#ifdef B2000000
467 case 2000000: baudrate = B2000000; break;
468#endif
469#ifdef B2500000
470 case 2500000: baudrate = B2500000; break;
471#endif
472#ifdef B3000000
473 case 3000000: baudrate = B3000000; break;
474#endif
475#ifdef B3500000
476 case 3500000: baudrate = B3500000; break;
477#endif
478#ifdef B4000000
479 case 4000000: baudrate = B4000000; break;
480#endif
481 default:
482 throw vpException(vpException::fatalError, "Cannot set serial baudrate to %ld", m_baudrate);
483 }
484
485#ifdef _BSD_SOURCE
486 ::cfsetspeed(&options, baudrate);
487#else
488 ::cfsetispeed(&options, baudrate);
489 ::cfsetospeed(&options, baudrate);
490#endif
491
492 // setup char len
493 options.c_cflag &= (tcflag_t) ~CSIZE;
494 switch(m_bytesize) {
495 case eightbits: options.c_cflag |= CS8; break;
496 case sevenbits: options.c_cflag |= CS7; break;
497 case sixbits: options.c_cflag |= CS6; break;
498 case fivebits: options.c_cflag |= CS5; break;
499 }
500
501 switch(m_stopbits) {
502 case stopbits_one: options.c_cflag &= (tcflag_t) ~(CSTOPB); break;
503 case stopbits_two: options.c_cflag |= (CSTOPB); break;
504 }
505
506 // setup parity
507 options.c_iflag &= (tcflag_t) ~(INPCK | ISTRIP);
508 switch(m_parity) {
509 case parity_none:
510 options.c_cflag &= (tcflag_t) ~(PARENB | PARODD); break;
511 case parity_even:
512 options.c_cflag &= (tcflag_t) ~(PARODD);
513 options.c_cflag |= (PARENB); break;
514 case parity_odd:
515 options.c_cflag |= (PARENB | PARODD); break;
516 }
517
518 // setup flow control
519 switch(m_flowcontrol) {
520 case flowcontrol_none:
521 m_xonxoff = false;
522 m_rtscts = false;
523 break;
525 m_xonxoff = true;
526 m_rtscts = false;
527 break;
529 m_xonxoff = false;
530 m_rtscts = true;
531 break;
532 }
533
534 // xonxoff
535 if (m_xonxoff)
536 options.c_iflag |= (IXON | IXOFF);
537 else
538#ifdef IXANY
539 options.c_iflag &= (tcflag_t) ~(IXON | IXOFF | IXANY);
540#else
541 options.c_iflag &= (tcflag_t) ~(IXON | IXOFF);
542#endif
543
544 // rtscts
545#ifdef CRTSCTS
546 if (m_rtscts)
547 options.c_cflag |= (CRTSCTS);
548 else
549 options.c_cflag &= (unsigned long) ~(CRTSCTS);
550#elif defined CNEW_RTSCTS
551 if (m_rtscts)
552 options.c_cflag |= (CNEW_RTSCTS);
553 else
554 options.c_cflag &= (unsigned long) ~(CNEW_RTSCTS);
555#else
556#error "OS doesn't support serial rtscts"
557#endif
558
559 options.c_cc[VMIN] = 0;
560 options.c_cc[VTIME] = 0;
561
562 // activate settings
563 ::tcsetattr (m_fd, TCSANOW, &options);
564}
565
566#elif !defined(VISP_BUILD_SHARED_LIBS)
567// Work arround to avoid warning: libvisp_ar.a(vpAROgre.cpp.o) has no symbols
568void dummy_vpSerial(){};
569#endif
error that can be emited by ViSP classes.
Definition: vpException.h:72
@ fatalError
Fatal error.
Definition: vpException.h:96
std::string readline(const std::string &eol)
Definition: vpSerial.cpp:318
flowcontrol_t
Definition: vpSerial.h:103
@ flowcontrol_software
Software flow control.
Definition: vpSerial.h:105
@ flowcontrol_none
No flow control.
Definition: vpSerial.h:104
@ flowcontrol_hardware
Hardware flow control.
Definition: vpSerial.h:106
void open()
Definition: vpSerial.cpp:249
void setParity(const parity_t &parity)
Definition: vpSerial.cpp:150
int available()
Definition: vpSerial.cpp:189
void setStopbits(const stopbits_t &stopbits)
Definition: vpSerial.cpp:159
vpSerial(const std::string &port="", unsigned long baudrate=9600, bytesize_t bytesize=eightbits, parity_t parity=parity_none, stopbits_t stopbits=stopbits_one, flowcontrol_t flowcontrol=flowcontrol_none)
Definition: vpSerial.cpp:100
@ parity_odd
Check for odd parity.
Definition: vpSerial.h:88
@ parity_none
No parity check.
Definition: vpSerial.h:87
@ parity_even
Check for even parity.
Definition: vpSerial.h:89
void close()
Definition: vpSerial.cpp:206
stopbits_t
Definition: vpSerial.h:95
@ stopbits_two
2 stop bits are used
Definition: vpSerial.h:97
@ stopbits_one
1 stop bit is used
Definition: vpSerial.h:96
void setFlowcontrol(const flowcontrol_t &flowcontrol)
Definition: vpSerial.cpp:141
bool read(char *c, long timeout_s)
Definition: vpSerial.cpp:284
void setBytesize(const bytesize_t &bytesize)
Definition: vpSerial.cpp:132
void write(const std::string &s)
Definition: vpSerial.cpp:343
virtual ~vpSerial()
Definition: vpSerial.cpp:114
void setPort(const std::string &port)
Definition: vpSerial.cpp:181
bytesize_t
Definition: vpSerial.h:76
@ eightbits
Data is encoded with 8 bits.
Definition: vpSerial.h:80
@ fivebits
Data is encoded with 5 bits.
Definition: vpSerial.h:77
@ sevenbits
Data is encoded with 7 bits.
Definition: vpSerial.h:79
@ sixbits
Data is encoded with 6 bits.
Definition: vpSerial.h:78
void setBaudrate(const unsigned long baudrate)
Definition: vpSerial.cpp:123