23 #ifndef IridiumShoreSBD20150227H 24 #define IridiumShoreSBD20150227H 26 #include "goby/acomms/protobuf/iridium_sbd_directip.pb.h" 27 #include "goby/acomms/protobuf/rudics_shore.pb.h" 28 #include "goby/common/time.h" 29 #include "goby/util/binary.h" 30 #include <boost/asio.hpp> 31 #include <boost/bind.hpp> 32 #include <boost/enable_shared_from_this.hpp> 42 : socket_(socket), pos_(0), data_(1 << 16)
46 virtual bool data_ready()
const = 0;
59 void pre_header_handler(
const boost::system::error_code& error, std::size_t bytes_transferred)
62 throw std::runtime_error(
"Error while reading: " + error.message());
64 pre_header_.set_protocol_ver(read_byte());
65 pre_header_.set_overall_length(read_uint16());
67 boost::asio::async_read(socket_, boost::asio::buffer(data_),
68 boost::asio::transfer_at_least(pre_header_.overall_length() +
69 PRE_HEADER_SIZE - bytes_transferred),
70 boost::bind(&SBDMessageReader::ie_handler,
this, _1, _2));
73 std::vector<char>& data() {
return data_; }
76 void ie_handler(
const boost::system::error_code& error, std::size_t bytes_transferred)
79 throw std::runtime_error(
"Error while reading: " + error.message());
81 char iei = read_byte();
82 unsigned length = read_uint16();
89 header_.set_length(length);
90 header_.set_cdr_reference(read_uint32());
92 header_.set_imei(read_imei());
94 header_.set_session_status(read_byte());
95 header_.set_momsn(read_uint16());
96 header_.set_mtmsn(read_uint16());
97 header_.set_time_of_session(read_uint32());
103 body_.set_length(length);
104 body_.set_payload(std::string(data_.begin() + pos_, data_.begin() + pos_ + length));
109 confirm_.set_iei(iei);
110 confirm_.set_length(length);
111 confirm_.set_client_id(read_uint32());
112 confirm_.set_imei(read_imei());
113 confirm_.set_auto_ref_id(read_uint32());
114 confirm_.set_status(read_int16());
121 if (pos_ < pre_header_.overall_length() + PRE_HEADER_SIZE)
122 ie_handler(error, bytes_transferred);
125 char read_byte() {
return data_.at(pos_++) & 0xff; }
127 unsigned read_uint16()
129 unsigned u = (data_.at(pos_++) & 0xff) << BITS_PER_BYTE;
130 u |= data_.at(pos_++) & 0xff;
136 int i = (data_.at(pos_++) & 0xff) << BITS_PER_BYTE;
137 i |= data_.at(pos_++) & 0xff;
140 int sign_bit_mask = 0x8000;
141 if (i & sign_bit_mask)
147 unsigned read_uint32()
150 for (
int i = 0; i < 4; ++i) u |= (data_.at(pos_++) & 0xff) << ((3 - i) * BITS_PER_BYTE);
154 std::string read_imei()
156 const int imei_size = 15;
157 std::string imei = std::string(data_.begin() + pos_, data_.begin() + pos_ + imei_size);
168 boost::asio::ip::tcp::socket& socket_;
170 std::vector<char>::size_type pos_;
171 std::vector<char> data_;
179 bool data_ready()
const 181 return pre_header().IsInitialized() && header().IsInitialized() && body().IsInitialized();
192 bool data_ready()
const {
return pre_header().IsInitialized() && confirm().IsInitialized(); }
198 static boost::shared_ptr<SBDConnection> create(boost::asio::io_service& io_service)
200 return boost::shared_ptr<SBDConnection>(
new SBDConnection(io_service));
203 boost::asio::ip::tcp::socket& socket() {
return socket_; }
207 remote_endpoint_str_ = boost::lexical_cast<std::string>(socket_.remote_endpoint());
210 boost::asio::async_read(
211 socket_, boost::asio::buffer(message_.data()),
212 boost::asio::transfer_at_least(SBDMessageReader::PRE_HEADER_SIZE),
213 boost::bind(&SBDMessageReader::pre_header_handler, &message_, _1, _2));
218 double connect_time()
const {
return connect_time_; }
221 const std::string& remote_endpoint_str() {
return remote_endpoint_str_; }
225 : socket_(io_service), connect_time_(-1), message_(socket_), remote_endpoint_str_(
"Unknown")
229 boost::asio::ip::tcp::socket socket_;
230 double connect_time_;
232 std::string remote_endpoint_str_;
238 SBDServer(boost::asio::io_service& io_service,
int port)
239 : acceptor_(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), port))
244 std::set<boost::shared_ptr<SBDConnection> >& connections() {
return connections_; }
249 boost::shared_ptr<SBDConnection> new_connection =
250 SBDConnection::create(acceptor_.get_io_service());
252 connections_.insert(new_connection);
254 acceptor_.async_accept(new_connection->socket(),
255 boost::bind(&SBDServer::handle_accept,
this, new_connection,
256 boost::asio::placeholders::error));
259 void handle_accept(boost::shared_ptr<SBDConnection> new_connection,
260 const boost::system::error_code& error)
267 glog.is(DEBUG1) &&
glog <<
"Received SBD connection from: " 268 << new_connection->socket().remote_endpoint() << std::endl;
270 new_connection->start();
276 std::set<boost::shared_ptr<SBDConnection> > connections_;
277 boost::asio::ip::tcp::acceptor acceptor_;
double goby_time< double >()
Returns current UTC time as seconds and fractional seconds since 1970-01-01 00:00:00.
common::FlexOstream glog
Access the Goby logger through this object.
The global namespace for the Goby project.