Goby3 3.2.3
2025.05.13
Loading...
Searching...
No Matches
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"
36
37namespace goby
38{
39namespace acomms
40{
41enum
42{
44 RATE_SBD = 0
45};
46
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
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
97class 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
105extern std::shared_ptr<dccl::Codec> iridium_header_dccl_;
106
107inline 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
119inline 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
140inline 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
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
simple exception class for goby applications
Definition exception.h:35
::goby::acomms::protobuf::ModemTransmission_TransmissionType type() const
void set_type(::goby::acomms::protobuf::ModemTransmission_TransmissionType value)
static const ::PROTOBUF_NAMESPACE_ID::Descriptor * descriptor()
void set_type(::goby::acomms::protobuf::ModemTransmission_TransmissionType value)
const std::string & frame(int index) const
::goby::acomms::protobuf::ModemTransmission_TransmissionType type() const
constexpr int IRIDIUM_SBD_CRC_BYTE_SIZE
void serialize_iridium_modem_message(std::string *out, const goby::acomms::protobuf::ModemTransmission &in)
void parse_iridium_modem_message(std::string in, goby::acomms::protobuf::ModemTransmission *out)
std::shared_ptr< dccl::Codec > iridium_header_dccl_
unsigned iridium_rate_to_bytes(int rate, iridium::protobuf::DeviceType device, Direction direction)
The global namespace for the Goby project.
STL namespace.