11 #include "LibCyberRadio/Common/SerialPort.h" 12 #include "LibCyberRadio/Common/BasicList.h" 13 #include "LibCyberRadio/Common/Pythonesque.h" 19 #include <sys/select.h> 26 const std::string& device,
49 memset(&_settings, 0,
sizeof(
struct termios));
50 this->
debug(
"CONSTRUCTED\n");
58 if ( _recvBuf != NULL )
60 this->
debug(
"DESTROYED\n");
65 _device(other._device),
66 _baudrate(other._baudrate),
67 _parity(other._parity),
68 _databits(other._databits),
69 _stopbits(other._stopbits),
70 _useXonXoff(other._useXonXoff),
71 _useRtsCts(other._useRtsCts),
72 _useDtsDtr(other._useDtsDtr),
74 _lastError(other._lastError),
75 _recvBuf(other._recvBuf),
76 _recvBufSize(other._recvBufSize)
78 memcpy(&_settings, &(other._settings),
sizeof(
struct termios));
87 _device = other._device;
88 _baudrate = other._baudrate;
89 _parity = other._parity;
90 _databits = other._databits;
91 _stopbits = other._stopbits;
92 _useXonXoff = other._useXonXoff;
93 _useRtsCts = other._useRtsCts;
94 _useDtsDtr = other._useDtsDtr;
96 _lastError = other._lastError;
97 _recvBuf = other._recvBuf;
98 _recvBufSize = other._recvBufSize;
99 memcpy(&_settings, &(other._settings),
sizeof(
struct termios));
106 this->
debug(
"[open] Called\n");
111 this->
debug(
"[open] Opening port\n");
112 _fd =
::open(_device.c_str(), O_RDWR | O_NOCTTY | O_NDELAY);
113 this->
debug(
"[open] -- FD = %d\n", _fd);
117 ::fcntl(_fd, F_SETFL, 0);
119 this->
debug(
"[open] Getting port settings\n");
120 if ( tcgetattr(_fd, &_settings) == 0 )
122 this->
debug(
"[open] -- SUCCESS\n");
123 this->
debug(
"[open] Setting initial port settings\n");
125 cfmakeraw(&_settings);
127 _settings.c_cflag |= CREAD;
129 _settings.c_cflag |= CLOCAL;
131 _settings.c_cc[VMIN] = 0;
132 _settings.c_cc[VTIME] = 1;
134 if ( tcsetattr(_fd, TCSANOW, &_settings) == 0 )
136 this->
debug(
"[open] -- SUCCESS\n");
140 this->
debug(
"[open] -- FAILED\n");
141 errors.push_back( strerror(errno) );
144 if ( tcsetattr(_fd, TCSANOW, &_settings) == 0 )
146 this->
debug(
"[open] -- SUCCESS\n");
150 this->
debug(
"[open] -- FAILED\n");
151 errors.push_back( strerror(errno) );
156 errors.push_back( _lastError );
161 errors.push_back( _lastError );
166 errors.push_back( _lastError );
171 errors.push_back( _lastError );
176 errors.push_back( _lastError );
181 errors.push_back( _lastError );
187 this->
debug(
"[open] -- FAILED\n");
188 errors.push_back( strerror(errno) );
192 if ( errors.size() == 0 )
194 _recvBuf =
new char[_recvBufSize];
197 if ( errors.size() > 0 )
200 this->
debug(
"[open] ERROR: %s\n", _lastError.c_str());
214 this->
debug(
"[close] Called\n");
223 _lastError =
"Port already closed";
225 if ( _lastError !=
"" )
226 this->
debug(
"[close] ERROR: %s\n", _lastError.c_str());
233 this->
debug(
"[read] Called\n");
238 this->
debug(
"[read] Entering read loop\n");
239 while ( (bytes > 0) && (_lastError ==
"") )
242 memset(_recvBuf, 0, _recvBufSize);
243 this->
debug(
"[read] -- Reading data\n");
244 bytes =
::read(_fd, _recvBuf, _recvBufSize);
245 this->
debug(
"[read] -- Bytes = %d\n", bytes);
249 for (
int i = 0; i < bytes; i++)
251 this->
debug(
"[read] -- %02x\n", (
int)_recvBuf[i]);
255 else if ( bytes < 0 )
258 _lastError = strerror(errno);
263 if ( (ret ==
"") && (_lastError ==
"") )
264 _lastError =
"Timeout";
265 if ( _lastError !=
"" )
266 this->
debug(
"[read] ERROR: %s\n", _lastError.c_str());
267 this->
debug(
"[read] Returning \"%s\"\n", ret.c_str());
273 this->
debug(
"[write] Called\n");
276 this->
debug(
"[write] Writing data\n");
277 ssize_t bytes =
::write(_fd, data.c_str(), data.size());
278 this->
debug(
"[write] -- Bytes = %d\n", bytes);
287 else if ( bytes == 0 )
290 _lastError =
"No data written";
295 _lastError = strerror(errno);
298 this->
debug(
"[write] ERROR: %s\n", _lastError.c_str());
310 this->
debug(
"[setBaudRate] Called, baudrate=%d\n", baudrate);
405 _lastError =
"Unsupported baud rate";
411 this->
debug(
"[getBaudRate] Setting port speed settings\n");
412 if ( (cfsetispeed(&_settings, baud) == 0) &&
413 (cfsetospeed(&_settings, baud) == 0) &&
414 (tcsetattr(_fd, TCSANOW, &_settings) == 0) )
416 this->
debug(
"[getBaudRate] -- SUCCESS\n");
417 _baudrate = baudrate;
421 this->
debug(
"[getBaudRate] -- FAILED\n");
422 _lastError = strerror(errno);
427 this->
debug(
"[getBaudRate] ERROR: %s\n", _lastError.c_str());
428 this->
debug(
"[getBaudRate] Returning %s\n", this->
debugBool(ret));
439 this->
debug(
"[setParity] Called, parity=%c\n", parity);
443 if ( (parity !=
'N') && (parity !=
'O') && (parity !=
'E') )
445 _lastError =
"Unsupported parity setting";
451 this->
debug(
"[setParity] Setting port parity settings\n");
453 _settings.c_cflag &= ~PARENB;
454 _settings.c_cflag &= ~PARODD;
458 _settings.c_cflag |= PARENB;
461 _settings.c_cflag |= PARODD;
463 if ( tcsetattr(_fd, TCSANOW, &_settings) == 0 )
465 this->
debug(
"[setParity] -- SUCCESS\n");
470 this->
debug(
"[setParity] -- FAILED\n");
471 _lastError = strerror(errno);
476 this->
debug(
"[setParity] ERROR: %s\n", _lastError.c_str());
488 this->
debug(
"[setDataBits] Called, databits=%d\n", databits);
508 _lastError =
"Unsupported data bits size";
514 this->
debug(
"[setDataBits] Setting port data bit settings\n");
516 _settings.c_cflag &= ~CSIZE;
518 _settings.c_cflag |= dbits;
519 if ( tcsetattr(_fd, TCSANOW, &_settings) == 0 )
521 this->
debug(
"[setDataBits] -- SUCCESS\n");
522 _databits = databits;
526 this->
debug(
"[setDataBits] -- FAILED\n");
527 _lastError = strerror(errno);
532 this->
debug(
"[setDataBits] ERROR: %s\n", _lastError.c_str());
533 this->
debug(
"[setDataBits] Returning %s\n", this->
debugBool(ret));
544 this->
debug(
"[setStopBits] Called, stopbits=%d\n", stopbits);
548 if ( (stopbits != 1) && (stopbits != 2) )
550 _lastError =
"Unsupported stop bits size";
556 this->
debug(
"[setStopBits] Setting port data bit settings\n");
559 _settings.c_cflag |= CSTOPB;
562 _settings.c_cflag &= ~CSTOPB;
563 if ( tcsetattr(_fd, TCSANOW, &_settings) == 0 )
565 this->
debug(
"[setStopBits] -- SUCCESS\n");
566 _stopbits = stopbits;
570 this->
debug(
"[setStopBits] -- FAILED\n");
571 _lastError = strerror(errno);
576 this->
debug(
"[setStopBits] ERROR: %s\n", _lastError.c_str());
577 this->
debug(
"[setStopBits] Returning %s\n", this->
debugBool(ret));
588 this->
debug(
"[enableXonXoffFlowControl] Called, enabled=%s\n",
595 this->
debug(
"[enableXonXoffFlowControl] Setting port XON/XOFF settings\n");
598 _settings.c_iflag |= (IXON | IXOFF | IXANY);
601 _settings.c_iflag &= ~(IXON | IXOFF | IXANY);
602 if ( tcsetattr(_fd, TCSANOW, &_settings) == 0 )
604 this->
debug(
"[enableXonXoffFlowControl] -- SUCCESS\n");
605 _useXonXoff = enabled;
609 this->
debug(
"[enableXonXoffFlowControl] -- FAILED\n");
610 _lastError = strerror(errno);
615 this->
debug(
"[enableXonXoffFlowControl] ERROR: %s\n", _lastError.c_str());
616 this->
debug(
"[enableXonXoffFlowControl] Returning %s\n", this->
debugBool(ret));
627 this->
debug(
"[enableRtsCtsFlowControl] Called, enabled=%s\n",
634 this->
debug(
"[enableRtsCtsFlowControl] Setting port XON/XOFF settings\n");
637 _settings.c_cflag |= CRTSCTS;
640 _settings.c_cflag &= ~CRTSCTS;
641 if ( tcsetattr(_fd, TCSANOW, &_settings) == 0 )
643 this->
debug(
"[enableRtsCtsFlowControl] -- SUCCESS\n");
644 _useRtsCts = enabled;
648 this->
debug(
"[enableRtsCtsFlowControl] -- FAILED\n");
649 _lastError = strerror(errno);
654 this->
debug(
"[enableRtsCtsFlowControl] ERROR: %s\n", _lastError.c_str());
655 this->
debug(
"[enableRtsCtsFlowControl] Returning %s\n", this->
debugBool(ret));
int getDataBits() const
Gets the current number of data bits.
int getStopBits() const
Gets the current number of stop bits.
bool setBaudRate(int baudrate)
Sets the current baud rate.
~SerialPort()
Destroys a SerialPort object.
bool setDataBits(int databits)
Sets the current number of data bits.
Debuggable & operator=(const Debuggable &other)
Assignment operator for Debuggable objects.
SerialPort(const std::string &device, int baudrate=115200, char parity='N', int databits=8, int stopbits=1, bool xonxoff=false, bool rtscts=false, bool debug=false)
Constructs a SerialPort object.
Class that manages communications with a serial port.
bool write(const std::string &data)
Writes data to the serial port.
char getParity() const
Gets the current parity setting.
Class that supports debug output.
bool setStopBits(int stopbits)
Sets the current number of stop bits.
bool open()
Open the serial port.
std::string getLastError() const
Gets the last error message.
bool enableXonXoffFlowControl(bool enabled)
Enables XON/XOFF (software) flow control on the serial port.
SerialPort & operator=(const SerialPort &other)
Assignment operator for SerialPort objects.
virtual int debug(const char *format,...)
Outputs debug information.
BASIC_LIST_CONTAINER< std::string > BasicStringList
Type representing a list of strings.
Defines functionality for LibCyberRadio applications.
bool usesRtsCtsFlowControl() const
Gets whether the serial port currently uses RTS/CTS (hardware) flow control.
virtual const char * debugBool(bool x)
Gets a debug output string for a Boolean value.
bool setParity(char parity)
Sets the current parity setting.
bool close()
Close the serial port.
bool usesXonXoffFlowControl() const
Gets whether the serial port currently uses XON/XOFF (software) flow control.
bool enableRtsCtsFlowControl(bool enabled)
Enables RTS/CTS (hardware) flow control on the serial port.
static std::string Join(const BasicStringList &vec, const std::string &sep)
Joins a list of string tokens, concatenating them into a single string.
std::string read()
Reads data from the serial port.
int getBaudRate() const
Gets the current baud rate.