mirror of
https://github.com/hyperion-project/hyperion.ng.git
synced 2023-10-10 13:36:59 +02:00
Serialport (#36)
* migrate serialport to qt5 serialport * remove old serialport add logging to serialport * remove try catch - qt serialport uses plain return values * tiny fix, but not working atm * make it work, tested with adalight
This commit is contained in:
parent
48134d0aef
commit
93e3981df1
1
dependencies/CMakeLists.txt
vendored
1
dependencies/CMakeLists.txt
vendored
@ -1,7 +1,6 @@
|
|||||||
add_subdirectory(build/getoptPlusPlus)
|
add_subdirectory(build/getoptPlusPlus)
|
||||||
add_subdirectory(build/hidapi)
|
add_subdirectory(build/hidapi)
|
||||||
add_subdirectory(build/jsoncpp)
|
add_subdirectory(build/jsoncpp)
|
||||||
add_subdirectory(build/serial)
|
|
||||||
add_subdirectory(build/tinkerforge)
|
add_subdirectory(build/tinkerforge)
|
||||||
|
|
||||||
if(ENABLE_WS281XPWM)
|
if(ENABLE_WS281XPWM)
|
||||||
|
23
dependencies/build/serial/CMakeLists.txt
vendored
23
dependencies/build/serial/CMakeLists.txt
vendored
@ -1,23 +0,0 @@
|
|||||||
|
|
||||||
project(serialport)
|
|
||||||
|
|
||||||
include_directories(../../include)
|
|
||||||
|
|
||||||
## Sources
|
|
||||||
set(serial_SRCS
|
|
||||||
src/serial.cc
|
|
||||||
../../include/serial/serial.h
|
|
||||||
../../include/serial/v8stdint.h)
|
|
||||||
|
|
||||||
if(UNIX)
|
|
||||||
list(APPEND serial_SRCS src/impl/unix.cc)
|
|
||||||
else()
|
|
||||||
list(APPEND serial_SRCS src/impl/win.cc)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
## Add serial library
|
|
||||||
add_library(${PROJECT_NAME} ${serial_SRCS})
|
|
||||||
|
|
||||||
if(UNIX AND NOT APPLE)
|
|
||||||
target_link_libraries(${PROJECT_NAME} rt)
|
|
||||||
endif()
|
|
204
dependencies/build/serial/include/serial/impl/unix.h
vendored
204
dependencies/build/serial/include/serial/impl/unix.h
vendored
@ -1,204 +0,0 @@
|
|||||||
/*!
|
|
||||||
* \file serial/impl/unix.h
|
|
||||||
* \author William Woodall <wjwwood@gmail.com>
|
|
||||||
* \author John Harrison <ash@greaterthaninfinity.com>
|
|
||||||
* \version 0.1
|
|
||||||
*
|
|
||||||
* \section LICENSE
|
|
||||||
*
|
|
||||||
* The MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012 William Woodall, John Harrison
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* \section DESCRIPTION
|
|
||||||
*
|
|
||||||
* This provides a unix based pimpl for the Serial class. This implementation is
|
|
||||||
* based off termios.h and uses select for multiplexing the IO ports.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
|
|
||||||
#ifndef SERIAL_IMPL_UNIX_H
|
|
||||||
#define SERIAL_IMPL_UNIX_H
|
|
||||||
|
|
||||||
#include "serial/serial.h"
|
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
namespace serial {
|
|
||||||
|
|
||||||
using std::size_t;
|
|
||||||
using std::string;
|
|
||||||
using std::invalid_argument;
|
|
||||||
|
|
||||||
using serial::SerialException;
|
|
||||||
using serial::IOException;
|
|
||||||
|
|
||||||
class serial::Serial::SerialImpl {
|
|
||||||
public:
|
|
||||||
SerialImpl (const string &port,
|
|
||||||
unsigned long baudrate,
|
|
||||||
bytesize_t bytesize,
|
|
||||||
parity_t parity,
|
|
||||||
stopbits_t stopbits,
|
|
||||||
flowcontrol_t flowcontrol);
|
|
||||||
|
|
||||||
virtual ~SerialImpl ();
|
|
||||||
|
|
||||||
void
|
|
||||||
open ();
|
|
||||||
|
|
||||||
void
|
|
||||||
close ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
isOpen () const;
|
|
||||||
|
|
||||||
size_t
|
|
||||||
available ();
|
|
||||||
|
|
||||||
size_t
|
|
||||||
read (uint8_t *buf, size_t size = 1);
|
|
||||||
|
|
||||||
size_t
|
|
||||||
write (const uint8_t *data, size_t length);
|
|
||||||
|
|
||||||
void
|
|
||||||
flush ();
|
|
||||||
|
|
||||||
void
|
|
||||||
flushInput ();
|
|
||||||
|
|
||||||
void
|
|
||||||
flushOutput ();
|
|
||||||
|
|
||||||
void
|
|
||||||
sendBreak (int duration);
|
|
||||||
|
|
||||||
void
|
|
||||||
setBreak (bool level);
|
|
||||||
|
|
||||||
void
|
|
||||||
setRTS (bool level);
|
|
||||||
|
|
||||||
void
|
|
||||||
setDTR (bool level);
|
|
||||||
|
|
||||||
bool
|
|
||||||
waitForChange ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getCTS ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getDSR ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getRI ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getCD ();
|
|
||||||
|
|
||||||
void
|
|
||||||
setPort (const string &port);
|
|
||||||
|
|
||||||
string
|
|
||||||
getPort () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setTimeout (Timeout &timeout);
|
|
||||||
|
|
||||||
Timeout
|
|
||||||
getTimeout () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setBaudrate (unsigned long baudrate);
|
|
||||||
|
|
||||||
unsigned long
|
|
||||||
getBaudrate () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setBytesize (bytesize_t bytesize);
|
|
||||||
|
|
||||||
bytesize_t
|
|
||||||
getBytesize () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setParity (parity_t parity);
|
|
||||||
|
|
||||||
parity_t
|
|
||||||
getParity () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setStopbits (stopbits_t stopbits);
|
|
||||||
|
|
||||||
stopbits_t
|
|
||||||
getStopbits () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setFlowcontrol (flowcontrol_t flowcontrol);
|
|
||||||
|
|
||||||
flowcontrol_t
|
|
||||||
getFlowcontrol () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
readLock ();
|
|
||||||
|
|
||||||
void
|
|
||||||
readUnlock ();
|
|
||||||
|
|
||||||
void
|
|
||||||
writeLock ();
|
|
||||||
|
|
||||||
void
|
|
||||||
writeUnlock ();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void reconfigurePort ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
string port_; // Path to the file descriptor
|
|
||||||
int fd_; // The current file descriptor
|
|
||||||
|
|
||||||
bool is_open_;
|
|
||||||
bool xonxoff_;
|
|
||||||
bool rtscts_;
|
|
||||||
|
|
||||||
Timeout timeout_; // Timeout for read operations
|
|
||||||
unsigned long baudrate_; // Baudrate
|
|
||||||
|
|
||||||
parity_t parity_; // Parity
|
|
||||||
bytesize_t bytesize_; // Size of the bytes
|
|
||||||
stopbits_t stopbits_; // Stop Bits
|
|
||||||
flowcontrol_t flowcontrol_; // Flow Control
|
|
||||||
|
|
||||||
// Mutex used to lock the read functions
|
|
||||||
pthread_mutex_t read_mutex;
|
|
||||||
// Mutex used to lock the write functions
|
|
||||||
pthread_mutex_t write_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // SERIAL_IMPL_UNIX_H
|
|
||||||
|
|
||||||
#endif // !defined(_WIN32)
|
|
201
dependencies/build/serial/include/serial/impl/win.h
vendored
201
dependencies/build/serial/include/serial/impl/win.h
vendored
@ -1,201 +0,0 @@
|
|||||||
/*!
|
|
||||||
* \file serial/impl/windows.h
|
|
||||||
* \author William Woodall <wjwwood@gmail.com>
|
|
||||||
* \author John Harrison <ash@greaterthaninfinity.com>
|
|
||||||
* \version 0.1
|
|
||||||
*
|
|
||||||
* \section LICENSE
|
|
||||||
*
|
|
||||||
* The MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012 William Woodall, John Harrison
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* \section DESCRIPTION
|
|
||||||
*
|
|
||||||
* This provides a windows implementation of the Serial class interface.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
|
|
||||||
#ifndef SERIAL_IMPL_WINDOWS_H
|
|
||||||
#define SERIAL_IMPL_WINDOWS_H
|
|
||||||
|
|
||||||
#include "serial/serial.h"
|
|
||||||
|
|
||||||
#include "windows.h"
|
|
||||||
|
|
||||||
namespace serial {
|
|
||||||
|
|
||||||
using std::string;
|
|
||||||
using std::wstring;
|
|
||||||
using std::invalid_argument;
|
|
||||||
|
|
||||||
using serial::SerialException;
|
|
||||||
using serial::IOException;
|
|
||||||
|
|
||||||
class serial::Serial::SerialImpl {
|
|
||||||
public:
|
|
||||||
SerialImpl (const string &port,
|
|
||||||
unsigned long baudrate,
|
|
||||||
bytesize_t bytesize,
|
|
||||||
parity_t parity,
|
|
||||||
stopbits_t stopbits,
|
|
||||||
flowcontrol_t flowcontrol);
|
|
||||||
|
|
||||||
virtual ~SerialImpl ();
|
|
||||||
|
|
||||||
void
|
|
||||||
open ();
|
|
||||||
|
|
||||||
void
|
|
||||||
close ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
isOpen () const;
|
|
||||||
|
|
||||||
size_t
|
|
||||||
available ();
|
|
||||||
|
|
||||||
size_t
|
|
||||||
read (uint8_t *buf, size_t size = 1);
|
|
||||||
|
|
||||||
size_t
|
|
||||||
write (const uint8_t *data, size_t length);
|
|
||||||
|
|
||||||
void
|
|
||||||
flush ();
|
|
||||||
|
|
||||||
void
|
|
||||||
flushInput ();
|
|
||||||
|
|
||||||
void
|
|
||||||
flushOutput ();
|
|
||||||
|
|
||||||
void
|
|
||||||
sendBreak (int duration);
|
|
||||||
|
|
||||||
void
|
|
||||||
setBreak (bool level);
|
|
||||||
|
|
||||||
void
|
|
||||||
setRTS (bool level);
|
|
||||||
|
|
||||||
void
|
|
||||||
setDTR (bool level);
|
|
||||||
|
|
||||||
bool
|
|
||||||
waitForChange ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getCTS ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getDSR ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getRI ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getCD ();
|
|
||||||
|
|
||||||
void
|
|
||||||
setPort (const string &port);
|
|
||||||
|
|
||||||
string
|
|
||||||
getPort () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setTimeout (Timeout &timeout);
|
|
||||||
|
|
||||||
Timeout
|
|
||||||
getTimeout () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setBaudrate (unsigned long baudrate);
|
|
||||||
|
|
||||||
unsigned long
|
|
||||||
getBaudrate () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setBytesize (bytesize_t bytesize);
|
|
||||||
|
|
||||||
bytesize_t
|
|
||||||
getBytesize () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setParity (parity_t parity);
|
|
||||||
|
|
||||||
parity_t
|
|
||||||
getParity () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setStopbits (stopbits_t stopbits);
|
|
||||||
|
|
||||||
stopbits_t
|
|
||||||
getStopbits () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setFlowcontrol (flowcontrol_t flowcontrol);
|
|
||||||
|
|
||||||
flowcontrol_t
|
|
||||||
getFlowcontrol () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
readLock ();
|
|
||||||
|
|
||||||
void
|
|
||||||
readUnlock ();
|
|
||||||
|
|
||||||
void
|
|
||||||
writeLock ();
|
|
||||||
|
|
||||||
void
|
|
||||||
writeUnlock ();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void reconfigurePort ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
wstring port_; // Path to the file descriptor
|
|
||||||
HANDLE fd_;
|
|
||||||
|
|
||||||
bool is_open_;
|
|
||||||
|
|
||||||
Timeout timeout_; // Timeout for read operations
|
|
||||||
unsigned long baudrate_; // Baudrate
|
|
||||||
|
|
||||||
parity_t parity_; // Parity
|
|
||||||
bytesize_t bytesize_; // Size of the bytes
|
|
||||||
stopbits_t stopbits_; // Stop Bits
|
|
||||||
flowcontrol_t flowcontrol_; // Flow Control
|
|
||||||
|
|
||||||
// Mutex used to lock the read functions
|
|
||||||
HANDLE read_mutex;
|
|
||||||
// Mutex used to lock the write functions
|
|
||||||
HANDLE write_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // SERIAL_IMPL_WINDOWS_H
|
|
||||||
|
|
||||||
#endif // if defined(_WIN32)
|
|
700
dependencies/build/serial/include/serial/serial.h
vendored
700
dependencies/build/serial/include/serial/serial.h
vendored
@ -1,700 +0,0 @@
|
|||||||
/*!
|
|
||||||
* \file serial/serial.h
|
|
||||||
* \author William Woodall <wjwwood@gmail.com>
|
|
||||||
* \author John Harrison <ash.gti@gmail.com>
|
|
||||||
* \version 0.1
|
|
||||||
*
|
|
||||||
* \section LICENSE
|
|
||||||
*
|
|
||||||
* The MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012 William Woodall
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* \section DESCRIPTION
|
|
||||||
*
|
|
||||||
* This provides a cross platform interface for interacting with Serial Ports.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SERIAL_H
|
|
||||||
#define SERIAL_H
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <cstring>
|
|
||||||
#include <sstream>
|
|
||||||
#include <exception>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <serial/v8stdint.h>
|
|
||||||
|
|
||||||
#define THROW(exceptionClass, message) throw exceptionClass(__FILE__, \
|
|
||||||
__LINE__, (message) )
|
|
||||||
|
|
||||||
namespace serial {
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Enumeration defines the possible bytesizes for the serial port.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
fivebits = 5,
|
|
||||||
sixbits = 6,
|
|
||||||
sevenbits = 7,
|
|
||||||
eightbits = 8
|
|
||||||
} bytesize_t;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Enumeration defines the possible parity types for the serial port.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
parity_none = 0,
|
|
||||||
parity_odd = 1,
|
|
||||||
parity_even = 2
|
|
||||||
} parity_t;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Enumeration defines the possible stopbit types for the serial port.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
stopbits_one = 1,
|
|
||||||
stopbits_two = 2,
|
|
||||||
stopbits_one_point_five
|
|
||||||
} stopbits_t;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Enumeration defines the possible flowcontrol types for the serial port.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
flowcontrol_none = 0,
|
|
||||||
flowcontrol_software,
|
|
||||||
flowcontrol_hardware
|
|
||||||
} flowcontrol_t;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Structure for setting the timeout of the serial port, times are
|
|
||||||
* in milliseconds.
|
|
||||||
*
|
|
||||||
* In order to disable the interbyte timeout, set it to Timeout::max().
|
|
||||||
*/
|
|
||||||
struct Timeout {
|
|
||||||
#ifdef max
|
|
||||||
# undef max
|
|
||||||
#endif
|
|
||||||
static uint32_t max() {return std::numeric_limits<uint32_t>::max();}
|
|
||||||
/*!
|
|
||||||
* Convenience function to generate Timeout structs using a
|
|
||||||
* single absolute timeout.
|
|
||||||
*
|
|
||||||
* \param timeout A long that defines the time in milliseconds until a
|
|
||||||
* timeout occurs after a call to read or write is made.
|
|
||||||
*
|
|
||||||
* \return Timeout struct that represents this simple timeout provided.
|
|
||||||
*/
|
|
||||||
static Timeout simpleTimeout(uint32_t timeout) {
|
|
||||||
return Timeout(max(), timeout, 0, timeout, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Number of milliseconds between bytes received to timeout on. */
|
|
||||||
uint32_t inter_byte_timeout;
|
|
||||||
/*! A constant number of milliseconds to wait after calling read. */
|
|
||||||
uint32_t read_timeout_constant;
|
|
||||||
/*! A multiplier against the number of requested bytes to wait after
|
|
||||||
* calling read.
|
|
||||||
*/
|
|
||||||
uint32_t read_timeout_multiplier;
|
|
||||||
/*! A constant number of milliseconds to wait after calling write. */
|
|
||||||
uint32_t write_timeout_constant;
|
|
||||||
/*! A multiplier against the number of requested bytes to wait after
|
|
||||||
* calling write.
|
|
||||||
*/
|
|
||||||
uint32_t write_timeout_multiplier;
|
|
||||||
|
|
||||||
explicit Timeout (uint32_t inter_byte_timeout_=0,
|
|
||||||
uint32_t read_timeout_constant_=0,
|
|
||||||
uint32_t read_timeout_multiplier_=0,
|
|
||||||
uint32_t write_timeout_constant_=0,
|
|
||||||
uint32_t write_timeout_multiplier_=0)
|
|
||||||
: inter_byte_timeout(inter_byte_timeout_),
|
|
||||||
read_timeout_constant(read_timeout_constant_),
|
|
||||||
read_timeout_multiplier(read_timeout_multiplier_),
|
|
||||||
write_timeout_constant(write_timeout_constant_),
|
|
||||||
write_timeout_multiplier(write_timeout_multiplier_)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Class that provides a portable serial port interface.
|
|
||||||
*/
|
|
||||||
class Serial {
|
|
||||||
public:
|
|
||||||
/*!
|
|
||||||
* Creates a Serial object and opens the port if a port is specified,
|
|
||||||
* otherwise it remains closed until serial::Serial::open is called.
|
|
||||||
*
|
|
||||||
* \param port A std::string containing the address of the serial port,
|
|
||||||
* which would be something like 'COM1' on Windows and '/dev/ttyS0'
|
|
||||||
* on Linux.
|
|
||||||
*
|
|
||||||
* \param baudrate An unsigned 32-bit integer that represents the baudrate
|
|
||||||
*
|
|
||||||
* \param timeout A serial::Timeout struct that defines the timeout
|
|
||||||
* conditions for the serial port. \see serial::Timeout
|
|
||||||
*
|
|
||||||
* \param bytesize Size of each byte in the serial transmission of data,
|
|
||||||
* default is eightbits, possible values are: fivebits, sixbits, sevenbits,
|
|
||||||
* eightbits
|
|
||||||
*
|
|
||||||
* \param parity Method of parity, default is parity_none, possible values
|
|
||||||
* are: parity_none, parity_odd, parity_even
|
|
||||||
*
|
|
||||||
* \param stopbits Number of stop bits used, default is stopbits_one,
|
|
||||||
* possible values are: stopbits_one, stopbits_one_point_five, stopbits_two
|
|
||||||
*
|
|
||||||
* \param flowcontrol Type of flowcontrol used, default is
|
|
||||||
* flowcontrol_none, possible values are: flowcontrol_none,
|
|
||||||
* flowcontrol_software, flowcontrol_hardware
|
|
||||||
*
|
|
||||||
* \throw serial::PortNotOpenedException
|
|
||||||
* \throw serial::IOException
|
|
||||||
* \throw std::invalid_argument
|
|
||||||
*/
|
|
||||||
Serial (const std::string &port = "",
|
|
||||||
uint32_t baudrate = 9600,
|
|
||||||
Timeout timeout = Timeout(),
|
|
||||||
bytesize_t bytesize = eightbits,
|
|
||||||
parity_t parity = parity_none,
|
|
||||||
stopbits_t stopbits = stopbits_one,
|
|
||||||
flowcontrol_t flowcontrol = flowcontrol_none);
|
|
||||||
|
|
||||||
/*! Destructor */
|
|
||||||
virtual ~Serial ();
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Opens the serial port as long as the port is set and the port isn't
|
|
||||||
* already open.
|
|
||||||
*
|
|
||||||
* If the port is provided to the constructor then an explicit call to open
|
|
||||||
* is not needed.
|
|
||||||
*
|
|
||||||
* \see Serial::Serial
|
|
||||||
*
|
|
||||||
* \throw std::invalid_argument
|
|
||||||
* \throw serial::SerialException
|
|
||||||
* \throw serial::IOException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
open ();
|
|
||||||
|
|
||||||
/*! Gets the open status of the serial port.
|
|
||||||
*
|
|
||||||
* \return Returns true if the port is open, false otherwise.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
isOpen () const;
|
|
||||||
|
|
||||||
/*! Closes the serial port. */
|
|
||||||
void
|
|
||||||
close ();
|
|
||||||
|
|
||||||
/*! Return the number of characters in the buffer. */
|
|
||||||
size_t
|
|
||||||
available ();
|
|
||||||
|
|
||||||
/*! Read a given amount of bytes from the serial port into a given buffer.
|
|
||||||
*
|
|
||||||
* The read function will return in one of three cases:
|
|
||||||
* * The number of requested bytes was read.
|
|
||||||
* * In this case the number of bytes requested will match the size_t
|
|
||||||
* returned by read.
|
|
||||||
* * A timeout occurred, in this case the number of bytes read will not
|
|
||||||
* match the amount requested, but no exception will be thrown. One of
|
|
||||||
* two possible timeouts occurred:
|
|
||||||
* * The inter byte timeout expired, this means that number of
|
|
||||||
* milliseconds elapsed between receiving bytes from the serial port
|
|
||||||
* exceeded the inter byte timeout.
|
|
||||||
* * The total timeout expired, which is calculated by multiplying the
|
|
||||||
* read timeout multiplier by the number of requested bytes and then
|
|
||||||
* added to the read timeout constant. If that total number of
|
|
||||||
* milliseconds elapses after the initial call to read a timeout will
|
|
||||||
* occur.
|
|
||||||
* * An exception occurred, in this case an actual exception will be thrown.
|
|
||||||
*
|
|
||||||
* \param buffer An uint8_t array of at least the requested size.
|
|
||||||
* \param size A size_t defining how many bytes to be read.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes read as a result of the
|
|
||||||
* call to read.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
read (uint8_t *buffer, size_t size);
|
|
||||||
|
|
||||||
/*! Read a given amount of bytes from the serial port into a give buffer.
|
|
||||||
*
|
|
||||||
* \param buffer A reference to a std::vector of uint8_t.
|
|
||||||
* \param size A size_t defining how many bytes to be read.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes read as a result of the
|
|
||||||
* call to read.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
read (std::vector<uint8_t> &buffer, size_t size = 1);
|
|
||||||
|
|
||||||
/*! Read a given amount of bytes from the serial port into a give buffer.
|
|
||||||
*
|
|
||||||
* \param buffer A reference to a std::string.
|
|
||||||
* \param size A size_t defining how many bytes to be read.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes read as a result of the
|
|
||||||
* call to read.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
read (std::string &buffer, size_t size = 1);
|
|
||||||
|
|
||||||
/*! Read a given amount of bytes from the serial port and return a string
|
|
||||||
* containing the data.
|
|
||||||
*
|
|
||||||
* \param size A size_t defining how many bytes to be read.
|
|
||||||
*
|
|
||||||
* \return A std::string containing the data read from the port.
|
|
||||||
*/
|
|
||||||
std::string
|
|
||||||
read (size_t size = 1);
|
|
||||||
|
|
||||||
/*! Reads in a line or until a given delimiter has been processed.
|
|
||||||
*
|
|
||||||
* Reads from the serial port until a single line has been read.
|
|
||||||
*
|
|
||||||
* \param buffer A std::string reference used to store the data.
|
|
||||||
* \param size A maximum length of a line, defaults to 65536 (2^16)
|
|
||||||
* \param eol A string to match against for the EOL.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes read.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
readline (std::string &buffer, size_t size = 65536, std::string eol = "\n");
|
|
||||||
|
|
||||||
/*! Reads in a line or until a given delimiter has been processed.
|
|
||||||
*
|
|
||||||
* Reads from the serial port until a single line has been read.
|
|
||||||
*
|
|
||||||
* \param size A maximum length of a line, defaults to 65536 (2^16)
|
|
||||||
* \param eol A string to match against for the EOL.
|
|
||||||
*
|
|
||||||
* \return A std::string containing the line.
|
|
||||||
*/
|
|
||||||
std::string
|
|
||||||
readline (size_t size = 65536, std::string eol = "\n");
|
|
||||||
|
|
||||||
/*! Reads in multiple lines until the serial port times out.
|
|
||||||
*
|
|
||||||
* This requires a timeout > 0 before it can be run. It will read until a
|
|
||||||
* timeout occurs and return a list of strings.
|
|
||||||
*
|
|
||||||
* \param size A maximum length of combined lines, defaults to 65536 (2^16)
|
|
||||||
*
|
|
||||||
* \param eol A string to match against for the EOL.
|
|
||||||
*
|
|
||||||
* \return A vector<string> containing the lines.
|
|
||||||
*/
|
|
||||||
std::vector<std::string>
|
|
||||||
readlines (size_t size = 65536, std::string eol = "\n");
|
|
||||||
|
|
||||||
/*! Write a string to the serial port.
|
|
||||||
*
|
|
||||||
* \param data A const reference containing the data to be written
|
|
||||||
* to the serial port.
|
|
||||||
*
|
|
||||||
* \param size A size_t that indicates how many bytes should be written from
|
|
||||||
* the given data buffer.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes actually written to
|
|
||||||
* the serial port.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
write (const uint8_t *data, size_t size);
|
|
||||||
|
|
||||||
/*! Write a string to the serial port.
|
|
||||||
*
|
|
||||||
* \param data A const reference containing the data to be written
|
|
||||||
* to the serial port.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes actually written to
|
|
||||||
* the serial port.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
write (const std::vector<uint8_t> &data);
|
|
||||||
|
|
||||||
/*! Write a string to the serial port.
|
|
||||||
*
|
|
||||||
* \param data A const reference containing the data to be written
|
|
||||||
* to the serial port.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes actually written to
|
|
||||||
* the serial port.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
write (const std::string &data);
|
|
||||||
|
|
||||||
/*! Sets the serial port identifier.
|
|
||||||
*
|
|
||||||
* \param port A const std::string reference containing the address of the
|
|
||||||
* serial port, which would be something like 'COM1' on Windows and
|
|
||||||
* '/dev/ttyS0' on Linux.
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setPort (const std::string &port);
|
|
||||||
|
|
||||||
/*! Gets the serial port identifier.
|
|
||||||
*
|
|
||||||
* \see Serial::setPort
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
std::string
|
|
||||||
getPort () const;
|
|
||||||
|
|
||||||
/*! Sets the timeout for reads and writes using the Timeout struct.
|
|
||||||
*
|
|
||||||
* There are two timeout conditions described here:
|
|
||||||
* * The inter byte timeout:
|
|
||||||
* * The inter_byte_timeout component of serial::Timeout defines the
|
|
||||||
* maximum amount of time, in milliseconds, between receiving bytes on
|
|
||||||
* the serial port that can pass before a timeout occurs. Setting this
|
|
||||||
* to zero will prevent inter byte timeouts from occurring.
|
|
||||||
* * Total time timeout:
|
|
||||||
* * The constant and multiplier component of this timeout condition,
|
|
||||||
* for both read and write, are defined in serial::Timeout. This
|
|
||||||
* timeout occurs if the total time since the read or write call was
|
|
||||||
* made exceeds the specified time in milliseconds.
|
|
||||||
* * The limit is defined by multiplying the multiplier component by the
|
|
||||||
* number of requested bytes and adding that product to the constant
|
|
||||||
* component. In this way if you want a read call, for example, to
|
|
||||||
* timeout after exactly one second regardless of the number of bytes
|
|
||||||
* you asked for then set the read_timeout_constant component of
|
|
||||||
* serial::Timeout to 1000 and the read_timeout_multiplier to zero.
|
|
||||||
* This timeout condition can be used in conjunction with the inter
|
|
||||||
* byte timeout condition with out any problems, timeout will simply
|
|
||||||
* occur when one of the two timeout conditions is met. This allows
|
|
||||||
* users to have maximum control over the trade-off between
|
|
||||||
* responsiveness and efficiency.
|
|
||||||
*
|
|
||||||
* Read and write functions will return in one of three cases. When the
|
|
||||||
* reading or writing is complete, when a timeout occurs, or when an
|
|
||||||
* exception occurs.
|
|
||||||
*
|
|
||||||
* \param timeout A serial::Timeout struct containing the inter byte
|
|
||||||
* timeout, and the read and write timeout constants and multipliers.
|
|
||||||
*
|
|
||||||
* \see serial::Timeout
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setTimeout (Timeout &timeout);
|
|
||||||
|
|
||||||
/*! Sets the timeout for reads and writes. */
|
|
||||||
void
|
|
||||||
setTimeout (uint32_t inter_byte_timeout, uint32_t read_timeout_constant,
|
|
||||||
uint32_t read_timeout_multiplier, uint32_t write_timeout_constant,
|
|
||||||
uint32_t write_timeout_multiplier)
|
|
||||||
{
|
|
||||||
Timeout timeout(inter_byte_timeout, read_timeout_constant,
|
|
||||||
read_timeout_multiplier, write_timeout_constant,
|
|
||||||
write_timeout_multiplier);
|
|
||||||
return setTimeout(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Gets the timeout for reads in seconds.
|
|
||||||
*
|
|
||||||
* \return A Timeout struct containing the inter_byte_timeout, and read
|
|
||||||
* and write timeout constants and multipliers.
|
|
||||||
*
|
|
||||||
* \see Serial::setTimeout
|
|
||||||
*/
|
|
||||||
Timeout
|
|
||||||
getTimeout () const;
|
|
||||||
|
|
||||||
/*! Sets the baudrate for the serial port.
|
|
||||||
*
|
|
||||||
* Possible baudrates depends on the system but some safe baudrates include:
|
|
||||||
* 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 56000,
|
|
||||||
* 57600, 115200
|
|
||||||
* Some other baudrates that are supported by some comports:
|
|
||||||
* 128000, 153600, 230400, 256000, 460800, 921600
|
|
||||||
*
|
|
||||||
* \param baudrate An integer that sets the baud rate for the serial port.
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setBaudrate (uint32_t baudrate);
|
|
||||||
|
|
||||||
/*! Gets the baudrate for the serial port.
|
|
||||||
*
|
|
||||||
* \return An integer that sets the baud rate for the serial port.
|
|
||||||
*
|
|
||||||
* \see Serial::setBaudrate
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
uint32_t
|
|
||||||
getBaudrate () const;
|
|
||||||
|
|
||||||
/*! Sets the bytesize for the serial port.
|
|
||||||
*
|
|
||||||
* \param bytesize Size of each byte in the serial transmission of data,
|
|
||||||
* default is eightbits, possible values are: fivebits, sixbits, sevenbits,
|
|
||||||
* eightbits
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setBytesize (bytesize_t bytesize);
|
|
||||||
|
|
||||||
/*! Gets the bytesize for the serial port.
|
|
||||||
*
|
|
||||||
* \see Serial::setBytesize
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
bytesize_t
|
|
||||||
getBytesize () const;
|
|
||||||
|
|
||||||
/*! Sets the parity for the serial port.
|
|
||||||
*
|
|
||||||
* \param parity Method of parity, default is parity_none, possible values
|
|
||||||
* are: parity_none, parity_odd, parity_even
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setParity (parity_t parity);
|
|
||||||
|
|
||||||
/*! Gets the parity for the serial port.
|
|
||||||
*
|
|
||||||
* \see Serial::setParity
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
parity_t
|
|
||||||
getParity () const;
|
|
||||||
|
|
||||||
/*! Sets the stopbits for the serial port.
|
|
||||||
*
|
|
||||||
* \param stopbits Number of stop bits used, default is stopbits_one,
|
|
||||||
* possible values are: stopbits_one, stopbits_one_point_five, stopbits_two
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setStopbits (stopbits_t stopbits);
|
|
||||||
|
|
||||||
/*! Gets the stopbits for the serial port.
|
|
||||||
*
|
|
||||||
* \see Serial::setStopbits
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
stopbits_t
|
|
||||||
getStopbits () const;
|
|
||||||
|
|
||||||
/*! Sets the flow control for the serial port.
|
|
||||||
*
|
|
||||||
* \param flowcontrol Type of flowcontrol used, default is flowcontrol_none,
|
|
||||||
* possible values are: flowcontrol_none, flowcontrol_software,
|
|
||||||
* flowcontrol_hardware
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setFlowcontrol (flowcontrol_t flowcontrol);
|
|
||||||
|
|
||||||
/*! Gets the flow control for the serial port.
|
|
||||||
*
|
|
||||||
* \see Serial::setFlowcontrol
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
flowcontrol_t
|
|
||||||
getFlowcontrol () const;
|
|
||||||
|
|
||||||
/*! Flush the input and output buffers */
|
|
||||||
void
|
|
||||||
flush ();
|
|
||||||
|
|
||||||
/*! Flush only the input buffer */
|
|
||||||
void
|
|
||||||
flushInput ();
|
|
||||||
|
|
||||||
/*! Flush only the output buffer */
|
|
||||||
void
|
|
||||||
flushOutput ();
|
|
||||||
|
|
||||||
/*! Sends the RS-232 break signal. See tcsendbreak(3). */
|
|
||||||
void
|
|
||||||
sendBreak (int duration);
|
|
||||||
|
|
||||||
/*! Set the break condition to a given level. Defaults to true. */
|
|
||||||
void
|
|
||||||
setBreak (bool level = true);
|
|
||||||
|
|
||||||
/*! Set the RTS handshaking line to the given level. Defaults to true. */
|
|
||||||
void
|
|
||||||
setRTS (bool level = true);
|
|
||||||
|
|
||||||
/*! Set the DTR handshaking line to the given level. Defaults to true. */
|
|
||||||
void
|
|
||||||
setDTR (bool level = true);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Blocks until CTS, DSR, RI, CD changes or something interrupts it.
|
|
||||||
*
|
|
||||||
* Can throw an exception if an error occurs while waiting.
|
|
||||||
* You can check the status of CTS, DSR, RI, and CD once this returns.
|
|
||||||
* Uses TIOCMIWAIT via ioctl if available (mostly only on Linux) with a
|
|
||||||
* resolution of less than +-1ms and as good as +-0.2ms. Otherwise a
|
|
||||||
* polling method is used which can give +-2ms.
|
|
||||||
*
|
|
||||||
* \return Returns true if one of the lines changed, false if something else
|
|
||||||
* occurred.
|
|
||||||
*
|
|
||||||
* \throw SerialException
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
waitForChange ();
|
|
||||||
|
|
||||||
/*! Returns the current status of the CTS line. */
|
|
||||||
bool
|
|
||||||
getCTS ();
|
|
||||||
|
|
||||||
/*! Returns the current status of the DSR line. */
|
|
||||||
bool
|
|
||||||
getDSR ();
|
|
||||||
|
|
||||||
/*! Returns the current status of the RI line. */
|
|
||||||
bool
|
|
||||||
getRI ();
|
|
||||||
|
|
||||||
/*! Returns the current status of the CD line. */
|
|
||||||
bool
|
|
||||||
getCD ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Disable copy constructors
|
|
||||||
Serial(const Serial&);
|
|
||||||
Serial& operator=(const Serial&);
|
|
||||||
|
|
||||||
std::string read_cache_; //!< Cache for doing reads in chunks.
|
|
||||||
|
|
||||||
// Pimpl idiom, d_pointer
|
|
||||||
class SerialImpl;
|
|
||||||
SerialImpl *pimpl_;
|
|
||||||
|
|
||||||
// Scoped Lock Classes
|
|
||||||
class ScopedReadLock;
|
|
||||||
class ScopedWriteLock;
|
|
||||||
|
|
||||||
// Read common function
|
|
||||||
size_t
|
|
||||||
read_ (uint8_t *buffer, size_t size);
|
|
||||||
// Write common function
|
|
||||||
size_t
|
|
||||||
write_ (const uint8_t *data, size_t length);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class SerialException : public std::exception
|
|
||||||
{
|
|
||||||
// Disable copy constructors
|
|
||||||
SerialException& operator=(const SerialException&);
|
|
||||||
std::string e_what_;
|
|
||||||
public:
|
|
||||||
SerialException (const char *description) {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "SerialException " << description << " failed.";
|
|
||||||
e_what_ = ss.str();
|
|
||||||
}
|
|
||||||
SerialException (const SerialException& other) : e_what_(other.e_what_) {}
|
|
||||||
virtual ~SerialException() throw() {}
|
|
||||||
virtual const char* what () const throw () {
|
|
||||||
return e_what_.c_str();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class IOException : public std::exception
|
|
||||||
{
|
|
||||||
// Disable copy constructors
|
|
||||||
IOException& operator=(const IOException&);
|
|
||||||
std::string file_;
|
|
||||||
int line_;
|
|
||||||
std::string e_what_;
|
|
||||||
int errno_;
|
|
||||||
public:
|
|
||||||
explicit IOException (std::string file, int line, int errnum)
|
|
||||||
: file_(file), line_(line), errno_(errnum) {
|
|
||||||
std::stringstream ss;
|
|
||||||
#if defined(_WIN32)
|
|
||||||
char error_str [1024];
|
|
||||||
strerror_s(error_str, 1024, errnum);
|
|
||||||
#else
|
|
||||||
char * error_str = strerror(errnum);
|
|
||||||
#endif
|
|
||||||
ss << "IO Exception (" << errno_ << "): " << error_str;
|
|
||||||
ss << ", file " << file_ << ", line " << line_ << ".";
|
|
||||||
e_what_ = ss.str();
|
|
||||||
}
|
|
||||||
explicit IOException (std::string file, int line, const char * description)
|
|
||||||
: file_(file), line_(line), errno_(0) {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "IO Exception: " << description;
|
|
||||||
ss << ", file " << file_ << ", line " << line_ << ".";
|
|
||||||
e_what_ = ss.str();
|
|
||||||
}
|
|
||||||
virtual ~IOException() throw() {}
|
|
||||||
IOException (const IOException& other) : e_what_(other.e_what_), line_(other.line_), errno_(other.errno_) {}
|
|
||||||
|
|
||||||
int getErrorNumber () { return errno_; }
|
|
||||||
|
|
||||||
virtual const char* what () const throw () {
|
|
||||||
return e_what_.c_str();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class PortNotOpenedException : public std::exception
|
|
||||||
{
|
|
||||||
// Disable copy constructors
|
|
||||||
const PortNotOpenedException& operator=(PortNotOpenedException);
|
|
||||||
std::string e_what_;
|
|
||||||
public:
|
|
||||||
PortNotOpenedException (const char * description) {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "PortNotOpenedException " << description << " failed.";
|
|
||||||
e_what_ = ss.str();
|
|
||||||
}
|
|
||||||
PortNotOpenedException (const PortNotOpenedException& other) : e_what_(other.e_what_) {}
|
|
||||||
virtual ~PortNotOpenedException() throw() {}
|
|
||||||
virtual const char* what () const throw () {
|
|
||||||
return e_what_.c_str();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace serial
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,57 +0,0 @@
|
|||||||
// This header is from the v8 google project:
|
|
||||||
// http://code.google.com/p/v8/source/browse/trunk/include/v8stdint.h
|
|
||||||
|
|
||||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
// Load definitions of standard types.
|
|
||||||
|
|
||||||
#ifndef V8STDINT_H_
|
|
||||||
#define V8STDINT_H_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
|
||||||
|
|
||||||
typedef signed char int8_t;
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
typedef short int16_t; // NOLINT
|
|
||||||
typedef unsigned short uint16_t; // NOLINT
|
|
||||||
typedef int int32_t;
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
typedef __int64 int64_t;
|
|
||||||
typedef unsigned __int64 uint64_t;
|
|
||||||
// intptr_t and friends are defined in crtdefs.h through stdio.h.
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // V8STDINT_H_
|
|
1025
dependencies/build/serial/src/impl/unix.cc
vendored
1025
dependencies/build/serial/src/impl/unix.cc
vendored
File diff suppressed because it is too large
Load Diff
601
dependencies/build/serial/src/impl/win.cc
vendored
601
dependencies/build/serial/src/impl/win.cc
vendored
@ -1,601 +0,0 @@
|
|||||||
#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
397
dependencies/build/serial/src/serial.cc
vendored
@ -1,397 +0,0 @@
|
|||||||
/* 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 ();
|
|
||||||
}
|
|
204
dependencies/include/serial/impl/unix.h
vendored
204
dependencies/include/serial/impl/unix.h
vendored
@ -1,204 +0,0 @@
|
|||||||
/*!
|
|
||||||
* \file serial/impl/unix.h
|
|
||||||
* \author William Woodall <wjwwood@gmail.com>
|
|
||||||
* \author John Harrison <ash@greaterthaninfinity.com>
|
|
||||||
* \version 0.1
|
|
||||||
*
|
|
||||||
* \section LICENSE
|
|
||||||
*
|
|
||||||
* The MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012 William Woodall, John Harrison
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* \section DESCRIPTION
|
|
||||||
*
|
|
||||||
* This provides a unix based pimpl for the Serial class. This implementation is
|
|
||||||
* based off termios.h and uses select for multiplexing the IO ports.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if !defined(_WIN32)
|
|
||||||
|
|
||||||
#ifndef SERIAL_IMPL_UNIX_H
|
|
||||||
#define SERIAL_IMPL_UNIX_H
|
|
||||||
|
|
||||||
#include "serial/serial.h"
|
|
||||||
|
|
||||||
#include <pthread.h>
|
|
||||||
|
|
||||||
namespace serial {
|
|
||||||
|
|
||||||
using std::size_t;
|
|
||||||
using std::string;
|
|
||||||
using std::invalid_argument;
|
|
||||||
|
|
||||||
using serial::SerialException;
|
|
||||||
using serial::IOException;
|
|
||||||
|
|
||||||
class serial::Serial::SerialImpl {
|
|
||||||
public:
|
|
||||||
SerialImpl (const string &port,
|
|
||||||
unsigned long baudrate,
|
|
||||||
bytesize_t bytesize,
|
|
||||||
parity_t parity,
|
|
||||||
stopbits_t stopbits,
|
|
||||||
flowcontrol_t flowcontrol);
|
|
||||||
|
|
||||||
virtual ~SerialImpl ();
|
|
||||||
|
|
||||||
void
|
|
||||||
open ();
|
|
||||||
|
|
||||||
void
|
|
||||||
close ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
isOpen () const;
|
|
||||||
|
|
||||||
size_t
|
|
||||||
available ();
|
|
||||||
|
|
||||||
size_t
|
|
||||||
read (uint8_t *buf, size_t size = 1);
|
|
||||||
|
|
||||||
size_t
|
|
||||||
write (const uint8_t *data, size_t length);
|
|
||||||
|
|
||||||
void
|
|
||||||
flush ();
|
|
||||||
|
|
||||||
void
|
|
||||||
flushInput ();
|
|
||||||
|
|
||||||
void
|
|
||||||
flushOutput ();
|
|
||||||
|
|
||||||
void
|
|
||||||
sendBreak (int duration);
|
|
||||||
|
|
||||||
void
|
|
||||||
setBreak (bool level);
|
|
||||||
|
|
||||||
void
|
|
||||||
setRTS (bool level);
|
|
||||||
|
|
||||||
void
|
|
||||||
setDTR (bool level);
|
|
||||||
|
|
||||||
bool
|
|
||||||
waitForChange ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getCTS ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getDSR ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getRI ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getCD ();
|
|
||||||
|
|
||||||
void
|
|
||||||
setPort (const string &port);
|
|
||||||
|
|
||||||
string
|
|
||||||
getPort () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setTimeout (Timeout &timeout);
|
|
||||||
|
|
||||||
Timeout
|
|
||||||
getTimeout () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setBaudrate (unsigned long baudrate);
|
|
||||||
|
|
||||||
unsigned long
|
|
||||||
getBaudrate () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setBytesize (bytesize_t bytesize);
|
|
||||||
|
|
||||||
bytesize_t
|
|
||||||
getBytesize () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setParity (parity_t parity);
|
|
||||||
|
|
||||||
parity_t
|
|
||||||
getParity () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setStopbits (stopbits_t stopbits);
|
|
||||||
|
|
||||||
stopbits_t
|
|
||||||
getStopbits () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setFlowcontrol (flowcontrol_t flowcontrol);
|
|
||||||
|
|
||||||
flowcontrol_t
|
|
||||||
getFlowcontrol () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
readLock ();
|
|
||||||
|
|
||||||
void
|
|
||||||
readUnlock ();
|
|
||||||
|
|
||||||
void
|
|
||||||
writeLock ();
|
|
||||||
|
|
||||||
void
|
|
||||||
writeUnlock ();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void reconfigurePort ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
string port_; // Path to the file descriptor
|
|
||||||
int fd_; // The current file descriptor
|
|
||||||
|
|
||||||
bool is_open_;
|
|
||||||
bool xonxoff_;
|
|
||||||
bool rtscts_;
|
|
||||||
|
|
||||||
Timeout timeout_; // Timeout for read operations
|
|
||||||
unsigned long baudrate_; // Baudrate
|
|
||||||
|
|
||||||
parity_t parity_; // Parity
|
|
||||||
bytesize_t bytesize_; // Size of the bytes
|
|
||||||
stopbits_t stopbits_; // Stop Bits
|
|
||||||
flowcontrol_t flowcontrol_; // Flow Control
|
|
||||||
|
|
||||||
// Mutex used to lock the read functions
|
|
||||||
pthread_mutex_t read_mutex;
|
|
||||||
// Mutex used to lock the write functions
|
|
||||||
pthread_mutex_t write_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // SERIAL_IMPL_UNIX_H
|
|
||||||
|
|
||||||
#endif // !defined(_WIN32)
|
|
201
dependencies/include/serial/impl/win.h
vendored
201
dependencies/include/serial/impl/win.h
vendored
@ -1,201 +0,0 @@
|
|||||||
/*!
|
|
||||||
* \file serial/impl/windows.h
|
|
||||||
* \author William Woodall <wjwwood@gmail.com>
|
|
||||||
* \author John Harrison <ash@greaterthaninfinity.com>
|
|
||||||
* \version 0.1
|
|
||||||
*
|
|
||||||
* \section LICENSE
|
|
||||||
*
|
|
||||||
* The MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012 William Woodall, John Harrison
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* \section DESCRIPTION
|
|
||||||
*
|
|
||||||
* This provides a windows implementation of the Serial class interface.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
|
||||||
|
|
||||||
#ifndef SERIAL_IMPL_WINDOWS_H
|
|
||||||
#define SERIAL_IMPL_WINDOWS_H
|
|
||||||
|
|
||||||
#include "serial/serial.h"
|
|
||||||
|
|
||||||
#include "windows.h"
|
|
||||||
|
|
||||||
namespace serial {
|
|
||||||
|
|
||||||
using std::string;
|
|
||||||
using std::wstring;
|
|
||||||
using std::invalid_argument;
|
|
||||||
|
|
||||||
using serial::SerialException;
|
|
||||||
using serial::IOException;
|
|
||||||
|
|
||||||
class serial::Serial::SerialImpl {
|
|
||||||
public:
|
|
||||||
SerialImpl (const string &port,
|
|
||||||
unsigned long baudrate,
|
|
||||||
bytesize_t bytesize,
|
|
||||||
parity_t parity,
|
|
||||||
stopbits_t stopbits,
|
|
||||||
flowcontrol_t flowcontrol);
|
|
||||||
|
|
||||||
virtual ~SerialImpl ();
|
|
||||||
|
|
||||||
void
|
|
||||||
open ();
|
|
||||||
|
|
||||||
void
|
|
||||||
close ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
isOpen () const;
|
|
||||||
|
|
||||||
size_t
|
|
||||||
available ();
|
|
||||||
|
|
||||||
size_t
|
|
||||||
read (uint8_t *buf, size_t size = 1);
|
|
||||||
|
|
||||||
size_t
|
|
||||||
write (const uint8_t *data, size_t length);
|
|
||||||
|
|
||||||
void
|
|
||||||
flush ();
|
|
||||||
|
|
||||||
void
|
|
||||||
flushInput ();
|
|
||||||
|
|
||||||
void
|
|
||||||
flushOutput ();
|
|
||||||
|
|
||||||
void
|
|
||||||
sendBreak (int duration);
|
|
||||||
|
|
||||||
void
|
|
||||||
setBreak (bool level);
|
|
||||||
|
|
||||||
void
|
|
||||||
setRTS (bool level);
|
|
||||||
|
|
||||||
void
|
|
||||||
setDTR (bool level);
|
|
||||||
|
|
||||||
bool
|
|
||||||
waitForChange ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getCTS ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getDSR ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getRI ();
|
|
||||||
|
|
||||||
bool
|
|
||||||
getCD ();
|
|
||||||
|
|
||||||
void
|
|
||||||
setPort (const string &port);
|
|
||||||
|
|
||||||
string
|
|
||||||
getPort () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setTimeout (Timeout &timeout);
|
|
||||||
|
|
||||||
Timeout
|
|
||||||
getTimeout () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setBaudrate (unsigned long baudrate);
|
|
||||||
|
|
||||||
unsigned long
|
|
||||||
getBaudrate () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setBytesize (bytesize_t bytesize);
|
|
||||||
|
|
||||||
bytesize_t
|
|
||||||
getBytesize () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setParity (parity_t parity);
|
|
||||||
|
|
||||||
parity_t
|
|
||||||
getParity () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setStopbits (stopbits_t stopbits);
|
|
||||||
|
|
||||||
stopbits_t
|
|
||||||
getStopbits () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
setFlowcontrol (flowcontrol_t flowcontrol);
|
|
||||||
|
|
||||||
flowcontrol_t
|
|
||||||
getFlowcontrol () const;
|
|
||||||
|
|
||||||
void
|
|
||||||
readLock ();
|
|
||||||
|
|
||||||
void
|
|
||||||
readUnlock ();
|
|
||||||
|
|
||||||
void
|
|
||||||
writeLock ();
|
|
||||||
|
|
||||||
void
|
|
||||||
writeUnlock ();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
void reconfigurePort ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
wstring port_; // Path to the file descriptor
|
|
||||||
HANDLE fd_;
|
|
||||||
|
|
||||||
bool is_open_;
|
|
||||||
|
|
||||||
Timeout timeout_; // Timeout for read operations
|
|
||||||
unsigned long baudrate_; // Baudrate
|
|
||||||
|
|
||||||
parity_t parity_; // Parity
|
|
||||||
bytesize_t bytesize_; // Size of the bytes
|
|
||||||
stopbits_t stopbits_; // Stop Bits
|
|
||||||
flowcontrol_t flowcontrol_; // Flow Control
|
|
||||||
|
|
||||||
// Mutex used to lock the read functions
|
|
||||||
HANDLE read_mutex;
|
|
||||||
// Mutex used to lock the write functions
|
|
||||||
HANDLE write_mutex;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // SERIAL_IMPL_WINDOWS_H
|
|
||||||
|
|
||||||
#endif // if defined(_WIN32)
|
|
700
dependencies/include/serial/serial.h
vendored
700
dependencies/include/serial/serial.h
vendored
@ -1,700 +0,0 @@
|
|||||||
/*!
|
|
||||||
* \file serial/serial.h
|
|
||||||
* \author William Woodall <wjwwood@gmail.com>
|
|
||||||
* \author John Harrison <ash.gti@gmail.com>
|
|
||||||
* \version 0.1
|
|
||||||
*
|
|
||||||
* \section LICENSE
|
|
||||||
*
|
|
||||||
* The MIT License
|
|
||||||
*
|
|
||||||
* Copyright (c) 2012 William Woodall
|
|
||||||
*
|
|
||||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
|
||||||
* copy of this software and associated documentation files (the "Software"),
|
|
||||||
* to deal in the Software without restriction, including without limitation
|
|
||||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
||||||
* and/or sell copies of the Software, and to permit persons to whom the
|
|
||||||
* Software is furnished to do so, subject to the following conditions:
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included in
|
|
||||||
* all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
||||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
||||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
||||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
||||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
||||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
* DEALINGS IN THE SOFTWARE.
|
|
||||||
*
|
|
||||||
* \section DESCRIPTION
|
|
||||||
*
|
|
||||||
* This provides a cross platform interface for interacting with Serial Ports.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef SERIAL_H
|
|
||||||
#define SERIAL_H
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
#include <vector>
|
|
||||||
#include <string>
|
|
||||||
#include <cstring>
|
|
||||||
#include <sstream>
|
|
||||||
#include <exception>
|
|
||||||
#include <stdexcept>
|
|
||||||
#include <serial/v8stdint.h>
|
|
||||||
|
|
||||||
#define THROW(exceptionClass, message) throw exceptionClass(__FILE__, \
|
|
||||||
__LINE__, (message) )
|
|
||||||
|
|
||||||
namespace serial {
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Enumeration defines the possible bytesizes for the serial port.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
fivebits = 5,
|
|
||||||
sixbits = 6,
|
|
||||||
sevenbits = 7,
|
|
||||||
eightbits = 8
|
|
||||||
} bytesize_t;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Enumeration defines the possible parity types for the serial port.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
parity_none = 0,
|
|
||||||
parity_odd = 1,
|
|
||||||
parity_even = 2
|
|
||||||
} parity_t;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Enumeration defines the possible stopbit types for the serial port.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
stopbits_one = 1,
|
|
||||||
stopbits_two = 2,
|
|
||||||
stopbits_one_point_five
|
|
||||||
} stopbits_t;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Enumeration defines the possible flowcontrol types for the serial port.
|
|
||||||
*/
|
|
||||||
typedef enum {
|
|
||||||
flowcontrol_none = 0,
|
|
||||||
flowcontrol_software,
|
|
||||||
flowcontrol_hardware
|
|
||||||
} flowcontrol_t;
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Structure for setting the timeout of the serial port, times are
|
|
||||||
* in milliseconds.
|
|
||||||
*
|
|
||||||
* In order to disable the interbyte timeout, set it to Timeout::max().
|
|
||||||
*/
|
|
||||||
struct Timeout {
|
|
||||||
#ifdef max
|
|
||||||
# undef max
|
|
||||||
#endif
|
|
||||||
static uint32_t max() {return std::numeric_limits<uint32_t>::max();}
|
|
||||||
/*!
|
|
||||||
* Convenience function to generate Timeout structs using a
|
|
||||||
* single absolute timeout.
|
|
||||||
*
|
|
||||||
* \param timeout A long that defines the time in milliseconds until a
|
|
||||||
* timeout occurs after a call to read or write is made.
|
|
||||||
*
|
|
||||||
* \return Timeout struct that represents this simple timeout provided.
|
|
||||||
*/
|
|
||||||
static Timeout simpleTimeout(uint32_t timeout) {
|
|
||||||
return Timeout(max(), timeout, 0, timeout, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Number of milliseconds between bytes received to timeout on. */
|
|
||||||
uint32_t inter_byte_timeout;
|
|
||||||
/*! A constant number of milliseconds to wait after calling read. */
|
|
||||||
uint32_t read_timeout_constant;
|
|
||||||
/*! A multiplier against the number of requested bytes to wait after
|
|
||||||
* calling read.
|
|
||||||
*/
|
|
||||||
uint32_t read_timeout_multiplier;
|
|
||||||
/*! A constant number of milliseconds to wait after calling write. */
|
|
||||||
uint32_t write_timeout_constant;
|
|
||||||
/*! A multiplier against the number of requested bytes to wait after
|
|
||||||
* calling write.
|
|
||||||
*/
|
|
||||||
uint32_t write_timeout_multiplier;
|
|
||||||
|
|
||||||
explicit Timeout (uint32_t inter_byte_timeout_=0,
|
|
||||||
uint32_t read_timeout_constant_=0,
|
|
||||||
uint32_t read_timeout_multiplier_=0,
|
|
||||||
uint32_t write_timeout_constant_=0,
|
|
||||||
uint32_t write_timeout_multiplier_=0)
|
|
||||||
: inter_byte_timeout(inter_byte_timeout_),
|
|
||||||
read_timeout_constant(read_timeout_constant_),
|
|
||||||
read_timeout_multiplier(read_timeout_multiplier_),
|
|
||||||
write_timeout_constant(write_timeout_constant_),
|
|
||||||
write_timeout_multiplier(write_timeout_multiplier_)
|
|
||||||
{}
|
|
||||||
};
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Class that provides a portable serial port interface.
|
|
||||||
*/
|
|
||||||
class Serial {
|
|
||||||
public:
|
|
||||||
/*!
|
|
||||||
* Creates a Serial object and opens the port if a port is specified,
|
|
||||||
* otherwise it remains closed until serial::Serial::open is called.
|
|
||||||
*
|
|
||||||
* \param port A std::string containing the address of the serial port,
|
|
||||||
* which would be something like 'COM1' on Windows and '/dev/ttyS0'
|
|
||||||
* on Linux.
|
|
||||||
*
|
|
||||||
* \param baudrate An unsigned 32-bit integer that represents the baudrate
|
|
||||||
*
|
|
||||||
* \param timeout A serial::Timeout struct that defines the timeout
|
|
||||||
* conditions for the serial port. \see serial::Timeout
|
|
||||||
*
|
|
||||||
* \param bytesize Size of each byte in the serial transmission of data,
|
|
||||||
* default is eightbits, possible values are: fivebits, sixbits, sevenbits,
|
|
||||||
* eightbits
|
|
||||||
*
|
|
||||||
* \param parity Method of parity, default is parity_none, possible values
|
|
||||||
* are: parity_none, parity_odd, parity_even
|
|
||||||
*
|
|
||||||
* \param stopbits Number of stop bits used, default is stopbits_one,
|
|
||||||
* possible values are: stopbits_one, stopbits_one_point_five, stopbits_two
|
|
||||||
*
|
|
||||||
* \param flowcontrol Type of flowcontrol used, default is
|
|
||||||
* flowcontrol_none, possible values are: flowcontrol_none,
|
|
||||||
* flowcontrol_software, flowcontrol_hardware
|
|
||||||
*
|
|
||||||
* \throw serial::PortNotOpenedException
|
|
||||||
* \throw serial::IOException
|
|
||||||
* \throw std::invalid_argument
|
|
||||||
*/
|
|
||||||
Serial (const std::string &port = "",
|
|
||||||
uint32_t baudrate = 9600,
|
|
||||||
Timeout timeout = Timeout(),
|
|
||||||
bytesize_t bytesize = eightbits,
|
|
||||||
parity_t parity = parity_none,
|
|
||||||
stopbits_t stopbits = stopbits_one,
|
|
||||||
flowcontrol_t flowcontrol = flowcontrol_none);
|
|
||||||
|
|
||||||
/*! Destructor */
|
|
||||||
virtual ~Serial ();
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Opens the serial port as long as the port is set and the port isn't
|
|
||||||
* already open.
|
|
||||||
*
|
|
||||||
* If the port is provided to the constructor then an explicit call to open
|
|
||||||
* is not needed.
|
|
||||||
*
|
|
||||||
* \see Serial::Serial
|
|
||||||
*
|
|
||||||
* \throw std::invalid_argument
|
|
||||||
* \throw serial::SerialException
|
|
||||||
* \throw serial::IOException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
open ();
|
|
||||||
|
|
||||||
/*! Gets the open status of the serial port.
|
|
||||||
*
|
|
||||||
* \return Returns true if the port is open, false otherwise.
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
isOpen () const;
|
|
||||||
|
|
||||||
/*! Closes the serial port. */
|
|
||||||
void
|
|
||||||
close ();
|
|
||||||
|
|
||||||
/*! Return the number of characters in the buffer. */
|
|
||||||
size_t
|
|
||||||
available ();
|
|
||||||
|
|
||||||
/*! Read a given amount of bytes from the serial port into a given buffer.
|
|
||||||
*
|
|
||||||
* The read function will return in one of three cases:
|
|
||||||
* * The number of requested bytes was read.
|
|
||||||
* * In this case the number of bytes requested will match the size_t
|
|
||||||
* returned by read.
|
|
||||||
* * A timeout occurred, in this case the number of bytes read will not
|
|
||||||
* match the amount requested, but no exception will be thrown. One of
|
|
||||||
* two possible timeouts occurred:
|
|
||||||
* * The inter byte timeout expired, this means that number of
|
|
||||||
* milliseconds elapsed between receiving bytes from the serial port
|
|
||||||
* exceeded the inter byte timeout.
|
|
||||||
* * The total timeout expired, which is calculated by multiplying the
|
|
||||||
* read timeout multiplier by the number of requested bytes and then
|
|
||||||
* added to the read timeout constant. If that total number of
|
|
||||||
* milliseconds elapses after the initial call to read a timeout will
|
|
||||||
* occur.
|
|
||||||
* * An exception occurred, in this case an actual exception will be thrown.
|
|
||||||
*
|
|
||||||
* \param buffer An uint8_t array of at least the requested size.
|
|
||||||
* \param size A size_t defining how many bytes to be read.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes read as a result of the
|
|
||||||
* call to read.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
read (uint8_t *buffer, size_t size);
|
|
||||||
|
|
||||||
/*! Read a given amount of bytes from the serial port into a give buffer.
|
|
||||||
*
|
|
||||||
* \param buffer A reference to a std::vector of uint8_t.
|
|
||||||
* \param size A size_t defining how many bytes to be read.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes read as a result of the
|
|
||||||
* call to read.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
read (std::vector<uint8_t> &buffer, size_t size = 1);
|
|
||||||
|
|
||||||
/*! Read a given amount of bytes from the serial port into a give buffer.
|
|
||||||
*
|
|
||||||
* \param buffer A reference to a std::string.
|
|
||||||
* \param size A size_t defining how many bytes to be read.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes read as a result of the
|
|
||||||
* call to read.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
read (std::string &buffer, size_t size = 1);
|
|
||||||
|
|
||||||
/*! Read a given amount of bytes from the serial port and return a string
|
|
||||||
* containing the data.
|
|
||||||
*
|
|
||||||
* \param size A size_t defining how many bytes to be read.
|
|
||||||
*
|
|
||||||
* \return A std::string containing the data read from the port.
|
|
||||||
*/
|
|
||||||
std::string
|
|
||||||
read (size_t size = 1);
|
|
||||||
|
|
||||||
/*! Reads in a line or until a given delimiter has been processed.
|
|
||||||
*
|
|
||||||
* Reads from the serial port until a single line has been read.
|
|
||||||
*
|
|
||||||
* \param buffer A std::string reference used to store the data.
|
|
||||||
* \param size A maximum length of a line, defaults to 65536 (2^16)
|
|
||||||
* \param eol A string to match against for the EOL.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes read.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
readline (std::string &buffer, size_t size = 65536, std::string eol = "\n");
|
|
||||||
|
|
||||||
/*! Reads in a line or until a given delimiter has been processed.
|
|
||||||
*
|
|
||||||
* Reads from the serial port until a single line has been read.
|
|
||||||
*
|
|
||||||
* \param size A maximum length of a line, defaults to 65536 (2^16)
|
|
||||||
* \param eol A string to match against for the EOL.
|
|
||||||
*
|
|
||||||
* \return A std::string containing the line.
|
|
||||||
*/
|
|
||||||
std::string
|
|
||||||
readline (size_t size = 65536, std::string eol = "\n");
|
|
||||||
|
|
||||||
/*! Reads in multiple lines until the serial port times out.
|
|
||||||
*
|
|
||||||
* This requires a timeout > 0 before it can be run. It will read until a
|
|
||||||
* timeout occurs and return a list of strings.
|
|
||||||
*
|
|
||||||
* \param size A maximum length of combined lines, defaults to 65536 (2^16)
|
|
||||||
*
|
|
||||||
* \param eol A string to match against for the EOL.
|
|
||||||
*
|
|
||||||
* \return A vector<string> containing the lines.
|
|
||||||
*/
|
|
||||||
std::vector<std::string>
|
|
||||||
readlines (size_t size = 65536, std::string eol = "\n");
|
|
||||||
|
|
||||||
/*! Write a string to the serial port.
|
|
||||||
*
|
|
||||||
* \param data A const reference containing the data to be written
|
|
||||||
* to the serial port.
|
|
||||||
*
|
|
||||||
* \param size A size_t that indicates how many bytes should be written from
|
|
||||||
* the given data buffer.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes actually written to
|
|
||||||
* the serial port.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
write (const uint8_t *data, size_t size);
|
|
||||||
|
|
||||||
/*! Write a string to the serial port.
|
|
||||||
*
|
|
||||||
* \param data A const reference containing the data to be written
|
|
||||||
* to the serial port.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes actually written to
|
|
||||||
* the serial port.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
write (const std::vector<uint8_t> &data);
|
|
||||||
|
|
||||||
/*! Write a string to the serial port.
|
|
||||||
*
|
|
||||||
* \param data A const reference containing the data to be written
|
|
||||||
* to the serial port.
|
|
||||||
*
|
|
||||||
* \return A size_t representing the number of bytes actually written to
|
|
||||||
* the serial port.
|
|
||||||
*/
|
|
||||||
size_t
|
|
||||||
write (const std::string &data);
|
|
||||||
|
|
||||||
/*! Sets the serial port identifier.
|
|
||||||
*
|
|
||||||
* \param port A const std::string reference containing the address of the
|
|
||||||
* serial port, which would be something like 'COM1' on Windows and
|
|
||||||
* '/dev/ttyS0' on Linux.
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setPort (const std::string &port);
|
|
||||||
|
|
||||||
/*! Gets the serial port identifier.
|
|
||||||
*
|
|
||||||
* \see Serial::setPort
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
std::string
|
|
||||||
getPort () const;
|
|
||||||
|
|
||||||
/*! Sets the timeout for reads and writes using the Timeout struct.
|
|
||||||
*
|
|
||||||
* There are two timeout conditions described here:
|
|
||||||
* * The inter byte timeout:
|
|
||||||
* * The inter_byte_timeout component of serial::Timeout defines the
|
|
||||||
* maximum amount of time, in milliseconds, between receiving bytes on
|
|
||||||
* the serial port that can pass before a timeout occurs. Setting this
|
|
||||||
* to zero will prevent inter byte timeouts from occurring.
|
|
||||||
* * Total time timeout:
|
|
||||||
* * The constant and multiplier component of this timeout condition,
|
|
||||||
* for both read and write, are defined in serial::Timeout. This
|
|
||||||
* timeout occurs if the total time since the read or write call was
|
|
||||||
* made exceeds the specified time in milliseconds.
|
|
||||||
* * The limit is defined by multiplying the multiplier component by the
|
|
||||||
* number of requested bytes and adding that product to the constant
|
|
||||||
* component. In this way if you want a read call, for example, to
|
|
||||||
* timeout after exactly one second regardless of the number of bytes
|
|
||||||
* you asked for then set the read_timeout_constant component of
|
|
||||||
* serial::Timeout to 1000 and the read_timeout_multiplier to zero.
|
|
||||||
* This timeout condition can be used in conjunction with the inter
|
|
||||||
* byte timeout condition with out any problems, timeout will simply
|
|
||||||
* occur when one of the two timeout conditions is met. This allows
|
|
||||||
* users to have maximum control over the trade-off between
|
|
||||||
* responsiveness and efficiency.
|
|
||||||
*
|
|
||||||
* Read and write functions will return in one of three cases. When the
|
|
||||||
* reading or writing is complete, when a timeout occurs, or when an
|
|
||||||
* exception occurs.
|
|
||||||
*
|
|
||||||
* \param timeout A serial::Timeout struct containing the inter byte
|
|
||||||
* timeout, and the read and write timeout constants and multipliers.
|
|
||||||
*
|
|
||||||
* \see serial::Timeout
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setTimeout (Timeout &timeout);
|
|
||||||
|
|
||||||
/*! Sets the timeout for reads and writes. */
|
|
||||||
void
|
|
||||||
setTimeout (uint32_t inter_byte_timeout, uint32_t read_timeout_constant,
|
|
||||||
uint32_t read_timeout_multiplier, uint32_t write_timeout_constant,
|
|
||||||
uint32_t write_timeout_multiplier)
|
|
||||||
{
|
|
||||||
Timeout timeout(inter_byte_timeout, read_timeout_constant,
|
|
||||||
read_timeout_multiplier, write_timeout_constant,
|
|
||||||
write_timeout_multiplier);
|
|
||||||
return setTimeout(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*! Gets the timeout for reads in seconds.
|
|
||||||
*
|
|
||||||
* \return A Timeout struct containing the inter_byte_timeout, and read
|
|
||||||
* and write timeout constants and multipliers.
|
|
||||||
*
|
|
||||||
* \see Serial::setTimeout
|
|
||||||
*/
|
|
||||||
Timeout
|
|
||||||
getTimeout () const;
|
|
||||||
|
|
||||||
/*! Sets the baudrate for the serial port.
|
|
||||||
*
|
|
||||||
* Possible baudrates depends on the system but some safe baudrates include:
|
|
||||||
* 110, 300, 600, 1200, 2400, 4800, 9600, 14400, 19200, 28800, 38400, 56000,
|
|
||||||
* 57600, 115200
|
|
||||||
* Some other baudrates that are supported by some comports:
|
|
||||||
* 128000, 153600, 230400, 256000, 460800, 921600
|
|
||||||
*
|
|
||||||
* \param baudrate An integer that sets the baud rate for the serial port.
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setBaudrate (uint32_t baudrate);
|
|
||||||
|
|
||||||
/*! Gets the baudrate for the serial port.
|
|
||||||
*
|
|
||||||
* \return An integer that sets the baud rate for the serial port.
|
|
||||||
*
|
|
||||||
* \see Serial::setBaudrate
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
uint32_t
|
|
||||||
getBaudrate () const;
|
|
||||||
|
|
||||||
/*! Sets the bytesize for the serial port.
|
|
||||||
*
|
|
||||||
* \param bytesize Size of each byte in the serial transmission of data,
|
|
||||||
* default is eightbits, possible values are: fivebits, sixbits, sevenbits,
|
|
||||||
* eightbits
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setBytesize (bytesize_t bytesize);
|
|
||||||
|
|
||||||
/*! Gets the bytesize for the serial port.
|
|
||||||
*
|
|
||||||
* \see Serial::setBytesize
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
bytesize_t
|
|
||||||
getBytesize () const;
|
|
||||||
|
|
||||||
/*! Sets the parity for the serial port.
|
|
||||||
*
|
|
||||||
* \param parity Method of parity, default is parity_none, possible values
|
|
||||||
* are: parity_none, parity_odd, parity_even
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setParity (parity_t parity);
|
|
||||||
|
|
||||||
/*! Gets the parity for the serial port.
|
|
||||||
*
|
|
||||||
* \see Serial::setParity
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
parity_t
|
|
||||||
getParity () const;
|
|
||||||
|
|
||||||
/*! Sets the stopbits for the serial port.
|
|
||||||
*
|
|
||||||
* \param stopbits Number of stop bits used, default is stopbits_one,
|
|
||||||
* possible values are: stopbits_one, stopbits_one_point_five, stopbits_two
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setStopbits (stopbits_t stopbits);
|
|
||||||
|
|
||||||
/*! Gets the stopbits for the serial port.
|
|
||||||
*
|
|
||||||
* \see Serial::setStopbits
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
stopbits_t
|
|
||||||
getStopbits () const;
|
|
||||||
|
|
||||||
/*! Sets the flow control for the serial port.
|
|
||||||
*
|
|
||||||
* \param flowcontrol Type of flowcontrol used, default is flowcontrol_none,
|
|
||||||
* possible values are: flowcontrol_none, flowcontrol_software,
|
|
||||||
* flowcontrol_hardware
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
void
|
|
||||||
setFlowcontrol (flowcontrol_t flowcontrol);
|
|
||||||
|
|
||||||
/*! Gets the flow control for the serial port.
|
|
||||||
*
|
|
||||||
* \see Serial::setFlowcontrol
|
|
||||||
*
|
|
||||||
* \throw InvalidConfigurationException
|
|
||||||
*/
|
|
||||||
flowcontrol_t
|
|
||||||
getFlowcontrol () const;
|
|
||||||
|
|
||||||
/*! Flush the input and output buffers */
|
|
||||||
void
|
|
||||||
flush ();
|
|
||||||
|
|
||||||
/*! Flush only the input buffer */
|
|
||||||
void
|
|
||||||
flushInput ();
|
|
||||||
|
|
||||||
/*! Flush only the output buffer */
|
|
||||||
void
|
|
||||||
flushOutput ();
|
|
||||||
|
|
||||||
/*! Sends the RS-232 break signal. See tcsendbreak(3). */
|
|
||||||
void
|
|
||||||
sendBreak (int duration);
|
|
||||||
|
|
||||||
/*! Set the break condition to a given level. Defaults to true. */
|
|
||||||
void
|
|
||||||
setBreak (bool level = true);
|
|
||||||
|
|
||||||
/*! Set the RTS handshaking line to the given level. Defaults to true. */
|
|
||||||
void
|
|
||||||
setRTS (bool level = true);
|
|
||||||
|
|
||||||
/*! Set the DTR handshaking line to the given level. Defaults to true. */
|
|
||||||
void
|
|
||||||
setDTR (bool level = true);
|
|
||||||
|
|
||||||
/*!
|
|
||||||
* Blocks until CTS, DSR, RI, CD changes or something interrupts it.
|
|
||||||
*
|
|
||||||
* Can throw an exception if an error occurs while waiting.
|
|
||||||
* You can check the status of CTS, DSR, RI, and CD once this returns.
|
|
||||||
* Uses TIOCMIWAIT via ioctl if available (mostly only on Linux) with a
|
|
||||||
* resolution of less than +-1ms and as good as +-0.2ms. Otherwise a
|
|
||||||
* polling method is used which can give +-2ms.
|
|
||||||
*
|
|
||||||
* \return Returns true if one of the lines changed, false if something else
|
|
||||||
* occurred.
|
|
||||||
*
|
|
||||||
* \throw SerialException
|
|
||||||
*/
|
|
||||||
bool
|
|
||||||
waitForChange ();
|
|
||||||
|
|
||||||
/*! Returns the current status of the CTS line. */
|
|
||||||
bool
|
|
||||||
getCTS ();
|
|
||||||
|
|
||||||
/*! Returns the current status of the DSR line. */
|
|
||||||
bool
|
|
||||||
getDSR ();
|
|
||||||
|
|
||||||
/*! Returns the current status of the RI line. */
|
|
||||||
bool
|
|
||||||
getRI ();
|
|
||||||
|
|
||||||
/*! Returns the current status of the CD line. */
|
|
||||||
bool
|
|
||||||
getCD ();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Disable copy constructors
|
|
||||||
Serial(const Serial&);
|
|
||||||
Serial& operator=(const Serial&);
|
|
||||||
|
|
||||||
std::string read_cache_; //!< Cache for doing reads in chunks.
|
|
||||||
|
|
||||||
// Pimpl idiom, d_pointer
|
|
||||||
class SerialImpl;
|
|
||||||
SerialImpl *pimpl_;
|
|
||||||
|
|
||||||
// Scoped Lock Classes
|
|
||||||
class ScopedReadLock;
|
|
||||||
class ScopedWriteLock;
|
|
||||||
|
|
||||||
// Read common function
|
|
||||||
size_t
|
|
||||||
read_ (uint8_t *buffer, size_t size);
|
|
||||||
// Write common function
|
|
||||||
size_t
|
|
||||||
write_ (const uint8_t *data, size_t length);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class SerialException : public std::exception
|
|
||||||
{
|
|
||||||
// Disable copy constructors
|
|
||||||
SerialException& operator=(const SerialException&);
|
|
||||||
std::string e_what_;
|
|
||||||
public:
|
|
||||||
SerialException (const char *description) {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "SerialException " << description << " failed.";
|
|
||||||
e_what_ = ss.str();
|
|
||||||
}
|
|
||||||
SerialException (const SerialException& other) : e_what_(other.e_what_) {}
|
|
||||||
virtual ~SerialException() throw() {}
|
|
||||||
virtual const char* what () const throw () {
|
|
||||||
return e_what_.c_str();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class IOException : public std::exception
|
|
||||||
{
|
|
||||||
// Disable copy constructors
|
|
||||||
IOException& operator=(const IOException&);
|
|
||||||
std::string file_;
|
|
||||||
int line_;
|
|
||||||
std::string e_what_;
|
|
||||||
int errno_;
|
|
||||||
public:
|
|
||||||
explicit IOException (std::string file, int line, int errnum)
|
|
||||||
: file_(file), line_(line), errno_(errnum) {
|
|
||||||
std::stringstream ss;
|
|
||||||
#if defined(_WIN32)
|
|
||||||
char error_str [1024];
|
|
||||||
strerror_s(error_str, 1024, errnum);
|
|
||||||
#else
|
|
||||||
char * error_str = strerror(errnum);
|
|
||||||
#endif
|
|
||||||
ss << "IO Exception (" << errno_ << "): " << error_str;
|
|
||||||
ss << ", file " << file_ << ", line " << line_ << ".";
|
|
||||||
e_what_ = ss.str();
|
|
||||||
}
|
|
||||||
explicit IOException (std::string file, int line, const char * description)
|
|
||||||
: file_(file), line_(line), errno_(0) {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "IO Exception: " << description;
|
|
||||||
ss << ", file " << file_ << ", line " << line_ << ".";
|
|
||||||
e_what_ = ss.str();
|
|
||||||
}
|
|
||||||
virtual ~IOException() throw() {}
|
|
||||||
IOException (const IOException& other) : file_(other.file_), line_(other.line_), e_what_(other.e_what_), errno_(other.errno_) {}
|
|
||||||
|
|
||||||
int getErrorNumber () { return errno_; }
|
|
||||||
|
|
||||||
virtual const char* what () const throw () {
|
|
||||||
return e_what_.c_str();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
class PortNotOpenedException : public std::exception
|
|
||||||
{
|
|
||||||
// Disable copy constructors
|
|
||||||
const PortNotOpenedException& operator=(PortNotOpenedException);
|
|
||||||
std::string e_what_;
|
|
||||||
public:
|
|
||||||
PortNotOpenedException (const char * description) {
|
|
||||||
std::stringstream ss;
|
|
||||||
ss << "PortNotOpenedException " << description << " failed.";
|
|
||||||
e_what_ = ss.str();
|
|
||||||
}
|
|
||||||
PortNotOpenedException (const PortNotOpenedException& other) : e_what_(other.e_what_) {}
|
|
||||||
virtual ~PortNotOpenedException() throw() {}
|
|
||||||
virtual const char* what () const throw () {
|
|
||||||
return e_what_.c_str();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace serial
|
|
||||||
|
|
||||||
#endif
|
|
57
dependencies/include/serial/v8stdint.h
vendored
57
dependencies/include/serial/v8stdint.h
vendored
@ -1,57 +0,0 @@
|
|||||||
// This header is from the v8 google project:
|
|
||||||
// http://code.google.com/p/v8/source/browse/trunk/include/v8stdint.h
|
|
||||||
|
|
||||||
// Copyright 2012 the V8 project authors. All rights reserved.
|
|
||||||
// Redistribution and use in source and binary forms, with or without
|
|
||||||
// modification, are permitted provided that the following conditions are
|
|
||||||
// met:
|
|
||||||
//
|
|
||||||
// * Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
// * Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
// * Neither the name of Google Inc. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
||||||
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
||||||
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
||||||
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
||||||
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
// Load definitions of standard types.
|
|
||||||
|
|
||||||
#ifndef V8STDINT_H_
|
|
||||||
#define V8STDINT_H_
|
|
||||||
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#if defined(_WIN32) && !defined(__MINGW32__)
|
|
||||||
|
|
||||||
typedef signed char int8_t;
|
|
||||||
typedef unsigned char uint8_t;
|
|
||||||
typedef short int16_t; // NOLINT
|
|
||||||
typedef unsigned short uint16_t; // NOLINT
|
|
||||||
typedef int int32_t;
|
|
||||||
typedef unsigned int uint32_t;
|
|
||||||
typedef __int64 int64_t;
|
|
||||||
typedef unsigned __int64 uint64_t;
|
|
||||||
// intptr_t and friends are defined in crtdefs.h through stdio.h.
|
|
||||||
|
|
||||||
#else
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif // V8STDINT_H_
|
|
@ -5,7 +5,7 @@ SET(CURRENT_SOURCE_DIR ${CMAKE_SOURCE_DIR}/libsrc/leddevice)
|
|||||||
|
|
||||||
#add libusb and pthreads (required for the Lighpack usb device)
|
#add libusb and pthreads (required for the Lighpack usb device)
|
||||||
find_package(libusb-1.0 REQUIRED)
|
find_package(libusb-1.0 REQUIRED)
|
||||||
find_package(Threads REQUIRED)
|
#find_package(Threads REQUIRED)
|
||||||
|
|
||||||
include_directories(
|
include_directories(
|
||||||
../../include/hidapi
|
../../include/hidapi
|
||||||
@ -137,11 +137,11 @@ add_library(leddevice
|
|||||||
${Leddevice_SOURCES}
|
${Leddevice_SOURCES}
|
||||||
)
|
)
|
||||||
|
|
||||||
qt5_use_modules(leddevice Network)
|
qt5_use_modules(leddevice Network SerialPort)
|
||||||
|
|
||||||
target_link_libraries(leddevice
|
target_link_libraries(leddevice
|
||||||
hyperion-utils
|
hyperion-utils
|
||||||
serialport
|
# serialport
|
||||||
${LIBUSB_1_LIBRARIES} #apt-get install libusb-1.0-0-dev
|
${LIBUSB_1_LIBRARIES} #apt-get install libusb-1.0-0-dev
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
// Stl includes
|
// Stl includes
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
// Build configuration
|
// Build configuration
|
||||||
|
@ -6,9 +6,6 @@
|
|||||||
// Qt includes
|
// Qt includes
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
|
|
||||||
// Serial includes
|
|
||||||
#include <serial/serial.h>
|
|
||||||
|
|
||||||
// Local Hyperion includes
|
// Local Hyperion includes
|
||||||
#include "LedRs232Device.h"
|
#include "LedRs232Device.h"
|
||||||
|
|
||||||
@ -16,112 +13,74 @@ LedRs232Device::LedRs232Device(const std::string& outputDevice, const unsigned b
|
|||||||
_deviceName(outputDevice),
|
_deviceName(outputDevice),
|
||||||
_baudRate_Hz(baudrate),
|
_baudRate_Hz(baudrate),
|
||||||
_delayAfterConnect_ms(delayAfterConnect_ms),
|
_delayAfterConnect_ms(delayAfterConnect_ms),
|
||||||
_rs232Port(),
|
_rs232Port(this),
|
||||||
_blockedForDelay(false)
|
_blockedForDelay(false),
|
||||||
|
_log(Logger::getInstance("LedDevice"))
|
||||||
{
|
{
|
||||||
// empty
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LedRs232Device::~LedRs232Device()
|
LedRs232Device::~LedRs232Device()
|
||||||
{
|
{
|
||||||
if (_rs232Port.isOpen())
|
if (_rs232Port.isOpen())
|
||||||
{
|
|
||||||
_rs232Port.close();
|
_rs232Port.close();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int LedRs232Device::open()
|
int LedRs232Device::open()
|
||||||
{
|
{
|
||||||
try
|
Info(_log, "Opening UART: %s", _deviceName.c_str());
|
||||||
|
_rs232Port.setPortName(_deviceName.c_str());
|
||||||
|
|
||||||
|
return tryOpen() ? 0 : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool LedRs232Device::tryOpen()
|
||||||
|
{
|
||||||
|
if ( ! _rs232Port.isOpen() )
|
||||||
{
|
{
|
||||||
std::cout << "Opening UART: " << _deviceName << std::endl;
|
if ( ! _rs232Port.open(QIODevice::WriteOnly) )
|
||||||
_rs232Port.setPort(_deviceName);
|
{
|
||||||
_rs232Port.setBaudrate(_baudRate_Hz);
|
Error(_log, "Unable to open RS232 device (%s)", _deviceName.c_str());
|
||||||
_rs232Port.open();
|
return false;
|
||||||
|
}
|
||||||
|
_rs232Port.setBaudRate(_baudRate_Hz);
|
||||||
|
}
|
||||||
|
|
||||||
if (_delayAfterConnect_ms > 0)
|
if (_delayAfterConnect_ms > 0)
|
||||||
{
|
{
|
||||||
_blockedForDelay = true;
|
_blockedForDelay = true;
|
||||||
QTimer::singleShot(_delayAfterConnect_ms, this, SLOT(unblockAfterDelay()));
|
QTimer::singleShot(_delayAfterConnect_ms, this, SLOT(unblockAfterDelay()));
|
||||||
std::cout << "Device blocked for " << _delayAfterConnect_ms << " ms" << std::endl;
|
Debug(_log, "Device blocked for %d ms", _delayAfterConnect_ms);
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (const std::exception& e)
|
|
||||||
{
|
|
||||||
std::cerr << "Unable to open RS232 device (" << e.what() << ")" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return _rs232Port.isOpen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int LedRs232Device::writeBytes(const unsigned size, const uint8_t * data)
|
int LedRs232Device::writeBytes(const unsigned size, const uint8_t * data)
|
||||||
{
|
{
|
||||||
if (_blockedForDelay)
|
if (_blockedForDelay)
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (!_rs232Port.isOpen())
|
if (!_rs232Port.isOpen())
|
||||||
{
|
{
|
||||||
// try to reopen
|
_delayAfterConnect_ms = 3000;
|
||||||
int status = open();
|
return tryOpen() ? 0 : -1;
|
||||||
if(status == -1){
|
|
||||||
// Try again in 3 seconds
|
|
||||||
int seconds = 3000;
|
|
||||||
_blockedForDelay = true;
|
|
||||||
QTimer::singleShot(seconds, this, SLOT(unblockAfterDelay()));
|
|
||||||
std::cout << "Device blocked for " << seconds << " ms" << std::endl;
|
|
||||||
}
|
|
||||||
return status;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// for (int i = 0; i < 20; ++i)
|
|
||||||
// std::cout << std::hex << (int)data[i] << " ";
|
|
||||||
// std::cout << std::endl;
|
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_rs232Port.flushOutput();
|
|
||||||
_rs232Port.write(data, size);
|
|
||||||
_rs232Port.flush();
|
_rs232Port.flush();
|
||||||
}
|
int result = _rs232Port.write(reinterpret_cast<const char*>(data), size);
|
||||||
catch (const serial::SerialException & serialExc)
|
_rs232Port.waitForBytesWritten(100);
|
||||||
{
|
Debug(_log, "write %d ", result);
|
||||||
// TODO[TvdZ]: Maybe we should limit the frequency of this error report somehow
|
|
||||||
std::cerr << "Serial exception caught while writing to device: " << serialExc.what() << std::endl;
|
|
||||||
std::cout << "Attempting to re-open the device." << std::endl;
|
|
||||||
|
|
||||||
// First make sure the device is properly closed
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_rs232Port.close();
|
|
||||||
}
|
|
||||||
catch (const std::exception & e) {}
|
|
||||||
|
|
||||||
// Attempt to open the device and write the data
|
|
||||||
try
|
|
||||||
{
|
|
||||||
_rs232Port.open();
|
|
||||||
_rs232Port.write(data, size);
|
|
||||||
_rs232Port.flush();
|
_rs232Port.flush();
|
||||||
}
|
|
||||||
catch (const std::exception & e)
|
|
||||||
{
|
|
||||||
// We failed again, this not good, do nothing maybe in the next loop we have more success
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (const std::exception& e)
|
|
||||||
{
|
|
||||||
std::cerr << "Unable to write to RS232 device (" << e.what() << ")" << std::endl;
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return (result<0) ? -1 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void LedRs232Device::unblockAfterDelay()
|
void LedRs232Device::unblockAfterDelay()
|
||||||
{
|
{
|
||||||
std::cout << "Device unblocked" << std::endl;
|
Debug(_log, "Device unblocked");
|
||||||
_blockedForDelay = false;
|
_blockedForDelay = false;
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
#include <QSerialPort>
|
||||||
// Serial includes
|
|
||||||
#include <serial/serial.h>
|
|
||||||
|
|
||||||
// Leddevice includes
|
// Leddevice includes
|
||||||
#include <leddevice/LedDevice.h>
|
#include <leddevice/LedDevice.h>
|
||||||
|
|
||||||
|
#include <utils/Logger.h>
|
||||||
|
|
||||||
///
|
///
|
||||||
/// The LedRs232Device implements an abstract base-class for LedDevices using a RS232-device.
|
/// The LedRs232Device implements an abstract base-class for LedDevices using a RS232-device.
|
||||||
///
|
///
|
||||||
@ -52,17 +52,23 @@ private slots:
|
|||||||
void unblockAfterDelay();
|
void unblockAfterDelay();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// tries to open device if not opened
|
||||||
|
bool tryOpen();
|
||||||
|
|
||||||
/// The name of the output device
|
/// The name of the output device
|
||||||
const std::string _deviceName;
|
const std::string _deviceName;
|
||||||
|
|
||||||
/// The used baudrate of the output device
|
/// The used baudrate of the output device
|
||||||
const int _baudRate_Hz;
|
const qint32 _baudRate_Hz;
|
||||||
|
|
||||||
/// Sleep after the connect before continuing
|
/// Sleep after the connect before continuing
|
||||||
const int _delayAfterConnect_ms;
|
int _delayAfterConnect_ms;
|
||||||
|
|
||||||
/// The RS232 serial-device
|
/// The RS232 serial-device
|
||||||
serial::Serial _rs232Port;
|
QSerialPort _rs232Port;
|
||||||
|
|
||||||
bool _blockedForDelay;
|
bool _blockedForDelay;
|
||||||
|
|
||||||
|
/// logger instance
|
||||||
|
Logger* _log;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user