Goby3  3.1.4
2024.02.22
iridium_driver_fsm.h
Go to the documentation of this file.
1 // Copyright 2013-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_IRIDIUM_DRIVER_FSM_H
26 #define GOBY_ACOMMS_MODEMDRIVER_IRIDIUM_DRIVER_FSM_H
27 
28 #include <algorithm> // for for_each
29 #include <iostream> // for basic_ost...
30 #include <locale> // for locale
31 #include <string> // for string
32 #include <utility> // for move, pair
33 #include <vector> // for vector
34 
35 #include <boost/algorithm/string/classification.hpp> // for is_any_ofF
36 #include <boost/algorithm/string/split.hpp> // for split
37 #include <boost/algorithm/string/trim.hpp> // for trim
38 #include <boost/bind/bind.hpp> // for bind_t, arg
39 #include <boost/circular_buffer.hpp> // for circular_...
40 #include <boost/lexical_cast/bad_lexical_cast.hpp> // for bad_lexic...
41 #include <boost/mpl/list.hpp> // for list
42 #include <boost/smart_ptr/intrusive_ptr.hpp> // for intrusive...
43 #include <boost/statechart/custom_reaction.hpp>
44 #include <boost/statechart/event.hpp> // for event
45 #include <boost/statechart/in_state_reaction.hpp> // for in_state_...
46 #include <boost/statechart/result.hpp> // for reaction_...
47 #include <boost/statechart/simple_state.hpp> // for simple_st...
48 #include <boost/statechart/state.hpp> // for state
49 #include <boost/statechart/state_machine.hpp> // for state_mac...
50 #include <boost/statechart/transition.hpp> // for transition
51 
52 #include "goby/acomms/modemdriver/iridium_driver_common.h" // for OnCallBase
53 #include "goby/acomms/protobuf/driver_base.pb.h" // for DriverConfig
54 #include "goby/acomms/protobuf/iridium_driver.pb.h" // for Config
55 #include "goby/acomms/protobuf/modem_message.pb.h" // for ModemTran...
56 #include "goby/util/as.h" // for as
57 #include "goby/util/debug_logger/flex_ostream.h" // for FlexOstream
58 #include "goby/util/debug_logger/flex_ostreambuf.h" // for DEBUG1, WARN
59 #include "goby/util/debug_logger/logger_manipulators.h" // for operator<<
60 
61 namespace goby
62 {
63 namespace acomms
64 {
65 namespace iridium
66 {
67 inline unsigned sbd_csum(const std::string& data)
68 {
69  unsigned int csum = 0;
70  for (char it : data) csum += it & 0xFF;
71  return csum;
72 }
73 
74 namespace fsm
75 {
77 {
78  StateNotify(std::string name) : name_(std::move(name))
79  {
80  glog.is(goby::util::logger::DEBUG1) && glog << group("iridiumdriver") << name_ << std::endl;
81  }
83  {
84  glog.is(goby::util::logger::DEBUG1) && glog << group("iridiumdriver") << "~" << name_
85  << std::endl;
86  }
87 
88  private:
89  std::string name_;
90 };
91 
92 // events
94 {
95  std::string line;
96 };
98 {
99 };
100 
101 struct EvRxOnCallSerial : boost::statechart::event<EvRxOnCallSerial>
102 {
103  std::string line;
104 };
105 struct EvTxOnCallSerial : boost::statechart::event<EvTxOnCallSerial>
106 {
107 };
108 
110 {
111  EvAck(std::string response) : response_(std::move(response)) {}
112 
113  std::string response_;
114 };
115 
117 {
118 };
120 {
121 };
122 
124 {
125 };
127 {
128 };
130 {
131 };
132 
134 {
135 };
136 
138 {
139 };
141 {
142 };
144 {
145 };
146 
148 {
149 };
150 
152 {
153 };
154 struct EvSBDBeginData : boost::statechart::event<EvSBDBeginData>
155 {
156  EvSBDBeginData(std::string data = "", bool in_response_to_ring_alert = false)
157  : data_(std::move(data)), in_response_to_ring_alert_(in_response_to_ring_alert)
158  {
159  }
160  std::string data_;
162 };
163 
164 struct EvSBDSendBufferCleared : boost::statechart::event<EvSBDSendBufferCleared>
165 {
166 };
167 
168 struct EvSBDWriteReady : boost::statechart::event<EvSBDWriteReady>
169 {
170 };
171 struct EvSBDWriteComplete : boost::statechart::event<EvSBDWriteComplete>
172 {
173 };
174 struct EvSBDTransmitComplete : boost::statechart::event<EvSBDTransmitComplete>
175 {
176  EvSBDTransmitComplete(std::string sbdi) : sbdi_(std::move(sbdi)) {}
177  std::string sbdi_;
178 };
179 struct EvSBDReceiveComplete : boost::statechart::event<EvSBDReceiveComplete>
180 {
181 };
182 
183 // pre-declare
184 struct Active;
185 struct Command;
186 struct Configure;
187 struct Ready;
188 struct Answer;
189 struct Dial;
190 struct Online;
191 struct OnCall;
192 struct NotOnCall;
193 struct SBD;
194 struct SBDReady;
195 struct SBDClearBuffers;
196 struct SBDWrite;
197 struct SBDTransmit;
198 struct SBDReceive;
199 
200 // state machine
201 struct IridiumDriverFSM : boost::statechart::state_machine<IridiumDriverFSM, Active>
202 {
203  private:
204  struct CIEVData
205  {
206  int rssi{-1};
207  bool service_available{false};
208  };
209 
210  public:
212  : serial_tx_buffer_(SERIAL_BUFFER_CAPACITY),
213  received_(RECEIVED_BUFFER_CAPACITY),
214  driver_cfg_(driver_cfg),
215  data_out_(DATA_BUFFER_CAPACITY)
216  {
217  ++count_;
218  glog_ir_group_ = "iridiumdriver::" + goby::util::as<std::string>(count_);
219  }
220 
222 
223  // messages for the serial line at next opportunity
224  boost::circular_buffer<std::string>& serial_tx_buffer() { return serial_tx_buffer_; }
225 
226  // received messages to be passed up out of the ModemDriver
227  boost::circular_buffer<goby::acomms::protobuf::ModemTransmission>& received()
228  {
229  return received_;
230  }
231 
232  // data that should (eventually) be sent out across the Iridium connection
233  boost::circular_buffer<goby::acomms::protobuf::ModemTransmission>& data_out()
234  {
235  return data_out_;
236  }
237 
238  const goby::acomms::protobuf::DriverConfig& driver_cfg() const { return driver_cfg_; }
240  {
241  return driver_cfg_.GetExtension(protobuf::config);
242  }
243 
244  const std::string& glog_ir_group() const { return glog_ir_group_; }
245 
246  const CIEVData& ciev_data() const { return ciev_data_; }
247 
248  void parse_ciev(const std::string& ciev);
249 
250  private:
251  enum
252  {
253  SERIAL_BUFFER_CAPACITY = 10
254  };
255  enum
256  {
257  RECEIVED_BUFFER_CAPACITY = 10
258  };
259 
260  boost::circular_buffer<std::string> serial_tx_buffer_;
261  boost::circular_buffer<goby::acomms::protobuf::ModemTransmission> received_;
262  const goby::acomms::protobuf::DriverConfig& driver_cfg_;
263 
264  enum
265  {
266  DATA_BUFFER_CAPACITY = 5
267  };
268  boost::circular_buffer<goby::acomms::protobuf::ModemTransmission> data_out_;
269 
270  std::string glog_ir_group_;
271 
272  static int count_;
273 
274  CIEVData ciev_data_;
275 };
276 
277 struct Active : boost::statechart::simple_state<Active, IridiumDriverFSM,
278  boost::mpl::list<Command, NotOnCall>>
279 {
280  typedef boost::mpl::list<boost::statechart::transition<EvReset, Active>> reactions;
281 };
282 
283 // Command
284 struct Command : boost::statechart::simple_state<Command, Active::orthogonal<0>,
285  boost::mpl::list<Configure, SBD>>,
287 {
288  public:
289  void in_state_react(const EvRxSerial&);
290  void in_state_react(const EvTxSerial&);
291  void in_state_react(const EvAck&);
292 
293  Command() : StateNotify("Command"), at_out_(AT_BUFFER_CAPACITY) {}
294  ~Command() override = default;
295 
296  using reactions = boost::mpl::list<
297  boost::statechart::in_state_reaction<EvRxSerial, Command, &Command::in_state_react>,
298  boost::statechart::in_state_reaction<EvTxSerial, Command, &Command::in_state_react>,
299  boost::statechart::transition<EvOnline, Online>,
300  boost::statechart::in_state_reaction<EvAck, Command, &Command::in_state_react>>;
301 
303  {
304  ATSentenceMeta() = default;
305  double last_send_time_{0};
306  int tries_{0};
307  };
308 
309  void push_at_command(const std::string& cmd)
310  {
311  at_out_.push_back(std::make_pair(ATSentenceMeta(), cmd));
312  }
313 
314  boost::circular_buffer<std::pair<ATSentenceMeta, std::string>>& at_out() { return at_out_; }
315 
316  void clear_sbd_rx_buffer() { sbd_rx_buffer_.clear(); }
317 
318  void handle_sbd_rx(const std::string& in);
319 
320  private:
321  enum
322  {
323  AT_BUFFER_CAPACITY = 100
324  };
325  boost::circular_buffer<std::pair<ATSentenceMeta, std::string>> at_out_;
326  enum
327  {
328  COMMAND_TIMEOUT_SECONDS = 2,
329  DIAL_TIMEOUT_SECONDS = 60,
330  SBDIX_TIMEOUT_SECONDS = DIAL_TIMEOUT_SECONDS,
331  TRIPLE_PLUS_TIMEOUT_SECONDS = 6,
332  HANGUP_TIMEOUT_SECONDS = 10,
333  ANSWER_TIMEOUT_SECONDS = 30
334  };
335 
336  enum
337  {
338  RETRIES_BEFORE_RESET = 3
339  };
340  std::string sbd_rx_buffer_;
341 };
342 
343 struct Configure : boost::statechart::state<Configure, Command::orthogonal<0>>, StateNotify
344 {
345  using reactions = boost::mpl::list<boost::statechart::transition<EvAtEmpty, Ready>>;
346 
347  Configure(my_context ctx) : my_base(std::move(ctx)), StateNotify("Configure")
348  {
349  context<Command>().push_at_command("");
350  const auto& iridium_driver_config = context<IridiumDriverFSM>().iridium_driver_cfg();
351  for (int i = 0, n = iridium_driver_config.config_size(); i < n; ++i)
352  {
353  context<Command>().push_at_command(iridium_driver_config.config(i));
354  }
355  }
356 
357  ~Configure() override { post_event(EvConfigured()); }
358 };
359 
360 struct Ready : boost::statechart::simple_state<Ready, Command::orthogonal<0>>, StateNotify
361 {
362  public:
363  Ready() : StateNotify("Ready") {}
364  ~Ready() override = default;
365 
366  boost::statechart::result react(const EvDial&)
367  {
368  if (state_downcast<const NotOnCall*>() != 0)
369  {
370  return transit<Dial>();
371  }
372  else
373  {
375  glog << group("iridiumdriver") << "Not dialing since we are already on a call."
376  << std::endl;
377  return discard_event();
378  }
379  }
380 
381  using reactions = boost::mpl::list<boost::statechart::transition<EvRing, Answer>,
382  boost::statechart::custom_reaction<EvDial>>;
383 
384  private:
385 };
386 
387 struct HangingUp : boost::statechart::state<HangingUp, Command::orthogonal<0>>, StateNotify
388 {
389  public:
390  HangingUp(my_context ctx) : my_base(std::move(ctx)), StateNotify("HangingUp")
391  {
392  context<Command>().push_at_command("+++");
393  context<Command>().push_at_command("H");
394  }
395  ~HangingUp() override = default;
396 
397  using reactions = boost::mpl::list<boost::statechart::transition<EvAtEmpty, Ready>>;
398 
399  private:
400 };
401 
402 struct PostDisconnected : boost::statechart::state<PostDisconnected, Command::orthogonal<0>>,
404 {
405  public:
406  PostDisconnected(my_context ctx) : my_base(std::move(ctx)), StateNotify("PostDisconnected")
407  {
409  glog << group("iridiumdriver") << "Disconnected; checking error details: " << std::endl;
410  context<Command>().push_at_command("+CEER");
411  }
412  ~PostDisconnected() override = default;
413 
414  using reactions = boost::mpl::list<boost::statechart::transition<EvAtEmpty, Ready>>;
415 
416  private:
417 };
418 
419 struct Dial : boost::statechart::state<Dial, Command::orthogonal<0>>, StateNotify
420 {
421  using reactions = boost::mpl::list<boost::statechart::custom_reaction<EvNoCarrier>>;
422 
423  Dial(my_context ctx) : my_base(std::move(ctx)), StateNotify("Dial"), dial_attempts_(0)
424  {
425  dial();
426  }
427  ~Dial() override = default;
428 
429  boost::statechart::result react(const EvNoCarrier&);
430  void dial();
431 
432  private:
433  int dial_attempts_;
434 };
435 
436 struct Answer : boost::statechart::state<Answer, Command::orthogonal<0>>, StateNotify
437 {
438  using reactions = boost::mpl::list<boost::statechart::transition<EvNoCarrier, Ready>>;
439 
440  Answer(my_context ctx) : my_base(std::move(ctx)), StateNotify("Answer")
441  {
442  context<Command>().push_at_command("A");
443  }
444  ~Answer() override = default;
445 };
446 
447 // Online
448 struct Online : boost::statechart::simple_state<Online, Active::orthogonal<0>>, StateNotify
449 {
450  Online() : StateNotify("Online") {}
451  ~Online() override = default;
452 
453  void in_state_react(const EvRxSerial&);
454  void in_state_react(const EvTxSerial&);
455 
456  using reactions = boost::mpl::list<
457  boost::statechart::transition<EvHangup, HangingUp>,
458  boost::statechart::transition<EvDisconnect, PostDisconnected>,
459  boost::statechart::in_state_reaction<EvRxSerial, Online, &Online::in_state_react>,
460  boost::statechart::in_state_reaction<EvTxSerial, Online, &Online::in_state_react>>;
461 };
462 
463 // Orthogonal on-call / not-on-call
464 struct NotOnCall : boost::statechart::simple_state<NotOnCall, Active::orthogonal<1>>, StateNotify
465 {
466  using reactions = boost::mpl::list<boost::statechart::transition<EvConnect, OnCall>>;
467 
468  NotOnCall() : StateNotify("NotOnCall") {}
469  ~NotOnCall() override = default;
470 };
471 
472 struct OnCall : boost::statechart::state<OnCall, Active::orthogonal<1>>, StateNotify, OnCallBase
473 {
474  public:
475  OnCall(my_context ctx) : my_base(std::move(ctx)), StateNotify("OnCall")
476  {
477  // add a brief identifier that is *different* than the "~" which is what PPP uses
478  // add a carriage return to clear out any garbage
479  // at the *beginning* of transmission
480  context<IridiumDriverFSM>().serial_tx_buffer().push_front("goby\r");
481 
482  // connecting necessarily puts the DTE online
483  post_event(EvOnline());
484  }
485  ~OnCall() override
486  {
487  // signal the disconnect event for the command state to handle
488  glog.is(goby::util::logger::DEBUG1) && glog << group("iridiumdriver") << "Sent "
489  << total_bytes_sent() << " bytes on this call."
490  << std::endl;
492  }
493 
494  void in_state_react(const EvRxOnCallSerial&);
495  void in_state_react(const EvTxOnCallSerial&);
496  void in_state_react(const EvSendBye&);
497 
498  using reactions = boost::mpl::list<
499  boost::statechart::transition<EvNoCarrier, NotOnCall>,
500  boost::statechart::in_state_reaction<EvRxOnCallSerial, OnCall, &OnCall::in_state_react>,
501  boost::statechart::in_state_reaction<EvTxOnCallSerial, OnCall, &OnCall::in_state_react>,
502  boost::statechart::in_state_reaction<EvSendBye, OnCall, &OnCall::in_state_react>>;
503 
504  private:
505 };
506 
507 struct SBD : boost::statechart::simple_state<SBD, Command::orthogonal<1>, SBDReady>, StateNotify
508 {
509  SBD() : StateNotify("SBD") {}
510  ~SBD() override = default;
511 
512  void set_data(const EvSBDBeginData& e)
513  {
514  set_data(e.data_);
515  in_response_to_ring_alert_ = e.in_response_to_ring_alert_;
516  }
517  void clear_data() { data_.clear(); }
518  const std::string& data() const { return data_; }
519  bool in_response_to_ring_alert() const { return in_response_to_ring_alert_; }
520 
521  private:
522  void set_data(const std::string& data)
523  {
524  if (data.empty())
525  data_ = data;
526  else
527  {
528  unsigned int csum = sbd_csum(data);
529 
530  const int bits_in_byte = 8;
531  data_ = data + std::string(1, (csum & 0xFF00) >> bits_in_byte) +
532  std::string(1, (csum & 0xFF));
533  }
534  }
535 
536  private:
537  std::string data_;
538  bool in_response_to_ring_alert_;
539 };
540 
541 /* struct SBDConfigure : boost::statechart::simple_state<SBDConfigure, SBD >, StateNotify */
542 /* { */
543 /* typedef boost::mpl::list< */
544 /* boost::statechart::transition< EvConfigured, SBDReady > */
545 /* > reactions; */
546 
547 /* SBDConfigure() : StateNotify("SBDConfigure") */
548 /* { */
549 /* } */
550 /* ~SBDConfigure() { */
551 /* } */
552 
553 /* }; */
554 
556 {
557  using reactions = boost::mpl::list<
558  boost::statechart::transition<EvSBDBeginData, SBDClearBuffers, SBD, &SBD::set_data>>;
559 
560  SBDReady() : StateNotify("SBDReady") {}
561 
562  ~SBDReady() override = default;
563 };
564 
565 struct SBDClearBuffers : boost::statechart::state<SBDClearBuffers, SBD>, StateNotify
566 {
567  using reactions =
568  boost::mpl::list<boost::statechart::transition<EvSBDSendBufferCleared, SBDWrite>>;
569 
570  SBDClearBuffers(my_context ctx) : my_base(std::move(ctx)), StateNotify("SBDClearBuffers")
571  {
572  context<Command>().clear_sbd_rx_buffer();
573  context<Command>().push_at_command("+SBDD2");
574  }
575 
576  ~SBDClearBuffers() override = default;
577 };
578 
580 {
581  SBDWrite(my_context ctx) : my_base(std::move(ctx)), StateNotify("SBDWrite")
582  {
583  if (context<SBD>().data().empty())
584  {
585  glog.is(goby::util::logger::DEBUG1) && glog << group("iridiumdriver")
586  << "Mailbox Check." << std::endl;
587  post_event(EvSBDWriteComplete()); // Mailbox Check
588  }
589  else
590  {
591  glog.is(goby::util::logger::DEBUG1) && glog << group("iridiumdriver") << "Writing data."
592  << std::endl;
593 
594  const int csum_bytes = 2;
595  context<Command>().push_at_command(
596  "+SBDWB=" + goby::util::as<std::string>(context<SBD>().data().size() - csum_bytes));
597  }
598  }
599 
601  {
602  context<IridiumDriverFSM>().serial_tx_buffer().push_back(context<SBD>().data());
603  }
604 
605  ~SBDWrite() override = default;
606 
607  using reactions = boost::mpl::list<
608  boost::statechart::in_state_reaction<EvSBDWriteReady, SBDWrite, &SBDWrite::in_state_react>,
609  boost::statechart::transition<EvSBDWriteComplete, SBDTransmit>>;
610 };
611 
613 {
614  using reactions = boost::mpl::list<boost::statechart::custom_reaction<EvSBDTransmitComplete>>;
615  SBDTransmit(my_context ctx) : my_base(std::move(ctx)), StateNotify("SBDTransmit")
616  {
617  if (context<SBD>().in_response_to_ring_alert())
618  context<Command>().push_at_command("+SBDIXA");
619  else
620  context<Command>().push_at_command("+SBDIX");
621  }
622  ~SBDTransmit() override { context<SBD>().clear_data(); }
623 
624  std::string mo_status_as_string(int code)
625  {
626  switch (code)
627  {
628  // success
629  case 0: return "MO message, if any, transferred successfully";
630  case 1:
631  return "MO message, if any, transferred successfully, but the MT message in the "
632  "queue was too big to be transferred";
633  case 2:
634  return "MO message, if any, transferred successfully, but the requested Location "
635  "Update was not accepted";
636  case 3:
637  case 4:
638  return "Reserved, but indicate MO session success if used";
639 
640  // failure
641  case 5:
642  case 6:
643  case 7:
644  case 8:
645  case 9:
646  case 20:
647  case 21:
648  case 22:
649  case 23:
650  case 24:
651  case 25:
652  case 26:
653  case 27:
654  case 28:
655  case 29:
656  case 30:
657  case 31:
658  case 33:
659  case 34:
660  case 36:
661  default: return "Reserved, but indicate MO session failure if used";
662  case 10: return "GSS reported that the call did not complete in the allowed time";
663  case 11: return "MO message queue at the GSS is full";
664  case 12: return "MO message has too many segments";
665  case 13: return "GSS reported that the session did not complete";
666  case 14: return "Invalid segment size";
667  case 15: return "Access is denied";
668  case 16: return "Modem has been locked and may not make SBD calls";
669  case 17: return "Gateway not responding (local session timeout)";
670  case 18: return "Connection lost (RF drop)";
671  case 19: return "Link failure (A protocol error caused termination of the call)";
672  case 32: return "No network service, unable to initiate call";
673  case 35: return "Iridium 9523 is busy, unable to initiate call";
674  }
675  }
676 
677  boost::statechart::result react(const EvSBDTransmitComplete& e)
678  {
679  // +SBDIX:<MO status>,<MOMSN>,<MT status>,<MTMSN>,<MT length>,<MT queued>
680  std::vector<std::string> sbdi_fields;
681  boost::algorithm::split(sbdi_fields, e.sbdi_, boost::is_any_of(":,"));
682 
683  std::for_each(
684  sbdi_fields.begin(), sbdi_fields.end(),
685  boost::bind(&boost::trim<std::string>, boost::placeholders::_1, std::locale()));
686 
687  if (sbdi_fields.size() != 7)
688  {
689  glog.is(goby::util::logger::DEBUG1) && glog << group("iridiumdriver")
690  << "Invalid +SBDI response: " << e.sbdi_
691  << std::endl;
692  return transit<SBDReady>();
693  }
694  else
695  {
696  enum
697  {
698  MO_STATUS = 1,
699  MOMSN = 2,
700  MT_STATUS = 3,
701  MTMSN = 4,
702  MT_LENGTH = 5,
703  MT_QUEUED = 6
704  };
705  enum
706  {
707  MT_STATUS_NO_MESSAGE = 0,
708  MT_STATUS_RECEIVED_MESSAGE = 1,
709  MT_STATUS_ERROR = 2
710  };
711 
712  // 0-4 OK, 5-36 FAILURE
713  enum
714  {
715  MO_STATUS_SUCCESS_MAX = 4,
716  MO_STATUS_FAILURE_MIN = 5
717  };
718 
719  int mo_status = goby::util::as<int>(sbdi_fields[MO_STATUS]);
720  if (mo_status <= MO_STATUS_SUCCESS_MAX)
721  {
723  glog << group("iridiumdriver")
724  << "Success sending SBDIX: " << mo_status_as_string(mo_status)
725  << std::endl;
726  }
727  else
728  {
730  glog << group("iridiumdriver")
731  << "Error sending SBD packet: " << mo_status_as_string(mo_status)
732  << std::endl;
733  return transit<SBDReady>();
734  }
735 
736  int mt_status = goby::util::as<int>(sbdi_fields[MT_STATUS]);
737  if (mt_status == MT_STATUS_RECEIVED_MESSAGE)
738  return transit<SBDReceive>();
739  else
740  return transit<SBDReady>();
741  }
742  }
743 };
744 
746 {
747  using reactions =
748  boost::mpl::list<boost::statechart::transition<EvSBDReceiveComplete, SBDReady>>;
749  SBDReceive(my_context ctx) : my_base(std::move(ctx)), StateNotify("SBDReceive")
750  {
751  context<Command>().push_at_command("+SBDRB");
752  }
753  ~SBDReceive() override = default;
754 };
755 
756 } // namespace fsm
757 } // namespace iridium
758 } // namespace acomms
759 } // namespace goby
760 
762 
763 #endif
goby::acomms::protobuf::DriverConfig
Definition: driver_base.pb.h:122
goby::acomms::iridium::fsm::SBD::~SBD
~SBD() override=default
goby::acomms::protobuf::ModemTransmission
Definition: modem_message.pb.h:166
goby::acomms::iridium::fsm::SBDTransmit::SBDTransmit
SBDTransmit(my_context ctx)
Definition: iridium_driver_fsm.h:615
goby::acomms::iridium::fsm::OnCall
Definition: iridium_driver_fsm.h:472
goby::acomms::iridium::fsm::Command
Definition: iridium_driver_fsm.h:284
goby::acomms::iridium::fsm::Online::reactions
boost::mpl::list< boost::statechart::transition< EvHangup, HangingUp >, boost::statechart::transition< EvDisconnect, PostDisconnected >, boost::statechart::in_state_reaction< EvRxSerial, Online, &Online::in_state_react >, boost::statechart::in_state_reaction< EvTxSerial, Online, &Online::in_state_react > > reactions
Definition: iridium_driver_fsm.h:460
goby::acomms::iridium::fsm::PostDisconnected::reactions
boost::mpl::list< boost::statechart::transition< EvAtEmpty, Ready > > reactions
Definition: iridium_driver_fsm.h:414
boost::statechart::simple_state< Configure, Command::orthogonal< 0 >, mpl::list<>, has_no_history >::post_event
void post_event(const event_base_ptr_type &pEvent)
Definition: simple_state.hpp:284
goby::acomms::iridium::fsm::SBDWrite::reactions
boost::mpl::list< boost::statechart::in_state_reaction< EvSBDWriteReady, SBDWrite, &SBDWrite::in_state_react >, boost::statechart::transition< EvSBDWriteComplete, SBDTransmit > > reactions
Definition: iridium_driver_fsm.h:609
goby::acomms::iridium::fsm::IridiumDriverFSM::IridiumDriverFSM
IridiumDriverFSM(const goby::acomms::protobuf::DriverConfig &driver_cfg)
Definition: iridium_driver_fsm.h:211
goby::acomms::iridium::fsm::StateNotify
Definition: iridium_driver_fsm.h:76
goby::acomms::iridium::fsm::SBDTransmit::react
boost::statechart::result react(const EvSBDTransmitComplete &e)
Definition: iridium_driver_fsm.h:677
goby::acomms::iridium::fsm::Command::Command
Command()
Definition: iridium_driver_fsm.h:293
goby::acomms::iridium::fsm::EvRxOnCallSerial
Definition: iridium_driver_fsm.h:101
goby::acomms::iridium::fsm::SBDTransmit::mo_status_as_string
std::string mo_status_as_string(int code)
Definition: iridium_driver_fsm.h:624
goby::acomms::iridium::fsm::Command::handle_sbd_rx
void handle_sbd_rx(const std::string &in)
goby::acomms::iridium::fsm::Command::reactions
boost::mpl::list< boost::statechart::in_state_reaction< EvRxSerial, Command, &Command::in_state_react >, boost::statechart::in_state_reaction< EvTxSerial, Command, &Command::in_state_react >, boost::statechart::transition< EvOnline, Online >, boost::statechart::in_state_reaction< EvAck, Command, &Command::in_state_react > > reactions
Definition: iridium_driver_fsm.h:300
goby::acomms::iridium::fsm::SBD::in_response_to_ring_alert
bool in_response_to_ring_alert() const
Definition: iridium_driver_fsm.h:519
goby::util::FlexOstream::is
bool is(goby::util::logger::Verbosity verbosity)
goby::acomms::iridium::fsm::EvAck
Definition: iridium_driver_fsm.h:109
goby
The global namespace for the Goby project.
Definition: acomms_constants.h:33
boost_statechart_compat.h
goby::acomms::iridium::fsm::Ready::Ready
Ready()
Definition: iridium_driver_fsm.h:363
goby::acomms::iridium::fsm::SBDClearBuffers::SBDClearBuffers
SBDClearBuffers(my_context ctx)
Definition: iridium_driver_fsm.h:570
goby::acomms::iridium::fsm::SBDReceive::SBDReceive
SBDReceive(my_context ctx)
Definition: iridium_driver_fsm.h:749
as.h
goby::acomms::iridium::fsm::Command::push_at_command
void push_at_command(const std::string &cmd)
Definition: iridium_driver_fsm.h:309
goby::acomms::iridium::fsm::EvSendBye
Definition: iridium_driver_fsm.h:147
goby::acomms::iridium::fsm::Dial::dial
void dial()
goby::acomms::iridium::fsm::EvSBDWriteReady
Definition: iridium_driver_fsm.h:168
goby::acomms::iridium::fsm::SBDReady::SBDReady
SBDReady()
Definition: iridium_driver_fsm.h:560
goby::util::logger::WARN
@ WARN
Definition: flex_ostreambuf.h:74
goby::acomms::iridium::fsm::SBDTransmit::~SBDTransmit
~SBDTransmit() override
Definition: iridium_driver_fsm.h:622
goby::util::e
constexpr T e
Definition: constants.h:35
event.hpp
goby::acomms::iridium::fsm::IridiumDriverFSM::glog_ir_group
const std::string & glog_ir_group() const
Definition: iridium_driver_fsm.h:244
goby::acomms::iridium::fsm::IridiumDriverFSM::received
boost::circular_buffer< goby::acomms::protobuf::ModemTransmission > & received()
Definition: iridium_driver_fsm.h:227
goby::acomms::iridium::fsm::SBDClearBuffers
Definition: iridium_driver_fsm.h:565
goby::acomms::iridium::fsm::HangingUp::reactions
boost::mpl::list< boost::statechart::transition< EvAtEmpty, Ready > > reactions
Definition: iridium_driver_fsm.h:397
group
goby::util::logger::GroupSetter group(std::string n)
Definition: logger_manipulators.h:134
goby::acomms::iridium::fsm::HangingUp::HangingUp
HangingUp(my_context ctx)
Definition: iridium_driver_fsm.h:390
modem_message.pb.h
boost::statechart::simple_state< Ready, Command::orthogonal< 0 > >::discard_event
result discard_event()
Definition: simple_state.hpp:294
goby::acomms::iridium::fsm::IridiumDriverFSM::buffer_data_out
void buffer_data_out(const goby::acomms::protobuf::ModemTransmission &msg)
goby::acomms::iridium::fsm::HangingUp::~HangingUp
~HangingUp() override=default
goby::acomms::iridium::fsm::IridiumDriverFSM
Definition: iridium_driver_fsm.h:201
goby::acomms::iridium::fsm::SBD
Definition: iridium_driver_fsm.h:507
goby::acomms::iridium::fsm::SBDWrite::in_state_react
void in_state_react(const EvSBDWriteReady &)
Definition: iridium_driver_fsm.h:600
flex_ostreambuf.h
goby::acomms::iridium::fsm::EvSBDBeginData::in_response_to_ring_alert_
bool in_response_to_ring_alert_
Definition: iridium_driver_fsm.h:161
iridium_driver_common.h
goby::acomms::iridium::fsm::EvSBDSendBufferCleared
Definition: iridium_driver_fsm.h:164
goby::acomms::iridium::fsm::Command::ATSentenceMeta::tries_
int tries_
Definition: iridium_driver_fsm.h:306
goby::acomms::iridium::fsm::OnCall::~OnCall
~OnCall() override
Definition: iridium_driver_fsm.h:485
goby::acomms::iridium::fsm::EvRxOnCallSerial::line
std::string line
Definition: iridium_driver_fsm.h:103
goby::acomms::iridium::fsm::Command::ATSentenceMeta::ATSentenceMeta
ATSentenceMeta()=default
goby::acomms::iridium::fsm::EvSBDBeginData::data_
std::string data_
Definition: iridium_driver_fsm.h:160
goby::acomms::iridium::fsm::Online
Definition: iridium_driver_fsm.h:448
goby::acomms::iridium::fsm::SBD::data
const std::string & data() const
Definition: iridium_driver_fsm.h:518
goby::acomms::iridium::fsm::EvRxSerial::line
std::string line
Definition: iridium_driver_fsm.h:95
goby::acomms::iridium::fsm::OnCall::reactions
boost::mpl::list< boost::statechart::transition< EvNoCarrier, NotOnCall >, boost::statechart::in_state_reaction< EvRxOnCallSerial, OnCall, &OnCall::in_state_react >, boost::statechart::in_state_reaction< EvTxOnCallSerial, OnCall, &OnCall::in_state_react >, boost::statechart::in_state_reaction< EvSendBye, OnCall, &OnCall::in_state_react > > reactions
Definition: iridium_driver_fsm.h:502
goby::acomms::iridium::fsm::EvRxSerial
Definition: iridium_driver_fsm.h:93
goby::acomms::iridium::protobuf::config
extern ::google::protobuf::internal::ExtensionIdentifier< ::goby::acomms::protobuf::DriverConfig, ::google::protobuf::internal::MessageTypeTraits< ::goby::acomms::iridium::protobuf::Config >, 11, false > config
Definition: iridium_driver.pb.h:1512
goby::acomms::iridium::fsm::EvSBDBeginData
Definition: iridium_driver_fsm.h:154
goby::acomms::iridium::fsm::SBDReady::reactions
boost::mpl::list< boost::statechart::transition< EvSBDBeginData, SBDClearBuffers, SBD, &SBD::set_data > > reactions
Definition: iridium_driver_fsm.h:558
goby::acomms::iridium::fsm::EvAck::response_
std::string response_
Definition: iridium_driver_fsm.h:113
goby::acomms::iridium::fsm::StateNotify::StateNotify
StateNotify(std::string name)
Definition: iridium_driver_fsm.h:78
goby::acomms::iridium::fsm::Answer::~Answer
~Answer() override=default
goby::acomms::iridium::fsm::Active::reactions
boost::mpl::list< boost::statechart::transition< EvReset, Active > > reactions
Definition: iridium_driver_fsm.h:280
goby::acomms::iridium::fsm::OnCall::OnCall
OnCall(my_context ctx)
Definition: iridium_driver_fsm.h:475
goby::acomms::iridium::fsm::Online::~Online
~Online() override=default
boost::statechart::simple_state
Definition: simple_state.hpp:191
goby::acomms::iridium::fsm::Dial::~Dial
~Dial() override=default
goby::acomms::iridium::fsm::SBDTransmit::reactions
boost::mpl::list< boost::statechart::custom_reaction< EvSBDTransmitComplete > > reactions
Definition: iridium_driver_fsm.h:614
goby::acomms::iridium::fsm::SBDClearBuffers::reactions
boost::mpl::list< boost::statechart::transition< EvSBDSendBufferCleared, SBDWrite > > reactions
Definition: iridium_driver_fsm.h:568
goby::acomms::iridium::fsm::EvOnline
Definition: iridium_driver_fsm.h:129
goby::acomms::iridium::fsm::IridiumDriverFSM::data_out
boost::circular_buffer< goby::acomms::protobuf::ModemTransmission > & data_out()
Definition: iridium_driver_fsm.h:233
boost::statechart::event
Definition: event.hpp:30
goby::acomms::iridium::fsm::Answer::reactions
boost::mpl::list< boost::statechart::transition< EvNoCarrier, Ready > > reactions
Definition: iridium_driver_fsm.h:438
goby::acomms::iridium::fsm::EvSBDWriteComplete
Definition: iridium_driver_fsm.h:171
goby::acomms::iridium::fsm::PostDisconnected::PostDisconnected
PostDisconnected(my_context ctx)
Definition: iridium_driver_fsm.h:406
goby::acomms::iridium::fsm::Active
Definition: iridium_driver_fsm.h:277
goby::acomms::iridium::fsm::SBDTransmit
Definition: iridium_driver_fsm.h:612
goby::acomms::iridium::fsm::EvTxSerial
Definition: iridium_driver_fsm.h:97
driver_base.pb.h
goby::acomms::iridium::fsm::Ready::react
boost::statechart::result react(const EvDial &)
Definition: iridium_driver_fsm.h:366
goby::acomms::iridium::fsm::Command::clear_sbd_rx_buffer
void clear_sbd_rx_buffer()
Definition: iridium_driver_fsm.h:316
goby::acomms::iridium::fsm::Dial::react
boost::statechart::result react(const EvNoCarrier &)
goby::acomms::iridium::fsm::EvSBDReceiveComplete
Definition: iridium_driver_fsm.h:179
goby::acomms::iridium::fsm::PostDisconnected::~PostDisconnected
~PostDisconnected() override=default
goby::acomms::iridium::fsm::IridiumDriverFSM::iridium_driver_cfg
const goby::acomms::iridium::protobuf::Config & iridium_driver_cfg() const
Definition: iridium_driver_fsm.h:239
goby::acomms::iridium::fsm::Dial
Definition: iridium_driver_fsm.h:419
goby::acomms::iridium::fsm::EvReset
Definition: iridium_driver_fsm.h:119
goby::acomms::iridium::fsm::IridiumDriverFSM::ciev_data
const CIEVData & ciev_data() const
Definition: iridium_driver_fsm.h:246
goby::acomms::iridium::fsm::Ready::reactions
boost::mpl::list< boost::statechart::transition< EvRing, Answer >, boost::statechart::custom_reaction< EvDial > > reactions
Definition: iridium_driver_fsm.h:382
goby::acomms::iridium::fsm::NotOnCall::reactions
boost::mpl::list< boost::statechart::transition< EvConnect, OnCall > > reactions
Definition: iridium_driver_fsm.h:466
goby::acomms::iridium::fsm::EvSBDTransmitComplete::sbdi_
std::string sbdi_
Definition: iridium_driver_fsm.h:177
goby::acomms::iridium::fsm::Ready
Definition: iridium_driver_fsm.h:360
goby::acomms::iridium::fsm::SBDReceive::~SBDReceive
~SBDReceive() override=default
goby::acomms::iridium::fsm::SBD::SBD
SBD()
Definition: iridium_driver_fsm.h:509
goby::acomms::iridium::fsm::SBDWrite::~SBDWrite
~SBDWrite() override=default
goby::acomms::OnCallBase
Definition: iridium_driver_common.h:53
goby::acomms::iridium::protobuf::Config
Definition: iridium_driver.pb.h:327
goby::acomms::iridium::fsm::Ready::~Ready
~Ready() override=default
boost::statechart::state_machine
Definition: state_machine.hpp:235
flex_ostream.h
goby::msg
extern ::google::protobuf::internal::ExtensionIdentifier< ::google::protobuf::MessageOptions, ::google::protobuf::internal::MessageTypeTraits< ::goby::GobyMessageOptions >, 11, false > msg
Definition: option_extensions.pb.h:1327
goby::acomms::iridium::fsm::SBDReady::~SBDReady
~SBDReady() override=default
goby::acomms::iridium::fsm::SBDWrite
Definition: iridium_driver_fsm.h:579
goby::acomms::iridium::fsm::Command::at_out
boost::circular_buffer< std::pair< ATSentenceMeta, std::string > > & at_out()
Definition: iridium_driver_fsm.h:314
goby::acomms::iridium::fsm::Answer
Definition: iridium_driver_fsm.h:436
goby::acomms::iridium::fsm::Command::~Command
~Command() override=default
goby::acomms::iridium::fsm::StateNotify::~StateNotify
~StateNotify()
Definition: iridium_driver_fsm.h:82
simple_state.hpp
goby::acomms::iridium::fsm::EvAtEmpty
Definition: iridium_driver_fsm.h:116
goby::acomms::iridium::fsm::Answer::Answer
Answer(my_context ctx)
Definition: iridium_driver_fsm.h:440
goby::acomms::bind
void bind(ModemDriverBase &driver, QueueManager &queue_manager)
binds the driver link-layer callbacks to the QueueManager
Definition: bind.h:45
goby::acomms::iridium::fsm::EvConnect
Definition: iridium_driver_fsm.h:137
goby::acomms::iridium::fsm::Configure
Definition: iridium_driver_fsm.h:343
goby::acomms::iridium::fsm::EvSBDBeginData::EvSBDBeginData
EvSBDBeginData(std::string data="", bool in_response_to_ring_alert=false)
Definition: iridium_driver_fsm.h:156
logger_manipulators.h
goby::acomms::iridium::fsm::SBDReceive::reactions
boost::mpl::list< boost::statechart::transition< EvSBDReceiveComplete, SBDReady > > reactions
Definition: iridium_driver_fsm.h:748
goby::acomms::iridium::fsm::Configure::~Configure
~Configure() override
Definition: iridium_driver_fsm.h:357
iridium_driver.pb.h
goby::acomms::iridium::fsm::EvSBDTransmitComplete::EvSBDTransmitComplete
EvSBDTransmitComplete(std::string sbdi)
Definition: iridium_driver_fsm.h:176
goby::acomms::iridium::fsm::SBD::set_data
void set_data(const EvSBDBeginData &e)
Definition: iridium_driver_fsm.h:512
goby::acomms::iridium::fsm::Online::in_state_react
void in_state_react(const EvRxSerial &)
goby::acomms::iridium::fsm::SBDReceive
Definition: iridium_driver_fsm.h:745
goby::acomms::iridium::fsm::EvConfigured
Definition: iridium_driver_fsm.h:151
goby::acomms::iridium::fsm::SBDWrite::SBDWrite
SBDWrite(my_context ctx)
Definition: iridium_driver_fsm.h:581
goby::acomms::iridium::fsm::SBD::clear_data
void clear_data()
Definition: iridium_driver_fsm.h:517
goby::acomms::iridium::fsm::SBDReady
Definition: iridium_driver_fsm.h:555
goby::acomms::iridium::fsm::EvSBDTransmitComplete
Definition: iridium_driver_fsm.h:174
goby::acomms::iridium::fsm::EvNoCarrier
Definition: iridium_driver_fsm.h:140
goby::acomms::iridium::fsm::PostDisconnected
Definition: iridium_driver_fsm.h:402
goby::acomms::iridium::fsm::Dial::reactions
boost::mpl::list< boost::statechart::custom_reaction< EvNoCarrier > > reactions
Definition: iridium_driver_fsm.h:421
goby::acomms::iridium::fsm::EvHangup
Definition: iridium_driver_fsm.h:133
goby::acomms::iridium::fsm::IridiumDriverFSM::parse_ciev
void parse_ciev(const std::string &ciev)
boost::statechart::state
Definition: state.hpp:28
goby::acomms::iridium::fsm::Command::ATSentenceMeta
Definition: iridium_driver_fsm.h:302
goby::acomms::iridium::fsm::SBDClearBuffers::~SBDClearBuffers
~SBDClearBuffers() override=default
state.hpp
goby::util::logger::DEBUG1
@ DEBUG1
Definition: flex_ostreambuf.h:77
goby::acomms::iridium::fsm::NotOnCall::NotOnCall
NotOnCall()
Definition: iridium_driver_fsm.h:468
httplib::detail::split
void split(const char *b, const char *e, char d, std::function< void(const char *, const char *)> fn)
Definition: httplib.h:2494
goby::glog
util::FlexOstream glog
Access the Goby logger through this object.
goby::acomms::iridium::fsm::EvRing
Definition: iridium_driver_fsm.h:126
goby::acomms::iridium::fsm::NotOnCall::~NotOnCall
~NotOnCall() override=default
goby::acomms::OnCallBase::total_bytes_sent
int total_bytes_sent() const
Definition: iridium_driver_common.h:70
goby::acomms::iridium::fsm::Command::ATSentenceMeta::last_send_time_
double last_send_time_
Definition: iridium_driver_fsm.h:305
goby::acomms::iridium::fsm::Configure::reactions
boost::mpl::list< boost::statechart::transition< EvAtEmpty, Ready > > reactions
Definition: iridium_driver_fsm.h:345
goby::acomms::iridium::sbd_csum
unsigned sbd_csum(const std::string &data)
Definition: iridium_driver_fsm.h:67
goby::acomms::iridium::fsm::IridiumDriverFSM::driver_cfg
const goby::acomms::protobuf::DriverConfig & driver_cfg() const
Definition: iridium_driver_fsm.h:238
state_machine.hpp
goby::acomms::iridium::fsm::EvDisconnect
Definition: iridium_driver_fsm.h:143
goby::acomms::iridium::fsm::NotOnCall
Definition: iridium_driver_fsm.h:464
goby::acomms::iridium::fsm::HangingUp
Definition: iridium_driver_fsm.h:387
goby::acomms::iridium::fsm::OnCall::in_state_react
void in_state_react(const EvRxOnCallSerial &)
goby::acomms::iridium::fsm::Configure::Configure
Configure(my_context ctx)
Definition: iridium_driver_fsm.h:347
goby::acomms::iridium::fsm::EvAck::EvAck
EvAck(std::string response)
Definition: iridium_driver_fsm.h:111
goby::acomms::iridium::fsm::Dial::Dial
Dial(my_context ctx)
Definition: iridium_driver_fsm.h:423
goby::acomms::iridium::fsm::IridiumDriverFSM::serial_tx_buffer
boost::circular_buffer< std::string > & serial_tx_buffer()
Definition: iridium_driver_fsm.h:224
goby::acomms::iridium::fsm::EvDial
Definition: iridium_driver_fsm.h:123
goby::acomms::iridium::fsm::Online::Online
Online()
Definition: iridium_driver_fsm.h:450
goby::acomms::iridium::fsm::Command::in_state_react
void in_state_react(const EvRxSerial &)
goby::acomms::iridium::fsm::EvTxOnCallSerial
Definition: iridium_driver_fsm.h:105