mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2025-03-01 10:33:28 +00:00
Added missing dependency of last commit (serial)
Former-commit-id: 2f50af95f36600716e14d5e884ddd7b55ae982fc
This commit is contained in:
1022
dependencies/build/serial/src/impl/unix.cc
vendored
Executable file
1022
dependencies/build/serial/src/impl/unix.cc
vendored
Executable file
File diff suppressed because it is too large
Load Diff
601
dependencies/build/serial/src/impl/win.cc
vendored
Normal file
601
dependencies/build/serial/src/impl/win.cc
vendored
Normal file
@@ -0,0 +1,601 @@
|
||||
#if defined(_WIN32)
|
||||
|
||||
/* Copyright 2012 William Woodall and John Harrison */
|
||||
|
||||
#include "serial/impl/win.h"
|
||||
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
using std::stringstream;
|
||||
using std::invalid_argument;
|
||||
using serial::Serial;
|
||||
using serial::Timeout;
|
||||
using serial::bytesize_t;
|
||||
using serial::parity_t;
|
||||
using serial::stopbits_t;
|
||||
using serial::flowcontrol_t;
|
||||
using serial::SerialException;
|
||||
using serial::PortNotOpenedException;
|
||||
using serial::IOException;
|
||||
|
||||
|
||||
Serial::SerialImpl::SerialImpl (const string &port, unsigned long baudrate,
|
||||
bytesize_t bytesize,
|
||||
parity_t parity, stopbits_t stopbits,
|
||||
flowcontrol_t flowcontrol)
|
||||
: port_ (port.begin(), port.end()), fd_ (INVALID_HANDLE_VALUE), is_open_ (false),
|
||||
baudrate_ (baudrate), parity_ (parity),
|
||||
bytesize_ (bytesize), stopbits_ (stopbits), flowcontrol_ (flowcontrol)
|
||||
{
|
||||
read_mutex = CreateMutex(NULL, false, NULL);
|
||||
write_mutex = CreateMutex(NULL, false, NULL);
|
||||
if (port_.empty () == false)
|
||||
open ();
|
||||
}
|
||||
|
||||
Serial::SerialImpl::~SerialImpl ()
|
||||
{
|
||||
this->close();
|
||||
CloseHandle(read_mutex);
|
||||
CloseHandle(write_mutex);
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::open ()
|
||||
{
|
||||
if (port_.empty ()) {
|
||||
throw invalid_argument ("Empty port is invalid.");
|
||||
}
|
||||
if (is_open_ == true) {
|
||||
throw SerialException ("Serial port already open.");
|
||||
}
|
||||
|
||||
LPCWSTR lp_port = port_.c_str();
|
||||
fd_ = CreateFileW(lp_port,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
0,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
0);
|
||||
|
||||
if (fd_ == INVALID_HANDLE_VALUE) {
|
||||
DWORD errno_ = GetLastError();
|
||||
stringstream ss;
|
||||
switch (errno_) {
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
// Use this->getPort to convert to a std::string
|
||||
ss << "Specified port, " << this->getPort() << ", does not exist.";
|
||||
THROW (IOException, ss.str().c_str());
|
||||
default:
|
||||
ss << "Unknown error opening the serial port: " << errno;
|
||||
THROW (IOException, ss.str().c_str());
|
||||
}
|
||||
}
|
||||
|
||||
reconfigurePort();
|
||||
is_open_ = true;
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::reconfigurePort ()
|
||||
{
|
||||
if (fd_ == INVALID_HANDLE_VALUE) {
|
||||
// Can only operate on a valid file descriptor
|
||||
THROW (IOException, "Invalid file descriptor, is the serial port open?");
|
||||
}
|
||||
|
||||
DCB dcbSerialParams = {0};
|
||||
|
||||
dcbSerialParams.DCBlength=sizeof(dcbSerialParams);
|
||||
|
||||
if (!GetCommState(fd_, &dcbSerialParams)) {
|
||||
//error getting state
|
||||
THROW (IOException, "Error getting the serial port state.");
|
||||
}
|
||||
|
||||
// setup baud rate
|
||||
switch (baudrate_) {
|
||||
#ifdef CBR_0
|
||||
case 0: dcbSerialParams.BaudRate = CBR_0; break;
|
||||
#endif
|
||||
#ifdef CBR_50
|
||||
case 50: dcbSerialParams.BaudRate = CBR_50; break;
|
||||
#endif
|
||||
#ifdef CBR_75
|
||||
case 75: dcbSerialParams.BaudRate = CBR_75; break;
|
||||
#endif
|
||||
#ifdef CBR_110
|
||||
case 110: dcbSerialParams.BaudRate = CBR_110; break;
|
||||
#endif
|
||||
#ifdef CBR_134
|
||||
case 134: dcbSerialParams.BaudRate = CBR_134; break;
|
||||
#endif
|
||||
#ifdef CBR_150
|
||||
case 150: dcbSerialParams.BaudRate = CBR_150; break;
|
||||
#endif
|
||||
#ifdef CBR_200
|
||||
case 200: dcbSerialParams.BaudRate = CBR_200; break;
|
||||
#endif
|
||||
#ifdef CBR_300
|
||||
case 300: dcbSerialParams.BaudRate = CBR_300; break;
|
||||
#endif
|
||||
#ifdef CBR_600
|
||||
case 600: dcbSerialParams.BaudRate = CBR_600; break;
|
||||
#endif
|
||||
#ifdef CBR_1200
|
||||
case 1200: dcbSerialParams.BaudRate = CBR_1200; break;
|
||||
#endif
|
||||
#ifdef CBR_1800
|
||||
case 1800: dcbSerialParams.BaudRate = CBR_1800; break;
|
||||
#endif
|
||||
#ifdef CBR_2400
|
||||
case 2400: dcbSerialParams.BaudRate = CBR_2400; break;
|
||||
#endif
|
||||
#ifdef CBR_4800
|
||||
case 4800: dcbSerialParams.BaudRate = CBR_4800; break;
|
||||
#endif
|
||||
#ifdef CBR_7200
|
||||
case 7200: dcbSerialParams.BaudRate = CBR_7200; break;
|
||||
#endif
|
||||
#ifdef CBR_9600
|
||||
case 9600: dcbSerialParams.BaudRate = CBR_9600; break;
|
||||
#endif
|
||||
#ifdef CBR_14400
|
||||
case 14400: dcbSerialParams.BaudRate = CBR_14400; break;
|
||||
#endif
|
||||
#ifdef CBR_19200
|
||||
case 19200: dcbSerialParams.BaudRate = CBR_19200; break;
|
||||
#endif
|
||||
#ifdef CBR_28800
|
||||
case 28800: dcbSerialParams.BaudRate = CBR_28800; break;
|
||||
#endif
|
||||
#ifdef CBR_57600
|
||||
case 57600: dcbSerialParams.BaudRate = CBR_57600; break;
|
||||
#endif
|
||||
#ifdef CBR_76800
|
||||
case 76800: dcbSerialParams.BaudRate = CBR_76800; break;
|
||||
#endif
|
||||
#ifdef CBR_38400
|
||||
case 38400: dcbSerialParams.BaudRate = CBR_38400; break;
|
||||
#endif
|
||||
#ifdef CBR_115200
|
||||
case 115200: dcbSerialParams.BaudRate = CBR_115200; break;
|
||||
#endif
|
||||
#ifdef CBR_128000
|
||||
case 128000: dcbSerialParams.BaudRate = CBR_128000; break;
|
||||
#endif
|
||||
#ifdef CBR_153600
|
||||
case 153600: dcbSerialParams.BaudRate = CBR_153600; break;
|
||||
#endif
|
||||
#ifdef CBR_230400
|
||||
case 230400: dcbSerialParams.BaudRate = CBR_230400; break;
|
||||
#endif
|
||||
#ifdef CBR_256000
|
||||
case 256000: dcbSerialParams.BaudRate = CBR_256000; break;
|
||||
#endif
|
||||
#ifdef CBR_460800
|
||||
case 460800: dcbSerialParams.BaudRate = CBR_460800; break;
|
||||
#endif
|
||||
#ifdef CBR_921600
|
||||
case 921600: dcbSerialParams.BaudRate = CBR_921600; break;
|
||||
#endif
|
||||
default:
|
||||
// Try to blindly assign it
|
||||
dcbSerialParams.BaudRate = baudrate_;
|
||||
}
|
||||
|
||||
// setup char len
|
||||
if (bytesize_ == eightbits)
|
||||
dcbSerialParams.ByteSize = 8;
|
||||
else if (bytesize_ == sevenbits)
|
||||
dcbSerialParams.ByteSize = 7;
|
||||
else if (bytesize_ == sixbits)
|
||||
dcbSerialParams.ByteSize = 6;
|
||||
else if (bytesize_ == fivebits)
|
||||
dcbSerialParams.ByteSize = 5;
|
||||
else
|
||||
throw invalid_argument ("invalid char len");
|
||||
|
||||
// setup stopbits
|
||||
if (stopbits_ == stopbits_one)
|
||||
dcbSerialParams.StopBits = ONESTOPBIT;
|
||||
else if (stopbits_ == stopbits_one_point_five)
|
||||
dcbSerialParams.StopBits = ONE5STOPBITS;
|
||||
else if (stopbits_ == stopbits_two)
|
||||
dcbSerialParams.StopBits = TWOSTOPBITS;
|
||||
else
|
||||
throw invalid_argument ("invalid stop bit");
|
||||
|
||||
// setup parity
|
||||
if (parity_ == parity_none) {
|
||||
dcbSerialParams.Parity = NOPARITY;
|
||||
} else if (parity_ == parity_even) {
|
||||
dcbSerialParams.Parity = EVENPARITY;
|
||||
} else if (parity_ == parity_odd) {
|
||||
dcbSerialParams.Parity = ODDPARITY;
|
||||
} else {
|
||||
throw invalid_argument ("invalid parity");
|
||||
}
|
||||
|
||||
// setup flowcontrol
|
||||
if (flowcontrol_ == flowcontrol_none) {
|
||||
dcbSerialParams.fOutxCtsFlow = false;
|
||||
dcbSerialParams.fRtsControl = 0x00;
|
||||
dcbSerialParams.fOutX = false;
|
||||
dcbSerialParams.fInX = false;
|
||||
}
|
||||
if (flowcontrol_ == flowcontrol_software) {
|
||||
dcbSerialParams.fOutxCtsFlow = false;
|
||||
dcbSerialParams.fRtsControl = 0x00;
|
||||
dcbSerialParams.fOutX = true;
|
||||
dcbSerialParams.fInX = true;
|
||||
}
|
||||
if (flowcontrol_ == flowcontrol_hardware) {
|
||||
dcbSerialParams.fOutxCtsFlow = true;
|
||||
dcbSerialParams.fRtsControl = 0x03;
|
||||
dcbSerialParams.fOutX = false;
|
||||
dcbSerialParams.fInX = false;
|
||||
}
|
||||
|
||||
// activate settings
|
||||
if (!SetCommState(fd_, &dcbSerialParams)){
|
||||
THROW (IOException, "Error setting serial port settings.");
|
||||
}
|
||||
|
||||
// Setup timeouts
|
||||
COMMTIMEOUTS timeouts = {0};
|
||||
timeouts.ReadIntervalTimeout = timeout_.inter_byte_timeout;
|
||||
timeouts.ReadTotalTimeoutConstant = timeout_.read_timeout_constant;
|
||||
timeouts.ReadTotalTimeoutMultiplier = timeout_.read_timeout_multiplier;
|
||||
timeouts.WriteTotalTimeoutConstant = timeout_.write_timeout_constant;
|
||||
timeouts.WriteTotalTimeoutMultiplier = timeout_.write_timeout_multiplier;
|
||||
if (!SetCommTimeouts(fd_, &timeouts)) {
|
||||
THROW (IOException, "Error setting timeouts.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::close ()
|
||||
{
|
||||
if (is_open_ == true) {
|
||||
if (fd_ != INVALID_HANDLE_VALUE) {
|
||||
CloseHandle(fd_);
|
||||
fd_ = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
is_open_ = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Serial::SerialImpl::isOpen () const
|
||||
{
|
||||
return is_open_;
|
||||
}
|
||||
|
||||
size_t
|
||||
Serial::SerialImpl::available ()
|
||||
{
|
||||
if (!is_open_) {
|
||||
return 0;
|
||||
}
|
||||
COMSTAT cs;
|
||||
if (!ClearCommError(fd_, NULL, &cs)) {
|
||||
stringstream ss;
|
||||
ss << "Error while checking status of the serial port: " << GetLastError();
|
||||
THROW (IOException, ss.str().c_str());
|
||||
}
|
||||
return static_cast<size_t>(cs.cbInQue);
|
||||
}
|
||||
|
||||
size_t
|
||||
Serial::SerialImpl::read (uint8_t *buf, size_t size)
|
||||
{
|
||||
if (!is_open_) {
|
||||
throw PortNotOpenedException ("Serial::read");
|
||||
}
|
||||
DWORD bytes_read;
|
||||
if (!ReadFile(fd_, buf, size, &bytes_read, NULL)) {
|
||||
stringstream ss;
|
||||
ss << "Error while reading from the serial port: " << GetLastError();
|
||||
THROW (IOException, ss.str().c_str());
|
||||
}
|
||||
return (size_t) (bytes_read);
|
||||
}
|
||||
|
||||
size_t
|
||||
Serial::SerialImpl::write (const uint8_t *data, size_t length)
|
||||
{
|
||||
if (is_open_ == false) {
|
||||
throw PortNotOpenedException ("Serial::write");
|
||||
}
|
||||
DWORD bytes_written;
|
||||
if (!WriteFile(fd_, data, length, &bytes_written, NULL)) {
|
||||
stringstream ss;
|
||||
ss << "Error while writing to the serial port: " << GetLastError();
|
||||
THROW (IOException, ss.str().c_str());
|
||||
}
|
||||
return (size_t) (bytes_written);
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::setPort (const string &port)
|
||||
{
|
||||
port_ = wstring(port.begin(), port.end());
|
||||
}
|
||||
|
||||
string
|
||||
Serial::SerialImpl::getPort () const
|
||||
{
|
||||
return string(port_.begin(), port_.end());
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::setTimeout (serial::Timeout &timeout)
|
||||
{
|
||||
timeout_ = timeout;
|
||||
if (is_open_) {
|
||||
reconfigurePort ();
|
||||
}
|
||||
}
|
||||
|
||||
serial::Timeout
|
||||
Serial::SerialImpl::getTimeout () const
|
||||
{
|
||||
return timeout_;
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::setBaudrate (unsigned long baudrate)
|
||||
{
|
||||
baudrate_ = baudrate;
|
||||
if (is_open_) {
|
||||
reconfigurePort ();
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long
|
||||
Serial::SerialImpl::getBaudrate () const
|
||||
{
|
||||
return baudrate_;
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::setBytesize (serial::bytesize_t bytesize)
|
||||
{
|
||||
bytesize_ = bytesize;
|
||||
if (is_open_) {
|
||||
reconfigurePort ();
|
||||
}
|
||||
}
|
||||
|
||||
serial::bytesize_t
|
||||
Serial::SerialImpl::getBytesize () const
|
||||
{
|
||||
return bytesize_;
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::setParity (serial::parity_t parity)
|
||||
{
|
||||
parity_ = parity;
|
||||
if (is_open_) {
|
||||
reconfigurePort ();
|
||||
}
|
||||
}
|
||||
|
||||
serial::parity_t
|
||||
Serial::SerialImpl::getParity () const
|
||||
{
|
||||
return parity_;
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::setStopbits (serial::stopbits_t stopbits)
|
||||
{
|
||||
stopbits_ = stopbits;
|
||||
if (is_open_) {
|
||||
reconfigurePort ();
|
||||
}
|
||||
}
|
||||
|
||||
serial::stopbits_t
|
||||
Serial::SerialImpl::getStopbits () const
|
||||
{
|
||||
return stopbits_;
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::setFlowcontrol (serial::flowcontrol_t flowcontrol)
|
||||
{
|
||||
flowcontrol_ = flowcontrol;
|
||||
if (is_open_) {
|
||||
reconfigurePort ();
|
||||
}
|
||||
}
|
||||
|
||||
serial::flowcontrol_t
|
||||
Serial::SerialImpl::getFlowcontrol () const
|
||||
{
|
||||
return flowcontrol_;
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::flush ()
|
||||
{
|
||||
if (is_open_ == false) {
|
||||
throw PortNotOpenedException ("Serial::flush");
|
||||
}
|
||||
FlushFileBuffers (fd_);
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::flushInput ()
|
||||
{
|
||||
THROW (IOException, "flushInput is not supported on Windows.");
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::flushOutput ()
|
||||
{
|
||||
THROW (IOException, "flushOutput is not supported on Windows.");
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::sendBreak (int duration)
|
||||
{
|
||||
THROW (IOException, "sendBreak is not supported on Windows.");
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::setBreak (bool level)
|
||||
{
|
||||
if (is_open_ == false) {
|
||||
throw PortNotOpenedException ("Serial::setBreak");
|
||||
}
|
||||
if (level) {
|
||||
EscapeCommFunction (fd_, SETBREAK);
|
||||
} else {
|
||||
EscapeCommFunction (fd_, CLRBREAK);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::setRTS (bool level)
|
||||
{
|
||||
if (is_open_ == false) {
|
||||
throw PortNotOpenedException ("Serial::setRTS");
|
||||
}
|
||||
if (level) {
|
||||
EscapeCommFunction (fd_, SETRTS);
|
||||
} else {
|
||||
EscapeCommFunction (fd_, CLRRTS);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::setDTR (bool level)
|
||||
{
|
||||
if (is_open_ == false) {
|
||||
throw PortNotOpenedException ("Serial::setDTR");
|
||||
}
|
||||
if (level) {
|
||||
EscapeCommFunction (fd_, SETDTR);
|
||||
} else {
|
||||
EscapeCommFunction (fd_, CLRDTR);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Serial::SerialImpl::waitForChange ()
|
||||
{
|
||||
if (is_open_ == false) {
|
||||
throw PortNotOpenedException ("Serial::waitForChange");
|
||||
}
|
||||
DWORD dwCommEvent;
|
||||
|
||||
if (!SetCommMask(fd_, EV_CTS | EV_DSR | EV_RING | EV_RLSD)) {
|
||||
// Error setting communications mask
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!WaitCommEvent(fd_, &dwCommEvent, NULL)) {
|
||||
// An error occurred waiting for the event.
|
||||
return false;
|
||||
} else {
|
||||
// Event has occurred.
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
Serial::SerialImpl::getCTS ()
|
||||
{
|
||||
if (is_open_ == false) {
|
||||
throw PortNotOpenedException ("Serial::getCTS");
|
||||
}
|
||||
DWORD dwModemStatus;
|
||||
if (!GetCommModemStatus(fd_, &dwModemStatus)) {
|
||||
THROW (IOException, "Error getting the status of the CTS line.");
|
||||
}
|
||||
|
||||
return (MS_CTS_ON & dwModemStatus) != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Serial::SerialImpl::getDSR ()
|
||||
{
|
||||
if (is_open_ == false) {
|
||||
throw PortNotOpenedException ("Serial::getDSR");
|
||||
}
|
||||
DWORD dwModemStatus;
|
||||
if (!GetCommModemStatus(fd_, &dwModemStatus)) {
|
||||
THROW (IOException, "Error getting the status of the DSR line.");
|
||||
}
|
||||
|
||||
return (MS_DSR_ON & dwModemStatus) != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Serial::SerialImpl::getRI()
|
||||
{
|
||||
if (is_open_ == false) {
|
||||
throw PortNotOpenedException ("Serial::getRI");
|
||||
}
|
||||
DWORD dwModemStatus;
|
||||
if (!GetCommModemStatus(fd_, &dwModemStatus)) {
|
||||
THROW (IOException, "Error getting the status of the RI line.");
|
||||
}
|
||||
|
||||
return (MS_RING_ON & dwModemStatus) != 0;
|
||||
}
|
||||
|
||||
bool
|
||||
Serial::SerialImpl::getCD()
|
||||
{
|
||||
if (is_open_ == false) {
|
||||
throw PortNotOpenedException ("Serial::getCD");
|
||||
}
|
||||
DWORD dwModemStatus;
|
||||
if (!GetCommModemStatus(fd_, &dwModemStatus)) {
|
||||
// Error in GetCommModemStatus;
|
||||
THROW (IOException, "Error getting the status of the CD line.");
|
||||
}
|
||||
|
||||
return (MS_RLSD_ON & dwModemStatus) != 0;
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::readLock()
|
||||
{
|
||||
if (WaitForSingleObject(read_mutex, INFINITE) != WAIT_OBJECT_0) {
|
||||
THROW (IOException, "Error claiming read mutex.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::readUnlock()
|
||||
{
|
||||
if (!ReleaseMutex(read_mutex)) {
|
||||
THROW (IOException, "Error releasing read mutex.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::writeLock()
|
||||
{
|
||||
if (WaitForSingleObject(write_mutex, INFINITE) != WAIT_OBJECT_0) {
|
||||
THROW (IOException, "Error claiming write mutex.");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Serial::SerialImpl::writeUnlock()
|
||||
{
|
||||
if (!ReleaseMutex(write_mutex)) {
|
||||
THROW (IOException, "Error releasing write mutex.");
|
||||
}
|
||||
}
|
||||
|
||||
#endif // #if defined(_WIN32)
|
||||
|
397
dependencies/build/serial/src/serial.cc
vendored
Executable file
397
dependencies/build/serial/src/serial.cc
vendored
Executable file
@@ -0,0 +1,397 @@
|
||||
/* Copyright 2012 William Woodall and John Harrison */
|
||||
#if !defined(_WIN32) && !defined(__OpenBSD__)
|
||||
# include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include "serial/serial.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "serial/impl/win.h"
|
||||
#else
|
||||
#include "serial/impl/unix.h"
|
||||
#endif
|
||||
|
||||
using std::invalid_argument;
|
||||
using std::min;
|
||||
using std::numeric_limits;
|
||||
using std::vector;
|
||||
using std::size_t;
|
||||
using std::string;
|
||||
|
||||
using serial::Serial;
|
||||
using serial::SerialException;
|
||||
using serial::IOException;
|
||||
using serial::bytesize_t;
|
||||
using serial::parity_t;
|
||||
using serial::stopbits_t;
|
||||
using serial::flowcontrol_t;
|
||||
|
||||
class Serial::ScopedReadLock {
|
||||
public:
|
||||
ScopedReadLock(SerialImpl *pimpl) : pimpl_(pimpl) {
|
||||
this->pimpl_->readLock();
|
||||
}
|
||||
~ScopedReadLock() {
|
||||
this->pimpl_->readUnlock();
|
||||
}
|
||||
private:
|
||||
// Disable copy constructors
|
||||
ScopedReadLock(const ScopedReadLock&);
|
||||
const ScopedReadLock& operator=(ScopedReadLock);
|
||||
|
||||
SerialImpl *pimpl_;
|
||||
};
|
||||
|
||||
class Serial::ScopedWriteLock {
|
||||
public:
|
||||
ScopedWriteLock(SerialImpl *pimpl) : pimpl_(pimpl) {
|
||||
this->pimpl_->writeLock();
|
||||
}
|
||||
~ScopedWriteLock() {
|
||||
this->pimpl_->writeUnlock();
|
||||
}
|
||||
private:
|
||||
// Disable copy constructors
|
||||
ScopedWriteLock(const ScopedWriteLock&);
|
||||
const ScopedWriteLock& operator=(ScopedWriteLock);
|
||||
SerialImpl *pimpl_;
|
||||
};
|
||||
|
||||
Serial::Serial (const string &port, uint32_t baudrate, serial::Timeout timeout,
|
||||
bytesize_t bytesize, parity_t parity, stopbits_t stopbits,
|
||||
flowcontrol_t flowcontrol)
|
||||
: read_cache_(""), pimpl_(new SerialImpl (port, baudrate, bytesize, parity,
|
||||
stopbits, flowcontrol))
|
||||
{
|
||||
pimpl_->setTimeout(timeout);
|
||||
}
|
||||
|
||||
Serial::~Serial ()
|
||||
{
|
||||
delete pimpl_;
|
||||
}
|
||||
|
||||
void
|
||||
Serial::open ()
|
||||
{
|
||||
pimpl_->open ();
|
||||
}
|
||||
|
||||
void
|
||||
Serial::close ()
|
||||
{
|
||||
pimpl_->close ();
|
||||
}
|
||||
|
||||
bool
|
||||
Serial::isOpen () const
|
||||
{
|
||||
return pimpl_->isOpen ();
|
||||
}
|
||||
|
||||
size_t
|
||||
Serial::available ()
|
||||
{
|
||||
return pimpl_->available ();
|
||||
}
|
||||
|
||||
size_t
|
||||
Serial::read_ (uint8_t *buffer, size_t size)
|
||||
{
|
||||
return this->pimpl_->read (buffer, size);
|
||||
}
|
||||
|
||||
size_t
|
||||
Serial::read (uint8_t *buffer, size_t size)
|
||||
{
|
||||
ScopedReadLock (this->pimpl_);
|
||||
return this->pimpl_->read (buffer, size);
|
||||
}
|
||||
|
||||
size_t
|
||||
Serial::read (std::vector<uint8_t> &buffer, size_t size)
|
||||
{
|
||||
ScopedReadLock (this->pimpl_);
|
||||
uint8_t *buffer_ = new uint8_t[size];
|
||||
size_t bytes_read = this->pimpl_->read (buffer_, size);
|
||||
buffer.insert (buffer.end (), buffer_, buffer_+bytes_read);
|
||||
delete[] buffer_;
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
size_t
|
||||
Serial::read (std::string &buffer, size_t size)
|
||||
{
|
||||
ScopedReadLock (this->pimpl_);
|
||||
uint8_t *buffer_ = new uint8_t[size];
|
||||
size_t bytes_read = this->pimpl_->read (buffer_, size);
|
||||
buffer.append (reinterpret_cast<const char*>(buffer_), bytes_read);
|
||||
delete[] buffer_;
|
||||
return bytes_read;
|
||||
}
|
||||
|
||||
string
|
||||
Serial::read (size_t size)
|
||||
{
|
||||
std::string buffer;
|
||||
this->read (buffer, size);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
size_t
|
||||
Serial::readline (string &buffer, size_t size, string eol)
|
||||
{
|
||||
ScopedReadLock (this->pimpl_);
|
||||
size_t eol_len = eol.length ();
|
||||
uint8_t *buffer_ = static_cast<uint8_t*>
|
||||
(alloca (size * sizeof (uint8_t)));
|
||||
size_t read_so_far = 0;
|
||||
while (true)
|
||||
{
|
||||
size_t bytes_read = this->read_ (buffer_ + read_so_far, 1);
|
||||
read_so_far += bytes_read;
|
||||
if (bytes_read == 0) {
|
||||
break; // Timeout occured on reading 1 byte
|
||||
}
|
||||
if (string (reinterpret_cast<const char*>
|
||||
(buffer_ + read_so_far - eol_len), eol_len) == eol) {
|
||||
break; // EOL found
|
||||
}
|
||||
if (read_so_far == size) {
|
||||
break; // Reached the maximum read length
|
||||
}
|
||||
}
|
||||
buffer.append(reinterpret_cast<const char*> (buffer_), read_so_far);
|
||||
return read_so_far;
|
||||
}
|
||||
|
||||
string
|
||||
Serial::readline (size_t size, string eol)
|
||||
{
|
||||
std::string buffer;
|
||||
this->readline (buffer, size, eol);
|
||||
return buffer;
|
||||
}
|
||||
|
||||
vector<string>
|
||||
Serial::readlines (size_t size, string eol)
|
||||
{
|
||||
ScopedReadLock (this->pimpl_);
|
||||
std::vector<std::string> lines;
|
||||
size_t eol_len = eol.length ();
|
||||
uint8_t *buffer_ = static_cast<uint8_t*>
|
||||
(alloca (size * sizeof (uint8_t)));
|
||||
size_t read_so_far = 0;
|
||||
size_t start_of_line = 0;
|
||||
while (read_so_far < size) {
|
||||
size_t bytes_read = this->read_ (buffer_+read_so_far, 1);
|
||||
read_so_far += bytes_read;
|
||||
if (bytes_read == 0) {
|
||||
if (start_of_line != read_so_far) {
|
||||
lines.push_back (
|
||||
string (reinterpret_cast<const char*> (buffer_ + start_of_line),
|
||||
read_so_far - start_of_line));
|
||||
}
|
||||
break; // Timeout occured on reading 1 byte
|
||||
}
|
||||
if (string (reinterpret_cast<const char*>
|
||||
(buffer_ + read_so_far - eol_len), eol_len) == eol) {
|
||||
// EOL found
|
||||
lines.push_back(
|
||||
string(reinterpret_cast<const char*> (buffer_ + start_of_line),
|
||||
read_so_far - start_of_line));
|
||||
start_of_line = read_so_far;
|
||||
}
|
||||
if (read_so_far == size) {
|
||||
if (start_of_line != read_so_far) {
|
||||
lines.push_back(
|
||||
string(reinterpret_cast<const char*> (buffer_ + start_of_line),
|
||||
read_so_far - start_of_line));
|
||||
}
|
||||
break; // Reached the maximum read length
|
||||
}
|
||||
}
|
||||
return lines;
|
||||
}
|
||||
|
||||
size_t
|
||||
Serial::write (const string &data)
|
||||
{
|
||||
ScopedWriteLock(this->pimpl_);
|
||||
return this->write_ (reinterpret_cast<const uint8_t*>(data.c_str()),
|
||||
data.length());
|
||||
}
|
||||
|
||||
size_t
|
||||
Serial::write (const std::vector<uint8_t> &data)
|
||||
{
|
||||
ScopedWriteLock(this->pimpl_);
|
||||
return this->write_ (&data[0], data.size());
|
||||
}
|
||||
|
||||
size_t
|
||||
Serial::write (const uint8_t *data, size_t size)
|
||||
{
|
||||
ScopedWriteLock(this->pimpl_);
|
||||
return this->write_(data, size);
|
||||
}
|
||||
|
||||
size_t
|
||||
Serial::write_ (const uint8_t *data, size_t length)
|
||||
{
|
||||
return pimpl_->write (data, length);
|
||||
}
|
||||
|
||||
void
|
||||
Serial::setPort (const string &port)
|
||||
{
|
||||
ScopedReadLock(this->pimpl_);
|
||||
ScopedWriteLock(this->pimpl_);
|
||||
bool was_open = pimpl_->isOpen ();
|
||||
if (was_open) close();
|
||||
pimpl_->setPort (port);
|
||||
if (was_open) open ();
|
||||
}
|
||||
|
||||
string
|
||||
Serial::getPort () const
|
||||
{
|
||||
return pimpl_->getPort ();
|
||||
}
|
||||
|
||||
void
|
||||
Serial::setTimeout (serial::Timeout &timeout)
|
||||
{
|
||||
pimpl_->setTimeout (timeout);
|
||||
}
|
||||
|
||||
serial::Timeout
|
||||
Serial::getTimeout () const {
|
||||
return pimpl_->getTimeout ();
|
||||
}
|
||||
|
||||
void
|
||||
Serial::setBaudrate (uint32_t baudrate)
|
||||
{
|
||||
pimpl_->setBaudrate (baudrate);
|
||||
}
|
||||
|
||||
uint32_t
|
||||
Serial::getBaudrate () const
|
||||
{
|
||||
return uint32_t(pimpl_->getBaudrate ());
|
||||
}
|
||||
|
||||
void
|
||||
Serial::setBytesize (bytesize_t bytesize)
|
||||
{
|
||||
pimpl_->setBytesize (bytesize);
|
||||
}
|
||||
|
||||
bytesize_t
|
||||
Serial::getBytesize () const
|
||||
{
|
||||
return pimpl_->getBytesize ();
|
||||
}
|
||||
|
||||
void
|
||||
Serial::setParity (parity_t parity)
|
||||
{
|
||||
pimpl_->setParity (parity);
|
||||
}
|
||||
|
||||
parity_t
|
||||
Serial::getParity () const
|
||||
{
|
||||
return pimpl_->getParity ();
|
||||
}
|
||||
|
||||
void
|
||||
Serial::setStopbits (stopbits_t stopbits)
|
||||
{
|
||||
pimpl_->setStopbits (stopbits);
|
||||
}
|
||||
|
||||
stopbits_t
|
||||
Serial::getStopbits () const
|
||||
{
|
||||
return pimpl_->getStopbits ();
|
||||
}
|
||||
|
||||
void
|
||||
Serial::setFlowcontrol (flowcontrol_t flowcontrol)
|
||||
{
|
||||
pimpl_->setFlowcontrol (flowcontrol);
|
||||
}
|
||||
|
||||
flowcontrol_t
|
||||
Serial::getFlowcontrol () const
|
||||
{
|
||||
return pimpl_->getFlowcontrol ();
|
||||
}
|
||||
|
||||
void Serial::flush ()
|
||||
{
|
||||
ScopedReadLock(this->pimpl_);
|
||||
ScopedWriteLock(this->pimpl_);
|
||||
pimpl_->flush ();
|
||||
read_cache_.clear ();
|
||||
}
|
||||
|
||||
void Serial::flushInput ()
|
||||
{
|
||||
ScopedReadLock(this->pimpl_);
|
||||
pimpl_->flushInput ();
|
||||
}
|
||||
|
||||
void Serial::flushOutput ()
|
||||
{
|
||||
ScopedWriteLock(this->pimpl_);
|
||||
pimpl_->flushOutput ();
|
||||
read_cache_.clear ();
|
||||
}
|
||||
|
||||
void Serial::sendBreak (int duration)
|
||||
{
|
||||
pimpl_->sendBreak (duration);
|
||||
}
|
||||
|
||||
void Serial::setBreak (bool level)
|
||||
{
|
||||
pimpl_->setBreak (level);
|
||||
}
|
||||
|
||||
void Serial::setRTS (bool level)
|
||||
{
|
||||
pimpl_->setRTS (level);
|
||||
}
|
||||
|
||||
void Serial::setDTR (bool level)
|
||||
{
|
||||
pimpl_->setDTR (level);
|
||||
}
|
||||
|
||||
bool Serial::waitForChange()
|
||||
{
|
||||
return pimpl_->waitForChange();
|
||||
}
|
||||
|
||||
bool Serial::getCTS ()
|
||||
{
|
||||
return pimpl_->getCTS ();
|
||||
}
|
||||
|
||||
bool Serial::getDSR ()
|
||||
{
|
||||
return pimpl_->getDSR ();
|
||||
}
|
||||
|
||||
bool Serial::getRI ()
|
||||
{
|
||||
return pimpl_->getRI ();
|
||||
}
|
||||
|
||||
bool Serial::getCD ()
|
||||
{
|
||||
return pimpl_->getCD ();
|
||||
}
|
Reference in New Issue
Block a user