AsyncTCPClient.cpp
Go to the documentation of this file.
1 // this is for emacs file handling -*- mode: c++; indent-tabs-mode: nil -*-
2 
3 // -- BEGIN LICENSE BLOCK ----------------------------------------------
4 
24 // -- END LICENSE BLOCK ------------------------------------------------
25 
26 //----------------------------------------------------------------------
33 //----------------------------------------------------------------------
34 
36 
37 namespace sick {
38 namespace communication {
40  boost::asio::io_service& io_service,
41  const boost::asio::ip::address_v4& server_ip,
42  const uint16_t& server_port)
43  : m_packet_handler(packet_handler)
44  , m_io_service(io_service)
45 
46 {
47  // Keep io_service busy
48  m_io_work_ptr = std::make_shared<boost::asio::io_service::work>(m_io_service);
49  try
50  {
51  m_socket_ptr = std::make_shared<boost::asio::ip::tcp::socket>(m_io_service);
52  }
53  catch (const std::exception& e)
54  {
55  ROS_ERROR("Exception while creating socket: %s", e.what());
56  }
57  m_remote_endpoint = boost::asio::ip::tcp::endpoint(server_ip, server_port);
58  ROS_INFO("TCP client is setup");
59 }
60 
62 
64 {
65  boost::mutex::scoped_lock lock(m_socket_mutex);
66  boost::system::error_code ec;
67  m_socket_ptr->shutdown(boost::asio::ip::tcp::socket::shutdown_both, ec);
68  if (ec != boost::system::errc::success)
69  {
70  ROS_ERROR("Error shutting socket down: %i", ec.value());
71  }
72  else
73  {
74  ROS_INFO("TCP Connection successfully shutdown");
75  }
76 
77  m_socket_ptr->close(ec);
78  if (ec != boost::system::errc::success)
79  {
80  ROS_ERROR("Error closing Socket: %i", ec.value());
81  }
82  else
83  {
84  ROS_INFO("TCP Socket successfully closed.");
85  }
86 }
87 
89 {
90  boost::mutex::scoped_lock lock(m_socket_mutex);
91  boost::mutex::scoped_lock lock_connect(m_connect_mutex);
92  m_socket_ptr->async_connect(m_remote_endpoint, [this](boost::system::error_code ec) {
93  if (ec != boost::system::errc::success)
94  {
95  ROS_ERROR("TCP error code: %i", ec.value());
96  }
97  else
98  {
99  ROS_INFO("TCP connection successfully established.");
100  }
101  m_connect_condition.notify_all();
102  });
103 
104  m_connect_condition.wait(lock_connect);
105 }
106 
107 
108 void AsyncTCPClient::doSendAndReceive(const std::vector<uint8_t>& sendBuffer)
109 {
110  boost::mutex::scoped_lock lock(m_socket_mutex);
111  if (!m_socket_ptr)
112  {
113  return;
114  }
115  boost::asio::async_write(*m_socket_ptr,
116  boost::asio::buffer(sendBuffer),
117  [this](boost::system::error_code ec, std::size_t bytes_send) {
118  this->handleSendAndReceive(ec, bytes_send);
119  });
120 }
121 
123 {
124  boost::mutex::scoped_lock lock(m_socket_mutex);
125  if (!m_socket_ptr)
126  {
127  return;
128  }
129  m_socket_ptr->async_read_some(boost::asio::buffer(m_recv_buffer),
130  [this](boost::system::error_code ec, std::size_t bytes_recvd) {
131  this->handleReceive(ec, bytes_recvd);
132  });
133 }
134 
136 {
137  m_packet_handler = packet_handler;
138 }
139 
140 void AsyncTCPClient::handleSendAndReceive(const boost::system::error_code& error,
141  const std::size_t& bytes_transferred)
142 {
143  // Check for errors
144  if (!error || error == boost::asio::error::message_size)
145  {
146  initiateReceive();
147  }
148  else
149  {
150  ROS_ERROR("Error in tcp handle send and receive: %i", error.value());
151  }
152 }
153 
154 
156 
157 void AsyncTCPClient::handleReceive(const boost::system::error_code& error,
158  const std::size_t& bytes_transferred)
159 {
160  if (!error)
161  {
162  sick::datastructure::PacketBuffer packet_buffer(m_recv_buffer, bytes_transferred);
163  m_packet_handler(packet_buffer);
164  }
165  else
166  {
167  ROS_ERROR("Error in tcp handle receive: %i", error.value());
168  }
169 }
170 
171 
172 } // namespace communication
173 } // namespace sick
boost::function< void(const sick::datastructure::PacketBuffer &)> PacketHandler
Typedef to a function referencing a packet handler. This can be passed to the class and therefore be ...
A packetbuffer for the raw data from the sensor.
Definition: PacketBuffer.h:61
void initiateReceive()
Initiates the listening for a message from the server.
datastructure::PacketBuffer::ArrayBuffer m_recv_buffer
void doSendAndReceive(const std::vector< uint8_t > &sendBuffer)
Start a cycle of sensing a command and waiting got the return.
void handleReceive(const boost::system::error_code &error, const std::size_t &bytes_transferred)
void doConnect()
Establishes a connection from the host to the sensor.
AsyncTCPClient(const PacketHandler &packet_handler, boost::asio::io_service &io_service, const boost::asio::ip::address_v4 &server_ip, const uint16_t &server_port)
Constructor of the asynchronous tcp client.
void handleSendAndReceive(const boost::system::error_code &error, const std::size_t &bytes_transferred)
#define ROS_INFO(...)
boost::asio::io_service & m_io_service
virtual ~AsyncTCPClient()
The destructor of the asynchronous tcp client.
void doDisconnect()
Disconnects the host from the sensor.
boost::asio::ip::tcp::endpoint m_remote_endpoint
std::shared_ptr< boost::asio::ip::tcp::socket > m_socket_ptr
void setPacketHandler(const PacketHandler &packet_handler)
Sets the packet handler function.
std::shared_ptr< boost::asio::io_service::work > m_io_work_ptr
#define ROS_ERROR(...)


sick_safetyscanners
Author(s): Lennart Puck
autogenerated on Fri Apr 2 2021 02:45:41