24 #ifndef GOBY_ACOMMS_MODEMDRIVER_IRIDIUM_SHORE_SBD_DIRECTIP_H
25 #define GOBY_ACOMMS_MODEMDRIVER_IRIDIUM_SHORE_SBD_DIRECTIP_H
27 #include <boost/asio.hpp>
28 #include <boost/bind/bind.hpp>
29 #include <boost/enable_shared_from_this.hpp>
49 : socket_(socket), pos_(0), data_(1 << 16)
55 const goby::acomms::iridium::protobuf::DirectIPMOPreHeader&
pre_header()
const
59 const goby::acomms::iridium::protobuf::DirectIPMOHeader&
header()
const {
return header_; }
60 const goby::acomms::iridium::protobuf::DirectIPMOPayload&
body()
const {
return body_; }
61 const goby::acomms::iridium::protobuf::DirectIPMTConfirmation&
confirm()
const
75 throw std::runtime_error(
"Error while reading: " + error.message());
77 pre_header_.set_protocol_ver(read_byte());
78 pre_header_.set_overall_length(read_uint16());
80 boost::asio::async_read(socket_, boost::asio::buffer(data_),
81 boost::asio::transfer_at_least(pre_header_.overall_length() +
84 boost::placeholders::_1, boost::placeholders::_2));
87 std::vector<char>&
data() {
return data_; }
90 void ie_handler(
const boost::system::error_code& error, std::size_t bytes_transferred)
93 throw std::runtime_error(
"Error while reading: " + error.message());
95 char iei = read_byte();
96 unsigned length = read_uint16();
102 header_.set_iei(iei);
103 header_.set_length(length);
104 header_.set_cdr_reference(read_uint32());
106 header_.set_imei(read_imei());
108 header_.set_session_status(read_byte());
109 header_.set_momsn(read_uint16());
110 header_.set_mtmsn(read_uint16());
111 header_.set_time_of_session(read_uint32());
117 body_.set_length(length);
118 body_.set_payload(std::string(data_.begin() + pos_, data_.begin() + pos_ + length));
123 confirm_.set_iei(iei);
124 confirm_.set_length(length);
125 confirm_.set_client_id(read_uint32());
126 confirm_.set_imei(read_imei());
127 confirm_.set_auto_ref_id(read_uint32());
128 confirm_.set_status(read_int16());
136 ie_handler(error, bytes_transferred);
139 char read_byte() {
return data_.at(pos_++) & 0xff; }
141 unsigned read_uint16()
144 u |= data_.at(pos_++) & 0xff;
151 i |= data_.at(pos_++) & 0xff;
154 int sign_bit_mask = 0x8000;
155 if (i & sign_bit_mask)
161 unsigned read_uint32()
164 for (
int i = 0; i < 4; ++i) u |= (data_.at(pos_++) & 0xff) << ((3 - i) *
BITS_PER_BYTE);
168 std::string read_imei()
170 const int imei_size = 15;
171 std::string imei = std::string(data_.begin() + pos_, data_.begin() + pos_ + imei_size);
177 goby::acomms::iridium::protobuf::DirectIPMOPreHeader pre_header_;
178 goby::acomms::iridium::protobuf::DirectIPMOHeader header_;
179 goby::acomms::iridium::protobuf::DirectIPMOPayload body_;
180 goby::acomms::iridium::protobuf::DirectIPMTConfirmation confirm_;
182 boost::asio::ip::tcp::socket& socket_;
184 std::vector<char>::size_type pos_;
185 std::vector<char> data_;
212 static std::shared_ptr<SBDConnection>
create(
214 boost::asio::io_service& executor)
216 const boost::asio::ip::tcp::socket::executor_type& executor)
219 return std::shared_ptr<SBDConnection>(
new SBDConnection(executor));
222 boost::asio::ip::tcp::socket&
socket() {
return socket_; }
226 remote_endpoint_str_ = boost::lexical_cast<std::string>(socket_.remote_endpoint());
229 boost::asio::async_read(socket_, boost::asio::buffer(message_.
data()),
232 boost::placeholders::_1, boost::placeholders::_2));
245 boost::asio::io_service& executor)
247 const boost::asio::ip::tcp::socket::executor_type& executor)
249 : socket_(executor), connect_time_(-1), message_(socket_), remote_endpoint_str_(
"Unknown")
253 boost::asio::ip::tcp::socket socket_;
254 double connect_time_;
255 SBDMOMessageReader message_;
256 std::string remote_endpoint_str_;
268 std::set<std::shared_ptr<SBDConnection>>&
connections() {
return connections_; }
273 std::shared_ptr<SBDConnection> new_connection =
274 #ifdef USE_BOOST_IO_SERVICE
279 connections_.insert(new_connection);
281 acceptor_.async_accept(new_connection->socket(),
282 boost::bind(&SBDServer::handle_accept,
this, new_connection,
283 boost::asio::placeholders::error));
286 void handle_accept(std::shared_ptr<SBDConnection> new_connection,
287 const boost::system::error_code& error)
295 << new_connection->socket().remote_endpoint() << std::endl;
297 new_connection->start();
303 std::set<std::shared_ptr<SBDConnection>> connections_;
304 boost::asio::ip::tcp::acceptor acceptor_;
#define USE_BOOST_IO_SERVICE
static std::shared_ptr< SBDConnection > create(const boost::asio::ip::tcp::socket::executor_type &executor)
boost::asio::ip::tcp::socket & socket()
double connect_time() const
const std::string & remote_endpoint_str()
const SBDMOMessageReader & message() const
SBDMOMessageReader(boost::asio::ip::tcp::socket &socket)
SBDMTConfirmationMessageReader(boost::asio::ip::tcp::socket &socket)
const goby::acomms::iridium::protobuf::DirectIPMOPayload & body() const
SBDMessageReader(boost::asio::ip::tcp::socket &socket)
const goby::acomms::iridium::protobuf::DirectIPMTConfirmation & confirm() const
const goby::acomms::iridium::protobuf::DirectIPMOPreHeader & pre_header() const
const goby::acomms::iridium::protobuf::DirectIPMOHeader & header() const
std::vector< char > & data()
virtual bool data_ready() const =0
void pre_header_handler(const boost::system::error_code &error, std::size_t bytes_transferred)
SBDServer(boost::asio::io_context &io_context, int port)
std::set< std::shared_ptr< SBDConnection > > & connections()
bool is(goby::util::logger::Verbosity verbosity)
void bind(ModemDriverBase &driver, QueueManager &queue_manager)
binds the driver link-layer callbacks to the QueueManager
The global namespace for the Goby project.
util::FlexOstream glog
Access the Goby logger through this object.
static time_point now() noexcept
Returns the current system time unless SimulatorSettings::using_sim_time is set to true,...