ChimeraTK-DeviceAccess  03.18.00
Connection.cc
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Deutsches Elektronen-Synchrotron DESY, MSK, ChimeraTK Project <chimeratk-support@desy.de>
2 // SPDX-License-Identifier: LGPL-3.0-or-later
3 
4 #include "Connection.h"
5 
6 #include "Exception.h"
7 
8 #include <utility>
9 namespace ChimeraTK::Rebot {
10 
11  using Error = boost::system::error_code;
12 
13  Connection::Connection(std::string address, std::string port, uint32_t connectionTimeout_sec)
14  : address_(std::move(address)), port_(std::move(port)), s_(ioService_), disconnectTimer_(ioService_),
15  connectionTimeout_(boost::posix_time::seconds(connectionTimeout_sec)) {}
16 
18  try {
19  disconnectionTimerStart();
20  boost::asio::ip::tcp::resolver r(ioService_);
21  boost::asio::async_connect(
22  s_, r.resolve({address_, port_}), [&](const Error ec, auto) { disconnectionTimerCancel(ec); });
23 
24  ioService_.reset();
25  ioService_.run();
26  }
27  catch(const boost::exception&) {
28  throw ChimeraTK::runtime_error("RebotBackend exception: Host unreachable:");
29  }
30  }
31 
32  std::vector<uint32_t> Connection::read(uint32_t numWords) {
33  std::vector<uint32_t> d(numWords);
34  disconnectionTimerStart();
35  boost::asio::async_read(s_, boost::asio::buffer(d), [&](Error ec, std::size_t) { disconnectionTimerCancel(ec); });
36 
37  ioService_.reset();
38  ioService_.run();
39  return d;
40  }
41 
42  void Connection::write(const std::vector<uint32_t>& d) {
43  disconnectionTimerStart();
44  boost::asio::async_write(s_, boost::asio::buffer(d), [&](Error ec, std::size_t) { disconnectionTimerCancel(ec); });
45 
46  ioService_.reset();
47  ioService_.run();
48  }
49 
51  if(s_.is_open()) {
52  s_.cancel();
53  s_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
54  s_.close();
55  }
56  }
57 
59  return s_.is_open();
60  }
61 
62  void Connection::disconnectionTimerStart() {
63  disconnectTimer_.expires_from_now(connectionTimeout_);
64  disconnectTimer_.async_wait([&](const Error& ec) {
65  if(ec == boost::asio::error::operation_aborted) {
66  // you have this error code when the timer was cancelled before expiry
67  return;
68  }
69  close();
70  });
71  }
72 
73  void Connection::disconnectionTimerCancel(const Error& ec) {
74  disconnectTimer_.cancel();
75  if(ec) {
76  close();
77  throw ChimeraTK::runtime_error("Rebot connection timed out");
78  }
79  }
80 
81 } // namespace ChimeraTK::Rebot
ChimeraTK::Rebot::Connection::close
void close()
Closes a connection with the device.
Definition: Connection.cc:50
ChimeraTK::Rebot
Definition: RebotBackend.h:26
ChimeraTK::runtime_error
Exception thrown when a runtime error has occured.
Definition: Exception.h:18
ChimeraTK::Rebot::Error
boost::system::error_code Error
Definition: Connection.cc:11
ChimeraTK::Rebot::Connection::isOpen
bool isOpen()
Get the connection state.
Definition: Connection.cc:58
ChimeraTK::Rebot::Connection::Connection
Connection(std::string address, std::string port, uint32_t connectionTimeout_sec)
Gets an IP address and port of the device but does not open the connection.
Definition: Connection.cc:13
ChimeraTK::Rebot::Connection::write
void write(const std::vector< uint32_t > &data)
Sends a std::vector of bytes to the socket.
Definition: Connection.cc:42
Connection.h
Exception.h
ChimeraTK::Rebot::Connection::open
void open()
Opens a connection to the device.
Definition: Connection.cc:17
ChimeraTK::Rebot::Connection::read
std::vector< uint32_t > read(uint32_t numWordsToRead)
Receives uint32_t words from the socket.
Definition: Connection.cc:32