Goby3 3.1.5a
2024.05.23
Loading...
Searching...
No Matches
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
61namespace goby
62{
63namespace acomms
64{
65namespace iridium
66{
67inline 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
74namespace 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
102{
103 std::string line;
104};
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};
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
164struct EvSBDSendBufferCleared : boost::statechart::event<EvSBDSendBufferCleared>
165{
166};
167
169{
170};
172{
173};
174struct EvSBDTransmitComplete : boost::statechart::event<EvSBDTransmitComplete>
175{
176 EvSBDTransmitComplete(std::string sbdi) : sbdi_(std::move(sbdi)) {}
177 std::string sbdi_;
178};
179struct EvSBDReceiveComplete : boost::statechart::event<EvSBDReceiveComplete>
180{
181};
182
183// pre-declare
184struct Active;
185struct Command;
186struct Configure;
187struct Ready;
188struct Answer;
189struct Dial;
190struct Online;
191struct OnCall;
192struct NotOnCall;
193struct SBD;
194struct SBDReady;
195struct SBDClearBuffers;
196struct SBDWrite;
197struct SBDTransmit;
198struct SBDReceive;
199
200// state machine
201struct 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_; }
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
277struct 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
284struct Command : boost::statechart::simple_state<Command, Active::orthogonal<0>,
285 boost::mpl::list<Configure, SBD>>,
287{
288 public:
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;
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
343struct 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
358};
359
360struct 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
387struct 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
402struct 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
419struct 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
436struct 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
448struct Online : boost::statechart::simple_state<Online, Active::orthogonal<0>>, StateNotify
449{
450 Online() : StateNotify("Online") {}
451 ~Online() override = default;
452
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
464struct 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
472struct 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
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
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
507struct SBD : boost::statechart::simple_state<SBD, Command::orthogonal<1>, SBDReady>, StateNotify
508{
509 SBD() : StateNotify("SBD") {}
510 ~SBD() override = default;
511
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
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
void post_event(const event_base_ptr_type &pEvent)
_proto_TypeTraits::Singular::ConstType GetExtension(const ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< DriverConfig, _proto_TypeTraits, _field_type, _is_packed > &id) const
bool is(goby::util::logger::Verbosity verbosity)
goby::util::logger::GroupSetter group(std::string n)
extern ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< ::goby::acomms::protobuf::DriverConfig, ::PROTOBUF_NAMESPACE_ID::internal::MessageTypeTraits< ::goby::acomms::iridium::protobuf::Config >, 11, false > config
unsigned sbd_csum(const std::string &data)
The global namespace for the Goby project.
extern ::PROTOBUF_NAMESPACE_ID::internal::ExtensionIdentifier< ::PROTOBUF_NAMESPACE_ID::MessageOptions, ::PROTOBUF_NAMESPACE_ID::internal::MessageTypeTraits< ::goby::GobyMessageOptions >, 11, false > msg
util::FlexOstream glog
Access the Goby logger through this object.
STL namespace.
boost::mpl::list< boost::statechart::transition< EvReset, Active > > reactions
boost::mpl::list< boost::statechart::transition< EvNoCarrier, Ready > > reactions
boost::circular_buffer< std::pair< ATSentenceMeta, std::string > > & at_out()
void in_state_react(const EvRxSerial &)
void in_state_react(const EvTxSerial &)
void in_state_react(const EvAck &)
void push_at_command(const std::string &cmd)
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
void handle_sbd_rx(const std::string &in)
boost::mpl::list< boost::statechart::transition< EvAtEmpty, Ready > > reactions
boost::mpl::list< boost::statechart::custom_reaction< EvNoCarrier > > reactions
boost::statechart::result react(const EvNoCarrier &)
EvSBDBeginData(std::string data="", bool in_response_to_ring_alert=false)
boost::mpl::list< boost::statechart::transition< EvAtEmpty, Ready > > reactions
const goby::acomms::iridium::protobuf::Config & iridium_driver_cfg() const
const goby::acomms::protobuf::DriverConfig & driver_cfg() const
boost::circular_buffer< goby::acomms::protobuf::ModemTransmission > & received()
void buffer_data_out(const goby::acomms::protobuf::ModemTransmission &msg)
boost::circular_buffer< std::string > & serial_tx_buffer()
boost::circular_buffer< goby::acomms::protobuf::ModemTransmission > & data_out()
void parse_ciev(const std::string &ciev)
IridiumDriverFSM(const goby::acomms::protobuf::DriverConfig &driver_cfg)
boost::mpl::list< boost::statechart::transition< EvConnect, 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
void in_state_react(const EvSendBye &)
void in_state_react(const EvRxOnCallSerial &)
void in_state_react(const EvTxOnCallSerial &)
void in_state_react(const EvTxSerial &)
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
void in_state_react(const EvRxSerial &)
boost::mpl::list< boost::statechart::transition< EvAtEmpty, Ready > > reactions
boost::statechart::result react(const EvDial &)
boost::mpl::list< boost::statechart::transition< EvRing, Answer >, boost::statechart::custom_reaction< EvDial > > reactions
boost::mpl::list< boost::statechart::transition< EvSBDSendBufferCleared, SBDWrite > > reactions
boost::mpl::list< boost::statechart::transition< EvSBDBeginData, SBDClearBuffers, SBD, &SBD::set_data > > reactions
boost::mpl::list< boost::statechart::transition< EvSBDReceiveComplete, SBDReady > > reactions
boost::statechart::result react(const EvSBDTransmitComplete &e)
boost::mpl::list< boost::statechart::custom_reaction< EvSBDTransmitComplete > > reactions
boost::mpl::list< boost::statechart::in_state_reaction< EvSBDWriteReady, SBDWrite, &SBDWrite::in_state_react >, boost::statechart::transition< EvSBDWriteComplete, SBDTransmit > > reactions
void in_state_react(const EvSBDWriteReady &)
const std::string & data() const
void set_data(const EvSBDBeginData &e)