mirror of
https://github.com/wjwwood/serial.git
synced 2026-01-22 11:44:53 +08:00
Reverting the deletion of the baud rate validation.
This commit is contained in:
parent
20f552bc80
commit
bca4eba672
178
src/impl/unix.cc
178
src/impl/unix.cc
@ -31,6 +31,7 @@ using serial::SerialExecption;
|
|||||||
using serial::PortNotOpenedException;
|
using serial::PortNotOpenedException;
|
||||||
using serial::IOException;
|
using serial::IOException;
|
||||||
|
|
||||||
|
|
||||||
Serial::SerialImpl::SerialImpl (const string &port, unsigned long baudrate,
|
Serial::SerialImpl::SerialImpl (const string &port, unsigned long baudrate,
|
||||||
long timeout, bytesize_t bytesize,
|
long timeout, bytesize_t bytesize,
|
||||||
parity_t parity, stopbits_t stopbits,
|
parity_t parity, stopbits_t stopbits,
|
||||||
@ -114,8 +115,131 @@ Serial::SerialImpl::reconfigurePort ()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// setup baud rate
|
// setup baud rate
|
||||||
// TODO(ash_git): validate baud rate
|
bool custom_baud = false;
|
||||||
cfsetspeed(&options, baudrate_);
|
speed_t baud;
|
||||||
|
switch (baudrate_)
|
||||||
|
{
|
||||||
|
#ifdef B0
|
||||||
|
case 0: baud = B0; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B50
|
||||||
|
case 50: baud = B50; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B75
|
||||||
|
case 75: baud = B75; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B110
|
||||||
|
case 110: baud = B110; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B134
|
||||||
|
case 134: baud = B134; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B150
|
||||||
|
case 150: baud = B150; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B200
|
||||||
|
case 200: baud = B200; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B300
|
||||||
|
case 300: baud = B300; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B600
|
||||||
|
case 600: baud = B600; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B1200
|
||||||
|
case 1200: baud = B1200; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B1800
|
||||||
|
case 1800: baud = B1800; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B2400
|
||||||
|
case 2400: baud = B2400; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B4800
|
||||||
|
case 4800: baud = B4800; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B7200
|
||||||
|
case 7200: baud = B7200; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B9600
|
||||||
|
case 9600: baud = B9600; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B14400
|
||||||
|
case 14400: baud = B14400; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B19200
|
||||||
|
case 19200: baud = B19200; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B28800
|
||||||
|
case 28800: baud = B28800; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B57600
|
||||||
|
case 57600: baud = B57600; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B76800
|
||||||
|
case 76800: baud = B76800; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B38400
|
||||||
|
case 38400: baud = B38400; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B115200
|
||||||
|
case 115200: baud = B115200; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B128000
|
||||||
|
case 128000: baud = B128000; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B153600
|
||||||
|
case 153600: baud = B153600; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B230400
|
||||||
|
case 230400: baud = B230400; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B256000
|
||||||
|
case 256000: baud = B256000; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B460800
|
||||||
|
case 460800: baud = B460800; break;
|
||||||
|
#endif
|
||||||
|
#ifdef B921600
|
||||||
|
case 921600: baud = B921600; break;
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
custom_baud = true;
|
||||||
|
// Mac OS X 10.x Support
|
||||||
|
#if defined(__APPLE__) && defined(__MACH__)
|
||||||
|
#define IOSSIOSPEED _IOW('T', 2, speed_t)
|
||||||
|
int new_baud = static_cast<int> (baudrate_);
|
||||||
|
if (ioctl (fd_, IOSSIOSPEED, &new_baud, 1) < 0)
|
||||||
|
{
|
||||||
|
throw IOException (errno);
|
||||||
|
}
|
||||||
|
// Linux Support
|
||||||
|
#elif defined(__linux__)
|
||||||
|
struct serial_struct ser;
|
||||||
|
ioctl(fd_, TIOCGSERIAL, &ser);
|
||||||
|
// set custom divisor
|
||||||
|
ser.custom_divisor = ser.baud_base / baudrate;
|
||||||
|
// update flags
|
||||||
|
ser.flags &= ~ASYNC_SPD_MASK;
|
||||||
|
ser.flags |= ASYNC_SPD_CUST;
|
||||||
|
|
||||||
|
if (ioctl(fd_, TIOCSSERIAL, buf) < 0)
|
||||||
|
{
|
||||||
|
throw IOException (errno);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
throw invalid_argument ("OS does not currently support custom bauds");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
if (custom_baud == false)
|
||||||
|
{
|
||||||
|
#ifdef _BSD_SOURCE
|
||||||
|
::cfsetspeed(&options, baud);
|
||||||
|
#else
|
||||||
|
::cfsetispeed(&options, baud);
|
||||||
|
::cfsetospeed(&options, baud);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
// setup char len
|
// setup char len
|
||||||
options.c_cflag &= (unsigned long) ~CSIZE;
|
options.c_cflag &= (unsigned long) ~CSIZE;
|
||||||
@ -265,7 +389,6 @@ Serial::SerialImpl::read (char* buf, size_t size)
|
|||||||
bytes_read = ::read (fd_, buf, size);
|
bytes_read = ::read (fd_, buf, size);
|
||||||
// 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.
|
||||||
// printf("bytes_read: %lu\n", bytes_read);
|
|
||||||
if (bytes_read < 1)
|
if (bytes_read < 1)
|
||||||
{
|
{
|
||||||
// Disconnected devices, at least on Linux, show the
|
// Disconnected devices, at least on Linux, show the
|
||||||
@ -292,24 +415,50 @@ Serial::SerialImpl::write (const string &data)
|
|||||||
throw PortNotOpenedException ("Serial::write");
|
throw PortNotOpenedException ("Serial::write");
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t n = ::write (fd_, data.c_str (), data.length ());
|
fd_set writefds;
|
||||||
|
ssize_t bytes_written = 0;
|
||||||
if (n != static_cast<ssize_t> (data.length ()))
|
while (true)
|
||||||
{
|
{
|
||||||
throw IOException ("Write did not complete");
|
if (timeout_ != -1)
|
||||||
}
|
|
||||||
else if (n == -1)
|
|
||||||
{
|
|
||||||
if (errno == EINTR)
|
|
||||||
{
|
{
|
||||||
return write (data);
|
FD_ZERO (&writefds);
|
||||||
|
FD_SET (fd_, &writefds);
|
||||||
|
struct timeval timeout;
|
||||||
|
timeout.tv_sec = timeout_ / 1000;
|
||||||
|
timeout.tv_usec = static_cast<int> (timeout_ % 1000) * 1000;
|
||||||
|
int r = select (fd_ + 1, NULL, &writefds, NULL, &timeout);
|
||||||
|
|
||||||
|
if (r == -1 && errno == EINTR)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (r == -1)
|
||||||
|
{
|
||||||
|
throw IOException (errno);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timeout_ == -1 || FD_ISSET (fd_, &writefds))
|
||||||
|
{
|
||||||
|
bytes_written = ::write (fd_, data.c_str (), data.length ());
|
||||||
|
// read should always return some data as select reported it was
|
||||||
|
// ready to read when we get to this point.
|
||||||
|
if (bytes_written < 1)
|
||||||
|
{
|
||||||
|
// Disconnected devices, at least on Linux, show the
|
||||||
|
// behavior that they are always ready to read immediately
|
||||||
|
// but reading returns nothing.
|
||||||
|
throw SerialExecption ("device reports readiness to read but "
|
||||||
|
"returned no data (device disconnected?)");
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
throw IOException (errno);
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return static_cast<size_t> (n);
|
|
||||||
|
return static_cast<size_t> (bytes_written);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -538,3 +687,4 @@ Serial::SerialImpl::getCD()
|
|||||||
int s = ioctl (fd_, TIOCMGET, 0);
|
int s = ioctl (fd_, TIOCMGET, 0);
|
||||||
return (s & TIOCM_CD) != 0;
|
return (s & TIOCM_CD) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user