Goby3  3.1.4
2024.02.22
iridium_driver_common.h
Go to the documentation of this file.
1 // Copyright 2015-2023:
2 // GobySoft, LLC (2013-)
3 // Community contributors (see AUTHORS file)
4 // File authors:
5 // Toby Schneider <toby@gobysoft.org>
6 //
7 //
8 // This file is part of the Goby Underwater Autonomy Project Libraries
9 // ("The Goby Libraries").
10 //
11 // The Goby Libraries are free software: you can redistribute them and/or modify
12 // them under the terms of the GNU Lesser General Public License as published by
13 // the Free Software Foundation, either version 2.1 of the License, or
14 // (at your option) any later version.
15 //
16 // The Goby Libraries are distributed in the hope that they will be useful,
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 // GNU Lesser General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public License
22 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
23 
24 #ifndef GOBY_ACOMMS_MODEMDRIVER_IRIDIUM_DRIVER_COMMON_H
25 #define GOBY_ACOMMS_MODEMDRIVER_IRIDIUM_DRIVER_COMMON_H
26 
27 #include <dccl/codec.h>
28 #include <dccl/field_codec_fixed.h>
29 #include <dccl/field_codec_manager.h>
30 
33 #include "goby/exception.h"
34 #include "goby/time/system_clock.h"
35 #include "goby/util/dccl_compat.h"
36 
37 namespace goby
38 {
39 namespace acomms
40 {
41 enum
42 {
45 };
46 
48 {
51 };
52 
54 {
55  public:
57  : last_tx_time_(time::SystemClock::now().time_since_epoch() / std::chrono::seconds(1)),
58  last_rx_time_(0),
59  bye_received_(false),
60  bye_sent_(false),
61  total_bytes_sent_(0),
62  last_bytes_sent_(0)
63  {
64  }
65  double last_rx_tx_time() const { return std::max(last_tx_time_, last_rx_time_); }
66  double last_rx_time() const { return last_rx_time_; }
67  double last_tx_time() const { return last_tx_time_; }
68 
69  int last_bytes_sent() const { return last_bytes_sent_; }
70  int total_bytes_sent() const { return total_bytes_sent_; }
71 
72  void set_bye_received(bool b) { bye_received_ = b; }
73  void set_bye_sent(bool b) { bye_sent_ = b; }
74 
75  bool bye_received() const { return bye_received_; }
76  bool bye_sent() const { return bye_sent_; }
77 
78  void set_last_tx_time(double d) { last_tx_time_ = d; }
79  void set_last_rx_time(double d) { last_rx_time_ = d; }
80 
81  void set_last_bytes_sent(int i)
82  {
83  last_bytes_sent_ = i;
84  total_bytes_sent_ += i;
85  }
86 
87  private:
88  double last_tx_time_;
89  double last_rx_time_;
90  bool bye_received_;
91  bool bye_sent_;
92  int total_bytes_sent_;
93  int last_bytes_sent_;
94 };
95 
96 // placeholder id codec that uses no bits, since we're always sending just this message on the wire
97 class IridiumHeaderIdentifierCodec : public dccl::TypedFixedFieldCodec<std::uint32_t>
98 {
99  dccl::Bitset encode() { return dccl::Bitset(); }
100  dccl::Bitset encode(const std::uint32_t& wire_value) { return dccl::Bitset(); }
101  std::uint32_t decode(dccl::Bitset* bits) { return 0; }
102  virtual unsigned size() { return 0; }
103 };
104 
105 extern std::shared_ptr<dccl::Codec> iridium_header_dccl_;
106 
107 inline void init_iridium_dccl()
108 {
109  auto iridium_id_name = "iridium_header_id";
110 #ifdef DCCL_VERSION_4_1_OR_NEWER
111  iridium_header_dccl_.reset(new dccl::Codec(iridium_id_name, IridiumHeaderIdentifierCodec()));
112 #else
113  dccl::FieldCodecManager::add<IridiumHeaderIdentifierCodec>(iridium_id_name);
114  iridium_header_dccl_.reset(new dccl::Codec(iridium_id_name));
115 #endif
117 }
118 
119 inline void serialize_iridium_modem_message(std::string* out,
121 {
123  header.set_src(in.src());
124  header.set_dest(in.dest());
125  if (in.has_rate())
126  header.set_rate(in.rate());
127  header.set_type(in.type());
128  if (in.has_ack_requested())
129  header.set_ack_requested(in.ack_requested());
130  if (in.has_frame_start())
131  header.set_frame_start(in.frame_start());
132  if (in.acked_frame_size())
133  header.set_acked_frame(in.acked_frame(0));
134 
135  iridium_header_dccl_->encode(out, header);
136  if (in.frame_size())
137  *out += in.frame(0);
138 }
139 
140 inline void parse_iridium_modem_message(std::string in,
142 {
144  iridium_header_dccl_->decode(&in, &header);
145 
146  out->set_src(header.src());
147  out->set_dest(header.dest());
148  if (header.has_rate())
149  out->set_rate(header.rate());
150  out->set_type(header.type());
151  if (header.has_ack_requested())
152  out->set_ack_requested(header.ack_requested());
153  if (header.has_frame_start())
154  out->set_frame_start(header.frame_start());
155  if (header.has_acked_frame())
156  out->add_acked_frame(header.acked_frame());
157 
158  if (in.size())
159  out->add_frame(in);
160 }
161 
162 inline unsigned iridium_rate_to_bytes(int rate, iridium::protobuf::DeviceType device,
163  Direction direction)
164 {
165  if (rate == RATE_RUDICS)
166  {
168  throw(
169  goby::Exception("Must use device = DEVICE_VOICE_ENABLED_ISU for RUDICS support."));
170 
171  return 1500; // somewhat arbitrary choice as we're dealing with a stream protocol
172  }
173  else if (rate == RATE_SBD)
174  {
176  ->options()
177  .GetExtension(dccl::msg)
178  .max_bytes()};
179 
180  const auto crc_bytes{goby::acomms::IRIDIUM_SBD_CRC_BYTE_SIZE};
181 
182  const auto overhead_bytes = head_bytes + crc_bytes;
183 
184  switch (direction)
185  {
187  // From ISU AT Command Reference
188  // The maximum mobile originated SBD message length is 1960 bytes for voice-enabled ISUs,
189  // 340 bytes for the 9602, 9602-SB, and 9603, and 205 bytes for the 9601. The minimum
190  // mobile originated SBD message length is 1 byte.
191  switch (device)
192  {
193  case iridium::protobuf::DEVICE_VOICE_ENABLED_ISU: return 1960 - overhead_bytes;
194  case iridium::protobuf::DEVICE_IRIDIUM_9602_9603: return 340 - overhead_bytes;
195  }
197  // For voice-enabled ISUs: The maximum mobile terminated SBD message length is 1890 bytes.
198  // For the 9602, 9602-SB, and 9603: The maximum mobile terminated SBD message length
199  // is limited by configuration in the Iridium network, normally to either 135 or 270 bytes
200  // (i.e. one or two segments). However the modem can receive SBD messages up to 1960 bytes.
201  switch (device)
202  {
203  case iridium::protobuf::DEVICE_VOICE_ENABLED_ISU: return 1890 - overhead_bytes;
205  return 270 -
206  overhead_bytes; // the user can limit this further if using a 1-segment configuration. RockBLOCK is 270B.
207  }
208  default: throw(goby::Exception("Invalid direction for the Iridium driver"));
209  }
210  }
211  else
212  {
213  throw(goby::Exception("Invalid rate " + std::to_string(rate) + " for the Iridium driver"));
214  }
215 }
216 
217 } // namespace acomms
218 } // namespace goby
219 
220 #endif
goby::acomms::protobuf::ModemTransmission
Definition: modem_message.pb.h:166
iridium_sbd_packet.h
goby::acomms::protobuf::ModemTransmission::has_ack_requested
bool has_ack_requested() const
Definition: modem_message.pb.h:1099
goby::acomms::iridium_header_dccl_
std::shared_ptr< dccl::Codec > iridium_header_dccl_
goby::acomms::iridium_rate_to_bytes
unsigned iridium_rate_to_bytes(int rate, iridium::protobuf::DeviceType device, Direction direction)
Definition: iridium_driver_common.h:162
goby::acomms::protobuf::ModemTransmission::set_type
void set_type(::goby::acomms::protobuf::ModemTransmission_TransmissionType value)
Definition: modem_message.pb.h:1043
goby::acomms::Direction
Direction
Definition: iridium_driver_common.h:47
goby::acomms::Bitset
dccl::Bitset Bitset
Definition: dccl.h:126
goby::acomms::iridium::protobuf::IridiumHeader::descriptor
static const ::google::protobuf::Descriptor * descriptor()
system_clock.h
goby::acomms::protobuf::ModemTransmission::add_acked_frame
void add_acked_frame(::google::protobuf::int32 value)
Definition: modem_message.pb.h:1230
goby::acomms::OnCallBase::last_rx_tx_time
double last_rx_tx_time() const
Definition: iridium_driver_common.h:65
goby::acomms::OnCallBase::set_last_tx_time
void set_last_tx_time(double d)
Definition: iridium_driver_common.h:78
goby
The global namespace for the Goby project.
Definition: acomms_constants.h:33
goby::acomms::OnCallBase::bye_sent
bool bye_sent() const
Definition: iridium_driver_common.h:76
goby::acomms::RATE_SBD
@ RATE_SBD
Definition: iridium_driver_common.h:44
goby::acomms::OnCallBase::last_tx_time
double last_tx_time() const
Definition: iridium_driver_common.h:67
goby::acomms::DIRECTION_MOBILE_TERMINATED
@ DIRECTION_MOBILE_TERMINATED
Definition: iridium_driver_common.h:50
dccl_compat.h
goby::acomms::iridium::protobuf::IridiumHeader::dest
::google::protobuf::int32 dest() const
Definition: iridium_driver.pb.h:2630
goby::acomms::IridiumHeaderIdentifierCodec
Definition: iridium_driver_common.h:97
goby::acomms::parse_iridium_modem_message
void parse_iridium_modem_message(std::string in, goby::acomms::protobuf::ModemTransmission *out)
Definition: iridium_driver_common.h:140
goby::acomms::RATE_RUDICS
@ RATE_RUDICS
Definition: iridium_driver_common.h:43
goby::acomms::OnCallBase::set_bye_received
void set_bye_received(bool b)
Definition: iridium_driver_common.h:72
goby::acomms::iridium::protobuf::IridiumHeader::set_type
void set_type(::goby::acomms::protobuf::ModemTransmission_TransmissionType value)
Definition: iridium_driver.pb.h:2682
goby::acomms::iridium::protobuf::IridiumHeader::src
::google::protobuf::int32 src() const
Definition: iridium_driver.pb.h:2606
goby::acomms::OnCallBase::bye_received
bool bye_received() const
Definition: iridium_driver_common.h:75
goby::acomms::iridium::protobuf::DEVICE_IRIDIUM_9602_9603
@ DEVICE_IRIDIUM_9602_9603
Definition: iridium_driver.pb.h:173
goby::acomms::protobuf::ModemTransmission::frame
const ::std::string & frame(int index) const
Definition: modem_message.pb.h:1129
goby::acomms::iridium::protobuf::IridiumHeader::has_frame_start
bool has_frame_start() const
Definition: iridium_driver.pb.h:2714
goby::acomms::serialize_iridium_modem_message
void serialize_iridium_modem_message(std::string *out, const goby::acomms::protobuf::ModemTransmission &in)
Definition: iridium_driver_common.h:119
goby::acomms::iridium::protobuf::IridiumHeader::has_acked_frame
bool has_acked_frame() const
Definition: iridium_driver.pb.h:2738
goby::acomms::IRIDIUM_SBD_CRC_BYTE_SIZE
constexpr int IRIDIUM_SBD_CRC_BYTE_SIZE
Definition: iridium_sbd_packet.h:45
goby::acomms::iridium::protobuf::IridiumHeader::type
::goby::acomms::protobuf::ModemTransmission_TransmissionType type() const
Definition: iridium_driver.pb.h:2678
goby::acomms::OnCallBase::OnCallBase
OnCallBase()
Definition: iridium_driver_common.h:56
goby::acomms::iridium::protobuf::DeviceType
DeviceType
Definition: iridium_driver.pb.h:171
goby::acomms::OnCallBase::last_bytes_sent
int last_bytes_sent() const
Definition: iridium_driver_common.h:69
goby::acomms::OnCallBase::set_last_bytes_sent
void set_last_bytes_sent(int i)
Definition: iridium_driver_common.h:81
goby::acomms::iridium::protobuf::IridiumHeader::acked_frame
::google::protobuf::int32 acked_frame() const
Definition: iridium_driver.pb.h:2751
goby::acomms::iridium::protobuf::IridiumHeader::set_dest
void set_dest(::google::protobuf::int32 value)
Definition: iridium_driver.pb.h:2634
goby::acomms::protobuf::ModemTransmission::frame_size
int frame_size() const
Definition: modem_message.pb.h:1123
goby::acomms::protobuf::ModemTransmission::set_src
void set_src(::google::protobuf::int32 value)
Definition: modem_message.pb.h:922
goby::acomms::OnCallBase
Definition: iridium_driver_common.h:53
to_string
NLOHMANN_BASIC_JSON_TPL_DECLARATION std::string to_string(const NLOHMANN_BASIC_JSON_TPL &j)
user-defined to_string function for JSON values
Definition: json.hpp:24301
goby::acomms::iridium::protobuf::IridiumHeader::ack_requested
bool ack_requested() const
Definition: iridium_driver.pb.h:2703
goby::acomms::iridium::protobuf::IridiumHeader::rate
::google::protobuf::int32 rate() const
Definition: iridium_driver.pb.h:2654
goby::msg
extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MessageOptions, ::google::protobuf::internal::MessageTypeTraits< ::goby::GobyMessageOptions >, 11, false > msg
Definition: option_extensions.pb.h:1327
goby::acomms::iridium::protobuf::IridiumHeader::set_rate
void set_rate(::google::protobuf::int32 value)
Definition: iridium_driver.pb.h:2658
goby::acomms::protobuf::ModemTransmission::acked_frame_size
int acked_frame_size() const
Definition: modem_message.pb.h:1216
goby::acomms::protobuf::ModemTransmission::set_frame_start
void set_frame_start(::google::protobuf::uint32 value)
Definition: modem_message.pb.h:1209
goby::acomms::protobuf::ModemTransmission::set_dest
void set_dest(::google::protobuf::int32 value)
Definition: modem_message.pb.h:946
goby::acomms::iridium::protobuf::IridiumHeader::frame_start
::google::protobuf::uint32 frame_start() const
Definition: iridium_driver.pb.h:2727
goby::acomms::protobuf::ModemTransmission::has_rate
bool has_rate() const
Definition: modem_message.pb.h:1002
goby::acomms::DIRECTION_MOBILE_ORIGINATED
@ DIRECTION_MOBILE_ORIGINATED
Definition: iridium_driver_common.h:49
iridium_driver.pb.h
goby::acomms::iridium::protobuf::IridiumHeader::set_acked_frame
void set_acked_frame(::google::protobuf::int32 value)
Definition: iridium_driver.pb.h:2755
goby::acomms::OnCallBase::set_last_rx_time
void set_last_rx_time(double d)
Definition: iridium_driver_common.h:79
goby::acomms::iridium::protobuf::IridiumHeader::has_rate
bool has_rate() const
Definition: iridium_driver.pb.h:2641
goby::acomms::iridium::protobuf::IridiumHeader::set_ack_requested
void set_ack_requested(bool value)
Definition: iridium_driver.pb.h:2707
boost::units::si::time
unit< time_dimension, si::system > time
Definition: time.hpp:22
goby::acomms::init_iridium_dccl
void init_iridium_dccl()
Definition: iridium_driver_common.h:107
goby::acomms::iridium::protobuf::DEVICE_VOICE_ENABLED_ISU
@ DEVICE_VOICE_ENABLED_ISU
Definition: iridium_driver.pb.h:172
goby::acomms::iridium::protobuf::IridiumHeader::set_src
void set_src(::google::protobuf::int32 value)
Definition: iridium_driver.pb.h:2610
goby::Exception
simple exception class for goby applications
Definition: exception.h:34
goby::acomms::protobuf::ModemTransmission::acked_frame
::google::protobuf::int32 acked_frame(int index) const
Definition: modem_message.pb.h:1222
goby::acomms::protobuf::ModemTransmission::has_frame_start
bool has_frame_start() const
Definition: modem_message.pb.h:1192
goby::acomms::protobuf::ModemTransmission::add_frame
::std::string * add_frame()
Definition: modem_message.pb.h:1157
goby::acomms::iridium::protobuf::IridiumHeader::has_ack_requested
bool has_ack_requested() const
Definition: iridium_driver.pb.h:2690
exception.h
goby::acomms::protobuf::ModemTransmission::type
::goby::acomms::protobuf::ModemTransmission_TransmissionType type() const
Definition: modem_message.pb.h:1039
goby::acomms::protobuf::ModemTransmission::rate
::google::protobuf::int32 rate() const
Definition: modem_message.pb.h:1015
goby::acomms::protobuf::ModemTransmission::ack_requested
bool ack_requested() const
Definition: modem_message.pb.h:1112
goby::acomms::protobuf::ModemTransmission::src
::google::protobuf::int32 src() const
Definition: modem_message.pb.h:918
goby::acomms::OnCallBase::total_bytes_sent
int total_bytes_sent() const
Definition: iridium_driver_common.h:70
goby::acomms::iridium::protobuf::IridiumHeader
Definition: iridium_driver.pb.h:1332
goby::acomms::protobuf::ModemTransmission::dest
::google::protobuf::int32 dest() const
Definition: modem_message.pb.h:942
goby::acomms::OnCallBase::last_rx_time
double last_rx_time() const
Definition: iridium_driver_common.h:66
goby::acomms::protobuf::ModemTransmission::set_rate
void set_rate(::google::protobuf::int32 value)
Definition: modem_message.pb.h:1019
goby::acomms::protobuf::ModemTransmission::set_ack_requested
void set_ack_requested(bool value)
Definition: modem_message.pb.h:1116
goby::acomms::protobuf::ModemTransmission::frame_start
::google::protobuf::uint32 frame_start() const
Definition: modem_message.pb.h:1205
goby::acomms::iridium::protobuf::IridiumHeader::set_frame_start
void set_frame_start(::google::protobuf::uint32 value)
Definition: iridium_driver.pb.h:2731
goby::acomms::OnCallBase::set_bye_sent
void set_bye_sent(bool b)
Definition: iridium_driver_common.h:73