tcp_interface.cpp
Go to the documentation of this file.
1 /*
2 * Unpublished Copyright (c) 2009-2017 AutonomouStuff, LLC, All Rights Reserved.
3 *
4 * This file is part of the network_interface ROS 1.0 driver which is released under the MIT license.
5 * See file LICENSE included with this software or go to https://opensource.org/licenses/MIT for full license details.
6 */
7 
8 #include <network_interface.h>
9 
10 using namespace AS::Network; // NOLINT
11 using boost::asio::ip::tcp;
12 
13 // Default constructor.
15  socket_(io_service_)
16 {
17 }
18 
19 // Default destructor.
21 {
22 }
23 
24 return_statuses TCPInterface::open(const char *ip_address, const int &port)
25 {
26  if (socket_.is_open())
27  return OK;
28 
29  std::stringstream sPort;
30  sPort << port;
31  tcp::resolver res(io_service_);
32  tcp::resolver::query query(tcp::v4(), ip_address, sPort.str());
33  tcp::resolver::iterator it = res.resolve(query);
34  boost::system::error_code ec;
35 
36  socket_.connect(*it, ec);
37 
38  if (ec.value() == boost::system::errc::success)
39  {
40  return OK;
41  }
42  else if (ec.value() == boost::asio::error::invalid_argument)
43  {
44  return BAD_PARAM;
45  }
46  else
47  {
48  close();
49  return INIT_FAILED;
50  }
51 }
52 
54 {
55  if (!socket_.is_open())
56  return OK;
57 
58  boost::system::error_code ec;
59  socket_.close(ec);
60 
61  if (ec.value() == boost::system::errc::success)
62  {
63  return OK;
64  }
65  else
66  {
67  return CLOSE_FAILED;
68  }
69 }
70 
72 {
73  return socket_.is_open();
74 }
75 
76 void TCPInterface::timeout_handler(const boost::system::error_code& error)
77 {
78  // If the operation was not aborted, store the bytes that were read and set the read flag
79  if (error != boost::asio::error::operation_aborted)
80  {
81  error_.assign(boost::system::errc::timed_out, boost::system::system_category());
82  }
83 }
84 
85 void TCPInterface::read_handler(const boost::system::error_code& error, size_t bytes_read)
86 {
87  bytes_read_ = bytes_read;
88 }
89 
91  const size_t &buf_size,
92  size_t &bytes_read,
93  int timeout_ms)
94 {
95  if (!socket_.is_open())
96  return SOCKET_CLOSED;
97 
98  error_.assign(boost::system::errc::success, boost::system::system_category());
99 
100  boost::asio::deadline_timer timer(io_service_);
101  // If requested timeout duration is set to 0 ms, don't set a deadline
102  if (timeout_ms > 0)
103  {
104  timer.expires_from_now(boost::posix_time::milliseconds(timeout_ms));
105  timer.async_wait(boost::bind(&TCPInterface::timeout_handler,
106  this,
107  boost::asio::placeholders::error));
108  }
109 
110  boost::asio::async_read(socket_,
111  boost::asio::buffer(msg, buf_size),
112  boost::bind(&TCPInterface::read_handler,
113  this,
114  boost::asio::placeholders::error,
115  boost::asio::placeholders::bytes_transferred));
116  // Run until a handler is called
117  while (io_service_.run_one())
118  {
119  if (error_.value() == boost::system::errc::success)
120  {
121  timer.cancel();
122  bytes_read = bytes_read_;
123  }
124  else if (error_.value() == boost::system::errc::timed_out)
125  {
126  socket_.cancel();
127  }
128  }
129  // Reset the io service so that it is available for the next call to TCPInterface::read
130  io_service_.reset();
131 
132  if (error_.value() == boost::system::errc::success)
133  {
134  return OK;
135  }
136  else if (error_.value() == boost::system::errc::timed_out)
137  {
138  return SOCKET_TIMEOUT;
139  }
140  else
141  {
142  return READ_FAILED;
143  }
144 }
145 
147  const size_t &buf_size,
148  const size_t &bytes_to_read,
149  int timeout_ms)
150 {
151  if (!socket_.is_open())
152  return SOCKET_CLOSED;
153 
154  error_.assign(boost::system::errc::success, boost::system::system_category());
155 
156  boost::asio::deadline_timer timer(io_service_);
157  // If requested timeout duration is set to 0 ms, don't set a deadline
158  if (timeout_ms > 0)
159  {
160  timer.expires_from_now(boost::posix_time::milliseconds(timeout_ms));
161  timer.async_wait(boost::bind(&TCPInterface::timeout_handler,
162  this,
163  boost::asio::placeholders::error));
164  }
165 
166  boost::asio::async_read(socket_,
167  boost::asio::buffer(msg, buf_size),
168  boost::asio::transfer_exactly(bytes_to_read),
169  boost::bind(&TCPInterface::read_handler,
170  this,
171  boost::asio::placeholders::error,
172  boost::asio::placeholders::bytes_transferred));
173  // Run until a handler is called
174  while (io_service_.run_one())
175  {
176  if (error_.value() == boost::system::errc::success)
177  {
178  timer.cancel();
179  }
180  else if (error_.value() == boost::system::errc::timed_out)
181  {
182  socket_.cancel();
183  }
184  }
185  // Reset the io service so that it is available for the next call to TCPInterface::read_exactly
186  io_service_.reset();
187 
188  if (error_.value() == boost::system::errc::success)
189  {
190  return OK;
191  }
192  else if (error_.value() == boost::system::errc::timed_out)
193  {
194  return SOCKET_TIMEOUT;
195  }
196  else
197  {
198  return READ_FAILED;
199  }
200 }
201 
202 return_statuses TCPInterface::write(unsigned char *msg, const size_t &msg_size)
203 {
204  if (!socket_.is_open())
205  return SOCKET_CLOSED;
206 
207  boost::system::error_code ec;
208  boost::asio::write(socket_, boost::asio::buffer(msg, msg_size), ec);
209 
210  if (ec.value() == boost::system::errc::success)
211  {
212  return OK;
213  }
214  else
215  {
216  return WRITE_FAILED;
217  }
218 }
return_statuses read_exactly(unsigned char *msg, const size_t &buf_size, const size_t &bytes_to_read, int timeout_ms=0)
boost::asio::ip::tcp::socket socket_
void timeout_handler(const boost::system::error_code &error)
return_statuses open(const char *ip_address, const int &port)
boost::system::error_code error_
return_statuses close()
void read_handler(const boost::system::error_code &error, size_t bytes_read)
boost::asio::io_service io_service_
return_statuses write(unsigned char *msg, const size_t &msg_size)
return_statuses read(unsigned char *msg, const size_t &buf_size, size_t &bytes_read, int timeout_ms=0)


network_interface
Author(s): Joshua Whitley , Daniel Stanek , Joe Kale
autogenerated on Sat Sep 7 2019 03:30:10