24 #ifndef GOBY_ACOMMS_MODEMDRIVER_IRIDIUM_SHORE_RUDICS_H
25 #define GOBY_ACOMMS_MODEMDRIVER_IRIDIUM_SHORE_RUDICS_H
28 #include <boost/asio.hpp>
30 #include <boost/bind/bind.hpp>
31 #include <boost/signals2.hpp>
44 static std::shared_ptr<RUDICSConnection>
create(
46 boost::asio::io_service& executor)
48 const boost::asio::ip::tcp::socket::executor_type& executor)
54 boost::asio::ip::tcp::socket&
socket() {
return socket_; }
58 remote_endpoint_str_ = boost::lexical_cast<std::string>(socket_.remote_endpoint());
64 socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_both);
70 boost::asio::async_read_until(socket_, buffer_,
'\r',
71 boost::bind(&RUDICSConnection::handle_read,
this, boost::placeholders::_1, boost::placeholders::_2));
76 boost::asio::async_write(socket_, boost::asio::buffer(data),
77 boost::bind(&RUDICSConnection::handle_write,
this, boost::placeholders::_1, boost::placeholders::_2));
84 glog.
is(
DEBUG1) &&
glog <<
"Disconnecting from: " << remote_endpoint_str_ << std::endl;
91 const int max_packet_failures = 3;
92 if (++packet_failures_ >= max_packet_failures)
94 glog.
is(
DEBUG1) &&
glog <<
"More than " << max_packet_failures <<
" bad RUDICS packets."
100 boost::signals2::signal<
void(
const std::string& line,
101 std::shared_ptr<RUDICSConnection> connection)>
110 boost::asio::io_service& executor)
112 const boost::asio::ip::tcp::socket::executor_type& executor)
114 : socket_(executor), remote_endpoint_str_(
"Unknown"), packet_failures_(0)
118 void handle_write(
const boost::system::error_code& error,
size_t bytes_transferred)
124 glog.
is(
WARN) &&
glog <<
"Error writing to TCP connection: " << error << std::endl;
129 void handle_read(
const boost::system::error_code& error,
size_t bytes_transferred)
136 std::istream istrm(&buffer_);
138 std::getline(istrm, line,
'\r');
144 if (error == boost::asio::error::eof)
148 else if (error == boost::asio::error::operation_aborted)
150 glog.
is(
DEBUG1) &&
glog <<
"Read operation aborted (socket closed)" << std::endl;
163 boost::asio::ip::tcp::socket socket_;
164 boost::asio::streambuf buffer_;
165 std::string remote_endpoint_str_;
166 int packet_failures_;
178 std::set<std::shared_ptr<RUDICSConnection> >&
connections() {
return connections_; }
182 void disconnect(std::shared_ptr<RUDICSConnection> connection) { connection->close(); }
187 std::shared_ptr<RUDICSConnection> new_connection =
188 #ifdef USE_BOOST_IO_SERVICE
193 acceptor_.async_accept(new_connection->socket(),
194 boost::bind(&RUDICSServer::handle_accept,
this, new_connection,
195 boost::asio::placeholders::error));
198 void handle_accept(std::shared_ptr<RUDICSConnection> new_connection,
199 const boost::system::error_code& error)
206 connections_.insert(new_connection);
208 new_connection->disconnect_signal.connect(
209 boost::bind(&RUDICSServer::handle_disconnect,
this, boost::placeholders::_1));
211 new_connection->start();
213 << new_connection->remote_endpoint_str() << std::endl;
219 void handle_disconnect(std::shared_ptr<RUDICSConnection> connection)
224 connections_.erase(connection);
227 glog <<
"Server removing connection: " << connection->remote_endpoint_str()
228 <<
". Remaining connection count: " << connections_.size() << std::endl;
231 std::set<std::shared_ptr<RUDICSConnection> > connections_;
232 boost::asio::ip::tcp::acceptor acceptor_;