⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 statemachine.cpp

📁 Conferencing code using Dialogic hardware
💻 CPP
字号:
/**********@@@SOFT@@@WARE@@@COPY@@@RIGHT@@@**********************************
* DIALOGIC CONFIDENTIAL
*
* Copyright (C) 2006-2007 Dialogic Corporation. All Rights Reserved.
* The source code contained or described herein and all documents related
* to the source code ("Material") are owned by Dialogic Corporation or its
* suppliers or licensors. Title to the Material remains with Dialogic Corporation
* or its suppliers and licensors. The Material contains trade secrets and
* proprietary and confidential information of Dialogic or its suppliers and
* licensors. The Material is protected by worldwide copyright and trade secret
* laws and treaty provisions. No part of the Material may be used, copied,
* reproduced, modified, published, uploaded, posted, transmitted, distributed,
* or disclosed in any way without Dialogic's prior express written permission.
*
* No license under any patent, copyright, trade secret or other intellectual
* property right is granted to or conferred upon you by disclosure or delivery
* of the Materials, either expressly, by implication, inducement, estoppel or
* otherwise. Any license under such intellectual property rights must be
* express and approved by Dialogic in writing.
*
***********************************@@@SOFT@@@WARE@@@COPY@@@RIGHT@@@**********/
//***********************************************************************
//***********************************************************************
// StateMachine.cpp: implementation of the CStateMachine class.
//
//////////////////////////////////////////////////////////////////////

#include "pdl.h"

//
// Global functions
//

//*****************************************************************************
// Purpose	: 
//   Find state name by given value
// Parameters:	
//    [in] state 
// Returns:	
//    value or <unknown state> if not found
//*****************************************************************************
const char *common_state_name(int state){

    static NAME_TABLE state_tbl[] = {
        { "S_END",         S_END },
        { "S_FINAL",       S_FINAL },
        { "S_ANY",         S_ANY },
        { "S_SAME",        S_SAME },
        { "S_BEGIN",       S_BEGIN },
        { "S_OPEN",        S_OPEN },
        { "S_OPEN_EXIT",   S_OPEN_EXIT },
        { "S_RELAX",       S_RELAX },
        { "S_RELAXCNF",    S_RELAXCNF },
        { "S_WAIT_SUBDEV", S_WAIT_SUBDEV },
    
        { 0, 0 } 
    }; 

   const char *name = "<Unknown state>";
   str_findname(state, &name, state_tbl);
 return name;
} //	End of common_state_name()


//*****************************************************************************
// Purpose	: 
//   Find action name by given value
// Parameters:	
//    [in] action 
// Returns:	
//    value or <unknown action> if not found
//*****************************************************************************
// find action name by value
const char *common_action_name(int action){
   static NAME_TABLE action_tbl[] = {
        { "A_NONE",        A_NONE      },
        { "A_RELAX",       A_RELAX     },
        { "A_RELAXCNF",    A_RELAXCNF  },
        { "A_CLOSE",       A_CLOSE     }, 
        { "A_ERROR",       A_ERROR     }, 
        { "A_EXIT",        A_EXIT      }, 
        { "A_GIVEUP",      A_GIVEUP    },
  
        { 0, 0 }
   };
   const char *name = "<Unknown action>";
   str_findname(action, &name, action_tbl);
 return name;
}  //	End of common_action_name()

//*****************************************************************************
// Purpose	: 
//    Determine if state machine can stay in given state 
//              forever without timing out
//      Relaxed states are BEGIN (initial state),
//                         RELAX (waiting for calls, or waiting somebody to join conference 
//                         RELAXCNF (waiting somebody to leave conference) 
// Parameters:	
//    [in] state 
// Returns:	
//    bool = yes, it is
//    false = nop
//*****************************************************************************
bool is_relaxed_state(int state){
 bool brc = false;
  switch (state){
    case S_BEGIN:
    case S_RELAX:
    case S_RELAXCNF:
    case S_WAIT_SUBDEV:
    case S_FINAL:
        brc = true;
        break;
    default: 
       break;
  } // switch state
  return brc;
}  //	End of is_relaxed_state()

//////////////////////////////////////////////////////////////
// Class members 
//////////////////////////////////////////////////////////////
//************************************************************
// Purpose	: 
//    Find appropriate line in table 'actions'
//    Match priorities:
//      1. exact match ( current state and event )
//      2. any state, this event
//      3. any event, this state
//      4. any state, any event
// Parameters:	
//    [in] state
//    [in] event
//    [out] Holder to place pointer to the line
// Returns:	
//    true = found
//    false = no appropriate line ( state machine error )
//************************************************************
bool CStateMachine::FindInStates(int state,
                                 int event, 
                                 PEVENT_STRU *ppNew){
 PEVENT_STRU match_with_any_state = 0;
 PEVENT_STRU match_with_any_event = 0;
 PEVENT_STRU match_with_any_any = 0;

  PEVENT_STRU pEvents = m_pEventStru;
  while ( S_END != pEvents->current_state ) {
      if ( event == pEvents->event) {
           if ( state == pEvents->current_state) {
                *ppNew = pEvents;
                return true;
           } else if ( S_ANY == pEvents->current_state ) {
                match_with_any_state = pEvents;
           } 
      }else if ( EVENT_ANY == pEvents->event ) {
            if ( state == pEvents->current_state ) {
                 match_with_any_event = pEvents;
            }else if ( S_ANY == pEvents->current_state ) {
                 match_with_any_any = pEvents;
            }
      }
      pEvents++;
  }

  if (match_with_any_state){
      *ppNew = match_with_any_state;
      return true;
  }

  if (match_with_any_event){
      *ppNew = match_with_any_event;
      return true;
  }

  if (match_with_any_any){
      *ppNew = match_with_any_any;
      return true;
  }

  return false;
} //	End of FindInStates()

//****************************************************
// Purpose	: 
//    Find appropriate line in table 'actions'
//    Match priorities:
//      1. exact match ( current state and action )
//      2. any state, this action
// Parameters:	
//    [in] state
//    [in] action
//    [out] Holder to place pointer to the line
// Returns:	
//    true = found
//    false = no appropriate line ( state machine error )
//****************************************************
bool CStateMachine::FindInActions(int state, 
                                  int action, 
                                  PACTION_STRU *ppNew){

PACTION_STRU match_with_any_state = 0;
PACTION_STRU pActions= m_pActionStru;

  while ( S_END != pActions->current_state ) {
      if ( action == pActions->action) {
           if ( state == pActions->current_state) {
                *ppNew = pActions;
                return true;
           } else if ( S_ANY == pActions->current_state ) {
                match_with_any_state = pActions;
           } 
      }
      pActions++;
  }

  if (match_with_any_state){
      *ppNew = match_with_any_state;
      return true;
  }

  return false;
} //	End of FindInActions()

//*****************************************************************************
// Purpose	: 
//    Enumerate events that can advance state machine from it's current state
// Parameters:	
//    [out] holder for event code 
//    [in / out]  handle
//      to start enumeration set handle = BEGIN_SEARCH and pass &handle
//      to continue search, pass previous &handle 
// Returns:	
//    true = missing event is set to next possible event
//*****************************************************************************
bool CStateMachine::EnumMissingEvents(int *missing_event, int *handle){
    while (S_END != m_pEventStru[++(*handle)].current_state ){
        if (m_pEventStru[*handle].current_state == m_current_state) {
            *missing_event = m_pEventStru[*handle].event;
            return true;
        }
    }
 return false;
} //	End of FindInActions()

//*****************************************************************************
// Purpose	: 
//    Validate state machine and request exit if it is invalid 
// Parameters:	
//    [in] object (CSrlDevice) that creates state machine
// Returns:	
//    true = state machine is valid
//    false = there are missing elements in event table or in action table
//*****************************************************************************
bool CStateMachine::Validate(PSrlDevice pDev){
EVENT_STRU *pEvent = m_pEventStru;
bool brc = true;
//   1. for each (event,action) in event table
//               (same state, same action) should exist in action table
    while (S_END != pEvent->current_state ){
        PACTION_STRU pAction;

        const char *evtname;
        evt_getname(pEvent->event, &evtname);
        if (!FindInActions(pEvent->current_state, pEvent->action, &pAction) ){
             pDev->LOG( LOG_ASSERT, pDev->GetName(),
                        "Missing action table entry for following event_table item(action)");

             pDev->LOG( LOG_ASSERT, pDev->GetName(),
                        "  =>state          = %5d %s",
                        pEvent->current_state, pDev->state_name(pEvent->current_state));
             pDev->LOG( LOG_ASSERT, pDev->GetName(),
                        "    event          = %5d %s",
                        pEvent->event, evtname );
             pDev->LOG( LOG_ASSERT, pDev->GetName(),
                        "  =>action         = %5d %s",
                        pEvent->action, pDev->action_name(pEvent->action));

             brc = false;
        }

        ++pEvent;
    }

//   2. for each (state, action, action_if_fail) in action table
//               (same state, action_if_fail (as action) should exist in action table
    ACTION_STRU *pAction = m_pActionStru;
    ACTION_STRU *pTmp;
    while (S_END != pAction->current_state ){
        if (!FindInActions(pAction->current_state, pAction->action_if_fail, &pTmp) ){
             pDev->LOG( LOG_ASSERT, pDev->GetName(),
                        "Missing action table entry for following action_table item(action_if_fail)");

             pDev->LOG( LOG_ASSERT, pDev->GetName(),
                        "  =>state          = %5d %s",
                        pAction->current_state, pDev->state_name(pAction->current_state));

             pDev->LOG( LOG_ASSERT, pDev->GetName(),
                        "    action         = %5d %s",
                        pAction->action, pDev->action_name(pAction->action));

             pDev->LOG( LOG_ASSERT, pDev->GetName(),
                        "    state_if_pass  = %5d %s",
                        pAction->state_if_pass, pDev->state_name(pAction->state_if_pass));

             pDev->LOG( LOG_ASSERT, pDev->GetName(),
                        "  =>action_if_fail = %5d %s",
                        pAction->action_if_fail, pDev->action_name(pAction->action_if_fail));


             brc = false;
        }

        ++pAction;
    }

    // 3. TBD check if all roads lead to Rome ( S_FINAL in our case )

 return brc;
} //	End of Validate()

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -