11#include <boost/bind/bind.hpp>
24 if(serverVersion == 0) {
25 return std::make_unique<RebotProtocol0>(c);
27 if(serverVersion == 1) {
28 return std::make_unique<RebotProtocol1>(c);
31 std::stringstream errorMessage;
32 errorMessage <<
"Server protocol version " << serverVersion <<
" not supported!";
39 std::vector<uint32_t> clientHelloMessage;
40 clientHelloMessage.push_back(Rebot::HELLO_TOKEN);
41 clientHelloMessage.push_back(Rebot::MAGIC_WORD);
42 clientHelloMessage.push_back(Rebot::CLIENT_PROTOCOL_VERSION);
44 c->write(clientHelloMessage);
50 auto serverHello = c->read(1);
52 if(serverHello.at(0) ==
static_cast<uint32_t
>(Rebot::UNKNOWN_INSTRUCTION)) {
56 auto remainingBytesOfAValidServerHello = c->read(Rebot::LENGTH_OF_HELLO_TOKEN_MESSAGE - 1);
59 serverHello.end(), remainingBytesOfAValidServerHello.begin(), remainingBytesOfAValidServerHello.end());
65 return serverHello.at(2);
69 std::string boardAddr, std::string port,
const std::string& mapFileName, uint32_t connectionTimeout_sec)
72 _connection(boost::make_shared<Rebot::
Connection>(_boardAddr, _port, connectionTimeout_sec)),
73 _lastSendTime(testable_rebot_sleep::now()), _connectionTimeout(Rebot::DEFAULT_CONNECTION_TIMEOUT),
89 catch(boost::system::system_error&) {
140 std::string , std::map<std::string, std::string> parameters) {
142 if(parameters[
"ip"].empty()) {
145 if(parameters[
"port"].empty()) {
149 std::string tmcbIP = parameters[
"ip"];
150 std::string portNumber = parameters[
"port"];
151 std::string mapFileName = parameters[
"map"];
154 auto it = parameters.find(
"timeout");
155 if(it != parameters.end()) {
156 timeout =
static_cast<uint32_t
>(std::stoul(it->second));
158 return boost::shared_ptr<RebotBackend>(
new RebotBackend(tmcbIP, portNumber, mapFileName, timeout));
170 boost::chrono::steady_clock::time_point wakeupTime;
178 if(threadInformerMutex->quitThread) {
196 setException(std::string(
"RebotBackend: Sending heartbeat failed. Caught exception: ") + e.
what());
void setOpenedAndClearException() noexcept
Backends should call this function at the end of a (successful) open() call.
void setException(const std::string &message) noexcept final
Set the backend into an exception state.
void checkActiveException() final
Function to be called by backends when needing to check for an active exception.
bool isOpen() override
Return whether a device has been opened or not.
std::atomic< bool > _opened
flag if backend is opened
Base class for address-based device backends (e.g.
Handles the communication over TCP protocol with RebotDevice-based devices.
void read(uint8_t bar, uint32_t addressInBytes, int32_t *data, size_t sizeInBytes) override
Deprecated read function using 32bit address for backwards compatibility.
RebotBackend(std::string boardAddr, std::string port, const std::string &mapFileName="", uint32_t connectionTimeout_sec=DEFAULT_CONNECTION_TIMEOUT_sec)
boost::chrono::steady_clock::time_point _lastSendTime
The time when the last command (read/write/heartbeat) was send.
void open() override
The function opens the connection to the device.
boost::thread _heartbeatThread
boost::shared_ptr< ThreadInformerMutex > _threadInformerMutex
unsigned int _connectionTimeout
void heartbeatLoop(const boost::shared_ptr< ThreadInformerMutex > &threadInformerMutex)
std::unique_ptr< RebotProtocolImplementor > _protocolImplementor
void write(uint8_t bar, uint32_t addressInBytes, int32_t const *data, size_t sizeInBytes) override
Deprecated write function using 32bit address for backwards compatibility.
static const uint32_t DEFAULT_CONNECTION_TIMEOUT_sec
boost::shared_ptr< Rebot::Connection > _connection
void closeImpl() override
All backends derrived from NumericAddressedBackend must implement closeImpl() instead of close.
static boost::shared_ptr< DeviceBackend > createInstance(std::string address, std::map< std::string, std::string > parameters)
Exception thrown when a logic error has occured.
Exception thrown when a runtime error has occured.
const char * what() const noexcept override
Return the message describing what exactly went wrong.
boost::chrono::steady_clock::time_point now()
void sleep_until(boost::chrono::steady_clock::time_point t)
There are two implementations with the same signature: One that calls boost::thread::this_thread::sle...
std::unique_ptr< RebotProtocolImplementor > getProtocolImplementor(boost::shared_ptr< Rebot::Connection > &c)
uint32_t parseRxServerHello(const std::vector< uint32_t > &serverHello)
uint32_t getProtocolVersion(boost::shared_ptr< Rebot::Connection > &c)