hsmCommunicator.cΒΆ

/**
        hsmCommunicator.c

        This file automatically generated by FSMLang
*/

#include "hsmCommunicator_priv.h"
#include <stddef.h>

/* Begin Native Implementation Prolog */


#define INIT_FSM_DATA {msg_none, { 0 }}

/* End Native Implementation Prolog */


#ifndef DBG_PRINTF
#define DBG_PRINTF(...)
#endif

extern HSM_COMMUNICATOR_SUB_FSM_IF hsmCommunicator_establishSession_sub_fsm_if;
extern HSM_COMMUNICATOR_SUB_FSM_IF hsmCommunicator_sendMessage_sub_fsm_if;

static HSM_COMMUNICATOR_EVENT_ENUM UNINITIALIZED_stateFn(pHSM_COMMUNICATOR,HSM_COMMUNICATOR_EVENT_ENUM);
static HSM_COMMUNICATOR_EVENT_ENUM IDLE_stateFn(pHSM_COMMUNICATOR,HSM_COMMUNICATOR_EVENT_ENUM);
static HSM_COMMUNICATOR_EVENT_ENUM ESTABLISHING_SESSION_stateFn(pHSM_COMMUNICATOR,HSM_COMMUNICATOR_EVENT_ENUM);
static HSM_COMMUNICATOR_EVENT_ENUM IN_SESSION_stateFn(pHSM_COMMUNICATOR,HSM_COMMUNICATOR_EVENT_ENUM);
static HSM_COMMUNICATOR_EVENT_ENUM findAndRunSubMachine(pHSM_COMMUNICATOR,HSM_COMMUNICATOR_EVENT_ENUM);

static void translateEventData(pHSM_COMMUNICATOR_DATA,pHSM_COMMUNICATOR_EVENT);

static void runAppropriateEntryFunction(pHSM_COMMUNICATOR_DATA,HSM_COMMUNICATOR_STATE);
static void runAppropriateExitFunction(pHSM_COMMUNICATOR_DATA,HSM_COMMUNICATOR_STATE);
static const HSM_COMMUNICATOR_STATE_FN hsmCommunicator_state_fn_array[hsmCommunicator_numStates] =
{
    UNINITIALIZED_stateFn
    , IDLE_stateFn
    , ESTABLISHING_SESSION_stateFn
    , IN_SESSION_stateFn
};


const pHSM_COMMUNICATOR_SUB_FSM_IF hsmCommunicator_sub_fsm_if_array[THIS(numSubMachines)] =
{
    &hsmCommunicator_establishSession_sub_fsm_if
    , &hsmCommunicator_sendMessage_sub_fsm_if
};

pHSM_COMMUNICATOR_SHARED_EVENT_STR sharing_hsmCommunicator_INIT[] =
{
    &sendMessage_share_hsmCommunicator_INIT_str
    , NULL
};

pHSM_COMMUNICATOR_SHARED_EVENT_STR sharing_hsmCommunicator_MESSAGE_RECEIVED[] =
{
    &establishSession_share_hsmCommunicator_MESSAGE_RECEIVED_str
    , &sendMessage_share_hsmCommunicator_MESSAGE_RECEIVED_str
    , NULL
};

HSM_COMMUNICATOR_EVENT_ENUM hsmCommunicator_pass_shared_event(pHSM_COMMUNICATOR pfsm,pHSM_COMMUNICATOR_SHARED_EVENT_STR sharer_list[])
{
    HSM_COMMUNICATOR_EVENT_ENUM return_event = THIS(noEvent);

    for (pHSM_COMMUNICATOR_SHARED_EVENT_STR *pcurrent_sharer = sharer_list;
            *pcurrent_sharer && return_event == THIS(noEvent);
            pcurrent_sharer++)
    {
        if ((*pcurrent_sharer)->data_translation_fn)
            (*(*pcurrent_sharer)->data_translation_fn)(&pfsm->data);
        return_event = (*(*pcurrent_sharer)->psub_fsm_if->subFSM)((*pcurrent_sharer)->event);
    }

    return return_event;
}

#ifndef INIT_FSM_DATA
#error INIT_FSM_DATA must be defined
#endif

HSM_COMMUNICATOR hsmCommunicator = {

    INIT_FSM_DATA,
    hsmCommunicator_UNINITIALIZED,
    THIS(INIT),
    &hsmCommunicator_state_fn_array,
    &hsmCommunicator_sub_fsm_if_array,
    hsmCommunicatorFSM
};

pHSM_COMMUNICATOR phsmCommunicator = &hsmCommunicator;

void run_hsmCommunicator(pHSM_COMMUNICATOR_EVENT e)
{
    if (phsmCommunicator)
    {
        phsmCommunicator->fsm(phsmCommunicator,e);
    }
}


#ifndef EVENT_IS_NOT_EXCLUDED_FROM_LOG
#define EVENT_IS_NOT_EXCLUDED_FROM_LOG(e) ((e) == (e))
#endif
void hsmCommunicatorFSM(pHSM_COMMUNICATOR pfsm, pHSM_COMMUNICATOR_EVENT event)
{
    HSM_COMMUNICATOR_EVENT_ENUM e = event->event;

    translateEventData(&pfsm->data, event);

    while (e != hsmCommunicator_noEvent) {

#ifdef HSM_COMMUNICATOR_DEBUG
        if (EVENT_IS_NOT_EXCLUDED_FROM_LOG(e))
        {
            DBG_PRINTF("event: %s; state: %s"
                       ,HSM_COMMUNICATOR_EVENT_NAMES[e]
                       ,HSM_COMMUNICATOR_STATE_NAMES[pfsm->state]
                      );
        }
#endif

        /* This is read-only data to facilitate error reporting in action functions */
        pfsm->event = e;

        if (e < hsmCommunicator_noEvent)
        {
            e = ((* (*pfsm->statesArray)[pfsm->state])(pfsm,e));
        }
        else
        {
            e = findAndRunSubMachine(pfsm, e);
        }

    }
}


static HSM_COMMUNICATOR_EVENT_ENUM findAndRunSubMachine(pHSM_COMMUNICATOR pfsm, HSM_COMMUNICATOR_EVENT_ENUM e)
{
    for (HSM_COMMUNICATOR_SUB_MACHINES machineIterator = THIS(firstSubMachine);
            machineIterator < THIS(numSubMachines);
            machineIterator++
        )
    {
        if (
            ((*pfsm->subMachineArray)[machineIterator]->first_event <= e)
            && ((*pfsm->subMachineArray)[machineIterator]->last_event > e)
        )
        {
            return ((*(*pfsm->subMachineArray)[machineIterator]->subFSM)(e));
        }
    }

    return THIS(noEvent);

}

static void runAppropriateEntryFunction(pHSM_COMMUNICATOR_DATA pdata,HSM_COMMUNICATOR_STATE s)
{
    switch(s)
    {
    case hsmCommunicator_IN_SESSION:
        hsmCommunicator_start_session_timer(pdata);
        break;
    default:
        break;
    }
}

static void runAppropriateExitFunction(pHSM_COMMUNICATOR_DATA pdata,HSM_COMMUNICATOR_STATE s)
{
    switch(s)
    {
    case hsmCommunicator_IN_SESSION:
        hsmCommunicator_stop_session_timer(pdata);
        break;
    default:
        break;
    }
}

static void translateEventData(pHSM_COMMUNICATOR_DATA pfsm_data, pHSM_COMMUNICATOR_EVENT pevent)
{
    switch(pevent->event)
    {
    case hsmCommunicator_MESSAGE_RECEIVED:
        UFMN(store_message)(pfsm_data, &pevent->event_data.MESSAGE_RECEIVED_data);
        break;
    default:
        break;
    }

}

static HSM_COMMUNICATOR_EVENT_ENUM UNINITIALIZED_stateFn(pHSM_COMMUNICATOR pfsm,HSM_COMMUNICATOR_EVENT_ENUM e)
{
    HSM_COMMUNICATOR_EVENT_ENUM retVal = THIS(noEvent);
    HSM_COMMUNICATOR_STATE new_s = hsmCommunicator_UNINITIALIZED;

    switch(e)
    {
    case THIS(INIT):
        retVal = UFMN(initialize)(pfsm);
        new_s = hsmCommunicator_IDLE;
        break;
    default:
        DBG_PRINTF("hsmCommunicator_noAction");
        break;
    }


    if (hsmCommunicator_UNINITIALIZED != new_s)
    {
        UFMN(track_transitions)(pfsm, new_s);
        runAppropriateExitFunction(&pfsm->data, hsmCommunicator_UNINITIALIZED);
        runAppropriateEntryFunction(&pfsm->data, new_s);
        pfsm->state = new_s;

    }


    return retVal;
}

static HSM_COMMUNICATOR_EVENT_ENUM IDLE_stateFn(pHSM_COMMUNICATOR pfsm,HSM_COMMUNICATOR_EVENT_ENUM e)
{
    HSM_COMMUNICATOR_EVENT_ENUM retVal = THIS(noEvent);
    HSM_COMMUNICATOR_STATE new_s = hsmCommunicator_IDLE;

    switch(e)
    {
    case THIS(SEND_MESSAGE):
        retVal = UFMN(startSessionEstablishment)(pfsm);
        new_s = hsmCommunicator_ESTABLISHING_SESSION;
        break;
    default:
        DBG_PRINTF("hsmCommunicator_noAction");
        break;
    }


    if (hsmCommunicator_IDLE != new_s)
    {
        UFMN(track_transitions)(pfsm, new_s);
        runAppropriateExitFunction(&pfsm->data, hsmCommunicator_IDLE);
        runAppropriateEntryFunction(&pfsm->data, new_s);
        pfsm->state = new_s;

    }


    return retVal;
}

static HSM_COMMUNICATOR_EVENT_ENUM ESTABLISHING_SESSION_stateFn(pHSM_COMMUNICATOR pfsm,HSM_COMMUNICATOR_EVENT_ENUM e)
{
    HSM_COMMUNICATOR_EVENT_ENUM retVal = THIS(noEvent);
    HSM_COMMUNICATOR_STATE new_s = hsmCommunicator_ESTABLISHING_SESSION;

    switch(e)
    {
    case THIS(MESSAGE_RECEIVED):
        retVal = UFMN(passMessageReceived)(pfsm);
        break;
    case THIS(SESSION_REJECTED):
        retVal = UFMN(clearQueue)(pfsm);
        new_s = hsmCommunicator_IDLE;
        break;
    case THIS(SESSION_ESTABLISHED):
        retVal = UFMN(completeSessionStart)(pfsm);
        new_s = hsmCommunicator_IN_SESSION;
        break;
    case THIS(SEND_MESSAGE):
        retVal = UFMN(requestMessageTransmission)(pfsm);
        break;
    default:
        DBG_PRINTF("hsmCommunicator_noAction");
        break;
    }


    if (hsmCommunicator_ESTABLISHING_SESSION != new_s)
    {
        UFMN(track_transitions)(pfsm, new_s);
        runAppropriateExitFunction(&pfsm->data, hsmCommunicator_ESTABLISHING_SESSION);
        runAppropriateEntryFunction(&pfsm->data, new_s);
        pfsm->state = new_s;

    }


    return retVal;
}

static HSM_COMMUNICATOR_EVENT_ENUM IN_SESSION_stateFn(pHSM_COMMUNICATOR pfsm,HSM_COMMUNICATOR_EVENT_ENUM e)
{
    HSM_COMMUNICATOR_EVENT_ENUM retVal = THIS(noEvent);
    HSM_COMMUNICATOR_STATE new_s = hsmCommunicator_IN_SESSION;

    switch(e)
    {
    case THIS(MESSAGE_RECEIVED):
        retVal = UFMN(passMessageReceived)(pfsm);
        break;
    case THIS(SEND_MESSAGE):
        retVal = UFMN(requestMessageTransmission)(pfsm);
        break;
    case THIS(SESSION_TIMEOUT):
        DBG_PRINTF("hsmCommunicator_noAction");
        new_s = hsmCommunicator_IDLE;
        break;
    default:
        DBG_PRINTF("hsmCommunicator_noAction");
        break;
    }


    if (hsmCommunicator_IN_SESSION != new_s)
    {
        UFMN(track_transitions)(pfsm, new_s);
        runAppropriateExitFunction(&pfsm->data, hsmCommunicator_IN_SESSION);
        runAppropriateEntryFunction(&pfsm->data, new_s);
        pfsm->state = new_s;

    }


    return retVal;
}


HSM_COMMUNICATOR_EVENT_ENUM UFMN(initialize)(pHSM_COMMUNICATOR pfsm)
{
    DBG_PRINTF("%s", __func__);
    return hsmCommunicator_pass_shared_event(pfsm, sharing_hsmCommunicator_INIT);
}

HSM_COMMUNICATOR_EVENT_ENUM UFMN(passMessageReceived)(pHSM_COMMUNICATOR pfsm)
{
    DBG_PRINTF("%s", __func__);
    return hsmCommunicator_pass_shared_event(pfsm, sharing_hsmCommunicator_MESSAGE_RECEIVED);
}


#ifdef HSM_COMMUNICATOR_DEBUG
char *HSM_COMMUNICATOR_EVENT_NAMES[] = {
    "hsmCommunicator_INIT"
    ,"hsmCommunicator_SEND_MESSAGE"
    ,"hsmCommunicator_SESSION_ESTABLISHED"
    ,"hsmCommunicator_SESSION_REJECTED"
    ,"hsmCommunicator_SESSION_TIMEOUT"
    ,"hsmCommunicator_MESSAGE_RECEIVED"
    , "hsmCommunicator_noEvent"
    , "hsmCommunicator_numEvents"
    , "hsmCommunicator_establishSession_ESTABLISH_SESSION_REQUEST"
    , "hsmCommunicator_establishSession_STEP0_RESPONSE"
    , "hsmCommunicator_establishSession_MESSAGE_RECEIVED"
    , "hsmCommunicator_establishSession_noEvent"
    , "hsmCommunicator_sendMessage_INIT"
    , "hsmCommunicator_sendMessage_MESSAGE_RECEIVED"
    , "hsmCommunicator_sendMessage_SEND_MESSAGE"
    , "hsmCommunicator_sendMessage_ACK"
    , "hsmCommunicator_sendMessage_noEvent"
};

char *HSM_COMMUNICATOR_STATE_NAMES[] = {
    "hsmCommunicator_UNINITIALIZED"
    ,"hsmCommunicator_IDLE"
    ,"hsmCommunicator_ESTABLISHING_SESSION"
    ,"hsmCommunicator_IN_SESSION"
};

#endif