RTC Toolkit 4.0.2
Loading...
Searching...
No Matches
supervisory.hpp
Go to the documentation of this file.
1
13#ifndef RTCTK_RTCSUPERVISOR_SUPERVISORY_HPP
14#define RTCTK_RTCSUPERVISOR_SUPERVISORY_HPP
15
20
22
23namespace rtctk::rtcSupervisor {
24
25using namespace rtctk::componentFramework;
26
27namespace detail {
39public:
46 explicit SetModesContext(rad::cii::Request<std::string, std::string> const& request)
47 : m_logger(GetLogger("rtctk")), m_request(request), m_arg() {
48 m_arg = JsonPayload::parse(m_request.GetRequestPayload());
49 }
50 SetModesContext(SetModesContext&&) noexcept = default;
51
55 JsonPayload const& GetArg() const noexcept {
56 return m_arg;
57 }
58
62 void SendReply() noexcept {
63 try {
64 m_request.SetReplyValue(STD_OK_REPLY);
65 } catch (std::exception const& exception) {
66 LOG4CPLUS_ERROR(
67 m_logger, "SetModesContext::SendReply: Failed to send reply: " << exception.what());
68 } catch (...) {
69 LOG4CPLUS_ERROR(
70 m_logger,
71 "SetModesContext::SendReply: Failed to send reply with unknown exception.");
72 }
73 }
74
80 void SendErrorReply(std::exception_ptr eptr) noexcept {
81 try {
82 m_request.SetException(RequestFailed(NestedExceptionPrinter(std::move(eptr)).Str()));
83 } catch (...) {
84 LOG4CPLUS_ERROR(
85 m_logger,
86 "SetModesContext::SendErrorReply: Failed to send reply with unknown exception.");
87 }
88 }
89
90private:
91 log4cplus::Logger& m_logger;
92
94 rad::cii::Request<std::string, std::string> m_request;
98 JsonPayload m_arg;
99};
111public:
118 explicit WriteBackContext(rad::cii::Request<std::string, std::string> const& request)
119 : m_logger(GetLogger("rtctk")), m_request(request), m_arg() {
120 m_arg = JsonPayload::parse(m_request.GetRequestPayload());
121 }
122 WriteBackContext(WriteBackContext&&) noexcept = default;
123
127 JsonPayload const& GetArg() const noexcept {
128 return m_arg;
129 }
130
134 void SendReply() noexcept {
135 try {
136 m_request.SetReplyValue(STD_OK_REPLY);
137 } catch (std::exception const& exception) {
138 LOG4CPLUS_ERROR(
139 m_logger,
140 "WriteBackContext::SendReply: Failed to send reply: " << exception.what());
141 } catch (...) {
142 LOG4CPLUS_ERROR(
143 m_logger,
144 "WriteBackContext::SendReply: Failed to send reply with unknown exception.");
145 }
146 }
147
153 void SendErrorReply(std::exception_ptr eptr) noexcept {
154 try {
155 m_request.SetException(RequestFailed(NestedExceptionPrinter(std::move(eptr)).Str()));
156 } catch (...) {
157 LOG4CPLUS_ERROR(
158 m_logger,
159 "WriteBackContext::SendErrorReply: Failed to send reply with unknown exception.");
160 }
161 }
162
166 void SendStopReply() noexcept {
167 try {
168 m_request.SetException(StdIfRequestAborted());
169 } catch (...) {
170 LOG4CPLUS_ERROR(
171 m_logger,
172 "SetModesContext::SendStopReply: Failed to send reply with unknown exception.");
173 }
174 }
175
176private:
177 log4cplus::Logger& m_logger;
178
180 rad::cii::Request<std::string, std::string> m_request;
184 JsonPayload m_arg;
185};
186} // namespace detail
187
212template <typename Super>
214 static_assert(std::is_base_of_v<RtcComponent, Super>, "'Supervisory' requires 'RtcComponent'");
215
221 public:
229 virtual std::string ActionGetStatus() {
230 return {};
231 }
242 virtual void ActivitySettingModes(StopToken st, JsonPayload const& arg) {
243 }
253 virtual bool GuardSettingModesAllowed(JsonPayload const& arg) {
254 return true;
255 }
265 virtual void ActionSetDeferredModes(JsonPayload const& arg) {
266 }
267
276 return {};
277 }
278
287 return {};
288 }
289
298 return {};
299 }
310 virtual void ActivityWritingBack(StopToken st, JsonPayload const& arg) {
311 }
322 virtual bool GuardWritingBackAllowed(JsonPayload const& arg) {
323 return true;
324 }
325 };
326
331 public:
333
334 void Start() override {
335 Super::InputStage::Start();
336
337 ModeCmdsImpl::Register(this->m_replier, this->m_engine);
338 WriteBackCmdsImpl::Register(this->m_replier, this->m_engine);
339 }
340 };
341
346 public:
348 // Handlers ###################################################################
349
350 engine.RegisterRejectHandler<events::SetModes, RequestRejected>();
351 engine.RegisterRejectHandler<events::SetDeferredModes, RequestRejected>();
352 engine.RegisterRejectHandler<events::GetDeferredModes, RequestRejected>();
353 engine.RegisterRejectHandler<events::GetAvailableModes, RequestRejected>();
354 engine.RegisterRejectHandler<events::GetActiveModes, RequestRejected>();
355 engine.RegisterRejectHandler<events::WriteBack, RequestRejected>();
356
358 this->m_engine.PostEvent(std::make_unique<events::SetModesDone>());
359 };
360
361 m_setmode_error_handler = [this](std::exception_ptr eptr) {
362 this->m_engine.PostEvent(std::make_unique<events::SetModesError>(std::move(eptr)));
363 };
364
366 this->m_engine.PostEvent(std::make_unique<events::WriteBackDone>());
367 };
368
369 m_writeback_error_handler = [this](std::exception_ptr eptr) {
370 this->m_engine.PostEvent(std::make_unique<events::WriteBackError>(std::move(eptr)));
371 };
372
373 // No Disable in states ###############################################################
374
375 this->m_no_disable_in_states.push_back("On:SetModes:Busy");
376
377 // No Update in states ################################################################
378
379 this->m_no_update_in_states.push_back("On:SetModes:Busy");
380
381 // No SetModes in states ##############################################################
382
383 this->m_no_setmode_in_states.push_back("On:Update:Busy");
384 this->m_no_setmode_in_states.push_back("On:WriteBack:Busy");
385 this->m_no_setmode_in_states.push_back("On::NotOperational::Starting");
386 this->m_no_setmode_in_states.push_back("On::NotOperational::NotReady");
387 this->m_no_setmode_in_states.push_back("On::NotOperational::Initialising");
388 this->m_no_setmode_in_states.push_back("On::NotOperational::Enabling");
389 this->m_no_setmode_in_states.push_back("On::NotOperational::Disabling");
390 this->m_no_setmode_in_states.push_back("On::Operational::Error");
391 this->m_no_setmode_in_states.push_back("On::Operational::Recovering");
392
393 // No WriteBack in states #############################################################
394
395 this->m_no_writeback_in_states.push_back("On::NotOperational::Starting");
396 this->m_no_writeback_in_states.push_back("On::NotOperational::NotReady");
397 this->m_no_writeback_in_states.push_back("On::NotOperational::Initialising");
398 this->m_no_writeback_in_states.push_back("On::NotOperational::Enabling");
399 this->m_no_writeback_in_states.push_back("On::NotOperational::Disabling");
400 this->m_no_writeback_in_states.push_back("On:SetModes:Busy");
401
402 // Guards #####################################################################
403
404 engine.RegisterGuardStatic<events::SetModes>(
405 "GuardSettingModesAllowed", [this](events::SetModes const& ev) -> bool {
414 auto act_state = this->m_engine.GetState();
415 for (auto& s : m_no_setmode_in_states) {
416 if (act_state.find(s) != std::string::npos) {
417 return false;
418 }
419 }
420 detail::SetModesContext ctx(ev.GetPayload());
421 if (static_cast<BizLogicIf&>(this->m_logic)
422 .GuardSettingModesAllowed(ctx.GetArg())) {
423 // SetModes is allowed so context is stored.
424 // If there's an active context (and correspondingly an active
425 // request being processed something have gone terribly wrong)
426 assert(!m_setmode_ctx);
427 m_setmode_ctx.emplace(std::move(ctx));
428 return true;
429 }
430 return false;
431 });
432
433 engine.RegisterGuardStatic<events::WriteBack>(
434 "GuardWritingBackAllowed", [this](events::WriteBack const& ev) -> bool {
443 auto act_state = this->m_engine.GetState();
444 for (auto& s : m_no_writeback_in_states) {
445 if (act_state.find(s) != std::string::npos) {
446 return false;
447 }
448 }
449 detail::WriteBackContext ctx(ev.GetPayload());
450 if (static_cast<BizLogicIf&>(this->m_logic)
451 .GuardWritingBackAllowed(ctx.GetArg())) {
452 // WriteBack is allowed so context is stored.
453 // If there's an active context (and correspondingly an active
454 // request being processed something have gone terribly wrong)
455 assert(!m_writeback_ctx);
456 m_writeback_ctx.emplace(std::move(ctx));
457 return true;
458 }
459 return false;
460 });
461
462 // Activities #####################################################################
463
464 engine.RegisterActivity(
465 "ActivitySettingModes",
466 [this](StopToken stop_token) {
467 assert(m_setmode_ctx);
468 static_cast<BizLogicIf&>(this->m_logic)
469 .ActivitySettingModes(stop_token, m_setmode_ctx->GetArg());
470 },
473
474 engine.RegisterActivity(
475 "ActivityWritingBack",
476 [this](StopToken stop_token) {
477 assert(m_writeback_ctx);
478 static_cast<BizLogicIf&>(this->m_logic)
479 .ActivityWritingBack(stop_token, m_writeback_ctx->GetArg());
480 },
483
484 // Actions #####################################################################
485
486 // override default implementation for ActionGetStatus in stdComponent.hpp
487 engine.RegisterAction("ActionGetStatus", [this](auto c) {
488 auto req = GetPayloadNothrow<events::GetStatus>(c);
489 if (req == nullptr) {
490 // no event or request
491 return;
492 }
493 auto status = static_cast<BizLogicIf&>(this->m_logic).ActionGetStatus();
494 req->SetReplyValue(status);
495 });
496
497 engine.RegisterActionStatic<events::SetDeferredModes>(
498 "ActionSetDeferredModes", [this](events::SetDeferredModes const& ev) {
499 auto req = GetPayloadNothrow<events::SetDeferredModes>(ev);
500 if (req == nullptr) {
501 // no event or request
502 return;
503 }
504 try {
505 auto json_arg = JsonPayload::parse(req->GetRequestPayload());
506 static_cast<BizLogicIf&>(this->m_logic).ActionSetDeferredModes(json_arg);
507 req->SetReplyValue(STD_OK_REPLY);
508 } catch (...) {
509 auto nested =
510 WrapWithNested(RtctkException("ActionSetDeferredModes: failed"));
511 auto eptr = std::make_exception_ptr(nested);
512 req->SetException(
513 RequestFailed(NestedExceptionPrinter(std::move(eptr)).Str()));
514 throw; // to be caught in stateMachineEngine.cpp
515 }
516 });
517
518 engine.RegisterActionStatic<events::GetAvailableModes>(
519 "ActionGetAvailableModes", [this](events::GetAvailableModes const& ev) {
520 auto req = GetPayloadNothrow<events::GetAvailableModes>(ev);
521 if (req == nullptr) {
522 // no event or request
523 return;
524 }
525 try {
526 auto result =
527 static_cast<BizLogicIf&>(this->m_logic).ActionGetAvailableModes();
528 req->SetReplyValue(result.dump());
529 } catch (...) {
530 auto nested =
531 WrapWithNested(RtctkException("ActionGetAvailableModes: failed"));
532 auto eptr = std::make_exception_ptr(nested);
533 req->SetException(
534 RequestFailed(NestedExceptionPrinter(std::move(eptr)).Str()));
535 throw; // to be caught in stateMachineEngine.cpp
536 }
537 });
538
539 engine.RegisterActionStatic<events::GetActiveModes>(
540 "ActionGetActiveModes", [this](events::GetActiveModes const& ev) {
541 auto req = GetPayloadNothrow<events::GetActiveModes>(ev);
542 if (req == nullptr) {
543 // no event or request
544 return;
545 }
546 try {
547 auto result =
548 static_cast<BizLogicIf&>(this->m_logic).ActionGetActiveModes();
549 req->SetReplyValue(result.dump());
550 } catch (...) {
551 auto nested =
552 WrapWithNested(RtctkException("ActionGetActiveModes: failed"));
553 auto eptr = std::make_exception_ptr(nested);
554 req->SetException(
555 RequestFailed(NestedExceptionPrinter(std::move(eptr)).Str()));
556 throw; // to be caught in stateMachineEngine.cpp
557 }
558 });
559
560 engine.RegisterActionStatic<events::GetDeferredModes>(
561 "ActionGetDeferredModes", [this](events::GetDeferredModes const& ev) {
562 auto req = GetPayloadNothrow<events::GetDeferredModes>(ev);
563 if (req == nullptr) {
564 // no event or request
565 return;
566 }
567 try {
568 auto result =
569 static_cast<BizLogicIf&>(this->m_logic).ActionGetDeferredModes();
570 req->SetReplyValue(result.dump());
571 } catch (...) {
572 auto nested =
573 WrapWithNested(RtctkException("ActionGetDeferredModes: failed"));
574 auto eptr = std::make_exception_ptr(nested);
575 req->SetException(
576 RequestFailed(NestedExceptionPrinter(std::move(eptr)).Str()));
577 throw; // to be caught in stateMachineEngine.cpp
578 }
579 });
580
581 engine.RegisterActionStatic<events::SetModesDone>("ActionSettingModesDone",
582 [this](events::SetModesDone const&) {
583 assert(m_setmode_ctx);
584 m_setmode_ctx->SendReply();
585 m_setmode_ctx.reset();
586 });
587
588 engine.RegisterActionStatic<events::SetModesError>(
589 "ActionSettingModesFailed", [this](events::SetModesError const& ev) {
590 m_setmode_ctx->SendErrorReply(ev.GetPayload());
591 m_setmode_ctx.reset();
592 });
593
594 engine.RegisterActionStatic<events::WriteBackDone>(
595 "ActionWriteBackDone", [this](events::WriteBackDone const&) {
596 assert(m_writeback_ctx);
597 m_writeback_ctx->SendReply();
598 m_writeback_ctx.reset();
599 });
600
601 engine.RegisterActionStatic<events::WriteBackError>(
602 "ActionWriteBackFailed", [this](events::WriteBackError const& ev) {
603 m_writeback_ctx->SendErrorReply(ev.GetPayload());
604 m_writeback_ctx.reset();
605 });
606
607 engine.RegisterActionStatic<events::Stop>(
608 "ActionWriteBackStopped", [this](events::Stop const& ev) {
609 auto req = GetPayloadNothrow<events::Stop>(ev);
610 if (req == nullptr) {
611 // no event or request
612 return;
613 }
614 m_writeback_ctx->SendStopReply();
615 m_writeback_ctx.reset();
616 req->SetReplyValue(STD_OK_REPLY);
617 });
618 }
619
620 protected:
621 std::optional<detail::SetModesContext> m_setmode_ctx;
622 std::optional<detail::WriteBackContext> m_writeback_ctx;
623 std::function<void()> m_setmode_success_handler;
624 std::function<void(std::exception_ptr)> m_setmode_error_handler;
625 std::function<void()> m_writeback_success_handler;
626 std::function<void(std::exception_ptr)> m_writeback_error_handler;
627 std::list<std::string> m_no_setmode_in_states;
628 std::list<std::string> m_no_writeback_in_states;
629 };
630
635 public:
636 explicit ModelBuilder(StateMachineEngine& engine) : Super::ModelBuilder(engine) {
637 // clang-format off
638 this->mm.AddState(Composite, "On:SetModes", "On");
639 this->mm.AddState(Initial, "On:SetModes:Initial", "On:SetModes");
640 this->mm.AddState(Simple, "On:SetModes:Idle", "On:SetModes");
641 this->mm.AddState(Simple, "On:SetModes:Busy", "On:SetModes", "ActivitySettingModes");
642
643 this->mm.AddTrans("On", "" , events::GetAvailableModes::ID, "", "ActionGetAvailableModes");
644 this->mm.AddTrans("On::NotOperational::NotReady", "" , events::SetDeferredModes::ID, "", "ActionSetDeferredModes");
645 this->mm.AddTrans("On::NotOperational::NotReady", "" , events::GetDeferredModes::ID, "", "ActionGetDeferredModes");
646 this->mm.AddTrans("On::NotOperational::Ready", "" , events::GetActiveModes::ID, "", "ActionGetActiveModes");
647 this->mm.AddTrans("On::NotOperational::Enabling", "" , events::GetActiveModes::ID, "", "ActionGetActiveModes");
648 this->mm.AddTrans("On::Operational", "" , events::GetActiveModes::ID, "", "ActionGetActiveModes");
649
650 this->mm.AddTrans("On:SetModes:Initial", "On:SetModes:Idle");
651 this->mm.AddTrans("On:SetModes:Idle", "On:SetModes:Busy", events::SetModes::ID, "GuardSettingModesAllowed");
652 this->mm.AddTrans("On:SetModes:Busy", "On:SetModes:Idle", events::SetModesDone::ID, "", "ActionSettingModesDone");
653 this->mm.AddTrans("On:SetModes:Busy", "On:SetModes:Idle", events::SetModesError::ID, "", "ActionSettingModesFailed");
654
655 this->mm.AddState(Composite, "On:WriteBack", "On");
656 this->mm.AddState(Initial, "On:WriteBack:Initial", "On:WriteBack");
657 this->mm.AddState(Simple, "On:WriteBack:Idle", "On:WriteBack");
658 this->mm.AddState(Simple, "On:WriteBack:Busy", "On:WriteBack", "ActivityWritingBack");
659
660 this->mm.AddTrans("On:WriteBack:Initial", "On:WriteBack:Idle");
661 this->mm.AddTrans("On:WriteBack:Idle", "On:WriteBack:Busy", events::WriteBack::ID, "GuardWritingBackAllowed");
662 this->mm.AddTrans("On:WriteBack:Busy", "On:WriteBack:Idle", events::WriteBackDone::ID, "", "ActionWriteBackDone");
663 this->mm.AddTrans("On:WriteBack:Busy", "On:WriteBack:Idle", events::WriteBackError::ID, "", "ActionWriteBackFailed");
664 this->mm.AddTrans("On:WriteBack:Busy", "On:WriteBack:Idle", events::Stop::ID, "", "ActionWriteBackStopped");
665 // clang-format on
666 }
667 };
668};
669
670} // namespace rtctk::rtcSupervisor
671
672#endif
Adapter object intended to be used in contexts without direct access to the output-stream object.
Definition: exceptions.hpp:185
Thrown if the command was accepted but the task to run failed.
Definition: rtcComponent.hpp:53
Thrown if a command is not allowed in current state or guard.
Definition: rtcComponent.hpp:40
The RtctkException class is the base class for all Rtctk exceptions.
Definition: exceptions.hpp:237
Definition: stateMachineEngine.hpp:35
void RegisterRejectHandler(std::string const &id, RejectMethod reject)
Register reject handler.
Definition: stateMachineEngine.cpp:131
void RegisterActivity(std::string const &id, ActivityMethod activity, SuccessMethod on_success, FailureMethod on_failure)
Register activity.
Definition: stateMachineEngine.cpp:123
void RegisterGuardStatic(std::string const &id, std::function< bool(Event const &)> guard)
Register guard for statically known event type.
Definition: stateMachineEngine.hpp:126
void RegisterAction(std::string const &id, ActionMethod action)
Register action.
Definition: stateMachineEngine.cpp:86
void RegisterActionStatic(std::string const &id, std::function< void(Event const &)> action)
Register action for statically known event type.
Definition: stateMachineEngine.hpp:93
Thrown if somebody sent a stop or abort command.
Definition: stdComponent.hpp:96
static void Register(CommandReplier &replier, StateMachineEngine &engine)
Definition: supervisoryCmdsImpl.hpp:40
Business logic interface for Supervisory mixin.
Definition: supervisory.hpp:220
virtual JsonPayload ActionGetActiveModes()
Action is used for mode inspection and executed in the state machine thread.
Definition: supervisory.hpp:286
virtual void ActivityWritingBack(StopToken st, JsonPayload const &arg)
Activity executed in its own thread that performs the writeback.
Definition: supervisory.hpp:310
virtual void ActionSetDeferredModes(JsonPayload const &arg)
Action is executed in the state machine thread and it performs deferred mode setting.
Definition: supervisory.hpp:265
virtual JsonPayload ActionGetDeferredModes()
Action is used for mode inspection and executed in the state machine thread.
Definition: supervisory.hpp:297
virtual void ActivitySettingModes(StopToken st, JsonPayload const &arg)
Activity executed in its own thread that performs the mode setting.
Definition: supervisory.hpp:242
virtual std::string ActionGetStatus()
Action is used for system status inspection and is executed in the state machine thread.
Definition: supervisory.hpp:229
virtual JsonPayload ActionGetAvailableModes()
Action is used for mode inspection and executed in the state machine thread.
Definition: supervisory.hpp:275
virtual bool GuardSettingModesAllowed(JsonPayload const &arg)
Determines if set mode is possible at this time with the provided argument.
Definition: supervisory.hpp:253
virtual bool GuardWritingBackAllowed(JsonPayload const &arg)
Determines if writeback is possible at this time with the provided argument.
Definition: supervisory.hpp:322
Definition: supervisory.hpp:330
void Start() override
Definition: supervisory.hpp:334
ModelBuilder(StateMachineEngine &engine)
Definition: supervisory.hpp:636
Definition: supervisory.hpp:345
std::list< std::string > m_no_writeback_in_states
Definition: supervisory.hpp:628
std::function< void()> m_writeback_success_handler
Definition: supervisory.hpp:625
std::function< void()> m_setmode_success_handler
Definition: supervisory.hpp:623
std::function< void(std::exception_ptr)> m_setmode_error_handler
Definition: supervisory.hpp:624
std::list< std::string > m_no_setmode_in_states
Definition: supervisory.hpp:627
std::function< void(std::exception_ptr)> m_writeback_error_handler
Definition: supervisory.hpp:626
OutputStage(StateMachineEngine &engine, BizLogicIf &bl)
Definition: supervisory.hpp:347
std::optional< detail::SetModesContext > m_setmode_ctx
Definition: supervisory.hpp:621
std::optional< detail::WriteBackContext > m_writeback_ctx
Definition: supervisory.hpp:622
static void Register(CommandReplier &replier, StateMachineEngine &engine)
Definition: supervisoryCmdsImpl.hpp:87
Holds context necessary for processing a SetModes request to completion.
Definition: supervisory.hpp:38
void SendErrorReply(std::exception_ptr eptr) noexcept
Send exceptional reply.
Definition: supervisory.hpp:80
SetModesContext(SetModesContext &&) noexcept=default
JsonPayload const & GetArg() const noexcept
Definition: supervisory.hpp:55
SetModesContext(rad::cii::Request< std::string, std::string > const &request)
Construct context with provided request.
Definition: supervisory.hpp:46
void SendReply() noexcept
Sends hardcoded string reply.
Definition: supervisory.hpp:62
Holds context necessary for processing a WriteBack request to completion.
Definition: supervisory.hpp:110
void SendReply() noexcept
Sends hardcoded string reply.
Definition: supervisory.hpp:134
WriteBackContext(rad::cii::Request< std::string, std::string > const &request)
Construct context with provided request.
Definition: supervisory.hpp:118
JsonPayload const & GetArg() const noexcept
Definition: supervisory.hpp:127
void SendStopReply() noexcept
Send stop reply.
Definition: supervisory.hpp:166
void SendErrorReply(std::exception_ptr eptr) noexcept
Send exceptional reply.
Definition: supervisory.hpp:153
WriteBackContext(WriteBackContext &&) noexcept=default
Provides macros and utilities for exception handling.
Defines the JSON payload type JsonPayload.
Definition: commandReplier.cpp:22
const std::string STD_OK_REPLY
Definition: stdComponent.hpp:86
auto WrapWithNested(E &&exception) noexcept(std::is_nothrow_constructible_v< detail::UnspecifiedNested< typename std::decay_t< E > >, E && >)
Constructs an unspecified exception that derives from both the provided object and std::nested_except...
Definition: exceptions.hpp:121
log4cplus::Logger & GetLogger(const std::string &name="app")
Get handle to a specific logger.
Definition: logger.cpp:180
nlohmann::json JsonPayload
Type requirements:
Definition: jsonPayload.hpp:25
rad::StopToken StopToken
Definition: stopToken.hpp:20
@ Simple
Definition: model.hpp:22
@ Composite
Definition: model.hpp:22
@ Initial
Definition: model.hpp:22
Definition: rtcSupervisor.cpp:21
Lifecycle of a basic 'RtcComponent'.
A simple Stop Token.
Life cycle extension to make RtcComponent Supervisory.
Definition: supervisory.hpp:213
Implementation of MAL commands for layer 'Supervisory'.