mirror of
https://github.com/wjwwood/serial.git
synced 2026-01-22 19:54:57 +08:00
Fixed some issues I found while testing my code, also implemented the drain, flush, set/send Break, get {CTS, RI, CD, DSR}, set {RTS, DTR}
This commit is contained in:
parent
99bf74faae
commit
11807e407b
16
Makefile
16
Makefile
@ -1,5 +1,11 @@
|
|||||||
ifdef ROS_ROOT
|
CXX=clang++
|
||||||
include $(shell rospack find mk)/cmake.mk
|
CXXFLAGS=-g -I./include
|
||||||
else
|
|
||||||
include serial.makefile
|
test: tests/serial_tests.o src/serial.o src/impl/unix.o
|
||||||
endif
|
$(CXX) -o test tests/serial_tests.o src/serial.o src/impl/unix.o
|
||||||
|
|
||||||
|
# ifdef ROS_ROOT
|
||||||
|
# include $(shell rospack find mk)/cmake.mk
|
||||||
|
# else
|
||||||
|
# include serial.makefile
|
||||||
|
# endif
|
||||||
|
|||||||
@ -58,22 +58,22 @@ public:
|
|||||||
void close ();
|
void close ();
|
||||||
bool isOpen ();
|
bool isOpen ();
|
||||||
|
|
||||||
size_t available ();
|
size_t available ();
|
||||||
string read (size_t size = 1);
|
string read (size_t size = 1);
|
||||||
size_t write (const string &data);
|
size_t write (const string &data);
|
||||||
|
|
||||||
void flush ();
|
void flush ();
|
||||||
void flushInput ();
|
void flushInput ();
|
||||||
void flushOutput ();
|
void flushOutput ();
|
||||||
|
|
||||||
void sendBreak();
|
void sendBreak(int duration);
|
||||||
void setBreak();
|
void setBreak(bool level);
|
||||||
void setRTS();
|
void setRTS(bool level);
|
||||||
void setDTR();
|
void setDTR(bool level);
|
||||||
void getCTS();
|
bool getCTS();
|
||||||
void getDSR();
|
bool getDSR();
|
||||||
void getRI();
|
bool getRI();
|
||||||
void getCD();
|
bool getCD();
|
||||||
|
|
||||||
void setPort (const string &port);
|
void setPort (const string &port);
|
||||||
string getPort () const;
|
string getPort () const;
|
||||||
@ -97,25 +97,25 @@ public:
|
|||||||
flowcontrol_t getFlowcontrol () const;
|
flowcontrol_t getFlowcontrol () const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void reconfigurePort ();
|
void reconfigurePort ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int fd_; // The current file descriptor.
|
int fd_; // The current file descriptor.
|
||||||
|
|
||||||
bool isOpen_;
|
bool isOpen_;
|
||||||
|
|
||||||
int interCharTimeout_;
|
int interCharTimeout_;
|
||||||
int writeTimeout_;
|
int writeTimeout_;
|
||||||
int xonxoff_;
|
int xonxoff_;
|
||||||
int rtscts_;
|
int rtscts_;
|
||||||
|
|
||||||
string port_; // Path to the file descriptor
|
string port_; // Path to the file descriptor
|
||||||
int baudrate_; // Baudrate
|
int baudrate_; // Baudrate
|
||||||
long timeout_; // Timeout for read operations
|
long timeout_; // Timeout for read operations
|
||||||
bytesize_t bytesize_; // Size of the bytes
|
bytesize_t bytesize_; // Size of the bytes
|
||||||
parity_t parity_; // Parity
|
parity_t parity_; // Parity
|
||||||
stopbits_t stopbits_; // Stop Bits
|
stopbits_t stopbits_; // Stop Bits
|
||||||
flowcontrol_t flowcontrol_; // Flow Control
|
flowcontrol_t flowcontrol_; // Flow Control
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -373,6 +373,18 @@ public:
|
|||||||
flowcontrol_t
|
flowcontrol_t
|
||||||
getFlowcontrol () const;
|
getFlowcontrol () const;
|
||||||
|
|
||||||
|
void flush();
|
||||||
|
void flushInput();
|
||||||
|
void flushOutput();
|
||||||
|
void sendBreak(int duration);
|
||||||
|
void setBreak(bool level = true);
|
||||||
|
void setRTS(bool level = true);
|
||||||
|
void setDTR(bool level = true);
|
||||||
|
bool getCTS();
|
||||||
|
bool getDSR();
|
||||||
|
bool getRI();
|
||||||
|
bool getCD();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Disable copy constructors
|
// Disable copy constructors
|
||||||
Serial(const Serial&);
|
Serial(const Serial&);
|
||||||
|
|||||||
305
src/impl/unix.cc
305
src/impl/unix.cc
@ -28,14 +28,15 @@ using std::string;
|
|||||||
Serial::SerialImpl::SerialImpl (const string &port, int baudrate,
|
Serial::SerialImpl::SerialImpl (const string &port, int baudrate,
|
||||||
long timeout, bytesize_t bytesize,
|
long timeout, bytesize_t bytesize,
|
||||||
parity_t parity, stopbits_t stopbits,
|
parity_t parity, stopbits_t stopbits,
|
||||||
flowcontrol_t flowcontrol)
|
flowcontrol_t flowcontrol)
|
||||||
: fd_(-1), isOpen_(false), interCharTimeout_(-1), port_(port), baudrate_(baudrate),
|
: fd_(-1), isOpen_(false), interCharTimeout_(-1), port_(port), baudrate_(baudrate),
|
||||||
timeout_(timeout), bytesize_(bytesize), parity_(parity), stopbits_(stopbits),
|
timeout_(timeout), bytesize_(bytesize), parity_(parity), stopbits_(stopbits),
|
||||||
flowcontrol_(flowcontrol)
|
flowcontrol_(flowcontrol)
|
||||||
{
|
{
|
||||||
if (port_.empty() == false) {
|
printf("Got port: %s\n", port.c_str());
|
||||||
this->open();
|
if (!port_.empty()) {
|
||||||
}
|
this->open();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial::SerialImpl::~SerialImpl () {
|
Serial::SerialImpl::~SerialImpl () {
|
||||||
@ -44,46 +45,48 @@ Serial::SerialImpl::~SerialImpl () {
|
|||||||
|
|
||||||
void
|
void
|
||||||
Serial::SerialImpl::open () {
|
Serial::SerialImpl::open () {
|
||||||
if (port_.empty() == false) {
|
if (port_.empty()) {
|
||||||
throw "error";
|
printf("Port was empty\n");
|
||||||
}
|
throw "error";
|
||||||
if (isOpen_ == false) {
|
}
|
||||||
throw "error";
|
if (isOpen_ == true) {
|
||||||
}
|
printf("Port already opened\n");
|
||||||
|
throw "error";
|
||||||
fd_ = ::open (port_.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
|
}
|
||||||
|
|
||||||
if (fd_ == -1) {
|
fd_ = ::open (port_.c_str(), O_RDWR | O_NOCTTY | O_NONBLOCK);
|
||||||
// printf("Error opening serial port %s - %s(%d).\n",
|
|
||||||
// port.c_str(), strerror(errno), errno);
|
if (fd_ == -1) {
|
||||||
throw "Error"; // Error
|
printf("Error opening serial port %s - %s(%d).\n",
|
||||||
}
|
port_.c_str(), strerror(errno), errno);
|
||||||
|
throw "Error"; // Error
|
||||||
reconfigurePort();
|
}
|
||||||
isOpen_ = true;
|
|
||||||
|
reconfigurePort();
|
||||||
|
isOpen_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Serial::SerialImpl::reconfigurePort () {
|
Serial::SerialImpl::reconfigurePort () {
|
||||||
if (fd_ == -1) {
|
if (fd_ == -1) {
|
||||||
throw "Error"; // Can only operate on a valid file descriptor
|
throw "Error"; // Can only operate on a valid file descriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
struct termios options; // The current options for the file descriptor
|
struct termios options; // The current options for the file descriptor
|
||||||
struct termios originalTTYAttrs; // The orignal file descriptor options
|
struct termios originalTTYAttrs; // The orignal file descriptor options
|
||||||
|
|
||||||
uint8_t vmin = 0, vtime = 0; // timeout is done via select
|
uint8_t vmin = 0, vtime = 0; // timeout is done via select
|
||||||
if (interCharTimeout_ == -1) {
|
if (interCharTimeout_ == -1) {
|
||||||
vmin = 1;
|
vmin = 1;
|
||||||
vtime = int(interCharTimeout_ * 10);
|
vtime = int(interCharTimeout_ * 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tcgetattr(fd_, &originalTTYAttrs) == -1) {
|
if (tcgetattr(fd_, &originalTTYAttrs) == -1) {
|
||||||
throw "Error";
|
throw "Error";
|
||||||
}
|
}
|
||||||
|
|
||||||
options = originalTTYAttrs;
|
options = originalTTYAttrs;
|
||||||
|
|
||||||
// set up raw mode / no echo / binary
|
// set up raw mode / no echo / binary
|
||||||
options.c_cflag |= (CLOCAL|CREAD);
|
options.c_cflag |= (CLOCAL|CREAD);
|
||||||
options.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|
|
options.c_lflag &= ~(ICANON|ECHO|ECHOE|ECHOK|ECHONL|
|
||||||
@ -95,12 +98,12 @@ Serial::SerialImpl::reconfigurePort () {
|
|||||||
options.c_iflag &= ~IUCLC;
|
options.c_iflag &= ~IUCLC;
|
||||||
#endif
|
#endif
|
||||||
#ifdef PARMRK
|
#ifdef PARMRK
|
||||||
options.c_iflag &= ~PARMRK;
|
options.c_iflag &= ~PARMRK;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// setup baud rate
|
// setup baud rate
|
||||||
// TODO(ash_git): validate baud rate
|
// TODO(ash_git): validate baud rate
|
||||||
cfsetspeed(&options, baudrate_);
|
cfsetspeed(&options, baudrate_);
|
||||||
|
|
||||||
// setup char len
|
// setup char len
|
||||||
options.c_cflag &= ~CSIZE;
|
options.c_cflag &= ~CSIZE;
|
||||||
@ -121,23 +124,23 @@ Serial::SerialImpl::reconfigurePort () {
|
|||||||
options.c_cflag |= (CSTOPB); // XXX same as TWO.. there is no POSIX support for 1.5
|
options.c_cflag |= (CSTOPB); // XXX same as TWO.. there is no POSIX support for 1.5
|
||||||
else if (stopbits_ == STOPBITS_TWO)
|
else if (stopbits_ == STOPBITS_TWO)
|
||||||
options.c_cflag |= (CSTOPB);
|
options.c_cflag |= (CSTOPB);
|
||||||
else
|
else
|
||||||
throw "ValueError(Invalid stop bit specification:)";
|
throw "ValueError(Invalid stop bit specification:)";
|
||||||
// setup parity
|
// setup parity
|
||||||
options.c_iflag &= ~(INPCK|ISTRIP);
|
options.c_iflag &= ~(INPCK|ISTRIP);
|
||||||
if (parity_ == PARITY_NONE) {
|
if (parity_ == PARITY_NONE) {
|
||||||
options.c_cflag &= ~(PARENB|PARODD);
|
options.c_cflag &= ~(PARENB|PARODD);
|
||||||
}
|
}
|
||||||
else if (parity_ == PARITY_EVEN) {
|
else if (parity_ == PARITY_EVEN) {
|
||||||
options.c_cflag &= ~(PARODD);
|
options.c_cflag &= ~(PARODD);
|
||||||
options.c_cflag |= (PARENB);
|
options.c_cflag |= (PARENB);
|
||||||
}
|
}
|
||||||
else if (parity_ == PARITY_ODD) {
|
else if (parity_ == PARITY_ODD) {
|
||||||
options.c_cflag |= (PARENB|PARODD);
|
options.c_cflag |= (PARENB|PARODD);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw "ValueError(Invalid parity:";
|
throw "ValueError(Invalid parity:";
|
||||||
}
|
}
|
||||||
// setup flow control
|
// setup flow control
|
||||||
// xonxoff
|
// xonxoff
|
||||||
#ifdef IXANY
|
#ifdef IXANY
|
||||||
@ -159,7 +162,7 @@ Serial::SerialImpl::reconfigurePort () {
|
|||||||
options.c_cflag &= ~(CRTSCTS);
|
options.c_cflag &= ~(CRTSCTS);
|
||||||
#elif defined CNEW_RTSCTS
|
#elif defined CNEW_RTSCTS
|
||||||
if (rtscts_)
|
if (rtscts_)
|
||||||
options.c_cflag |= (CNEW_RTSCTS);
|
options.c_cflag |= (CNEW_RTSCTS);
|
||||||
else
|
else
|
||||||
options.c_cflag &= ~(CNEW_RTSCTS);
|
options.c_cflag &= ~(CNEW_RTSCTS);
|
||||||
#else
|
#else
|
||||||
@ -173,18 +176,18 @@ Serial::SerialImpl::reconfigurePort () {
|
|||||||
options.c_cc[VTIME] = vtime;
|
options.c_cc[VTIME] = vtime;
|
||||||
|
|
||||||
// activate settings
|
// activate settings
|
||||||
::tcsetattr(fd_, TCSANOW, &options);
|
::tcsetattr(fd_, TCSANOW, &options);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Serial::SerialImpl::close () {
|
Serial::SerialImpl::close () {
|
||||||
if (isOpen_ == true) {
|
if (isOpen_ == true) {
|
||||||
if (fd_ != -1) {
|
if (fd_ != -1) {
|
||||||
::close(fd_);
|
::close(fd_);
|
||||||
fd_ = -1;
|
fd_ = -1;
|
||||||
}
|
}
|
||||||
isOpen_ = false;
|
isOpen_ = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -194,73 +197,73 @@ Serial::SerialImpl::isOpen () {
|
|||||||
|
|
||||||
size_t
|
size_t
|
||||||
Serial::SerialImpl::available () {
|
Serial::SerialImpl::available () {
|
||||||
if (!isOpen_) {
|
if (!isOpen_) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int count = 0;
|
int count = 0;
|
||||||
int result = ioctl(fd_, TIOCINQ, &count);
|
int result = ioctl(fd_, TIOCINQ, &count);
|
||||||
if (result == 0) {
|
if (result == 0) {
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw "Error";
|
throw "Error";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string
|
string
|
||||||
Serial::SerialImpl::read (size_t size) {
|
Serial::SerialImpl::read (size_t size) {
|
||||||
if (!isOpen_) {
|
if (!isOpen_) {
|
||||||
throw "PortNotOpenError()"; //
|
throw "PortNotOpenError()"; //
|
||||||
}
|
}
|
||||||
string message = "";
|
string message = "";
|
||||||
char buf[1024];
|
char buf[1024]; // TODO(ash_gti): Should this be 1024? or...?
|
||||||
fd_set readfds;
|
fd_set readfds;
|
||||||
while (message.length() < size) {
|
while (message.length() < size) {
|
||||||
FD_ZERO(&readfds);
|
FD_ZERO(&readfds);
|
||||||
FD_SET(fd_, &readfds);
|
FD_SET(fd_, &readfds);
|
||||||
struct timeval timeout;
|
struct timeval timeout;
|
||||||
timeout.tv_sec = timeout_ / 1000;
|
timeout.tv_sec = timeout_ / 1000;
|
||||||
timeout.tv_usec = timeout_ % 1000;
|
timeout.tv_usec = timeout_ % 1000;
|
||||||
int r = select(1, &readfds, NULL, NULL, &timeout);
|
int r = select(fd_ + 1, &readfds, NULL, NULL, &timeout);
|
||||||
|
|
||||||
if (r == -1 && errno == EINTR)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (r == -1) {
|
if (r == -1 && errno == EINTR)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (r == -1) {
|
||||||
perror("select()");
|
perror("select()");
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FD_ISSET(fd_, &readfds)) {
|
if (FD_ISSET(fd_, &readfds)) {
|
||||||
memset(buf, 0, 1024);
|
memset(buf, 0, 1024);
|
||||||
size_t bytes_read = ::read(fd_, buf, 1024);
|
size_t bytes_read = ::read(fd_, buf, size-strlen(buf));
|
||||||
// read should always return some data as select reported it was
|
// read should always return some data as select reported it was
|
||||||
// ready to read when we get to this point.
|
// ready to read when we get to this point.
|
||||||
if (bytes_read < 1) {
|
if (bytes_read < 1) {
|
||||||
// Disconnected devices, at least on Linux, show the
|
// Disconnected devices, at least on Linux, show the
|
||||||
// behavior that they are always ready to read immediately
|
// behavior that they are always ready to read immediately
|
||||||
// but reading returns nothing.
|
// but reading returns nothing.
|
||||||
throw "SerialException('device reports readiness to read but returned no data (device disconnected?)')";
|
throw "SerialException('device reports readiness to read but returned no data (device disconnected?)')";
|
||||||
}
|
}
|
||||||
message.append(buf, bytes_read);
|
message.append(buf, bytes_read);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
break; // Timeout
|
break; // Timeout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return message;
|
return message;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
Serial::SerialImpl::write (const string &data) {
|
Serial::SerialImpl::write (const string &data) {
|
||||||
if (isOpen_ == false) {
|
if (isOpen_ == false) {
|
||||||
throw "portNotOpenError";
|
throw "portNotOpenError";
|
||||||
}
|
}
|
||||||
size_t t = data.length();
|
size_t t = data.length();
|
||||||
size_t n = ::write(fd_, data.c_str(), data.length());
|
size_t n = ::write(fd_, data.c_str(), data.length());
|
||||||
if (n == -1) {
|
if (n == -1) {
|
||||||
throw "Write error";
|
throw "Write error";
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -286,8 +289,8 @@ Serial::SerialImpl::getTimeout () const {
|
|||||||
|
|
||||||
void
|
void
|
||||||
Serial::SerialImpl::setBaudrate (int baudrate) {
|
Serial::SerialImpl::setBaudrate (int baudrate) {
|
||||||
baudrate_ = baudrate;
|
baudrate_ = baudrate;
|
||||||
reconfigurePort();
|
reconfigurePort();
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -297,7 +300,7 @@ Serial::SerialImpl::getBaudrate () const {
|
|||||||
|
|
||||||
void
|
void
|
||||||
Serial::SerialImpl::setBytesize (serial::bytesize_t bytesize) {
|
Serial::SerialImpl::setBytesize (serial::bytesize_t bytesize) {
|
||||||
bytesize_ = bytesize;
|
bytesize_ = bytesize;
|
||||||
}
|
}
|
||||||
|
|
||||||
serial::bytesize_t
|
serial::bytesize_t
|
||||||
@ -336,6 +339,96 @@ Serial::SerialImpl::getFlowcontrol () const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Serial::SerialImpl::flush () {
|
||||||
|
if (isOpen_ == false) {
|
||||||
|
throw "portNotOpen";
|
||||||
|
}
|
||||||
|
tcdrain(fd_);
|
||||||
|
}
|
||||||
|
void Serial::SerialImpl::flushInput () {
|
||||||
|
if (isOpen_ == false) {
|
||||||
|
throw "portNotOpen";
|
||||||
|
}
|
||||||
|
tcflush(fd_, TCIFLUSH);
|
||||||
|
}
|
||||||
|
void Serial::SerialImpl::flushOutput () {
|
||||||
|
if (isOpen_ == false) {
|
||||||
|
throw "portNotOpen";
|
||||||
|
}
|
||||||
|
tcflush(fd_, TCOFLUSH);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Serial::SerialImpl::sendBreak(int duration) {
|
||||||
|
if (isOpen_ == false) {
|
||||||
|
throw "portNotOpen";
|
||||||
|
}
|
||||||
|
tcsendbreak(fd_, int(duration/4));
|
||||||
|
}
|
||||||
|
void Serial::SerialImpl::setBreak(bool level) {
|
||||||
|
if (isOpen_ == false) {
|
||||||
|
throw "portNotOpen";
|
||||||
|
}
|
||||||
|
if (level) {
|
||||||
|
ioctl(fd_, TIOCSBRK);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ioctl(fd_, TIOCCBRK);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Serial::SerialImpl::setRTS(bool level) {
|
||||||
|
if (isOpen_ == false) {
|
||||||
|
throw "portNotOpen";
|
||||||
|
}
|
||||||
|
if (level) {
|
||||||
|
ioctl(fd_, TIOCMBIS, TIOCM_RTS);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ioctl(fd_, TIOCMBIC, TIOCM_RTS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
void Serial::SerialImpl::setDTR(bool level) {
|
||||||
|
if (isOpen_ == false) {
|
||||||
|
throw "portNotOpen";
|
||||||
|
}
|
||||||
|
if (level) {
|
||||||
|
ioctl(fd_, TIOCMBIS, TIOCM_DTR);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ioctl(fd_, TIOCMBIC, TIOCM_DTR);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
bool Serial::SerialImpl::getCTS() {
|
||||||
|
if (isOpen_ == false) {
|
||||||
|
throw "portNotOpen";
|
||||||
|
}
|
||||||
|
int s = ioctl(fd_, TIOCMGET, 0);
|
||||||
|
return (s & TIOCM_CTS) != 0;
|
||||||
|
}
|
||||||
|
bool Serial::SerialImpl::getDSR() {
|
||||||
|
if (isOpen_ == false) {
|
||||||
|
throw "portNotOpen";
|
||||||
|
}
|
||||||
|
int s = ioctl(fd_, TIOCMGET, 0);
|
||||||
|
return (s & TIOCM_DSR) != 0;
|
||||||
|
}
|
||||||
|
bool Serial::SerialImpl::getRI() {
|
||||||
|
if (isOpen_ == false) {
|
||||||
|
throw "portNotOpen";
|
||||||
|
}
|
||||||
|
int s = ioctl(fd_, TIOCMGET, 0);
|
||||||
|
return (s & TIOCM_RI) != 0;
|
||||||
|
}
|
||||||
|
bool Serial::SerialImpl::getCD() {
|
||||||
|
if (isOpen_ == false) {
|
||||||
|
throw "portNotOpen";
|
||||||
|
}
|
||||||
|
int s = ioctl(fd_, TIOCMGET, 0);
|
||||||
|
return (s & TIOCM_CD) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,6 @@ Serial::Serial (const string &port, int baudrate,
|
|||||||
: pimpl(new SerialImpl(port,baudrate,timeout,bytesize,parity,stopbits,
|
: pimpl(new SerialImpl(port,baudrate,timeout,bytesize,parity,stopbits,
|
||||||
flowcontrol))
|
flowcontrol))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Serial::~Serial () {
|
Serial::~Serial () {
|
||||||
@ -62,12 +61,12 @@ Serial::read (size_t size) {
|
|||||||
string
|
string
|
||||||
Serial::readline(size_t size, string eol) {
|
Serial::readline(size_t size, string eol) {
|
||||||
size_t leneol = eol.length();
|
size_t leneol = eol.length();
|
||||||
string line;
|
string line = "";
|
||||||
while (true) {
|
while (true) {
|
||||||
string c = read(1);
|
string c = pimpl->read(1);
|
||||||
if (c.empty()) {
|
if (!c.empty()) {
|
||||||
line += c;
|
line.append(c);
|
||||||
if (line.substr(line.length() - leneol, leneol) == eol) {
|
if (line.length() > leneol && line.substr(line.length() - leneol, leneol) == eol) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (line.length() >= size) {
|
if (line.length() >= size) {
|
||||||
@ -186,6 +185,39 @@ Serial::getFlowcontrol () const {
|
|||||||
return this->pimpl->getFlowcontrol ();
|
return this->pimpl->getFlowcontrol ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Serial::flush() {
|
||||||
|
this->pimpl->flush();
|
||||||
|
}
|
||||||
|
void Serial::flushInput() {
|
||||||
|
this->pimpl->flushInput();
|
||||||
|
}
|
||||||
|
void Serial::flushOutput() {
|
||||||
|
this->pimpl->flushOutput();
|
||||||
|
}
|
||||||
|
void Serial::sendBreak(int duration) {
|
||||||
|
this->pimpl->sendBreak(duration);
|
||||||
|
}
|
||||||
|
void Serial::setBreak(bool level) {
|
||||||
|
this->pimpl->setBreak(level);
|
||||||
|
}
|
||||||
|
void Serial::setRTS(bool level) {
|
||||||
|
this->pimpl->setRTS(level);
|
||||||
|
}
|
||||||
|
void Serial::setDTR(bool level) {
|
||||||
|
this->pimpl->setDTR(level);
|
||||||
|
}
|
||||||
|
bool Serial::getCTS() {
|
||||||
|
return this->pimpl->getCTS();
|
||||||
|
}
|
||||||
|
bool Serial::getDSR() {
|
||||||
|
return this->pimpl->getDSR();
|
||||||
|
}
|
||||||
|
bool Serial::getRI() {
|
||||||
|
return this->pimpl->getRI();
|
||||||
|
}
|
||||||
|
bool Serial::getCD() {
|
||||||
|
return this->pimpl->getCD();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
29
tests/serial_tests.cc
Normal file
29
tests/serial_tests.cc
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
|
||||||
|
// OMG this is so nasty...
|
||||||
|
// #define private public
|
||||||
|
// #define protected public
|
||||||
|
#include <string>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
#include "serial/serial.h"
|
||||||
|
|
||||||
|
using std::string;
|
||||||
|
using std::cout;
|
||||||
|
using std::endl;
|
||||||
|
using serial::Serial;
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
Serial s("/dev/tty.usbserial-A900adHq", 9600, 2000);
|
||||||
|
s.flush();
|
||||||
|
int count = 0;
|
||||||
|
while (count < 10) {
|
||||||
|
size_t available = s.available();
|
||||||
|
cout << "avialable: " << available << endl;
|
||||||
|
string line = s.readline();
|
||||||
|
cout << count << ": " << line;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user