//------------------------------------------------------------------------------
static tOplkError processStateChangeEvent(const tEventNmtStateChange* pNmtStateChange_p,
                                          void* pUserArg_p)
{
    tOplkError  ret = kErrorOk;

    UNUSED_PARAMETER(pUserArg_p);

    if (instance_l.config.pfGsOff == NULL)
    {
        console_printlog("Application event module is not initialized!\n");
        return kErrorGeneralError;
    }

    eventlog_printStateEvent(pNmtStateChange_p);

    switch (pNmtStateChange_p->newNmtState)
    {
        case kNmtGsOff:
           // NMT state machine was shut down,
            // because of user signal (CTRL-C) or critical POWERLINK stack error
            // -> also shut down oplk_process() and main()
            ret = kErrorShutdown;

            printf("Stack received kNmtGsOff!\n");

            // signal that stack is off
            *instance_l.config.pfGsOff = TRUE;
            break;

        case kNmtGsResetCommunication:
            break;

        case kNmtGsResetConfiguration:
            break;

        case kNmtGsInitialising:
        case kNmtGsResetApplication:        // Implement
        case kNmtMsNotActive:               // handling of
        case kNmtMsPreOperational1:         // different
        case kNmtMsPreOperational2:         // states here
        case kNmtMsReadyToOperate:
        case kNmtMsOperational:
        case kNmtMsBasicEthernet:           // no break

        default:
            printf("Stack entered state: %s\n",
                   debugstr_getNmtStateStr(pNmtStateChange_p->newNmtState));
            break;
    }

    return ret;
}
//------------------------------------------------------------------------------
static tOplkError processNodeEvent(tOplkApiEventType EventType_p,
                                   tOplkApiEventArg* pEventArg_p,
                                   void* pUserArg_p)
{
    tOplkApiEventNode*   pNode = &pEventArg_p->nodeEvent;

    UNUSED_PARAMETER(EventType_p);
    UNUSED_PARAMETER(pUserArg_p);

    // check additional argument
    switch (pNode->nodeEvent)
    {
        case kNmtNodeEventCheckConf:
            PRINTF("NodeEvent: (Node=%u, CheckConf)\n", pNode->nodeId);
            break;

        case kNmtNodeEventUpdateConf:
            PRINTF("NodeEvent: (Node=%u, UpdateConf)\n", pNode->nodeId);
            break;

        case kNmtNodeEventNmtState:
            PRINTF("NodeEvent: (Node=%u, NmtState=%s)\n",
                   pNode->nodeId,
                   debugstr_getNmtStateStr(pNode->nmtState));
            break;

        case kNmtNodeEventError:
            PRINTF("NodeEvent: (Node=%u): Error=%s (0x%.4X)\n",
                   pNode->nodeId,
                   debugstr_getEmergErrCodeStr(pNode->errorCode),
                   pNode->errorCode);
            break;

        case kNmtNodeEventFound:
            PRINTF("NodeEvent: (Node=%u, Found)\n", pNode->nodeId);
            break;

        default:
            break;
    }
    return kErrorOk;
}
//------------------------------------------------------------------------------
static tOplkError processNodeEvent(const tOplkApiEventNode* pNode_p,
                                   void* pUserArg_p)
{
    UNUSED_PARAMETER(pUserArg_p);

    eventlog_printNodeEvent(pNode_p);

    // check additional argument
    switch (pNode_p->nodeEvent)
    {
        case kNmtNodeEventCheckConf:
            break;

        case kNmtNodeEventUpdateConf:
            break;

        case kNmtNodeEventNmtState:
            printf("Node %d entered state %s\n",
                   pNode_p->nodeId,
                   debugstr_getNmtStateStr(pNode_p->nmtState));
            break;

        case kNmtNodeEventError:
            break;

        case kNmtNodeEventFound:
            printf("Stack found node %d\n",
                   pNode_p->nodeId);
            break;

        case kNmtNodeEventAmniReceived:
            break;

        case kNmtNodeEventUpdateSw:
            break;

        default:
            break;
    }

    return kErrorOk;
}
//------------------------------------------------------------------------------
tOplkError ProcessThread::processStateChangeEvent(tOplkApiEventType eventType_p,
                                                  tOplkApiEventArg* pEventArg_p,
                                                  void* pUserArg_p)
{
    tOplkError                  ret = kErrorOk;
    tEventNmtStateChange*       pNmtStateChange = &pEventArg_p->nmtStateChange;
#if !defined(CONFIG_INCLUDE_CFM)
    UINT                        varLen;
#endif
    QString                     str;

    UNUSED_PARAMETER(eventType_p);
    UNUSED_PARAMETER(pUserArg_p);

    sigNmtState(pNmtStateChange->newNmtState);

    sigPrintLog(QString("StateChangeEvent %1: %2 -> %3")
                        .arg(debugstr_getNmtEventStr(pNmtStateChange->nmtEvent))
                        .arg(debugstr_getNmtStateStr(pNmtStateChange->oldNmtState))
                        .arg(debugstr_getNmtStateStr(pNmtStateChange->newNmtState)));

    switch (pNmtStateChange->newNmtState)
    {
        case kNmtGsOff:
            pProcessThread_g->sigOplkStatus(0);

            // NMT state machine was shut down,
            // because of user signal (CTRL-C) or critical POWERLINK stack error
            // -> also shut down oplk_process()
            ret = kErrorShutdown;
            // and unblock DataInDataOutThread
            oplk_freeProcessImage(); //jba do we need it here?

            reachedNmtStateOff();
            break;

        case kNmtGsResetCommunication:
#if !defined(CONFIG_INCLUDE_CFM)
            ret = setDefaultNodeAssignment();
#endif
            pProcessThread_g->sigOplkStatus(1);
            break;

        case kNmtGsResetConfiguration:
#if !defined(CONFIG_INCLUDE_CFM)
        // Configuration Manager is not available,
        // so fetch object 0x1006 NMT_CycleLen_U32 from local OD
        // (in little endian byte order)
        // for configuration of remote CN
            varLen = sizeof(UINT32);
            ret = oplk_readObject(NULL, 0, 0x1006, 0x00, &cycleLen_g,
                                  &varLen, kSdoTypeAsnd, NULL);
            if (ret != kErrorOk)
            {
                sigPrintLog(QString("  oplk_readObject() failed with 0x%1\n\"2\"")
                                    .arg(ret)
                                    .arg(debugstr_getRetValStr(ret)));
                break;
            }
#endif
            sigOplkStatus(1);
            break;

        case kNmtCsNotActive:
        case kNmtMsNotActive:
        case kNmtRmsNotActive:
        case kNmtGsInitialising:
        case kNmtGsResetApplication:
        case kNmtCsPreOperational1:
        case kNmtMsPreOperational1:
        case kNmtCsPreOperational2:
        case kNmtMsPreOperational2:
        case kNmtCsReadyToOperate:
        case kNmtMsReadyToOperate:
        case kNmtCsBasicEthernet:
        case kNmtMsBasicEthernet:
            sigOplkStatus(1);
            break;

        case kNmtCsOperational:
        case kNmtMsOperational:
            sigOplkStatus(2);
            break;


        default:
            sigOplkStatus(-1);
            break;
    }

    return ret;
}