0

I have a 2D state table as shown in the code below. This is for a provisioning application of a wifi device. I understand the idea of a 1D state table, but not a 2D which is why I am confused. Can anyone explain how this works? How does "event" determine which function is triggered? Does "event" determine the next "state"? A chart/diagram of the workflow could be helpful.

I tried to reference: https://en.wikipedia.org/wiki/State_transition_table#Two-dimensional_state_tables

The full code is attached here: https://drive.google.com/file/d/1uvJMmRV7iccjnsIGB0G9wSZSY-DXVMjJ/view?usp=sharing


unsigned char event;
mq_receive(gProvisioningSMQueue, (char *)&event, 1, NULL);
/* Find Next event entry */
pEntry = (Provisioning_TableEntry_t *)&gTransitionTable[g_CurrentState][event];
/* Change state acording to event */
if (pEntry->nextState != g_CurrentState)
{
   g_CurrentState = pEntry->nextState;
}

const Provisioning_TableEntry_t gTransitionTable[AppState_MAX][AppEvent_MAX] =
{
        /* AppState_STARTING */
    {
        /* Event: AppEvent_STARTED */ {StartConnection,
                                       AppState_WAIT_FOR_CONNECTION     },
        /* Event: AppEvent_CONNECTED */ {HandleWaitForIp, AppState_WAIT_FOR_IP },
        /* Event: AppEvent_IP_ACQUIRED */ {ReportError, AppState_ERROR      },
        /* Event: AppEvent_DISCONNECT */ {ReportError, AppState_ERROR       },
        /* Event: AppEvent_PING_COMPLETE */ {ReportError, AppState_ERROR    },
        /* AppEvent_PROVISIONING_STARTED */ {ReportError, AppState_ERROR    },
        /* AppEvent_PROVISIONING_SUCCESS */ {ReportError, AppState_ERROR    },
        /* AppEvent_PROVISIONING_STOPPED */ {ReportError, AppState_ERROR    },
        /* AppEvent_PROVISIONING_WAIT_CONN */ {ReportError, AppState_ERROR  },
        /* Event: AppEvent_TIMEOUT */ {ReportError, AppState_ERROR          },
        /* Event: AppEvent_ERROR */ {ReportError, AppState_ERROR            },
        /* Event: AppEvent_RESTART */ {ProvisioningStart,
                                       AppState_PROVISIONING_IN_PROGRESS}
    },
    /* AppState_WAIT_FOR_CONNECTION */
    {
        /* Event: AppEvent_STARTED */ 
        {StartConnection, AppState_WAIT_FOR_CONNECTION            },
        /** Event: AppEvent_CONNECTED */ 
        {HandleWaitForIp, AppState_WAIT_FOR_IP                    },
        /* Event: AppEvent_IP_ACQUIRED */
         {ReportError, AppState_ERROR                             },
        /* Event: AppEvent_DISCONNECT */ 
        {StartConnection, AppState_WAIT_FOR_CONNECTION            },
        /* Event: AppEvent_PING_COMPLETE */
         {HandleProvisioningComplete, AppState_PINGING_GW         },
        /* AppEvent_PROVISIONING_STARTED */ 
        {ProvisioningStart, AppState_PROVISIONING_IN_PROGRESS     },
        /* AppEvent_PROVISIONING_SUCCESS */ 
        {DoNothing, AppState_WAIT_FOR_CONNECTION                  },
        /* AppEvent_PROVISIONING_STOPPED */ 
         {CheckLanConnection, AppState_WAIT_FOR_CONNECTION        },
        /* AppEvent_PROVISIONING_WAIT_CONN */ 
        {DoNothing, AppState_WAIT_FOR_CONNECTION                  },
        /* Event: AppEvent_TIMEOUT */
         {ProvisioningStart, AppState_PROVISIONING_IN_PROGRESS    },
        /* Event: AppEvent_ERROR */ 
        {ProvisioningStart, AppState_PROVISIONING_IN_PROGRESS     },
        /* Event: AppEvent_RESTART */ 
        {ProcessRestartRequest, AppState_WAIT_FOR_CONNECTION      }
    },
    /* AppState_WAIT_FOR_IP */
    {
        /* Event: AppEvent_STARTED */
         {ProvisioningStart, AppState_PROVISIONING_IN_PROGRESS          },
        /* Event: AppEvent_CONNECTED */ {ReportError, AppState_ERROR    },
        /* Event: AppEvent_IP_ACQUIRED */
         {CheckLanConnection, AppState_PINGING_GW                       },
        /* Event: AppEvent_DISCONNECT */ 
        {StartConnection, AppState_WAIT_FOR_CONNECTION                  },
        /* Event: AppEvent_PING_COMPLETE */ 
        {DoNothing, AppState_WAIT_FOR_IP                                },
        /* AppEvent_PROVISIONING_STARTED */
         {ProvisioningStart, AppState_PROVISIONING_IN_PROGRESS          },
        /* AppEvent_PROVISIONING_SUCCESS */ 
        {DoNothing, AppState_WAIT_FOR_IP                                },
        /* AppEvent_PROVISIONING_STOPPED */ 
        {HandleProvisioningComplete, AppState_PINGING_GW                },
        /* AppEvent_PROVISIONING_WAIT_CONN */ 
        {DoNothing, AppState_WAIT_FOR_IP                                },
        /* Event: AppEvent_TIMEOUT */ 
        {ReportError, AppState_ERROR                                    },
        /* Event: AppEvent_ERROR */
         {ReportError, AppState_ERROR                                   },
        /* Event: AppEvent_RESTART */ 
        {ProcessRestartRequest,
                                       AppState_WAIT_FOR_CONNECTION     }
    },
    /* AppState_PINGING_GW */
    {
        /* Event: AppEvent_STARTED */ 
        {DoNothing, AppState_PINGING_GW                                  },
        /* Event: AppEvent_CONNECTED */ 
        {HandleWaitForIp, AppState_WAIT_FOR_IP                           },
        /* Event: AppEvent_IP_ACQUIRED */
         {CheckInternetConnection, AppState_PINGING_GW                   },
        /* Event: AppEvent_DISCONNECT */ 
        {HandleDiscnctEvt, AppState_WAIT_FOR_CONNECTION                  },
        /* Event: AppEvent_PING_COMPLETE */ 
        {DoNothing, AppState_PINGING_GW                                  },
        /* AppEvent_PROVISIONING_STARTED */ 
        {ProvisioningStart, AppState_PROVISIONING_IN_PROGRESS            },
        /* AppEvent_PROVISIONING_SUCCESS */
         {DoNothing, AppState_PINGING_GW                                 },
        /* AppEvent_PROVISIONING_STOPPED */ 
        {HandleUserApplication, AppState_PINGING_GW                      },
        /* AppEvent_PROVISIONING_WAIT_CONN */ 
        {DoNothing, AppState_PINGING_GW                                  },
        /*  Event: AppEvent_TIMEOUT */
         {SendPingToGW, AppState_PINGING_GW                              },
        /* Event: AppEvent_ERROR */ 
        {ReportError, AppState_ERROR                                     },
        /* Event: AppEvent_RESTART */ 
        {ProcessRestartRequest, AppState_WAIT_FOR_CONNECTION             }
    },
    /* AppState_PROVISIONING_IN_PROGRESS  */
    {
        /* Event: AppEvent_STARTED */ 
        {ProcessStartRequest, AppState_PROVISIONING_IN_PROGRESS    },
        /* Event: AppEvent_CONNECTED */
         {HandleConnection, AppState_PROVISIONING_IN_PROGRESS            },
        /* Event: AppEvent_IP_ACQUIRED */
        {CheckInternetConnection, AppState_PROVISIONING_IN_PROGRESS      },
        /* Event: AppEvent_DISCONNECT */ 
        {HandleDiscnctEvt, AppState_PROVISIONING_IN_PROGRESS             },
        /* Event: AppEvent_PING_COMPLETE */ 
        {DoNothing, AppState_PROVISIONING_IN_PROGRESS                    },
        /* AppEvent_PROVISIONING_STARTED */
         {DoNothing, AppState_PROVISIONING_IN_PROGRESS                   },
        /* AppEvent_PROVISIONING_SUCCESS */ 
        {HandleProvisioningComplete, AppState_PROVISIONING_WAIT_COMPLETE},
        /* AppEvent_PROVISIONING_STOPPED */
         {HandleProvisioningComplete, AppState_PINGING_GW               },
        /* AppEvent_PROVISIONING_WAIT_CONN */
         {DoNothing, AppState_WAIT_FOR_CONNECTION                       },
        /* Event: AppEvent_TIMEOUT */ 
        {ProcessRestartRequest, AppState_WAIT_FOR_CONNECTION            },
        /* Event: AppEvent_ERROR */
        {ReportError, AppState_ERROR                                    },
        /* Event: AppEvent_RESTART */ 
        {ProcessRestartRequest, AppState_WAIT_FOR_CONNECTION            }

    },
    /* AppState_PROVISIONING_WAIT_COMPLETE */
    {
        /* Event: AppEvent_STARTED */
         {DoNothing, AppState_PROVISIONING_WAIT_COMPLETE },
        /* Event: AppEvent_CONNECTED */ 
        {DoNothing, AppState_PROVISIONING_WAIT_COMPLETE  },
        /* Event: AppEvent_IP_ACQUIRED */
         {DoNothing, AppState_PROVISIONING_WAIT_COMPLETE },
        /* Event: AppEvent_DISCONNECT */ 
        {HandleDiscnctEvt, AppState_PROVISIONING_WAIT_COMPLETE },
        /* Event: AppEvent_PING_COMPLETE */ 
        {DoNothing, AppState_PROVISIONING_WAIT_COMPLETE },
        /* AppEvent_PROVISIONING_STARTED */ 
        {DoNothing, AppState_PROVISIONING_WAIT_COMPLETE },
        /* AppEvent_PROVISIONING_SUCCESS */ 
        {DoNothing, AppState_PROVISIONING_WAIT_COMPLETE },
        /* AppEvent_PROVISIONING_STOPPED */ 
        {HandleUserApplication, AppState_PINGING_GW     },
        /* AppEvent_PROVISIONING_WAIT_CONN */ 
        {DoNothing, AppState_WAIT_FOR_CONNECTION        },
        /* Event: AppEvent_TIMEOUT */ 
        {HandleProvisioningTimeOut, AppState_PROVISIONING_WAIT_COMPLETE },
        /* Event: AppEvent_ERROR */
        {ReportError, AppState_ERROR },
        /* Event: AppEvent_RESTART */ 
        {ProcessRestartRequest, AppState_PROVISIONING_WAIT_COMPLETE }
    },
    /* AppState_ERROR */
    /* we will restart connection for all errors */
    {
        /* Event: AppEvent_STARTED */
         {ReportError, AppState_WAIT_FOR_CONNECTION     },
        /* Event: AppEvent_CONNECTED */ 
        {ReportError, AppState_WAIT_FOR_CONNECTION     },
        /* Event: AppEvent_IP_ACQUIRED */ 
        {ReportError, AppState_WAIT_FOR_CONNECTION     },
        /* Event: AppEvent_DISCONNECT */ 
        {ReportError, AppState_WAIT_FOR_CONNECTION     },
        /* Event: AppEvent_PING_COMPLETE */ 
        {ReportError, AppState_WAIT_FOR_CONNECTION     },
        /* AppEvent_PROVISIONING_STARTED */
        {ReportError, AppState_WAIT_FOR_CONNECTION     },
        /* AppEvent_PROVISIONING_SUCCESS */ 
        {ReportError, AppState_WAIT_FOR_CONNECTION     },
        /* AppEvent_PROVISIONING_STOPPED */ 
        {ReportError, AppState_WAIT_FOR_CONNECTION     },
        /* AppEvent_PROVISIONING_WAIT_CONN */ 
        {ReportError, AppState_WAIT_FOR_CONNECTION     },
        /* Event: AppEvent_TIMEOUT */
         {ReportError, AppState_WAIT_FOR_CONNECTION    },
        /* Event: AppEvent_ERROR */
         {ReportError,AppState_WAIT_FOR_CONNECTION     },
        /* Event: AppEvent_RESTART */ 
        {ReportError, AppState_WAIT_FOR_CONNECTION     }
    }
};
Alex Feng
  • 45
  • 1
  • 9
  • 1
    Each state has its own transition table indexed by event. So the first index selects the transition table, based on the current state, and the second index selects the new state, based on the event. – Tom Karzes May 24 '19 at 01:26
  • Possible duplicate: https://stackoverflow.com/questions/1371460/state-machines-tutorials – David C. Rankin May 24 '19 at 03:58

0 Answers0