Goby3  3.1.5
2024.05.14
benthos_atm900_driver.h
Go to the documentation of this file.
1 // Copyright 2011-2023:
2 // GobySoft, LLC (2013-)
3 // Massachusetts Institute of Technology (2007-2014)
4 // Community contributors (see AUTHORS file)
5 // File authors:
6 // Toby Schneider <toby@gobysoft.org>
7 //
8 //
9 // This file is part of the Goby Underwater Autonomy Project Libraries
10 // ("The Goby Libraries").
11 //
12 // The Goby Libraries are free software: you can redistribute them and/or modify
13 // them under the terms of the GNU Lesser General Public License as published by
14 // the Free Software Foundation, either version 2.1 of the License, or
15 // (at your option) any later version.
16 //
17 // The Goby Libraries are distributed in the hope that they will be useful,
18 // but WITHOUT ANY WARRANTY; without even the implied warranty of
19 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 // GNU Lesser General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public License
23 // along with Goby. If not, see <http://www.gnu.org/licenses/>.
24 
25 #ifndef GOBY_ACOMMS_MODEMDRIVER_BENTHOS_ATM900_DRIVER_H
26 #define GOBY_ACOMMS_MODEMDRIVER_BENTHOS_ATM900_DRIVER_H
27 
28 #include <boost/algorithm/string/classification.hpp> // for is_any_ofF, is_...
29 #include <boost/algorithm/string/constants.hpp> // for token_compress_on
30 #include <boost/algorithm/string/split.hpp> // for split
31 #include <boost/any.hpp> // for bad_any_cast
32 #include <cstdint> // for uint32_t
33 #include <dccl/bitset.h> // for Bitset
34 #include <dccl/codec.h> // for Codec
35 #include <dccl/common.h> // for uint32
36 #include <dccl/exception.h> // for NullValueException
37 #include <dccl/field_codec_fixed.h> // for TypedFixedField...
38 #include <dccl/field_codec_manager.h> // for FieldCodecManager
39 #include <dccl/version.h>
40 #include <memory> // for shared_ptr, __s...
41 #include <string> // for string, operator+
42 #include <vector> // for vector
43 
44 #include "benthos_atm900_driver_fsm.h" // for BenthosATM900FSM
45 #include "driver_base.h" // for ModemDriverBase
46 #include "goby/acomms/protobuf/benthos_atm900.pb.h" // for BenthosHeader
47 #include "goby/acomms/protobuf/driver_base.pb.h" // for DriverConfig
48 #include "goby/acomms/protobuf/modem_message.pb.h" // for ModemTransmission
49 #include "goby/util/dccl_compat.h"
50 #include "iridium_rudics_packet.h" // for parse_rudics_pa...
51 
52 namespace goby
53 {
54 namespace acomms
55 {
57 {
58  public:
60  void startup(const protobuf::DriverConfig& cfg) override;
61  void shutdown() override;
62  void do_work() override;
63  void handle_initiate_transmission(const protobuf::ModemTransmission& m) override;
64 
65  private:
66  void receive(const protobuf::ModemTransmission& msg);
67  void send(const protobuf::ModemTransmission& msg);
68  void try_serial_tx();
69 
70  const benthos::protobuf::Config& benthos_driver_cfg() const
71  {
72  return driver_cfg_.GetExtension(benthos::protobuf::config);
73  }
74 
75  private:
76  enum
77  {
78  DEFAULT_BAUD = 9600
79  };
80  static const std::string SERIAL_DELIMITER;
81 
82  benthos::fsm::BenthosATM900FSM fsm_;
83  protobuf::DriverConfig driver_cfg_; // configuration given to you at launch
84 };
85 
86 // placeholder id codec that uses no bits, since we're always sending just this message on the wire
87 class NoOpIdentifierCodec : public dccl::TypedFixedFieldCodec<dccl::uint32>
88 {
89  dccl::Bitset encode() override { return dccl::Bitset(); }
90  dccl::Bitset encode(const std::uint32_t& /*wire_value*/) override { return dccl::Bitset(); }
91  dccl::uint32 decode(dccl::Bitset* /*bits*/) override { return 0; }
92  unsigned size() override { return 0; }
93 };
94 
95 extern std::shared_ptr<dccl::Codec> benthos_header_dccl_;
96 
97 inline void init_benthos_dccl()
98 {
99  auto benthos_id_name = "benthos_header_id";
100 #ifdef DCCL_VERSION_4_1_OR_NEWER
101  benthos_header_dccl_.reset(new dccl::Codec(benthos_id_name, NoOpIdentifierCodec()));
102 #else
103  dccl::FieldCodecManager::add<NoOpIdentifierCodec>(benthos_id_name);
104  benthos_header_dccl_.reset(new dccl::Codec(benthos_id_name));
105 #endif
106 
107  benthos_header_dccl_->load<benthos::protobuf::BenthosHeader>();
108 }
109 
110 inline void serialize_benthos_modem_message(std::string* out,
111  const goby::acomms::protobuf::ModemTransmission& in)
112 {
113  benthos::protobuf::BenthosHeader header;
114  header.set_type(in.type());
115  if (in.has_ack_requested())
116  header.set_ack_requested(in.ack_requested());
117 
118  for (int i = 0, n = in.acked_frame_size(); i < n; ++i)
119  header.add_acked_frame(in.acked_frame(i));
120 
121  benthos_header_dccl_->encode(out, header);
122 
123  // frame message
124  for (int i = 0, n = in.frame_size(); i < n; ++i)
125  {
126  if (in.frame(i).empty())
127  break;
128 
129  std::string rudics_packet;
130  serialize_rudics_packet(in.frame(i), &rudics_packet, "\r", false);
131  *out += rudics_packet;
132  }
133 }
134 
135 inline void parse_benthos_modem_message(std::string in,
136  goby::acomms::protobuf::ModemTransmission* out)
137 {
138  benthos::protobuf::BenthosHeader header;
139  benthos_header_dccl_->decode(&in, &header);
140 
141  out->set_type(header.type());
142  if (header.has_ack_requested())
143  out->set_ack_requested(header.ack_requested());
144 
145  for (int i = 0, n = header.acked_frame_size(); i < n; ++i)
146  out->add_acked_frame(header.acked_frame(i));
147 
148  std::vector<std::string> encoded_frames;
149  boost::split(encoded_frames, in, boost::is_any_of("\r"), boost::token_compress_on);
150 
151  for (auto& encoded_frame : encoded_frames)
152  {
153  if (!encoded_frame.empty())
154  parse_rudics_packet(out->add_frame(), encoded_frame + "\r", "\r", false);
155  }
156 }
157 
158 } // namespace acomms
159 } // namespace goby
160 #endif
void do_work() override
Allows the modem driver to do its work.
void shutdown() override
Shuts down the modem driver.
void handle_initiate_transmission(const protobuf::ModemTransmission &m) override
Virtual initiate_transmission method. Typically connected to MACManager::signal_initiate_transmission...
void startup(const protobuf::DriverConfig &cfg) override
Starts the modem driver. Must be called before poll().
provides an abstract base class for acoustic modem drivers. This is subclassed by the various drivers...
Definition: driver_base.h:59
extern ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< ::goby::acomms::protobuf::DriverConfig, ::PROTOBUF_NAMESPACE_ID::internal::MessageTypeTraits< ::goby::acomms::benthos::protobuf::Config >, 11, false > config
dccl::Bitset Bitset
Definition: dccl.h:126
void serialize_benthos_modem_message(std::string *out, const goby::acomms::protobuf::ModemTransmission &in)
void parse_benthos_modem_message(std::string in, goby::acomms::protobuf::ModemTransmission *out)
void parse_rudics_packet(std::string *bytes, std::string rudics_pkt, const std::string &reserved=std::string("\0\r\n", 3)+std::string(1, 0xff), bool include_crc=true)
void serialize_rudics_packet(std::string bytes, std::string *rudics_pkt, const std::string &reserved=std::string("\0\r\n", 3)+std::string(1, 0xff), bool include_crc=true)
std::shared_ptr< dccl::Codec > benthos_header_dccl_
The global namespace for the Goby project.
std::uint32_t uint32
extern ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< ::google::protobuf::MessageOptions, ::PROTOBUF_NAMESPACE_ID::internal::MessageTypeTraits< ::goby::GobyMessageOptions >, 11, false > msg
void split(const char *b, const char *e, char d, std::function< void(const char *, const char *)> fn)
Definition: httplib.h:2494