36 #include <boost/asio.hpp> 37 #include <boost/lambda/lambda.hpp> 40 #include <boost/lexical_cast.hpp> 49 deadline_(io_service_),
57 deadline_.expires_at(boost::posix_time::pos_infin);
67 using boost::asio::ip::tcp;
68 using boost::lambda::var;
69 using boost::lambda::_1;
74 tcp::resolver::iterator iterator;
79 iterator = resolver.resolve(query);
81 catch (boost::system::system_error &e)
83 ROS_FATAL(
"Could not resolve host: ... (%d)(%s)", e.code().value(), e.code().message().c_str());
89 boost::system::error_code ec;
91 for ( ; iterator != tcp::resolver::iterator(); ++iterator)
93 std::string repr = boost::lexical_cast<std::string>(iterator->endpoint());
100 ec = boost::asio::error::would_block;
101 ROS_DEBUG(
"Attempting to connect to %s", repr.c_str());
102 socket_.async_connect(iterator->endpoint(), boost::lambda::var(ec) = _1);
105 do io_service_.run_one();
while (ec == boost::asio::error::would_block);
110 ROS_INFO(
"Succesfully connected to %s", repr.c_str());
113 ROS_ERROR(
"Failed to connect to %s", repr.c_str());
137 catch (boost::system::system_error &e)
139 ROS_ERROR(
"An error occured during closing of the connection: %d:%s", e.code().value(), e.code().message().c_str());
147 if (
deadline_.expires_at() <= boost::asio::deadline_timer::traits_type::now())
152 deadline_.expires_at(boost::posix_time::pos_infin);
162 deadline_.expires_from_now(boost::posix_time::milliseconds(timeout_ms));
163 const char end_delim =
static_cast<char>(0x03);
164 ec_ = boost::asio::error::would_block;
168 boost::asio::async_read_until(
175 boost::asio::placeholders::error,
176 boost::asio::placeholders::bytes_transferred
179 do io_service_.run_one();
while (
ec_ == boost::asio::error::would_block);
185 if (
ec_ != boost::asio::error::would_block)
187 ROS_ERROR(
"sendSOPASCommand: failed attempt to read from socket: %d: %s",
ec_.value(),
ec_.message().c_str());
188 diagnostics_.
broadcast(diagnostic_msgs::DiagnosticStatus::ERROR,
"sendSOPASCommand: exception during read_until().");
189 if (exception_occured != 0)
190 *exception_occured =
true;
203 istr.read(buffer, to_read);
219 *bytes_read = to_read;
230 ROS_ERROR(
"sendSOPASCommand: socket not open");
231 diagnostics_.
broadcast(diagnostic_msgs::DiagnosticStatus::ERROR,
"sendSOPASCommand: socket not open.");
240 boost::asio::write(
socket_, boost::asio::buffer(request, strlen(request)));
242 catch (boost::system::system_error &e)
244 ROS_ERROR(
"write error for command: %s", request);
245 diagnostics_.
broadcast(diagnostic_msgs::DiagnosticStatus::ERROR,
"Write error for sendSOPASCommand.");
250 const int BUF_SIZE = 1000;
251 char buffer[BUF_SIZE];
255 ROS_ERROR_THROTTLE(1.0,
"sendSOPASCommand: no full reply available for read after 1s");
256 diagnostics_.
broadcast(diagnostic_msgs::DiagnosticStatus::ERROR,
"sendSOPASCommand: no full reply available for read after 5 s.");
262 reply->resize(bytes_read);
263 std::copy(buffer, buffer + bytes_read, &(*reply)[0]);
272 ROS_ERROR(
"get_datagram: socket not open");
280 std::vector<unsigned char> reply;
283 size_t timeout = 1000;
284 bool exception_occured =
false;
286 char *buffer =
reinterpret_cast<char *
>(receiveBuffer);
290 ROS_ERROR_THROTTLE(1.0,
"get_datagram: no data available for read after %zu ms", timeout);
291 diagnostics_.
broadcast(diagnostic_msgs::DiagnosticStatus::ERROR,
"get_datagram: no data available for read after timeout.");
297 ROS_INFO(
"Failure - attempting to reconnect");
int readWithTimeout(size_t timeout_ms, char *buffer, int buffer_size, int *bytes_read=0, bool *exception_occured=0)
boost::asio::streambuf input_buffer_
boost::system::error_code ec_
boost::asio::io_service io_service_
boost::asio::ip::tcp::socket socket_
virtual ~SickTimCommonTcp()
#define ROS_ERROR_THROTTLE(rate,...)
virtual int get_datagram(unsigned char *receiveBuffer, int bufferSize, int *actual_length)
Read a datagram from the device.
virtual int close_device()
virtual int stop_scanner()
diagnostic_updater::Updater diagnostics_
virtual int sendSOPASCommand(const char *request, std::vector< unsigned char > *reply)
Send a SOPAS command to the device and print out the response to the console.
SickTimCommonTcp(const std::string &hostname, const std::string &port, int &timelimit, AbstractParser *parser)
boost::asio::deadline_timer deadline_
void handleRead(boost::system::error_code error, size_t bytes_transfered)
void broadcast(int lvl, const std::string msg)
virtual int init_device()