25 #ifndef GOBY_ACOMMS_MODEMDRIVER_BENTHOS_ATM900_DRIVER_FSM_H
26 #define GOBY_ACOMMS_MODEMDRIVER_BENTHOS_ATM900_DRIVER_FSM_H
33 #include <boost/circular_buffer.hpp>
34 #include <boost/date_time/date.hpp>
35 #include <boost/date_time/gregorian_calendar.hpp>
36 #include <boost/date_time/posix_time/ptime.hpp>
37 #include <boost/date_time/time.hpp>
38 #include <boost/date_time/time_system_counted.hpp>
39 #include <boost/format.hpp>
40 #include <boost/lexical_cast/bad_lexical_cast.hpp>
41 #include <boost/mpl/list.hpp>
42 #include <boost/smart_ptr/intrusive_ptr.hpp>
43 #include <boost/statechart/custom_reaction.hpp>
44 #include <boost/statechart/deep_history.hpp>
46 #include <boost/statechart/event_base.hpp>
47 #include <boost/statechart/in_state_reaction.hpp>
48 #include <boost/statechart/result.hpp>
52 #include <boost/statechart/transition.hpp>
166 : serial_tx_buffer_(SERIAL_BUFFER_CAPACITY),
167 received_(RECEIVED_BUFFER_CAPACITY),
169 data_out_(DATA_BUFFER_CAPACITY)
172 glog_fsm_group_ =
"benthosatm900::fsm::" + goby::util::as<std::string>(count_);
181 boost::circular_buffer<goby::acomms::protobuf::ModemTransmission>&
received()
187 boost::circular_buffer<goby::acomms::protobuf::ModemTransmission>&
data_out()
203 SERIAL_BUFFER_CAPACITY = 10
207 RECEIVED_BUFFER_CAPACITY = 10
210 boost::circular_buffer<std::string> serial_tx_buffer_;
211 boost::circular_buffer<goby::acomms::protobuf::ModemTransmission> received_;
216 DATA_BUFFER_CAPACITY = 5
218 boost::circular_buffer<goby::acomms::protobuf::ModemTransmission> data_out_;
220 std::string glog_fsm_group_;
244 boost::statechart::has_deep_history>,
252 typedef boost::mpl::list<
253 boost::statechart::transition<EvReset, Active>,
254 boost::statechart::in_state_reaction<EvRxSerial, Active, &Active::in_state_react>,
255 boost::statechart::transition<EvReceive, ReceiveData> >
267 boost::statechart::in_state_reaction<EvRxSerial, ReceiveData, &ReceiveData::in_state_react>,
268 boost::statechart::transition<EvReceiveComplete, boost::statechart::deep_history<Command>>>;
277 boost::statechart::has_deep_history>,
285 if (at_out_.empty() || at_out_.front().second !=
"+++")
288 return transit<Online>();
300 context<Command>().push_at_command(
"+++");
302 context<Command>().push_clam_command(
"@OpMode=0");
307 boost::statechart::custom_reaction<EvConnect>,
308 boost::statechart::in_state_reaction<EvAck, Command, &Command::in_state_react>,
309 boost::statechart::in_state_reaction<EvTxSerial, Command, &Command::in_state_react>>;
330 boost::circular_buffer<std::pair<ATSentenceMeta, std::string> >&
at_out() {
return at_out_; }
335 AT_BUFFER_CAPACITY = 100
337 boost::circular_buffer<std::pair<ATSentenceMeta, std::string> > at_out_;
340 COMMAND_TIMEOUT_SECONDS = 2
345 RETRIES_BEFORE_RESET = 10
351 using reactions = boost::mpl::list<boost::statechart::transition<EvAtEmpty, SetClock>>;
355 context<Command>().push_at_command(
"");
358 context<Command>().push_clam_command(
"@P1EchoChar=Dis");
360 if (context<BenthosATM900FSM>().benthos_driver_cfg().factory_reset())
361 context<Command>().push_clam_command(
"factory_reset");
363 if (context<BenthosATM900FSM>().benthos_driver_cfg().has_config_load())
365 context<Command>().push_clam_command(
366 "cfg load " + context<BenthosATM900FSM>().benthos_driver_cfg().config_load());
369 for (
int i = 0, n = context<BenthosATM900FSM>().benthos_driver_cfg().config_size(); i < n;
372 context<Command>().push_clam_command(
373 context<BenthosATM900FSM>().benthos_driver_cfg().
config(i));
377 context<Command>().push_clam_command(
"@P1Prompt=7");
378 context<Command>().push_clam_command(
"@Verbose=3");
381 context<Command>().push_clam_command(
"@DataRetry=0");
384 context<Command>().push_clam_command(
"@FwdDelay=0.05");
385 context<Command>().push_clam_command(
387 goby::util::as<std::string>(context<BenthosATM900FSM>().driver_cfg().modem_id()));
390 context<Command>().push_clam_command(
"@PrintHex=Ena");
393 context<Command>().push_clam_command(
"@WakeTones=Ena");
396 context<Command>().push_clam_command(
"@RcvAll=Ena");
399 context<Command>().push_clam_command(
"@ShowBadData=Ena");
402 context<Command>().push_clam_command(
"@OpMode=0");
413 using reactions = boost::mpl::list<boost::statechart::transition<EvAtEmpty, Ready>>;
417 auto p = time::SystemClock::now<boost::posix_time::ptime>();
419 std::string date_str =
boost::str(boost::format(
"-d%02d/%02d/%04d") %
420 (
int)p.date().month() % p.date().day() % p.date().year());
421 std::string time_str =
422 boost::str(boost::format(
"-t%02d:%02d:%02d") % p.time_of_day().hours() %
423 p.time_of_day().minutes() % p.time_of_day().seconds());
425 context<Command>().push_clam_command(
"date " + time_str +
" " + date_str);
434 void in_state_react(
const EvRequestLowPower&) { context<Command>().push_at_command(
"L"); }
438 ~Ready()
override =
default;
441 boost::statechart::transition<EvDial, Dial>, boost::statechart::transition<EvRange, Range>,
442 boost::statechart::in_state_reaction<EvRequestLowPower, Ready, &Ready::in_state_react>,
443 boost::statechart::transition<EvLowPower, LowPower>>;
467 dest_ = evdial->dest_;
472 rate_ = evdial->rate_;
474 context<Command>().push_clam_command(
"@RemoteAddr=" + goby::util::as<std::string>(dest_));
475 context<Command>().push_clam_command(
"@TxRate=" + goby::util::as<std::string>(rate_));
476 context<Command>().push_at_command(
"O");
478 ~Dial()
override =
default;
501 context<Command>().push_at_command(
"R" + goby::util::as<std::string>(dest_));
503 ~Range()
override =
default;
506 boost::statechart::transition<EvRangingComplete, Ready>,
507 boost::statechart::in_state_reaction<EvRxSerial, Range, &Range::in_state_react>>;
520 boost::statechart::transition<EvShellPrompt, boost::statechart::deep_history<Command>>>;
527 if (!context<BenthosATM900FSM>().data_out().empty())
532 using reactions = boost::mpl::list<boost::statechart::transition<EvTransmit, TransmitData>>;
544 boost::statechart::transition<EvTransmitBegun, Ready>,
547 boost::statechart::in_state_reaction<EvAck, TransmitData, &TransmitData::in_state_react>>;