Пример #1
0
tEplKernel PUBLIC AppCbEvent(
    tEplApiEventType        EventType_p,   // IN: event type (enum)
    tEplApiEventArg*        pEventArg_p,   // IN: event argument (union)
    void GENERIC*           pUserArg_p)
{
tEplKernel          EplRet = kEplSuccessful;

    UNUSED_PARAMETER(pUserArg_p);

    // check if NMT_GS_OFF is reached
    switch (EventType_p)
    {
        case kEplApiEventNmtStateChange:
        {
            switch (pEventArg_p->m_NmtStateChange.m_NewNmtState)
            {
                case kEplNmtGsOff:
                {   // NMT state machine was shut down,
                    // because of user signal (CTRL-C) or critical EPL stack error
                    // -> also shut down EplApiProcess() and main()
                    EplRet = kEplShutdown;

                    PRINTF("%s:kEplNmtGsOff originating event = 0x%X (%s)\n",
                            __func__, pEventArg_p->m_NmtStateChange.m_NmtEvent,
                            EplGetNmtEventStr(pEventArg_p->m_NmtStateChange.m_NmtEvent));
                    // wake up EplLinExit()
                    /*atomic_set(&AtomicShutdown_g, TRUE);
                    wake_up_interruptible(&WaitQueueShutdown_g);*/
                    break;
                }

                case kEplNmtGsResetCommunication:
                {
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFM)) == 0)
                DWORD   dwNodeAssignment;

                    // configure OD for MN in state ResetComm after reseting the OD
                    // TODO: setup your own network configuration here
                    dwNodeAssignment = (EPL_NODEASSIGN_NODE_IS_CN |
                                        EPL_NODEASSIGN_NODE_EXISTS); // 0x00000003L
                    EplRet = EplApiWriteLocalObject(0x1F81, 0x01, &dwNodeAssignment,
                                                    sizeof (dwNodeAssignment));
                    EplRet = EplApiWriteLocalObject(0x1F81, 0x20, &dwNodeAssignment,
                                                    sizeof (dwNodeAssignment));
                    EplRet = EplApiWriteLocalObject(0x1F81, 0x6E, &dwNodeAssignment,
                                                    sizeof (dwNodeAssignment));
                    EplRet = EplApiWriteLocalObject(0x1F81, 0xFE, &dwNodeAssignment,
                                                    sizeof (dwNodeAssignment));

                    // dwNodeAssignment |= EPL_NODEASSIGN_MANDATORY_CN;    // 0x0000000BL
                    // EplRet = EplApiWriteLocalObject(0x1F81, 0x6E, &dwNodeAssignment, sizeof (dwNodeAssignment));
                    dwNodeAssignment = (EPL_NODEASSIGN_MN_PRES |
                                    EPL_NODEASSIGN_NODE_EXISTS);       // 0x00010001L
                    EplRet = EplApiWriteLocalObject(0x1F81, 0xF0, &dwNodeAssignment,
                                                    sizeof (dwNodeAssignment));
#endif
                }

                case kEplNmtGsResetConfiguration:
                {
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFM)) != 0)
                    if (uiCycleLen_g != 0)
                    {
                        EplRet = EplApiWriteLocalObject(0x1006, 0x00,
                                                        &uiCycleLen_g,
                                                        sizeof (uiCycleLen_g));
                    }
#else
                    unsigned int uiSize;

                    // fetch object 0x1006 NMT_CycleLen_U32 from local OD
                    // (in little endian byte order) for configuration of
                    // remote CN
                    uiSize = 4;
                    EplRet = EplApiReadObject(NULL, 0, 0x1006, 0x00,
                                              &dw_le_CycleLen_g, &uiSize,
                                              kEplSdoTypeAsnd, NULL);
                    if (EplRet != kEplSuccessful)
                    {   // local OD access failed
                        break;
                    }
#endif
                }

                case kEplNmtMsPreOperational1:
                {
                    PRINTF("%s(0x%X) originating event = 0x%X (%s)\n",
                            __func__,
                           pEventArg_p->m_NmtStateChange.m_NewNmtState,
                           pEventArg_p->m_NmtStateChange.m_NmtEvent,
                           EplGetNmtEventStr(pEventArg_p->m_NmtStateChange.m_NmtEvent));

                    // continue
                }

                case kEplNmtGsInitialising:
                case kEplNmtGsResetApplication:
                case kEplNmtMsNotActive:
                case kEplNmtCsNotActive:
                case kEplNmtCsPreOperational1:
                {
                    break;
                }

                case kEplNmtCsOperational:
                case kEplNmtMsOperational:
                {
                    break;
                }

                default:
                {
                    break;
                }
            }

            break;
        }

        case kEplApiEventCriticalError:
        case kEplApiEventWarning:
        {   // error or warning occurred within the stack or the application
            // on error the API layer stops the NMT state machine

            PRINTF("%s(Err/Warn): Source=%02X EplError=0x%03X",
                    __func__,
                    pEventArg_p->m_InternalError.m_EventSource,
                    pEventArg_p->m_InternalError.m_EplError);
            // check additional argument
            switch (pEventArg_p->m_InternalError.m_EventSource)
            {
                case kEplEventSourceEventk:
                case kEplEventSourceEventu:
                {   // error occurred within event processing
                    // either in kernel or in user part
                    PRINTF(" OrgSource=%02X\n",
                            pEventArg_p->m_InternalError.m_Arg.m_EventSource);
                    break;
                }

                case kEplEventSourceDllk:
                {   // error occurred within the data link layer (e.g. interrupt processing)
                    // the DWORD argument contains the DLL state and the NMT event
                    PRINTF(" val=%lX\n",
                            (ULONG) pEventArg_p->m_InternalError.m_Arg.m_dwArg);
                    break;
                }

                case kEplEventSourceObdk:
                case kEplEventSourceObdu:
                {   // error occurred within OBD module
                    // either in kernel or in user part
                    PRINTF(" Object=0x%04X/%u\n",
                            pEventArg_p->m_InternalError.m_Arg.m_ObdError.m_uiIndex,
                            pEventArg_p->m_InternalError.m_Arg.m_ObdError.m_uiSubIndex);
                    break;
                }

                default:
                {
                    PRINTF("\n");
                    break;
                }
            }
            break;
        }

        case kEplApiEventHistoryEntry:
        {   // new history entry
            PRINTF("%s(HistoryEntry): Type=0x%04X Code=0x%04X (0x%02X %02X %02X %02X %02X %02X %02X %02X)\n",
                    __func__,
                    pEventArg_p->m_ErrHistoryEntry.m_wEntryType,
                    pEventArg_p->m_ErrHistoryEntry.m_wErrorCode,
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[0],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[1],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[2],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[3],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[4],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[5],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[6],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[7]);
            break;
        }

        case kEplApiEventNode:
        {
            // check additional argument
            switch (pEventArg_p->m_Node.m_NodeEvent)
            {
                case kEplNmtNodeEventCheckConf:
                {
                    PRINTF("%s(Node=0x%X, CheckConf)\n", __func__,
                            pEventArg_p->m_Node.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeEventUpdateConf:
                {
                    PRINTF("%s(Node=0x%X, UpdateConf)\n", __func__,
                            pEventArg_p->m_Node.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeEventNmtState:
                {
                    PRINTF("%s(Node=0x%X, NmtState=0x%X)\n", __func__,
                            pEventArg_p->m_Node.m_uiNodeId,
                            pEventArg_p->m_Node.m_NmtState);
                    break;
                }

                case kEplNmtNodeEventError:
                {
                    PRINTF("%s (Node=0x%X): Error = %s (0x%.4X)\n", __func__,
                            pEventArg_p->m_Node.m_uiNodeId,
                            EplGetEmergErrCodeStr(pEventArg_p->m_Node.m_wErrorCode),
                            pEventArg_p->m_Node.m_wErrorCode);
                    break;
                }

                case kEplNmtNodeEventFound:
                {
                    PRINTF("%s(Node=0x%X, Found)\n", __func__,
                            pEventArg_p->m_Node.m_uiNodeId);
                    break;
                }

                default:
                {
                    break;
                }
            }
            break;
        }

#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFM)) != 0)
        case kEplApiEventCfmProgress:
        {
            PRINTF("%s(Node=0x%X, CFM-Progress: Object 0x%X/%u, ",
                    __func__, pEventArg_p->m_CfmProgress.m_uiNodeId,
                    pEventArg_p->m_CfmProgress.m_uiObjectIndex,
                    pEventArg_p->m_CfmProgress.m_uiObjectSubIndex);
            PRINTF("%lu/%lu Bytes",
                    (ULONG) pEventArg_p->m_CfmProgress.m_dwBytesDownloaded,
                    (ULONG) pEventArg_p->m_CfmProgress.m_dwTotalNumberOfBytes);
            if ((pEventArg_p->m_CfmProgress.m_dwSdoAbortCode != 0)
                || (pEventArg_p->m_CfmProgress.m_EplError != kEplSuccessful))
            {
                PRINTF(" -> SDO Abort=0x%lX, Error=0x%X)\n",
                        (unsigned long) pEventArg_p->m_CfmProgress.m_dwSdoAbortCode,
                        pEventArg_p->m_CfmProgress.m_EplError);
            }
            else
            {
                PRINTF(")\n");
            }
            break;
        }

        case kEplApiEventCfmResult:
        {
            switch (pEventArg_p->m_CfmResult.m_NodeCommand)
            {
                case kEplNmtNodeCommandConfOk:
                {
                    PRINTF("%s(Node=0x%X, ConfOk)\n", __func__,
                            pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfErr:
                {
                    PRINTF("%s(Node=0x%X, ConfErr)\n", __func__,
                            pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfReset:
                {
                    PRINTF("%s(Node=0x%X, ConfReset)\n", __func__,
                            pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfRestored:
                {
                    PRINTF("%s(Node=0x%X, ConfRestored)\n", __func__,
                            pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                default:
                {
                    PRINTF("%s(Node=0x%X, CfmResult=0x%X)\n", __func__,
                            pEventArg_p->m_CfmResult.m_uiNodeId,
                            pEventArg_p->m_CfmResult.m_NodeCommand);
                    break;
                }
            }
            break;
        }
#endif

        default:
            break;
    }

    return EplRet;
}
tEplKernel PUBLIC AppCbEvent
(
    tEplApiEventType        EventType_p,   // IN: event type (enum)
    tEplApiEventArg*        pEventArg_p,   // IN: event argument (union)
    void GENERIC*           pUserArg_p    //__attribute((unused))
)
{
    tEplKernel          EplRet = kEplSuccessful;
    UINT                uiVarLen;

    UNUSED_PARAMETER(pUserArg_p);

    // check if NMT_GS_OFF is reached
    switch (EventType_p)
    {
        case kEplApiEventNmtStateChange:
        {
            switch (pEventArg_p->m_NmtStateChange.m_NewNmtState)
            {
                case kEplNmtGsOff:
                {   // NMT state machine was shut down,
                    // because of user signal (CTRL-C) or critical EPL stack error
                    // -> also shut down EplApiProcess() and main()
                    EplRet = kEplShutdown;

                    printlog("Event:kEplNmtGsOff originating event = 0x%X (%s)\n", pEventArg_p->m_NmtStateChange.m_NmtEvent,
                             EplGetNmtEventStr(pEventArg_p->m_NmtStateChange.m_NmtEvent));
                    break;
                }

                case kEplNmtGsResetCommunication:
                {
                    // continue
                }

                case kEplNmtGsResetConfiguration:
                {
                    if (uiCycleLen_g != 0)
                    {
                        EplRet = EplApiWriteLocalObject(0x1006, 0x00, &uiCycleLen_g, sizeof (uiCycleLen_g));
                        uiCurCycleLen_g = uiCycleLen_g;
                    }
                    else
                    {
                        uiVarLen = sizeof(uiCurCycleLen_g);
                        EplApiReadLocalObject(0x1006, 0x00, &uiCurCycleLen_g, &uiVarLen);
                    }
                    // continue
                }

                case kEplNmtMsPreOperational1:
                {
                    printlog("AppCbEvent(0x%X) originating event = 0x%X (%s)\n",
                           pEventArg_p->m_NmtStateChange.m_NewNmtState,
                           pEventArg_p->m_NmtStateChange.m_NmtEvent,
                           EplGetNmtEventStr(pEventArg_p->m_NmtStateChange.m_NmtEvent));

                    // continue
                }

                case kEplNmtGsInitialising:
                case kEplNmtGsResetApplication:
                case kEplNmtMsNotActive:
                case kEplNmtCsNotActive:
                case kEplNmtCsPreOperational1:
                {
                    break;
                }

                case kEplNmtCsOperational:
                case kEplNmtMsOperational:
                {
                    break;
                }

                default:
                {
                    break;
                }
            }

            break;
        }

        case kEplApiEventCriticalError:
        case kEplApiEventWarning:
        {   // error or warning occurred within the stack or the application
            // on error the API layer stops the NMT state machine

            printlog( "%s(Err/Warn): Source = %s (%02X) EplError = %s (0x%03X)\n",
                        __func__,
                        EplGetEventSourceStr(pEventArg_p->m_InternalError.m_EventSource),
                        pEventArg_p->m_InternalError.m_EventSource,
                        EplGetEplKernelStr(pEventArg_p->m_InternalError.m_EplError),
                        pEventArg_p->m_InternalError.m_EplError
                        );
            FTRACE_MARKER("%s(Err/Warn): Source = %s (%02X) EplError = %s (0x%03X)\n",
                        __func__,
                        EplGetEventSourceStr(pEventArg_p->m_InternalError.m_EventSource),
                        pEventArg_p->m_InternalError.m_EventSource,
                        EplGetEplKernelStr(pEventArg_p->m_InternalError.m_EplError),
                        pEventArg_p->m_InternalError.m_EplError
                        );
            // check additional argument
            switch (pEventArg_p->m_InternalError.m_EventSource)
            {
                case kEplEventSourceEventk:
                case kEplEventSourceEventu:
                {   // error occurred within event processing
                    // either in kernel or in user part
                    printlog(" OrgSource = %s %02X\n",  EplGetEventSourceStr(pEventArg_p->m_InternalError.m_Arg.m_EventSource),
                                                        pEventArg_p->m_InternalError.m_Arg.m_EventSource);
                    FTRACE_MARKER(" OrgSource = %s %02X\n",     EplGetEventSourceStr(pEventArg_p->m_InternalError.m_Arg.m_EventSource),
                                                                pEventArg_p->m_InternalError.m_Arg.m_EventSource);
                    break;
                }

                case kEplEventSourceDllk:
                {   // error occurred within the data link layer (e.g. interrupt processing)
                    // the DWORD argument contains the DLL state and the NMT event
                    printlog(" val = %X\n", pEventArg_p->m_InternalError.m_Arg.m_dwArg);
                    FTRACE_MARKER(" val = %X\n", pEventArg_p->m_InternalError.m_Arg.m_dwArg);
                    break;
                }

                default:
                {
                    printlog("\n");
                    break;
                }
            }
            break;
        }

        case kEplApiEventHistoryEntry:
        {   // new history entry

            printlog("%s(HistoryEntry): Type=0x%04X Code=0x%04X (0x%02X %02X %02X %02X %02X %02X %02X %02X)\n",
                    __func__,
                    pEventArg_p->m_ErrHistoryEntry.m_wEntryType,
                    pEventArg_p->m_ErrHistoryEntry.m_wErrorCode,
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[0],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[1],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[2],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[3],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[4],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[5],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[6],
                    (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[7]);
            FTRACE_MARKER("%s(HistoryEntry): Type=0x%04X Code=0x%04X (0x%02X %02X %02X %02X %02X %02X %02X %02X)\n",
                                __func__,
                                pEventArg_p->m_ErrHistoryEntry.m_wEntryType,
                                pEventArg_p->m_ErrHistoryEntry.m_wErrorCode,
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[0],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[1],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[2],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[3],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[4],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[5],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[6],
                                (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[7]);
            break;
        }

        case kEplApiEventPdoChange:
        {
            unsigned int uiSubIndex;
            QWORD qwMappObject;

            printlog("%s(%sPDO=0x%X to node 0x%X with %d objects %s)\n",
                    __func__,
                    (pEventArg_p->m_PdoChange.m_fTx ? "T" : "R"),
                    pEventArg_p->m_PdoChange.m_uiPdoMappIndex,
                    pEventArg_p->m_PdoChange.m_uiNodeId,
                    pEventArg_p->m_PdoChange.m_uiMappObjectCount,
                    (pEventArg_p->m_PdoChange.m_fActivated ? "activated" : "deleted"));
            for (uiSubIndex = 1; uiSubIndex <= pEventArg_p->m_PdoChange.m_uiMappObjectCount; uiSubIndex++)
            {
                uiVarLen = sizeof(qwMappObject);
                EplRet = EplApiReadLocalObject(
                        pEventArg_p->m_PdoChange.m_uiPdoMappIndex,
                        uiSubIndex, &qwMappObject, &uiVarLen);
                if (EplRet != kEplSuccessful)
                {
                    printlog("  Reading 0x%X/%d failed with 0x%X\n",
                            pEventArg_p->m_PdoChange.m_uiPdoMappIndex,
                            uiSubIndex, EplRet);
                    continue;
                }
                printlog("  %d. mapped object 0x%X/%d\n",
                        uiSubIndex,
                        qwMappObject & 0x00FFFFULL,
                        (qwMappObject & 0xFF0000ULL) >> 16);
            }
            break;
        }

#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
        case kEplApiEventNode:
        {
            // check additional argument
            switch (pEventArg_p->m_Node.m_NodeEvent)
            {
                case kEplNmtNodeEventCheckConf:
                {
                    printlog("%s(Node=0x%X, CheckConf)\n", __func__, pEventArg_p->m_Node.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeEventUpdateConf:
                {
                    printlog("%s(Node=0x%X, UpdateConf)\n", __func__, pEventArg_p->m_Node.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeEventNmtState:
                {
                    printlog("%s(Node=0x%X, NmtState=%s)\n", __func__, pEventArg_p->m_Node.m_uiNodeId, EplGetNmtStateStr(pEventArg_p->m_Node.m_NmtState));

                    break;
                }

                case kEplNmtNodeEventError:
                {
                    printlog("%s (Node=0x%X): Error = %s (0x%.4X)\n", __func__,
                            pEventArg_p->m_Node.m_uiNodeId,
                            EplGetEmergErrCodeStr(pEventArg_p->m_Node.m_wErrorCode),
                            pEventArg_p->m_Node.m_wErrorCode);

                    break;
                }

                case kEplNmtNodeEventFound:
                {
                    printlog("%s(Node=0x%X, Found)\n", __func__, pEventArg_p->m_Node.m_uiNodeId);

                    break;
                }

                default:
                {
                    break;
                }
            }
            break;
        }

#endif

#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_CFM)) != 0)
       case kEplApiEventCfmProgress:
        {
            printlog("%s(Node=0x%X, CFM-Progress: Object 0x%X/%u, ", __func__, pEventArg_p->m_CfmProgress.m_uiNodeId, pEventArg_p->m_CfmProgress.m_uiObjectIndex, pEventArg_p->m_CfmProgress.m_uiObjectSubIndex);
            printlog("%lu/%lu Bytes", (ULONG) pEventArg_p->m_CfmProgress.m_dwBytesDownloaded, (ULONG) pEventArg_p->m_CfmProgress.m_dwTotalNumberOfBytes);
            if ((pEventArg_p->m_CfmProgress.m_dwSdoAbortCode != 0)
                || (pEventArg_p->m_CfmProgress.m_EplError != kEplSuccessful))
            {
                printlog(" -> SDO Abort=0x%lX, Error=0x%X)\n", (unsigned long) pEventArg_p->m_CfmProgress.m_dwSdoAbortCode,
                                                              pEventArg_p->m_CfmProgress.m_EplError);
            }
            else
            {
                printlog(")\n");
            }
            break;
        }

        case kEplApiEventCfmResult:
        {
            switch (pEventArg_p->m_CfmResult.m_NodeCommand)
            {
                case kEplNmtNodeCommandConfOk:
                {
                    printlog("%s(Node=0x%X, ConfOk)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfErr:
                {
                    printlog("%s(Node=0x%X, ConfErr)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfReset:
                {
                    printlog("%s(Node=0x%X, ConfReset)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                case kEplNmtNodeCommandConfRestored:
                {
                    printlog("%s(Node=0x%X, ConfRestored)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
                    break;
                }

                default:
                {
                    printlog("%s(Node=0x%X, CfmResult=0x%X)\n", __func__, pEventArg_p->m_CfmResult.m_uiNodeId, pEventArg_p->m_CfmResult.m_NodeCommand);
                    break;
                }
            }
            break;
        }
#endif

        default:
            break;
    }

    return EplRet;
}
Пример #3
0
//---------------------------------------------------------------------------
//
// Function:    AppCbEvent
//
// Description: event callback function called by EPL API layer within
//              user part (low priority).
//
// Parameters:  EventType_p     = event type
//              pEventArg_p     = pointer to union, which describes
//                                the event in detail
//              pUserArg_p      = user specific argument
//
// Returns:     tEplKernel      = error code,
//                                kEplSuccessful = no error
//                                kEplReject = reject further processing
//                                otherwise = post error event to API layer
//
// State:
//
//---------------------------------------------------------------------------
tEplKernel PUBLIC AppCbEvent (
			      tEplApiEventType EventType_p,   // IN: event type (enum)
			      tEplApiEventArg* pEventArg_p,   // IN: event argument (union)
			      io_sAgent* pUserArg_p    
			      )
{
    
  UINT uiVarLen;
  tEplKernel EplRet = kEplSuccessful;
  pwr_sClass_Epl_MN *op = (pwr_sClass_Epl_MN *)pUserArg_p->op;
  io_sRack *rp;
	
  // check if NMT_GS_OFF is reached
  switch (EventType_p) {
  case kEplApiEventNmtStateChange: {
    op->NmtState = pEventArg_p->m_NmtStateChange.m_NewNmtState;
    op->Status = op->NmtState == pwr_eEplNmtState_EplNmtMsOperational ? IOM__EPL_OPER : IOM__EPL_NOOPER;
			
    switch (pEventArg_p->m_NmtStateChange.m_NewNmtState) {
    case kEplNmtGsOff: {
      // NMT state machine was shut down,
      // because of user signal (CTRL-C) or critical EPL stack error
      // -> also shut down EplApiProcess() and main()
      EplRet = kEplShutdown;
					
      errh_Fatal("Event:kEplNmtGsOff originating event = 0x%X (%s)", pEventArg_p->m_NmtStateChange.m_NmtEvent,
		 EplGetNmtEventStr(pEventArg_p->m_NmtStateChange.m_NmtEvent));
                    
      break;
    }

    case kEplNmtGsResetCommunication: {
      break;
    }

    case kEplNmtGsResetConfiguration: {
      if (uiCycleLen_g != 0) {
	EplRet = EplApiWriteLocalObject(0x1006, 0x00, &uiCycleLen_g, sizeof (uiCycleLen_g));
	uiCurCycleLen_g = uiCycleLen_g;
      }
      else {
	uiVarLen = sizeof(uiCurCycleLen_g);
	EplApiReadLocalObject(0x1006, 0x00, &uiCurCycleLen_g, &uiVarLen);
      }
      break;
    }
    case kEplNmtCsPreOperational1:
    case kEplNmtMsPreOperational1: {
      errh_Info("AppCbEvent(0x%X) originating event = 0x%X (%s)", pEventArg_p->m_NmtStateChange.m_NewNmtState, pEventArg_p->m_NmtStateChange.m_NmtEvent, EplGetNmtEventStr(pEventArg_p->m_NmtStateChange.m_NmtEvent));
      break;
    }
				
    case kEplNmtCsPreOperational2:
    case kEplNmtMsPreOperational2: {
      break;
    }
    case kEplNmtCsReadyToOperate:
    case kEplNmtMsReadyToOperate: {
      break;
    }
    case kEplNmtGsInitialising: {
      break;
    }
    case kEplNmtGsResetApplication: {
      break;
    }
    case kEplNmtMsNotActive:
    case kEplNmtCsNotActive: {
      break;
    }
    case kEplNmtCsOperational:
    case kEplNmtMsOperational: {
      break;
    }
    case kEplNmtCsBasicEthernet:
    case kEplNmtMsBasicEthernet: {
      break;
    }

    default: {
    }
    }
            

    break;
  }

  case kEplApiEventCriticalError:
  case kEplApiEventWarning: {   
    // error or warning occurred within the stack or the application
    // on error the API layer stops the NMT state machine
			
    errh_Error( "%s(Err/Warn): Source = %s (%02X) EplError = %s (0x%03X)",
		__func__,
		EplGetEventSourceStr(pEventArg_p->m_InternalError.m_EventSource),
		pEventArg_p->m_InternalError.m_EventSource,
		EplGetEplKernelStr(pEventArg_p->m_InternalError.m_EplError),
		pEventArg_p->m_InternalError.m_EplError);
            
    // check additional argument
    switch (pEventArg_p->m_InternalError.m_EventSource) {
    case kEplEventSourceEventk:
    case kEplEventSourceEventu: {   
      // error occurred within event processing
      // either in kernel or in user part
                    
      errh_Error(" OrgSource = %s %02X",  EplGetEventSourceStr(pEventArg_p->m_InternalError.m_Arg.m_EventSource),
		 pEventArg_p->m_InternalError.m_Arg.m_EventSource);
                    
      break;
    }

    case kEplEventSourceDllk: {   
      // error occurred within the data link layer (e.g. interrupt processing)
      // the DWORD argument contains the DLL state and the NMT event
                    
      errh_Error(" val = %X", pEventArg_p->m_InternalError.m_Arg.m_dwArg);
                    
      break;
    }

    default: {
      break;
    }
    }
    break;
  }

  case kEplApiEventHistoryEntry: {   
    // new history entry
			
    errh_Info("%s(HistoryEntry): Type=0x%04X Code=0x%04X (0x%02X %02X %02X %02X %02X %02X %02X %02X)",
	      __func__,
	      pEventArg_p->m_ErrHistoryEntry.m_wEntryType,
	      pEventArg_p->m_ErrHistoryEntry.m_wErrorCode,
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[0],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[1],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[2],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[3],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[4],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[5],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[6],
	      (WORD) pEventArg_p->m_ErrHistoryEntry.m_abAddInfo[7]);
            
    break;
  }
        
  case kEplApiEventNode: {
    switch (pEventArg_p->m_Node.m_NodeEvent) {
    case kEplNmtNodeEventCheckConf: {
      errh_Info("%s(Node=0x%X, CheckConf)", __func__, pEventArg_p->m_Node.m_uiNodeId);
      break;
    }

    case kEplNmtNodeEventUpdateConf: {
      errh_Info("%s(Node=0x%X, UpdateConf)", __func__, pEventArg_p->m_Node.m_uiNodeId);
      break;
    }

    case kEplNmtNodeEventFound: {
                    
      break;
    }

    case kEplNmtNodeEventNmtState: {
      for ( rp = pUserArg_p->racklist; rp; rp = rp->next)
	if(((pwr_sClass_Epl_CN *)rp->op)->NodeId == pEventArg_p->m_Node.m_uiNodeId) {
	  ((pwr_sClass_Epl_CN *)rp->op)->NmtState = pEventArg_p->m_Node.m_NmtState;
		  
	}
					
      switch (pEventArg_p->m_Node.m_NmtState) {
      case kEplNmtGsOff:
      case kEplNmtGsInitialising:
      case kEplNmtGsResetApplication:
      case kEplNmtGsResetCommunication:
      case kEplNmtGsResetConfiguration:
      case kEplNmtCsNotActive: {                           
	break;
      }
      case kEplNmtCsPreOperational1:
      case kEplNmtCsPreOperational2:
      case kEplNmtCsReadyToOperate: {                            
	break;
      }
      case kEplNmtCsOperational: {                            
	break;
      }
      case kEplNmtCsBasicEthernet:
      case kEplNmtCsStopped:
      default: {                            
	break;
      }
      }
      break;
    }

    case kEplNmtNodeEventError: {
                    
      errh_Error("AppCbEvent (Node=0x%X): Error = %s (0x%.4X)",
		 pEventArg_p->m_Node.m_uiNodeId,
		 EplGetEmergErrCodeStr(pEventArg_p->m_Node.m_wErrorCode),
		 pEventArg_p->m_Node.m_wErrorCode);
      break;
    }

    default: {
      break;
    }
    }
    break;
  }

  case kEplApiEventCfmProgress: {
    errh_Info("%s(Node=0x%X, CFM-Progress: Object 0x%X/%u,  %lu/%lu Bytes", __func__, pEventArg_p->m_CfmProgress.m_uiNodeId, pEventArg_p->m_CfmProgress.m_uiObjectIndex, pEventArg_p->m_CfmProgress.m_uiObjectSubIndex, (ULONG) pEventArg_p->m_CfmProgress.m_dwBytesDownloaded, (ULONG) pEventArg_p->m_CfmProgress.m_dwTotalNumberOfBytes);

    if ((pEventArg_p->m_CfmProgress.m_dwSdoAbortCode != 0)
	|| (pEventArg_p->m_CfmProgress.m_EplError != kEplSuccessful)) {
      errh_Error(" -> SDO Abort=0x%lX, Error=0x%X)", (unsigned long) pEventArg_p->m_CfmProgress.m_dwSdoAbortCode,
		 pEventArg_p->m_CfmProgress.m_EplError);
    }
    else {
    }
    break;
  }

  case kEplApiEventCfmResult: {
    switch (pEventArg_p->m_CfmResult.m_NodeCommand) {
    case kEplNmtNodeCommandConfOk: {
      errh_Info("%s(Node=0x%X, ConfOk)", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
      break;
    }

    case kEplNmtNodeCommandConfErr: {
      errh_Info("%s(Node=0x%X, ConfErr)", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
      break;
    }

    case kEplNmtNodeCommandConfReset: {
      errh_Info("%s(Node=0x%X, ConfReset)", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
      break;
    }

    case kEplNmtNodeCommandConfRestored: {
      errh_Info("%s(Node=0x%X, ConfRestored)", __func__, pEventArg_p->m_CfmResult.m_uiNodeId);
      break;
    }

    default: {
      errh_Info("%s(Node=0x%X, CfmResult=0x%X)", __func__, pEventArg_p->m_CfmResult.m_uiNodeId, pEventArg_p->m_CfmResult.m_NodeCommand);
      break;
    }
    }
    break;
  }

  default:
    break;
  }

  return EplRet;
}