25 #include <boost/algorithm/string.hpp> 26 #include <boost/date_time/posix_time/posix_time.hpp> 27 #include <boost/foreach.hpp> 28 #include <boost/lexical_cast.hpp> 29 #include <boost/math/special_functions/fpclassify.hpp> 30 #include <boost/numeric/conversion/cast.hpp> 32 #include "goby/acomms/modemdriver/benthos_atm900_driver.h" 33 #include "goby/acomms/modemdriver/iridium_driver.h" 34 #include "goby/acomms/modemdriver/iridium_shore_driver.h" 35 #include "goby/acomms/modemdriver/udp_driver.h" 36 #include "goby/moos/moos_bluefin_driver.h" 38 #include "goby/moos/moos_ufield_sim_driver.h" 39 #include "goby/moos/protobuf/bluefin_driver.pb.h" 40 #include "goby/moos/protobuf/frontseat.pb.h" 41 #include "goby/moos/protobuf/ufield_sim_driver.pb.h" 42 #include "goby/pb/pb_modem_driver.h" 43 #include "goby/util/sci.h" 44 #include "pAcommsHandler.h" 48 using goby::acomms::operator<<;
49 using goby::moos::operator<<;
51 using google::protobuf::uint32;
56 CpAcommsHandler* CpAcommsHandler::inst_ = 0;
57 std::map<std::string, void*> CpAcommsHandler::driver_plugins_;
59 CpAcommsHandler* CpAcommsHandler::get_instance()
62 inst_ =
new CpAcommsHandler();
66 void CpAcommsHandler::delete_instance() {
delete inst_; }
68 CpAcommsHandler::CpAcommsHandler()
70 translator_(
goby::moos::protobuf::TranslatorEntry(), cfg_.common().lat_origin(),
71 cfg_.common().lon_origin(), cfg_.modem_id_lookup_path()),
72 dccl_(
goby::acomms::DCCLCodec::get()), work_(timer_io_service_), router_(0)
74 #ifdef ENABLE_GOBY_V1_TRANSITIONAL_SUPPORT 75 transitional_dccl_.convert_to_v2_representation(&cfg_);
76 glog.is(DEBUG2) &&
glog << group(
"pAcommsHandler")
77 <<
"Configuration after transitional configuration modifications: \n" 78 << cfg_ << std::flush;
80 if (cfg_.has_transitional_cfg())
81 glog.is(WARN) &&
glog <<
"transitional_cfg is set but pAcommsHandler was not compiled with " 82 "the CMake flag 'enable_goby_v1_transitional_support' set to ON" 86 translator_.add_entry(cfg_.translator_entry());
89 &CpAcommsHandler::handle_queue_receive);
93 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
94 cfg_.moos_var().queue_ack_transmission(), _2,
95 cfg_.moos_var().queue_ack_original_msg()));
97 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
98 cfg_.moos_var().queue_receive(), _1,
""));
100 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
101 cfg_.moos_var().queue_expire(), _1,
""));
103 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
104 cfg_.moos_var().queue_size(), _1,
""));
108 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
109 cfg_.moos_var().mac_initiate_transmission(), _1,
""));
112 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
113 cfg_.moos_var().mac_slot_start(), _1,
""));
116 &CpAcommsHandler::handle_encode_on_demand);
118 process_configuration();
122 for (std::map<boost::shared_ptr<goby::acomms::ModemDriverBase>,
124 end = drivers_.end();
130 bind(queue_manager_, *router_);
134 subscribe(cfg_.moos_var().prefix() + cfg_.moos_var().mac_cycle_update(),
135 &CpAcommsHandler::handle_mac_cycle_update,
this);
137 subscribe(cfg_.moos_var().prefix() + cfg_.moos_var().queue_flush(),
138 &CpAcommsHandler::handle_flush_queue,
this);
140 subscribe(cfg_.moos_var().prefix() + cfg_.moos_var().config_file_request(),
141 &CpAcommsHandler::handle_config_file_request,
this);
143 subscribe(cfg_.moos_var().prefix() + cfg_.moos_var().mac_initiate_transmission(),
144 &CpAcommsHandler::handle_external_initiate_transmission,
this);
146 subscribe(cfg_.moos_var().prefix() + cfg_.moos_var().driver_reset(),
147 &CpAcommsHandler::handle_driver_reset,
this);
149 subscribe_pb(cfg_.moos_var().prefix() + cfg_.moos_var().driver_cfg_update(),
150 &CpAcommsHandler::handle_driver_cfg_update,
this);
153 CpAcommsHandler::~CpAcommsHandler() {}
155 void CpAcommsHandler::loop()
157 timer_io_service_.poll();
159 if (driver_restart_time_.size())
162 for (std::map<boost::shared_ptr<goby::acomms::ModemDriverBase>,
164 end = drivers_.end();
167 if (!driver_restart_time_.count(it->first))
171 it->first->do_work();
175 driver_reset(it->first, e);
182 if (!driver_restart_time_.count(driver_))
184 queue_manager_.do_work();
191 void CpAcommsHandler::handle_mac_cycle_update(
const CMOOSMsg& msg)
196 glog << group(
"pAcommsHandler") <<
"got update for MAC: " << update_msg << std::endl;
198 if (update_msg.dest() != cfg_.modem_id())
200 glog << group(
"pAcommsHandler") <<
"update not for us" << std::endl;
204 goby::acomms::MACManager::iterator it1 = mac_.begin(), it2 = mac_.begin();
206 for (
int i = 0, n = update_msg.first_iterator(); i < n; ++i) ++it1;
208 for (
int i = 0, n = update_msg.second_iterator(); i < n; ++i) ++it2;
210 switch (update_msg.update_type())
212 case goby::acomms::protobuf::MACUpdate::ASSIGN:
213 mac_.assign(update_msg.slot().begin(), update_msg.slot().end());
216 case goby::acomms::protobuf::MACUpdate::PUSH_BACK:
217 for (
int i = 0, n = update_msg.slot_size(); i < n; ++i)
218 mac_.push_back(update_msg.slot(i));
221 case goby::acomms::protobuf::MACUpdate::PUSH_FRONT:
222 for (
int i = 0, n = update_msg.slot_size(); i < n; ++i)
223 mac_.push_front(update_msg.slot(i));
226 case goby::acomms::protobuf::MACUpdate::POP_BACK:
230 glog.is(WARN) &&
glog << group(
"pAcommsHandler")
231 <<
"Cannot POP_BACK of empty MAC cycle" << std::endl;
234 case goby::acomms::protobuf::MACUpdate::POP_FRONT:
238 glog.is(WARN) &&
glog << group(
"pAcommsHandler")
239 <<
"Cannot POP_FRONT of empty MAC cycle" << std::endl;
242 case goby::acomms::protobuf::MACUpdate::INSERT:
243 mac_.insert(it1, update_msg.slot().begin(), update_msg.slot().end());
246 case goby::acomms::protobuf::MACUpdate::ERASE:
247 if (update_msg.second_iterator() != -1)
248 mac_.erase(it1, it2);
253 case goby::acomms::protobuf::MACUpdate::CLEAR: mac_.clear();
break;
255 case goby::acomms::protobuf::MACUpdate::NO_CHANGE:
break;
260 if (update_msg.has_cycle_state())
262 switch (update_msg.cycle_state())
264 case goby::acomms::protobuf::MACUpdate::STARTED:
267 for (std::map<boost::shared_ptr<goby::acomms::ModemDriverBase>,
269 it = drivers_.begin(),
270 end = drivers_.end();
273 if (!driver_restart_time_.count(it->first))
278 driver->set_silent(
false);
283 case goby::acomms::protobuf::MACUpdate::STOPPED:
284 for (std::map<boost::shared_ptr<goby::acomms::ModemDriverBase>,
286 it = drivers_.begin(),
287 end = drivers_.end();
290 if (!driver_restart_time_.count(it->first))
295 driver->set_silent(
true);
305 void CpAcommsHandler::handle_flush_queue(
const CMOOSMsg& msg)
310 glog.is(VERBOSE) &&
glog << group(
"pAcommsHandler") <<
"Queue flush request: " << flush
312 queue_manager_.flush_queue(flush);
315 void CpAcommsHandler::handle_config_file_request(
const CMOOSMsg&)
317 publish(cfg_.moos_var().prefix() + cfg_.moos_var().config_file(),
318 dccl::b64_encode(cfg_.SerializeAsString()));
321 void CpAcommsHandler::handle_driver_reset(
const CMOOSMsg& msg)
323 driver_reset(driver_,
325 "Manual reset", goby::acomms::protobuf::ModemDriverStatus::MANUAL_RESET));
330 glog.is(VERBOSE) &&
glog << group(
"pAcommsHandler") <<
"Driver config update request: " << cfg
333 bool driver_found =
false;
334 for (std::map<boost::shared_ptr<goby::acomms::ModemDriverBase>,
336 end = drivers_.end();
339 if (it->second->modem_id() == cfg.modem_id())
342 if (it->first && !driver_restart_time_.count(it->first))
343 it->first->update_cfg(cfg);
347 glog.is(WARN) &&
glog << group(
"pAcommsHandler")
348 <<
"Could not find driver with modem id: " << cfg.modem_id()
352 void CpAcommsHandler::handle_external_initiate_transmission(
const CMOOSMsg& msg)
355 if (msg.GetSource() == CMOOSApp::GetAppName())
363 glog.is(VERBOSE) &&
glog << group(
"pAcommsHandler")
364 <<
"Initiating transmission: " << transmission << std::endl;
365 driver_->handle_initiate_transmission(transmission);
370 const std::string& moos_var1,
372 const std::string& moos_var2)
375 if (!moos_var1.empty())
376 publish_pb(cfg_.moos_var().prefix() + moos_var1, msg1);
378 if (!moos_var2.empty())
379 publish_pb(cfg_.moos_var().prefix() + moos_var2, msg2);
383 const std::string& moos_var)
385 publish(cfg_.moos_var().prefix() + moos_var, msg.raw());
392 void CpAcommsHandler::process_configuration()
395 create_driver(driver_, cfg_.driver_type(), cfg_.mutable_driver_cfg(), &mac_);
397 drivers_.insert(std::make_pair(driver_, cfg_.mutable_driver_cfg()));
400 if (cfg_.listen_driver_type_size() == cfg_.listen_driver_cfg_size())
402 for (
int i = 0, n = cfg_.listen_driver_type_size(); i < n; ++i)
404 boost::shared_ptr<goby::acomms::ModemDriverBase> driver;
405 create_driver(driver, cfg_.listen_driver_type(i), cfg_.mutable_listen_driver_cfg(i), 0);
406 drivers_.insert(std::make_pair(driver, cfg_.mutable_listen_driver_cfg(i)));
411 glog.is(DIE) &&
glog <<
"You must specify the same number of listen_driver_type fields to " 412 "correspond with the listen_driver_cfg fields." 416 if (cfg_.has_route_cfg() && cfg_.route_cfg().route().hop_size() > 0)
425 <<
" is reserved for broadcast messages. You must specify a modem_id != " 428 publish(
"MODEM_ID", cfg_.modem_id());
429 publish(
"VEHICLE_ID", cfg_.modem_id());
431 cfg_.mutable_queue_cfg()->set_modem_id(cfg_.modem_id());
432 cfg_.mutable_mac_cfg()->set_modem_id(cfg_.modem_id());
433 cfg_.mutable_transitional_cfg()->set_modem_id(cfg_.modem_id());
435 for (std::map<boost::shared_ptr<goby::acomms::ModemDriverBase>,
437 end = drivers_.end();
440 if (!it->second->has_modem_id())
441 it->second->set_modem_id(cfg_.modem_id());
444 std::vector<void*> handles;
446 for (
int i = 0, n = cfg_.load_shared_library_size(); i < n; ++i)
448 glog.is(VERBOSE) &&
glog << group(
"pAcommsHandler")
449 <<
"Loading shared library: " << cfg_.load_shared_library(i)
453 goby::util::DynamicProtobufManager::load_from_shared_lib(cfg_.load_shared_library(i));
454 handles.push_back(handle);
458 glog.is(DIE) &&
glog <<
"Failed ... check path provided or add to /etc/ld.so.conf " 459 <<
"or LD_LIBRARY_PATH" << std::endl;
462 glog << group(
"pAcommsHandler") <<
"Loading shared library dccl codecs." << std::endl;
466 dccl_->set_cfg(cfg_.dccl_cfg());
467 for (
int i = 0, n = handles.size(); i < n; ++i) dccl_->load_shared_library_codecs(handles[i]);
470 goby::util::DynamicProtobufManager::enable_compilation();
471 for (
int i = 0, n = cfg_.load_proto_file_size(); i < n; ++i)
473 glog.is(VERBOSE) &&
glog << group(
"pAcommsHandler")
474 <<
"Loading protobuf file: " << cfg_.load_proto_file(i)
477 if (!goby::util::DynamicProtobufManager::load_from_proto_file(cfg_.load_proto_file(i)))
478 glog.is(DIE) &&
glog <<
"Failed to load file." << std::endl;
483 for (std::map<boost::shared_ptr<goby::acomms::ModemDriverBase>,
485 end = drivers_.end();
487 driver_restart_time_.insert(std::make_pair(it->first, 0));
490 queue_manager_.set_cfg(cfg_.queue_cfg());
492 router_->set_cfg(cfg_.route_cfg());
495 for (
int i = 0, n = cfg_.translator_entry_size(); i < n; ++i)
497 typedef boost::shared_ptr<google::protobuf::Message> GoogleProtobufMessagePointer;
498 glog.is(VERBOSE) &&
glog << group(
"pAcommsHandler") <<
"Checking translator entry: " 499 << cfg_.translator_entry(i).protobuf_name() << std::endl;
502 GoogleProtobufMessagePointer msg =
503 goby::util::DynamicProtobufManager::new_protobuf_message<GoogleProtobufMessagePointer>(
504 cfg_.translator_entry(i).protobuf_name());
506 if (cfg_.translator_entry(i).trigger().type() ==
507 goby::moos::protobuf::TranslatorEntry::Trigger::TRIGGER_PUBLISH)
510 GobyMOOSApp::subscribe(cfg_.translator_entry(i).trigger().moos_var(),
511 boost::bind(&CpAcommsHandler::create_on_publish,
this, _1,
512 cfg_.translator_entry(i)));
514 else if (cfg_.translator_entry(i).trigger().type() ==
515 goby::moos::protobuf::TranslatorEntry::Trigger::TRIGGER_TIME)
517 timers_.push_back(boost::shared_ptr<Timer>(
new Timer(timer_io_service_)));
519 Timer& new_timer = *timers_.back();
521 new_timer.expires_from_now(
522 boost::posix_time::seconds(cfg_.translator_entry(i).trigger().period()));
524 new_timer.async_wait(boost::bind(&CpAcommsHandler::create_on_timer,
this, _1,
525 cfg_.translator_entry(i), &new_timer));
528 for (
int j = 0, m = cfg_.translator_entry(i).create_size(); j < m; ++j)
531 subscribe(cfg_.translator_entry(i).create(j).moos_var());
535 for (
int i = 0, m = cfg_.multiplex_create_moos_var_size(); i < m; ++i)
537 GobyMOOSApp::subscribe(cfg_.multiplex_create_moos_var(i),
538 &CpAcommsHandler::create_on_multiplex_publish,
this);
541 for (
int i = 0, n = cfg_.dccl_frontseat_forward_name_size(); i < n; ++i)
543 const google::protobuf::Descriptor* desc =
544 goby::util::DynamicProtobufManager::find_descriptor(
545 cfg_.dccl_frontseat_forward_name(i));
548 dccl_frontseat_forward_.insert(desc);
552 glog.is(DIE) &&
glog <<
"Invalid message name given to dccl_frontseat_forward_name: " 553 << cfg_.dccl_frontseat_forward_name(i) << std::endl;
558 void CpAcommsHandler::create_driver(boost::shared_ptr<goby::acomms::ModemDriverBase>& driver,
559 goby::acomms::protobuf::DriverType driver_type,
563 if (driver_cfg->has_driver_name())
565 std::map<std::string, void*>::const_iterator driver_it =
566 driver_plugins_.find(driver_cfg->driver_name());
568 if (driver_it == driver_plugins_.end())
569 glog.is(DIE) &&
glog <<
"Could not find driver_plugin_name '" 570 << driver_cfg->driver_name()
571 <<
"'. Make sure it is loaded using the PACOMMSHANDLER_PLUGINS " 578 dlsym(driver_it->second, "goby_make_driver");
580 if (!driver_function)
582 glog.is(DIE) &&
glog <<
"Could not load goby::acomms::ModemDriverBase* " 583 "goby_make_driver() for driver name '" 584 << driver_cfg->driver_name() <<
"'." << std::endl;
588 driver.reset((*driver_function)());
596 case goby::acomms::protobuf::DRIVER_WHOI_MICROMODEM:
600 case goby::acomms::protobuf::DRIVER_BENTHOS_ATM900:
604 case goby::acomms::protobuf::DRIVER_ABC_EXAMPLE_MODEM:
608 case goby::acomms::protobuf::DRIVER_UFIELD_SIM_DRIVER:
610 driver_cfg->SetExtension(goby::moos::protobuf::Config::modem_id_lookup_path,
611 cfg_.modem_id_lookup_path());
614 case goby::acomms::protobuf::DRIVER_PB_STORE_SERVER:
615 zeromq_service_.push_back(boost::shared_ptr<goby::common::ZeroMQService>(
620 case goby::acomms::protobuf::DRIVER_IRIDIUM:
624 case goby::acomms::protobuf::DRIVER_UDP:
625 asio_service_.push_back(
626 boost::shared_ptr<boost::asio::io_service>(
new boost::asio::io_service));
630 case goby::acomms::protobuf::DRIVER_BLUEFIN_MOOS:
632 driver_cfg->SetExtension(goby::moos::protobuf::BluefinConfig::moos_server,
633 cfg_.common().server_host());
634 driver_cfg->SetExtension(goby::moos::protobuf::BluefinConfig::moos_port,
635 cfg_.common().server_port());
638 case goby::acomms::protobuf::DRIVER_IRIDIUM_SHORE:
642 case goby::acomms::protobuf::DRIVER_NONE:
break;
651 std::multimap<std::string, CMOOSMsg> out;
653 out = translator_.protobuf_to_moos(msg);
655 for (std::multimap<std::string, CMOOSMsg>::iterator it = out.begin(), n = out.end();
658 glog.is(DEBUG2) &&
glog << group(
"pAcommsHandler") <<
"Publishing: " << it->second
663 catch (std::runtime_error& e)
665 glog.is(WARN) &&
glog << group(
"pAcommsHandler")
666 <<
"Failed to translate received message: " << e.what() << std::endl;
670 if (dccl_frontseat_forward_.count(msg.GetDescriptor()))
673 dccl_->encode(fs_data.mutable_dccl_message(), msg);
674 publish_pb(cfg_.moos_var().ifrontseat_data_out(), fs_data);
679 if (router_ && msg.GetDescriptor() == goby::acomms::protobuf::RouteCommand::descriptor())
682 route_cmd.CopyFrom(msg);
683 glog.is(VERBOSE) &&
glog << group(
"pAcommsHandler")
684 <<
"Received RouteCommand: " << msg.DebugString() << std::endl;
686 cfg.mutable_route()->CopyFrom(route_cmd.new_route());
687 router_->set_cfg(cfg);
691 void CpAcommsHandler::handle_encode_on_demand(
695 glog.is(VERBOSE) &&
glog << group(
"pAcommsHandler")
696 <<
"Received encode on demand request: " << request_msg << std::endl;
698 boost::shared_ptr<google::protobuf::Message> created_message =
699 translator_.moos_to_protobuf<boost::shared_ptr<google::protobuf::Message> >(
700 dynamic_vars().all(), data_msg->GetDescriptor()->full_name());
702 data_msg->CopyFrom(*created_message);
705 void CpAcommsHandler::create_on_publish(
const CMOOSMsg& trigger_msg,
708 glog.is(DEBUG2) &&
glog << group(
"pAcommsHandler")
709 <<
"Received trigger: " << trigger_msg.GetKey() << std::endl;
711 if (!entry.trigger().has_mandatory_content() ||
712 trigger_msg.GetString().find(entry.trigger().mandatory_content()) != std::string::npos)
713 translate_and_push(entry);
716 glog << group(
"pAcommsHandler")
717 <<
"Message missing mandatory content for: " << entry.protobuf_name() << std::endl;
720 void CpAcommsHandler::create_on_multiplex_publish(
const CMOOSMsg& moos_msg)
722 boost::shared_ptr<google::protobuf::Message> msg = dynamic_parse_for_moos(moos_msg.GetString());
726 glog.is(WARN) &&
glog << group(
"pAcommsHandler")
727 <<
"Multiplex receive failed: Unknown Protobuf type for " 728 << moos_msg.GetString()
729 <<
"; be sure it is compiled in or directly loaded into the " 730 "goby::util::DynamicProtobufManager." 735 std::multimap<std::string, CMOOSMsg> out;
739 out = translator_.protobuf_to_inverse_moos(*msg);
741 for (std::multimap<std::string, CMOOSMsg>::iterator it = out.begin(), n = out.end();
744 glog.is(VERBOSE) &&
glog << group(
"pAcommsHandler")
745 <<
"Inverse Publishing: " << it->second.GetKey() << std::endl;
749 catch (std::exception& e)
751 glog.is(WARN) &&
glog << group(
"pAcommsHandler")
752 <<
"Failed to inverse publish: " << e.what() << std::endl;
756 void CpAcommsHandler::create_on_timer(
const boost::system::error_code& error,
763 goby::util::as<double>(timer->expires_at()));
764 if (skew_seconds > ALLOWED_TIMER_SKEW_SECONDS)
766 glog.is(VERBOSE) &&
glog << group(
"pAcommsHandler") << warn <<
"clock skew of " 767 << skew_seconds <<
" seconds detected, resetting timer." 771 boost::posix_time::seconds(boost::posix_time::seconds(entry.trigger().period())));
776 timer->expires_at(timer->expires_at() +
777 boost::posix_time::seconds(entry.trigger().period()));
780 timer->async_wait(boost::bind(&CpAcommsHandler::create_on_timer,
this, _1, entry, timer));
782 glog.is(DEBUG2) &&
glog << group(
"pAcommsHandler")
783 <<
"Received trigger for: " << entry.protobuf_name() << std::endl;
784 glog.is(DEBUG2) &&
glog << group(
"pAcommsHandler") <<
"Next expiry: " << timer->expires_at()
787 translate_and_push(entry);
795 boost::shared_ptr<google::protobuf::Message> created_message =
796 translator_.moos_to_protobuf<boost::shared_ptr<google::protobuf::Message> >(
797 dynamic_vars().all(), entry.protobuf_name());
799 glog.is(DEBUG2) &&
glog << group(
"pAcommsHandler") <<
"Created message: \n" 800 << created_message->DebugString() << std::endl;
802 queue_manager_.push_message(*created_message);
804 catch (std::runtime_error& e)
806 glog.is(WARN) &&
glog << group(
"pAcommsHandler")
807 <<
"Failed to translate or queue message: " << e.what() << std::endl;
811 void CpAcommsHandler::driver_reset(
812 boost::shared_ptr<goby::acomms::ModemDriverBase> driver,
814 pAcommsHandlerConfig::DriverFailureApproach::DriverFailureTechnique
817 glog.is(WARN) &&
glog << group(
"pAcommsHandler") <<
"Driver exception: " << e.what()
819 glog.is(WARN) &&
glog << group(
"pAcommsHandler") <<
"Shutting down driver: " << driver
825 case pAcommsHandlerConfig::DriverFailureApproach::DISABLE_AND_MOVE_LISTEN_DRIVER_TO_PRIMARY:
826 case pAcommsHandlerConfig::DriverFailureApproach::MOVE_LISTEN_DRIVER_TO_PRIMARY:
828 if (driver == driver_)
830 glog.is(WARN) &&
glog << group(
"pAcommsHandler")
831 <<
"Now using listen driver as new primary." << std::endl;
835 if (drivers_.size() == 1)
837 glog.is(DIE) &&
glog <<
"No more drivers to try..." << std::endl;
841 std::map<boost::shared_ptr<goby::acomms::ModemDriverBase>,
843 drivers_.find(driver);
844 std::map<boost::shared_ptr<goby::acomms::ModemDriverBase>,
849 if (new_it == drivers_.end())
850 new_it = drivers_.begin();
853 driver_ = new_it->first;
854 if (!driver_restart_time_.count(driver_))
861 int new_id = old_config.modem_id();
862 old_config.set_modem_id(new_config.modem_id());
863 new_config.set_modem_id(new_id);
869 driver_restart_time_.insert(std::make_pair(driver_, 0));
874 DISABLE_AND_MOVE_LISTEN_DRIVER_TO_PRIMARY)
877 drivers_.erase(driver);
878 driver_restart_time_.erase(driver);
883 case pAcommsHandlerConfig::DriverFailureApproach::CONTINUALLY_RESTART_DRIVER:
885 glog.is(WARN) &&
glog << group(
"pAcommsHandler") <<
"Attempting to restart driver in " 886 << cfg_.driver_failure_approach().driver_backoff_sec()
887 <<
" seconds." << std::endl;
888 driver_restart_time_.insert(
890 cfg_.driver_failure_approach().driver_backoff_sec()));
896 void CpAcommsHandler::restart_drivers()
899 std::set<boost::shared_ptr<goby::acomms::ModemDriverBase> > drivers_to_start;
901 for (std::map<boost::shared_ptr<goby::acomms::ModemDriverBase>,
double>::iterator it =
902 driver_restart_time_.begin();
903 it != driver_restart_time_.end();)
905 if (it->second < now)
907 drivers_to_start.insert(it->first);
908 driver_restart_time_.erase(it++);
916 for (std::set<boost::shared_ptr<goby::acomms::ModemDriverBase> >::iterator
917 it = drivers_to_start.begin(),
918 end = drivers_to_start.end();
921 boost::shared_ptr<goby::acomms::ModemDriverBase> driver = *it;
924 glog.is(DEBUG1) &&
glog <<
"Starting up driver: " << driver << std::endl;
925 driver->startup(*drivers_[driver]);
929 driver_reset(driver, e);
934 void CpAcommsHandler::driver_bind()
943 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
944 cfg_.moos_var().driver_receive(), _1,
""));
947 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
948 cfg_.moos_var().driver_transmit(), _1,
""));
951 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
952 cfg_.moos_var().driver_raw_msg_in(), _1,
""));
954 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
955 cfg_.moos_var().driver_raw_msg_out(), _1,
""));
958 &driver_->signal_raw_incoming,
959 boost::bind(&CpAcommsHandler::handle_raw,
this, _1, cfg_.moos_var().driver_raw_in()));
962 &driver_->signal_raw_outgoing,
963 boost::bind(&CpAcommsHandler::handle_raw,
this, _1, cfg_.moos_var().driver_raw_out()));
967 void CpAcommsHandler::driver_unbind()
976 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
977 cfg_.moos_var().driver_receive(), _1,
""));
980 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
981 cfg_.moos_var().driver_transmit(), _1,
""));
984 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
985 cfg_.moos_var().driver_raw_msg_in(), _1,
""));
987 boost::bind(&CpAcommsHandler::handle_goby_signal,
this, _1,
988 cfg_.moos_var().driver_raw_msg_out(), _1,
""));
991 &driver_->signal_raw_incoming,
992 boost::bind(&CpAcommsHandler::handle_raw,
this, _1, cfg_.moos_var().driver_raw_in()));
995 &driver_->signal_raw_outgoing,
996 boost::bind(&CpAcommsHandler::handle_raw,
this, _1, cfg_.moos_var().driver_raw_out()));
Contains functions for adding color to Terminal window streams.
void startup(const protobuf::MACConfig &cfg)
Starts the MAC with given configuration.
provides an API to the imaginary ABC modem (as an example how to write drivers)
void do_work()
Allows the MAC timer to do its work. Does not block. If you prefer more control you can directly cont...
provides a driver for the Bluefin Huxley communications infrastructure (initially uses SonarDyne as u...
void parse_for_moos(const std::string &in, google::protobuf::Message *msg)
Parses the string in to Google Protocol Buffers message msg. All errors are written to the goby::util...
Helpers for MOOS applications for serializing and parsed Google Protocol buffers messages.
provides an API to the WHOI Micro-Modem driver
double goby_time< double >()
Returns current UTC time as seconds and fractional seconds since 1970-01-01 00:00:00.
ReturnType goby_time()
Returns current UTC time as a boost::posix_time::ptime.
const int BROADCAST_ID
special modem id for the broadcast destination - no one is assigned this address. Analogous to 192...
provides an API to the goby-acomms MAC library. MACManager is essentially a std::list<protobuf::Modem...
void shutdown()
Shutdown the MAC.
void connect(Signal *signal, Slot slot)
connect a signal to a slot (e.g. function pointer)
common::FlexOstream glog
Access the Goby logger through this object.
The global namespace for the Goby project.
provides an simulator driver to the uFldNodeComms MOOS module: http://oceanai.mit.edu/moos-ivp/pmwiki/pmwiki.php?n=Modules.UFldNodeComms
boost::signals2::signal< void(const protobuf::ModemTransmission &m)> signal_slot_start
Signals the start of all transmissions (even when we don't transmit)
provides an abstract base class for acoustic modem drivers. This is subclassed by the various drivers...
void unbind(ModemDriverBase &driver, QueueManager &queue_manager)
unbinds the driver link-layer callbacks to the QueueManager
void restart()
Restarts the MAC with original configuration.
void update()
You must call this after any change to the underlying list that would invalidate iterators or change ...
boost::signals2::signal< void(const protobuf::ModemTransmission &m)> signal_initiate_transmission
Signals when it is time for this platform to begin transmission of an acoustic message at the start o...
void bind(ModemDriverBase &driver, QueueManager &queue_manager)
binds the driver link-layer callbacks to the QueueManager
void disconnect(Signal *signal, Slot slot)
disconnect a signal to a slot (e.g. function pointer)