23 #include "moos_ufield_sim_driver.h" 24 #include "goby/acomms/modemdriver/driver_exception.h" 25 #include "goby/acomms/protobuf/mm_driver.pb.h" 26 #include "goby/common/logger.h" 27 #include "goby/moos/modem_id_convert.h" 28 #include "goby/moos/moos_string.h" 29 #include "goby/moos/protobuf/ufield_sim_driver.pb.h" 30 #include "goby/util/binary.h" 33 using goby::util::hex_decode;
34 using goby::util::hex_encode;
36 using goby::acomms::operator<<;
38 goby::moos::UFldDriver::UFldDriver() : last_ccmpc_dest_(-1) {}
42 glog.is(DEBUG1) &&
glog << group(glog_out_group())
43 <<
"Goby MOOS uField Toolbox driver starting up." << std::endl;
49 driver_cfg_.GetExtension(protobuf::Config::modem_id_lookup_path))
61 const std::string& moos_server = driver_cfg_.GetExtension(protobuf::Config::moos_server);
62 int moos_port = driver_cfg_.GetExtension(protobuf::Config::moos_port);
63 moos_client_.Run(moos_server.c_str(), moos_port,
"goby.moos.UFldDriver");
66 while (!moos_client_.IsConnected())
68 glog.is(DEBUG1) &&
glog << group(glog_out_group()) <<
"Trying to connect to MOOSDB at " 69 << moos_server <<
":" << moos_port <<
", try " << i++ << std::endl;
72 glog.is(DEBUG1) &&
glog << group(glog_out_group()) <<
"Connected to MOOSDB." << std::endl;
74 moos_client_.Register(driver_cfg_.GetExtension(protobuf::Config::incoming_moos_var), 0);
75 moos_client_.Register(
76 driver_cfg_.GetExtension(protobuf::Config::micromodem_mimic).range_report_var(), 0);
92 case goby::acomms::protobuf::ModemTransmission::DATA:
94 if (driver_cfg_.modem_id() == msg.src())
98 if (msg.rate() < driver_cfg_.ExtensionSize(protobuf::Config::rate_to_bytes))
99 msg.set_max_frame_bytes(
100 driver_cfg_.GetExtension(protobuf::Config::rate_to_bytes, msg.rate()));
102 msg.set_max_frame_bytes(DEFAULT_PACKET_SIZE);
105 if (msg.frame_size() == 0)
106 ModemDriverBase::signal_data_request(&msg);
109 if (msg.frame_size() && msg.frame(0).size())
117 msg.SetExtension(goby::moos::protobuf::poll_src, msg.src());
118 msg.SetExtension(goby::moos::protobuf::poll_dest, msg.dest());
120 msg.set_dest(msg.src());
121 msg.set_src(driver_cfg_.modem_id());
123 msg.set_type(goby::acomms::protobuf::ModemTransmission::DRIVER_SPECIFIC);
124 msg.SetExtension(goby::moos::protobuf::type,
125 goby::moos::protobuf::UFIELD_DRIVER_POLL);
132 case goby::acomms::protobuf::ModemTransmission::DRIVER_SPECIFIC:
134 if (msg.HasExtension(micromodem::protobuf::type))
136 switch (msg.GetExtension(micromodem::protobuf::type))
138 case micromodem::protobuf::MICROMODEM_TWO_WAY_PING: ccmpc(msg);
break;
141 glog << group(glog_out_group()) << warn
142 <<
"Not initiating transmission because we were given a " 143 "DRIVER_SPECIFIC transmission type for the Micro-Modem that " 144 "isn't supported by the uFld simulator driver" 145 << msg.ShortDebugString() << std::endl;
151 glog.is(DEBUG1) &&
glog << group(glog_out_group()) << warn
152 <<
"Not initiating transmission because we were given a " 153 "missing or unrecognized DRIVER_SPECIFIC type: " 154 << msg.ShortDebugString() << std::endl;
159 case goby::acomms::protobuf::ModemTransmission::UNKNOWN:
160 case goby::acomms::protobuf::ModemTransmission::ACK:
break;
166 std::string dest =
"unknown";
170 dest = modem_lookup_.get_name_from_id(msg.dest());
172 std::string src = modem_lookup_.get_name_from_id(msg.src());
174 std::string hex = hex_encode(msg.SerializeAsString());
176 std::stringstream out_ss;
177 out_ss <<
"src_node=" << src <<
",dest_node=" << dest
178 <<
",var_name=" << driver_cfg_.GetExtension(protobuf::Config::incoming_moos_var)
179 <<
",string_val=" << hex;
182 out_raw.set_raw(out_ss.str());
183 ModemDriverBase::signal_raw_outgoing(out_raw);
185 const std::string& out_moos_var = driver_cfg_.GetExtension(protobuf::Config::outgoing_moos_var);
187 glog.is(DEBUG1) &&
glog << group(glog_out_group()) << out_moos_var <<
": " << hex << std::endl;
189 moos_client_.Notify(out_moos_var, hex);
191 const std::string& out_ufield_moos_var =
192 driver_cfg_.GetExtension(protobuf::Config::ufield_outgoing_moos_var);
194 glog.is(DEBUG1) &&
glog << group(glog_out_group()) << out_ufield_moos_var <<
": " 195 << out_ss.str() << std::endl;
197 moos_client_.Notify(out_ufield_moos_var, out_ss.str());
203 if (moos_client_.Fetch(msgs))
205 for (MOOSMSG_LIST::iterator it = msgs.begin(), end = msgs.end(); it != end; ++it)
207 const std::string& in_moos_var =
208 driver_cfg_.GetExtension(protobuf::Config::incoming_moos_var);
209 if (it->GetKey() == in_moos_var)
211 const std::string& value = it->GetString();
213 glog.is(DEBUG1) &&
glog << group(glog_in_group()) << in_moos_var <<
": " << value
216 in_raw.set_raw(value);
217 ModemDriverBase::signal_raw_incoming(in_raw);
220 msg.ParseFromString(hex_decode(value));
221 receive_message(msg);
223 else if (it->GetKey() == driver_cfg_.GetExtension(protobuf::Config::micromodem_mimic)
233 if (!val_from_string(target, it->GetString(),
"target"))
234 throw(std::runtime_error(
"No `target` field"));
235 if (!val_from_string(range, it->GetString(),
"range"))
236 throw(std::runtime_error(
"No `range` field"));
237 if (!val_from_string(time, it->GetString(),
"time"))
238 throw(std::runtime_error(
"No `time` field"));
240 if (target != modem_lookup_.get_name_from_id(last_ccmpc_dest_))
242 glog.is(DEBUG1) &&
glog << group(glog_in_group())
243 <<
"Ignoring report from target: " << target
248 m.set_time(static_cast<uint64>(time) * 1000000);
250 m.set_src(driver_cfg_.modem_id());
251 m.set_dest(last_ccmpc_dest_);
254 m.MutableExtension(micromodem::protobuf::ranging_reply);
256 ranging_reply->add_one_way_travel_time(range / NOMINAL_SPEED_OF_SOUND);
258 m.set_type(goby::acomms::protobuf::ModemTransmission::DRIVER_SPECIFIC);
259 m.SetExtension(micromodem::protobuf::type,
260 micromodem::protobuf::MICROMODEM_TWO_WAY_PING);
263 glog << group(glog_in_group())
264 <<
"Received mimic of MICROMODEM_TWO_WAY_PING response from " 265 << m.src() <<
", 1-way travel time: " 266 << ranging_reply->one_way_travel_time(
267 ranging_reply->one_way_travel_time_size() - 1)
270 ModemDriverBase::signal_receive(m);
271 last_ccmpc_dest_ = -1;
274 catch (std::exception& e)
276 glog.is(DEBUG1) &&
glog << group(glog_in_group()) << warn
277 <<
"Failed to parse incoming range report message: " 278 << e.what() << std::endl;
287 if (msg.type() == goby::acomms::protobuf::ModemTransmission::DRIVER_SPECIFIC &&
288 msg.GetExtension(goby::moos::protobuf::type) == goby::moos::protobuf::UFIELD_DRIVER_POLL)
291 data_msg.set_type(goby::acomms::protobuf::ModemTransmission::DATA);
292 data_msg.set_src(msg.GetExtension(goby::moos::protobuf::poll_src));
293 data_msg.set_dest(msg.GetExtension(goby::moos::protobuf::poll_dest));
295 data_msg.ClearExtension(goby::moos::protobuf::type);
296 data_msg.ClearExtension(goby::moos::protobuf::poll_dest);
297 data_msg.ClearExtension(goby::moos::protobuf::poll_src);
304 if (msg.type() == acomms::protobuf::ModemTransmission::DATA && msg.ack_requested() &&
308 ack.set_type(goby::acomms::protobuf::ModemTransmission::ACK);
309 ack.set_src(msg.dest());
310 ack.set_dest(msg.src());
311 for (
int i = 0, n = msg.frame_size(); i < n; ++i) ack.add_acked_frame(i);
315 ModemDriverBase::signal_receive(msg);
322 glog.is(DEBUG1) &&
glog << group(glog_out_group())
323 <<
"\tthis is a mimic of the MICROMODEM_TWO_WAY_PING transmission" 326 std::string src = modem_lookup_.get_name_from_id(msg.src());
327 last_ccmpc_dest_ = msg.dest();
329 driver_cfg_.GetExtension(protobuf::Config::micromodem_mimic).range_request_var(),
void do_work()
Allows the modem driver to do its work.
void shutdown()
Shuts down the modem driver.
void startup(const goby::acomms::protobuf::DriverConfig &cfg)
Starts the modem driver. Must be called before poll().
const int BROADCAST_ID
special modem id for the broadcast destination - no one is assigned this address. Analogous to 192...
void handle_initiate_transmission(const goby::acomms::protobuf::ModemTransmission &m)
Virtual initiate_transmission method. Typically connected to MACManager::signal_initiate_transmission...
void handle_initiate_transmission(const goby::acomms::protobuf::ModemTransmission &m)
Virtual initiate_transmission method. Typically connected to MACManager::signal_initiate_transmission...
common::FlexOstream glog
Access the Goby logger through this object.
boost::signals2::signal< void(protobuf::ModemTransmission *msg_request)> signal_modify_transmission
Called before the modem driver begins processing a transmission. This allows a third party to modify ...