LCOV - code coverage report
Current view: top level - bfd - bfd_state_machine.cc (source / functions) Hit Total Coverage
Test: OpenSDN C/C++ coverage (all TARGET_SET jobs) Lines: 45 48 93.8 %
Date: 2026-06-04 02:06:09 Functions: 17 18 94.4 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 2014 CodiLime, Inc. All rights reserved.
       3             :  */
       4             : 
       5             : #include "bfd/bfd_common.h"
       6             : #include "bfd/bfd_session.h"
       7             : #include "bfd/bfd_state_machine.h"
       8             : 
       9             : #include <list>
      10             : #include <boost/optional.hpp>
      11             : #include <boost/bind/bind.hpp>
      12             : #include <boost/statechart/event.hpp>
      13             : #include <boost/statechart/transition.hpp>
      14             : #include <boost/statechart/state_machine.hpp>
      15             : #include <boost/statechart/simple_state.hpp>
      16             : #include <boost/statechart/custom_reaction.hpp>
      17             : #include <boost/mpl/list.hpp>
      18             : 
      19             : #include "base/logging.h"
      20             : 
      21             : using namespace boost::placeholders;
      22             : namespace mpl = boost::mpl;
      23             : namespace sc = boost::statechart;
      24             : 
      25             : namespace BFD {
      26             : 
      27             : struct EvRecvInit : sc::event<EvRecvInit> {};
      28             : struct EvRecvDown : sc::event<EvRecvDown> {};
      29             : struct EvRecvUp : sc::event<EvRecvUp> {};
      30             : struct EvRecvAdminDown : sc::event<EvRecvAdminDown> {};
      31             : struct EvTimeout : sc::event<EvTimeout> {};
      32             : // struct EvReset : sc::event<EvReset> {};
      33             : 
      34             : struct BFDStateAware {
      35             :     virtual BFDState getState() const = 0;
      36         172 :     virtual ~BFDStateAware(){}
      37             : };
      38             : 
      39             : struct InitState;
      40             : struct DownState;
      41             : struct UpState;
      42             : class StateMachineImpl : public StateMachine,
      43             :                          public sc::state_machine<StateMachineImpl, DownState> {
      44             :  public:
      45          32 :     explicit StateMachineImpl(EventManager *evm, Session *session) :
      46          32 :             evm_(evm), session_(session) {
      47          32 :         initiate();
      48          32 :     }
      49             : 
      50          62 :     void Notify(BFDState state) {
      51          62 :         LOG(DEBUG, "StateMachine state: " << state);
      52          62 :         if (cb_.is_initialized() && session_) {
      53          55 :             (cb_.get())(session_->key(), GetState());
      54             :         } else {
      55           7 :             LOG(ERROR, "StateMachine cb initialized: "
      56             :                 << cb_.is_initialized() << " session: " << session_);
      57             :         }
      58          62 :     }
      59             : 
      60         127 :     void ProcessRemoteState(BFDState state) {
      61         127 :         BFDState old_state = GetState();
      62         127 :         switch (state) {
      63           0 :             case kAdminDown:
      64           0 :                 process_event(EvRecvAdminDown());
      65           0 :                 break;
      66          28 :             case kDown:
      67          28 :                 process_event(EvRecvDown());
      68          28 :                 break;
      69          29 :             case kInit:
      70          29 :                 process_event(EvRecvInit());
      71          29 :                 break;
      72          70 :             case kUp:
      73          70 :                 process_event(EvRecvUp());
      74          70 :                 break;
      75             :         }
      76         127 :         if (old_state != GetState()) {
      77          56 :             Notify(GetState());
      78             :         }
      79         127 :     }
      80             : 
      81          13 :     void ProcessTimeout() {
      82          13 :         BFDState old_state = GetState();
      83          13 :         process_event(EvTimeout());
      84          13 :         if (old_state != GetState())
      85           6 :             Notify(GetState());
      86          13 :     }
      87             : 
      88       11657 :     BFDState GetState() {
      89       11657 :         return state_cast<const BFDStateAware &>().getState();
      90             :     }
      91             : 
      92          59 :     void SetCallback(boost::optional<ChangeCb> cb) {
      93          59 :         cb_ = cb;
      94          59 :     }
      95             : 
      96             :  private:
      97             :     boost::optional<ChangeCb> cb_;
      98             :     EventManager *evm_;
      99             :     Session *session_;
     100             : };
     101             : 
     102             : struct InitState : sc::simple_state<InitState, StateMachineImpl>,
     103             :                    BFDStateAware {
     104             :     typedef mpl::list<
     105             :         sc::transition<EvRecvInit, UpState>,
     106             :         sc::transition<EvRecvDown, InitState>,
     107             :         sc::transition<EvRecvUp, UpState>,
     108             :         sc::transition<EvRecvAdminDown, DownState>,
     109             :         sc::transition<EvTimeout, DownState>
     110             :         > reactions;
     111        4949 :     virtual BFDState getState() const { return kInit; }
     112          50 :     virtual ~InitState() {}
     113             : };
     114             : 
     115             : struct UpState : sc::simple_state<UpState, StateMachineImpl>, BFDStateAware {
     116             :     typedef mpl::list<
     117             :         sc::transition<EvRecvInit, UpState>,
     118             :         sc::transition<EvRecvDown, DownState>,
     119             :         sc::transition<EvRecvUp, UpState>,
     120             :         sc::transition<EvRecvAdminDown, DownState>,
     121             :         sc::transition<EvTimeout, DownState>
     122             :         > reactions;
     123         637 :     virtual BFDState getState() const { return kUp; }
     124         196 :     virtual ~UpState() {}
     125             : };
     126             : 
     127             : struct DownState : sc::simple_state<DownState, StateMachineImpl>,
     128             :                    BFDStateAware {
     129             :     typedef mpl::list<
     130             :         sc::transition<EvRecvInit, UpState>,
     131             :         sc::transition<EvRecvDown, InitState>,
     132             :         sc::transition<EvRecvUp, DownState>,
     133             :         sc::transition<EvRecvAdminDown, DownState>,
     134             :         sc::transition<EvTimeout, DownState>
     135             :         > reactions;
     136        6071 :     virtual BFDState getState() const { return kDown; }
     137          98 :     virtual ~DownState() {}
     138             : };
     139             : 
     140          32 : StateMachine *CreateStateMachine(EventManager *evm, Session *session) {
     141          32 :     return new StateMachineImpl(evm, session);
     142             : }
     143             : 
     144             : }  // namespace BFD

Generated by: LCOV version 1.14