//---------------------------------------------------------------------------
//
// Function:        EplNmtkProcess
//
// Description: main process function
//              -> process NMT-State-Maschine und read NMT-Events from Queue
//
//
//
// Parameters:  EPL_MCO_DECL_PTR_INSTANCE_PTR_ = Instance pointer
//              pEvent_p    =   Epl-Event with NMT-event to process
//
//
// Returns:     tEplKernel  =   Errorcode
//
//
// State:
//
//---------------------------------------------------------------------------
EPLDLLEXPORT tEplKernel PUBLIC EplNmtkProcess(EPL_MCO_DECL_PTR_INSTANCE_PTR_
					      tEplEvent * pEvent_p)
{
	tEplKernel Ret;
	tEplNmtState OldNmtState;
	tEplNmtEvent NmtEvent;
	tEplEvent Event;
	tEplEventNmtStateChange NmtStateChange;

	// check for all API function if instance is valid
	EPL_MCO_CHECK_INSTANCE_STATE();

	Ret = kEplSuccessful;

	switch (pEvent_p->m_EventType) {
	case kEplEventTypeNmtEvent:
		{
			NmtEvent = *((tEplNmtEvent *) pEvent_p->m_pArg);
			break;
		}

	case kEplEventTypeTimer:
		{
			NmtEvent =
			    (tEplNmtEvent) ((tEplTimerEventArg *) pEvent_p->
					    m_pArg)->m_ulArg;
			break;
		}
	default:
		{
			Ret = kEplNmtInvalidEvent;
			goto Exit;
		}
	}

	// save NMT-State
	// needed for later comparison to
	// inform hgher layer about state change
	OldNmtState = EPL_MCO_GLB_VAR(m_NmtState);

	// NMT-State-Maschine
	switch (EPL_MCO_GLB_VAR(m_NmtState)) {
		//-----------------------------------------------------------
		// general part of the statemaschine

		// first init of the hardware
	case kEplNmtGsOff:
		{
			// leave this state only if higher layer says so
			if (NmtEvent == kEplNmtEventSwReset) {	// new state kEplNmtGsInitialising
				EPL_MCO_GLB_VAR(m_NmtState) =
				    kEplNmtGsInitialising;
			}
			break;
		}

		// first init of the hardware
	case kEplNmtGsInitialising:
		{
			// leave this state only if higher layer says so

			// check events
			switch (NmtEvent) {
				// 2006/07/31 d.k.: react also on NMT reset commands in ResetApp state
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// new state kEplNmtGsResetApplication
			case kEplNmtEventEnterResetApp:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

			default:
				{
					break;
				}
			}
			break;
		}

		// init of the manufacturer-specific profile area and the
		// standardised device profile area
	case kEplNmtGsResetApplication:
		{
			// check events
			switch (NmtEvent) {
				// 2006/07/31 d.k.: react also on NMT reset commands in ResetApp state
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// leave this state only if higher layer
				// say so
			case kEplNmtEventEnterResetCom:
				{
					// new state kEplNmtGsResetCommunication
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

			default:
				{
					break;
				}
			}
			break;
		}

		// init of the communication profile area
	case kEplNmtGsResetCommunication:
		{
			// check events
			switch (NmtEvent) {
				// 2006/07/31 d.k.: react also on NMT reset commands in ResetComm state
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// leave this state only if higher layer
				// say so
			case kEplNmtEventEnterResetConfig:
				{
					// new state kEplNmtGsResetCommunication
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
					break;
				}

			default:
				{
					break;
				}
			}
			break;
		}

		// build the configuration with infos from OD
	case kEplNmtGsResetConfiguration:
		{
			// reset flags
			EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) = FALSE;
			EPL_MCO_GLB_VAR(m_fAppReadyToOperate) = FALSE;
			EPL_MCO_GLB_VAR(m_fFrozen) = FALSE;

			// check events
			switch (NmtEvent) {
				// 2006/07/31 d.k.: react also on NMT reset commands in ResetConf state
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// NMT Command ResetCommunication
			case kEplNmtEventResetCom:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// leave this state only if higher layer says so
			case kEplNmtEventEnterCsNotActive:
				{	// Node should be CN
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsNotActive;
					break;

				}

			case kEplNmtEventEnterMsNotActive:
				{	// Node should be CN
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0)
					// no MN functionality
					// TODO: -create error E_NMT_BA1_NO_MN_SUPPORT
					EPL_MCO_GLB_VAR(m_fFrozen) = TRUE;
#else

					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtMsNotActive;
#endif
					break;

				}

			default:
				{
					break;
				}
			}
			break;
		}

		//-----------------------------------------------------------
		// CN part of the statemaschine

		// node liste for EPL-Frames and check timeout
	case kEplNmtCsNotActive:
		{

			// check events
			switch (NmtEvent) {
				// 2006/07/31 d.k.: react also on NMT reset commands in NotActive state
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
					break;
				}

				// NMT Command ResetCommunication
				// or internal Communication error
			case kEplNmtEventResetCom:
			case kEplNmtEventInternComError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
					break;
				}

				// NMT Command Reset Configuration
			case kEplNmtEventResetConfig:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
					break;
				}

				// see if SoA or SoC received
				// k.t. 20.07.2006: only SoA forces change of state
				// see EPL V2 DS 1.0.0 p.267
				// case kEplNmtEventDllCeSoc:
			case kEplNmtEventDllCeSoa:
				{	// new state PRE_OPERATIONAL1
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsPreOperational1;
//                    Ret = EplTimerkDeleteTimer(&EPL_MCO_GLB_VAR(m_TimerHdl));
					break;
				}
				// timeout for SoA and Soc
			case kEplNmtEventTimerBasicEthernet:
				{
					// new state BASIC_ETHERNET
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsBasicEthernet;
					break;
				}

			default:
				{
					break;
				}
			}	// end of switch(NmtEvent)

			break;
		}

		// node processes only async frames
	case kEplNmtCsPreOperational1:
		{

			// check events
			switch (NmtEvent) {
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// NMT Command ResetCommunication
				// or internal Communication error
			case kEplNmtEventResetCom:
			case kEplNmtEventInternComError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// NMT Command Reset Configuration
			case kEplNmtEventResetConfig:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
					break;
				}

				// NMT Command StopNode
			case kEplNmtEventStopNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsStopped;
					break;
				}

				// check if SoC received
			case kEplNmtEventDllCeSoc:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsPreOperational2;
					break;
				}

			default:
				{
					break;
				}

			}	// end of switch(NmtEvent)

			break;
		}

		// node processes isochronous and asynchronous frames
	case kEplNmtCsPreOperational2:
		{
			// check events
			switch (NmtEvent) {
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// NMT Command ResetCommunication
				// or internal Communication error
			case kEplNmtEventResetCom:
			case kEplNmtEventInternComError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// NMT Command Reset Configuration
			case kEplNmtEventResetConfig:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
					break;
				}

				// NMT Command StopNode
			case kEplNmtEventStopNode:
				{
					// reset flags
					EPL_MCO_GLB_VAR(m_fEnableReadyToOperate)
					    = FALSE;
					EPL_MCO_GLB_VAR(m_fAppReadyToOperate) =
					    FALSE;
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsStopped;
					break;
				}

				// error occured
			case kEplNmtEventNmtCycleError:
				{
					// reset flags
					EPL_MCO_GLB_VAR(m_fEnableReadyToOperate)
					    = FALSE;
					EPL_MCO_GLB_VAR(m_fAppReadyToOperate) =
					    FALSE;
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsPreOperational1;
					break;
				}

				// check if application is ready to operate
			case kEplNmtEventEnterReadyToOperate:
				{
					// check if command NMTEnableReadyToOperate from MN was received
					if (EPL_MCO_GLB_VAR(m_fEnableReadyToOperate) == TRUE) {	// reset flags
						EPL_MCO_GLB_VAR
						    (m_fEnableReadyToOperate) =
						    FALSE;
						EPL_MCO_GLB_VAR
						    (m_fAppReadyToOperate) =
						    FALSE;
						// change state
						EPL_MCO_GLB_VAR(m_NmtState) =
						    kEplNmtCsReadyToOperate;
					} else {	// set Flag
						EPL_MCO_GLB_VAR
						    (m_fAppReadyToOperate) =
						    TRUE;
					}
					break;
				}

				// NMT Commando EnableReadyToOperate
			case kEplNmtEventEnableReadyToOperate:
				{
					// check if application is ready
					if (EPL_MCO_GLB_VAR(m_fAppReadyToOperate) == TRUE) {	// reset flags
						EPL_MCO_GLB_VAR
						    (m_fEnableReadyToOperate) =
						    FALSE;
						EPL_MCO_GLB_VAR
						    (m_fAppReadyToOperate) =
						    FALSE;
						// change state
						EPL_MCO_GLB_VAR(m_NmtState) =
						    kEplNmtCsReadyToOperate;
					} else {	// set Flag
						EPL_MCO_GLB_VAR
						    (m_fEnableReadyToOperate) =
						    TRUE;
					}
					break;
				}

			default:
				{
					break;
				}

			}	// end of switch(NmtEvent)
			break;
		}

		// node should be configured und application is ready
	case kEplNmtCsReadyToOperate:
		{
			// check events
			switch (NmtEvent) {
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// NMT Command ResetCommunication
				// or internal Communication error
			case kEplNmtEventResetCom:
			case kEplNmtEventInternComError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// NMT Command ResetConfiguration
			case kEplNmtEventResetConfig:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
					break;
				}

				// NMT Command StopNode
			case kEplNmtEventStopNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsStopped;
					break;
				}

				// error occured
			case kEplNmtEventNmtCycleError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsPreOperational1;
					break;
				}

				// NMT Command StartNode
			case kEplNmtEventStartNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsOperational;
					break;
				}

			default:
				{
					break;
				}

			}	// end of switch(NmtEvent)
			break;
		}

		// normal work state
	case kEplNmtCsOperational:
		{

			// check events
			switch (NmtEvent) {
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// NMT Command ResetCommunication
				// or internal Communication error
			case kEplNmtEventResetCom:
			case kEplNmtEventInternComError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// NMT Command ResetConfiguration
			case kEplNmtEventResetConfig:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
					break;
				}

				// NMT Command StopNode
			case kEplNmtEventStopNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsStopped;
					break;
				}

				// NMT Command EnterPreOperational2
			case kEplNmtEventEnterPreOperational2:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsPreOperational2;
					break;
				}

				// error occured
			case kEplNmtEventNmtCycleError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsPreOperational1;
					break;
				}

			default:
				{
					break;
				}

			}	// end of switch(NmtEvent)
			break;
		}

		// node stopped by MN
		// -> only process asynchronous frames
	case kEplNmtCsStopped:
		{
			// check events
			switch (NmtEvent) {
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// NMT Command ResetCommunication
				// or internal Communication error
			case kEplNmtEventResetCom:
			case kEplNmtEventInternComError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// NMT Command ResetConfiguration
			case kEplNmtEventResetConfig:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
					break;
				}

				// NMT Command EnterPreOperational2
			case kEplNmtEventEnterPreOperational2:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsPreOperational2;
					break;
				}

				// error occured
			case kEplNmtEventNmtCycleError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsPreOperational1;
					break;
				}

			default:
				{
					break;
				}

			}	// end of switch(NmtEvent)
			break;
		}

		// no epl cycle
		// -> normal ethernet communication
	case kEplNmtCsBasicEthernet:
		{
			// check events
			switch (NmtEvent) {
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// NMT Command ResetCommunication
				// or internal Communication error
			case kEplNmtEventResetCom:
			case kEplNmtEventInternComError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// NMT Command ResetConfiguration
			case kEplNmtEventResetConfig:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
					break;
				}

				// error occured
				// d.k.: how does this error occur? on CRC errors
/*                case kEplNmtEventNmtCycleError:
                {
                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
                    break;
                }
*/
			case kEplNmtEventDllCeSoc:
			case kEplNmtEventDllCePreq:
			case kEplNmtEventDllCePres:
			case kEplNmtEventDllCeSoa:
				{	// Epl-Frame on net -> stop any communication
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtCsPreOperational1;
					break;
				}

			default:
				{
					break;
				}

			}	// end of switch(NmtEvent)

			break;
		}

		//-----------------------------------------------------------
		// MN part of the statemaschine

		// MN listen to network
		// -> if no EPL traffic go to next state
	case kEplNmtMsNotActive:
		{
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0)
			// no MN functionality
			// TODO: -create error E_NMT_BA1_NO_MN_SUPPORT
			EPL_MCO_GLB_VAR(m_fFrozen) = TRUE;
#else

			// check events
			switch (NmtEvent) {
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// NMT Command ResetCommunication
				// or internal Communication error
			case kEplNmtEventResetCom:
			case kEplNmtEventInternComError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// NMT Command ResetConfiguration
			case kEplNmtEventResetConfig:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
					break;
				}

				// EPL frames received
			case kEplNmtEventDllCeSoc:
			case kEplNmtEventDllCeSoa:
				{	// other MN in network
					// $$$ d.k.: generate error history entry
					EPL_MCO_GLB_VAR(m_fFrozen) = TRUE;
					break;
				}

				// timeout event
			case kEplNmtEventTimerBasicEthernet:
				{
					if (EPL_MCO_GLB_VAR(m_fFrozen) == FALSE) {	// new state BasicEthernet
						EPL_MCO_GLB_VAR(m_NmtState) =
						    kEplNmtMsBasicEthernet;
					}
					break;
				}

				// timeout event
			case kEplNmtEventTimerMsPreOp1:
				{
					if (EPL_MCO_GLB_VAR(m_fFrozen) == FALSE) {	// new state PreOp1
						EPL_MCO_GLB_VAR(m_NmtState) =
						    kEplNmtMsPreOperational1;
						EPL_MCO_GLB_VAR
						    (m_fTimerMsPreOp2) = FALSE;
						EPL_MCO_GLB_VAR
						    (m_fAllMandatoryCNIdent) =
						    FALSE;

					}
					break;
				}

			default:
				{
					break;
				}

			}	// end of switch(NmtEvent)

#endif // ((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) == 0)

			break;
		}
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
		// MN process reduces epl cycle
	case kEplNmtMsPreOperational1:
		{
			// check events
			switch (NmtEvent) {
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// NMT Command ResetCommunication
				// or internal Communication error
			case kEplNmtEventResetCom:
			case kEplNmtEventInternComError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// NMT Command ResetConfiguration
			case kEplNmtEventResetConfig:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
					break;
				}

				// EPL frames received
			case kEplNmtEventDllCeSoc:
			case kEplNmtEventDllCeSoa:
				{	// other MN in network
					// $$$ d.k.: generate error history entry
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// error occured
				// d.k. MSPreOp1->CSPreOp1: nonsense -> keep state
				/*
				   case kEplNmtEventNmtCycleError:
				   {
				   EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
				   break;
				   }
				 */

			case kEplNmtEventAllMandatoryCNIdent:
				{	// all mandatory CN identified
					if (EPL_MCO_GLB_VAR(m_fTimerMsPreOp2) !=
					    FALSE) {
						EPL_MCO_GLB_VAR(m_NmtState) =
						    kEplNmtMsPreOperational2;
					} else {
						EPL_MCO_GLB_VAR
						    (m_fAllMandatoryCNIdent) =
						    TRUE;
					}
					break;
				}

			case kEplNmtEventTimerMsPreOp2:
				{	// residence time for PreOp1 is elapsed
					if (EPL_MCO_GLB_VAR
					    (m_fAllMandatoryCNIdent) != FALSE) {
						EPL_MCO_GLB_VAR(m_NmtState) =
						    kEplNmtMsPreOperational2;
					} else {
						EPL_MCO_GLB_VAR
						    (m_fTimerMsPreOp2) = TRUE;
					}
					break;
				}

			default:
				{
					break;
				}

			}	// end of switch(NmtEvent)
			break;
		}

		// MN process full epl cycle
	case kEplNmtMsPreOperational2:
		{
			// check events
			switch (NmtEvent) {
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// NMT Command ResetCommunication
				// or internal Communication error
			case kEplNmtEventResetCom:
			case kEplNmtEventInternComError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// NMT Command ResetConfiguration
			case kEplNmtEventResetConfig:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
					break;
				}

				// EPL frames received
			case kEplNmtEventDllCeSoc:
			case kEplNmtEventDllCeSoa:
				{	// other MN in network
					// $$$ d.k.: generate error history entry
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// error occured
			case kEplNmtEventNmtCycleError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtMsPreOperational1;
					break;
				}

			case kEplNmtEventEnterReadyToOperate:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtMsReadyToOperate;
					break;
				}

			default:
				{
					break;
				}

			}	// end of switch(NmtEvent)

			break;
		}

		// all madatory nodes ready to operate
		// -> MN process full epl cycle
	case kEplNmtMsReadyToOperate:
		{

			// check events
			switch (NmtEvent) {
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// NMT Command ResetCommunication
				// or internal Communication error
			case kEplNmtEventResetCom:
			case kEplNmtEventInternComError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// NMT Command ResetConfiguration
			case kEplNmtEventResetConfig:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
					break;
				}

				// EPL frames received
			case kEplNmtEventDllCeSoc:
			case kEplNmtEventDllCeSoa:
				{	// other MN in network
					// $$$ d.k.: generate error history entry
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// error occured
			case kEplNmtEventNmtCycleError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtMsPreOperational1;
					break;
				}

			case kEplNmtEventEnterMsOperational:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtMsOperational;
					break;
				}

			default:
				{
					break;
				}

			}	// end of switch(NmtEvent)

			break;
		}

		// normal eplcycle processing
	case kEplNmtMsOperational:
		{
			// check events
			switch (NmtEvent) {
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// NMT Command ResetCommunication
				// or internal Communication error
			case kEplNmtEventResetCom:
			case kEplNmtEventInternComError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// NMT Command ResetConfiguration
			case kEplNmtEventResetConfig:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
					break;
				}

				// EPL frames received
			case kEplNmtEventDllCeSoc:
			case kEplNmtEventDllCeSoa:
				{	// other MN in network
					// $$$ d.k.: generate error history entry
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// error occured
			case kEplNmtEventNmtCycleError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtMsPreOperational1;
					break;
				}

			default:
				{
					break;
				}

			}	// end of switch(NmtEvent)
			break;
		}

		//  normal ethernet traffic
	case kEplNmtMsBasicEthernet:
		{

			// check events
			switch (NmtEvent) {
				// NMT Command SwitchOff
			case kEplNmtEventCriticalError:
			case kEplNmtEventSwitchOff:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsOff;
					break;
				}

				// NMT Command SwReset
			case kEplNmtEventSwReset:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsInitialising;
					break;
				}

				// NMT Command ResetNode
			case kEplNmtEventResetNode:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetApplication;
					break;
				}

				// NMT Command ResetCommunication
				// or internal Communication error
			case kEplNmtEventResetCom:
			case kEplNmtEventInternComError:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// NMT Command ResetConfiguration
			case kEplNmtEventResetConfig:
				{
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetConfiguration;
					break;
				}

				// EPL frames received
			case kEplNmtEventDllCeSoc:
			case kEplNmtEventDllCeSoa:
				{	// other MN in network
					// $$$ d.k.: generate error history entry
					EPL_MCO_GLB_VAR(m_NmtState) =
					    kEplNmtGsResetCommunication;
					break;
				}

				// error occured
				// d.k. BE->PreOp1 on cycle error? No
/*                case kEplNmtEventNmtCycleError:
                {
                    EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtCsPreOperational1;
                    break;
                }
*/
			default:
				{
					break;
				}

			}	// end of switch(NmtEvent)
			break;
		}
#endif //#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)

	default:
		{
			//DEBUG_EPL_DBGLVL_NMTK_TRACE0(EPL_DBGLVL_NMT ,"Error in EplNmtProcess: Unknown NMT-State");
			//EPL_MCO_GLB_VAR(m_NmtState) = kEplNmtGsResetApplication;
			Ret = kEplNmtInvalidState;
			goto Exit;
		}

	}			// end of switch(NmtEvent)

	// inform higher layer about State-Change if needed
	if (OldNmtState != EPL_MCO_GLB_VAR(m_NmtState)) {
		EPL_NMTK_DBG_POST_TRACE_VALUE(NmtEvent, OldNmtState,
					      EPL_MCO_GLB_VAR(m_NmtState));

		// d.k.: memorize NMT state before posting any events
		NmtStateChange.m_NewNmtState = EPL_MCO_GLB_VAR(m_NmtState);

		// inform DLL
		if ((OldNmtState > kEplNmtGsResetConfiguration)
		    && (EPL_MCO_GLB_VAR(m_NmtState) <=
			kEplNmtGsResetConfiguration)) {
			// send DLL DEINIT
			Event.m_EventSink = kEplEventSinkDllk;
			Event.m_EventType = kEplEventTypeDllkDestroy;
			EPL_MEMSET(&Event.m_NetTime, 0x00,
				   sizeof(Event.m_NetTime));
			Event.m_pArg = &OldNmtState;
			Event.m_uiSize = sizeof(OldNmtState);
			// d.k.: directly call DLLk process function, because
			//       1. execution of process function is still synchonized and serialized,
			//       2. it is the same as without event queues (i.e. well tested),
			//       3. DLLk will get those necessary events even if event queue is full,
			//       4. event queue is very inefficient
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
			Ret = EplDllkProcess(&Event);
#else
			Ret = EplEventkPost(&Event);
#endif
		} else if ((OldNmtState <= kEplNmtGsResetConfiguration)
			   && (EPL_MCO_GLB_VAR(m_NmtState) >
			       kEplNmtGsResetConfiguration)) {
			// send DLL INIT
			Event.m_EventSink = kEplEventSinkDllk;
			Event.m_EventType = kEplEventTypeDllkCreate;
			EPL_MEMSET(&Event.m_NetTime, 0x00,
				   sizeof(Event.m_NetTime));
			Event.m_pArg = &NmtStateChange.m_NewNmtState;
			Event.m_uiSize = sizeof(NmtStateChange.m_NewNmtState);
			// d.k.: directly call DLLk process function, because
			//       1. execution of process function is still synchonized and serialized,
			//       2. it is the same as without event queues (i.e. well tested),
			//       3. DLLk will get those necessary events even if event queue is full
			//       4. event queue is very inefficient
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
			Ret = EplDllkProcess(&Event);
#else
			Ret = EplEventkPost(&Event);
#endif
		} else
		    if ((EPL_MCO_GLB_VAR(m_NmtState) == kEplNmtCsBasicEthernet)
			|| (EPL_MCO_GLB_VAR(m_NmtState) ==
			    kEplNmtMsBasicEthernet)) {
			tEplDllAsyncReqPriority AsyncReqPriority;

			// send DLL Fill Async Tx Buffer, because state BasicEthernet was entered
			Event.m_EventSink = kEplEventSinkDllk;
			Event.m_EventType = kEplEventTypeDllkFillTx;
			EPL_MEMSET(&Event.m_NetTime, 0x00,
				   sizeof(Event.m_NetTime));
			AsyncReqPriority = kEplDllAsyncReqPrioGeneric;
			Event.m_pArg = &AsyncReqPriority;
			Event.m_uiSize = sizeof(AsyncReqPriority);
			// d.k.: directly call DLLk process function, because
			//       1. execution of process function is still synchonized and serialized,
			//       2. it is the same as without event queues (i.e. well tested),
			//       3. DLLk will get those necessary events even if event queue is full
			//       4. event queue is very inefficient
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
			Ret = EplDllkProcess(&Event);
#else
			Ret = EplEventkPost(&Event);
#endif
		}
		// inform higher layer about state change
		NmtStateChange.m_NmtEvent = NmtEvent;
		Event.m_EventSink = kEplEventSinkNmtu;
		Event.m_EventType = kEplEventTypeNmtStateChange;
		EPL_MEMSET(&Event.m_NetTime, 0x00, sizeof(Event.m_NetTime));
		Event.m_pArg = &NmtStateChange;
		Event.m_uiSize = sizeof(NmtStateChange);
		Ret = EplEventkPost(&Event);
		EPL_DBGLVL_NMTK_TRACE2
		    ("EplNmtkProcess(NMT-Event = 0x%04X): New NMT-State = 0x%03X\n",
		     NmtEvent, NmtStateChange.m_NewNmtState);

	}

      Exit:

	return Ret;
}
tEplKernel PUBLIC EplEventkProcess(tEplEvent* pEvent_p)
{
tEplKernel              Ret;
tEplEventSource         EventSource;

    Ret = kEplSuccessful;

#if (EPL_USE_SHAREDBUFF != FALSE) \
    && (EPL_EVENT_USE_KERNEL_QUEUE != FALSE)
    // error handling if event queue is full
    if (EplEventkInstance_g.m_uiUserToKernelFullCount > 0)
    {   // UserToKernel event queue has run out of space -> kEplNmtEventInternComError
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
        tEplEvent   Event;
        tEplNmtEvent NmtEvent;
#endif

        // directly call NMTk process function, because event queue is full
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
        NmtEvent = kEplNmtEventInternComError;
        Event.m_EventSink = kEplEventSinkNmtk;
        Event.m_NetTime.m_dwNanoSec = 0;
        Event.m_NetTime.m_dwSec = 0;
        Event.m_EventType = kEplEventTypeNmtEvent;
        Event.m_pArg = &NmtEvent;
        Event.m_uiSize = sizeof(NmtEvent);
        Ret = EplNmtkProcess(&Event);
#endif

        // NMT state machine changed to reset (i.e. NMT_GS_RESET_COMMUNICATION)
        // now, it is safe to reset the counter and empty the event queue
        ShbCirResetBuffer (EplEventkInstance_g.m_pShbUserToKernelInstance, 1000, NULL);

        EplEventkInstance_g.m_uiUserToKernelFullCount = 0;
        TGT_DBG_SIGNAL_TRACE_POINT(22);

        // also discard the current event (it doesn't matter if we lose another event)
        goto Exit;
    }
#endif

    // check m_EventSink
    switch(pEvent_p->m_EventSink)
    {
        // NMT-Kernel-Modul
        case kEplEventSinkNmtk:
        {
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
            Ret = EplNmtkProcess(pEvent_p);
            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
            {
                EventSource = kEplEventSourceNmtk;

                // Error event for API layer
                EplEventkPostError(kEplEventSourceEventk,
                                Ret,
                                sizeof(EventSource),
                                &EventSource);
            }
#endif
            BENCHMARK_MOD_27_RESET(0);
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
            if ((pEvent_p->m_EventType == kEplEventTypeNmtEvent)
                && (*((tEplNmtEvent*)pEvent_p->m_pArg) == kEplNmtEventDllCeSoa))
            {

                BENCHMARK_MOD_27_SET(0);

#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
                // forward SoA event to DLLk module for cycle preprocessing
                Ret = EplDllkProcess(pEvent_p);
                if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
                {
                    EventSource = kEplEventSourceDllk;

                    // Error event for API layer
                    EplEventkPostError(kEplEventSourceEventk,
                                    Ret,
                                    sizeof(EventSource),
                                    &EventSource);
                }
#endif
                BENCHMARK_MOD_27_RESET(0);

            }
#endif
            break;
        }

        // events for Dllk module
        case kEplEventSinkDllk:
        {
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
            Ret = EplDllkProcess(pEvent_p);
            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
            {
                EventSource = kEplEventSourceDllk;

                // Error event for API layer
                EplEventkPostError(kEplEventSourceEventk,
                                Ret,
                                sizeof(EventSource),
                                &EventSource);
            }
#endif
            break;
        }

        // events for DllkCal module
        case kEplEventSinkDllkCal:
        {
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
            Ret = EplDllkCalProcess(pEvent_p);
            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
            {
                EventSource = kEplEventSourceDllk;

                // Error event for API layer
                EplEventkPostError(kEplEventSourceEventk,
                                Ret,
                                sizeof(EventSource),
                                &EventSource);
            }
#endif
            break;
        }

#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
        // events for PDO CAL module
        case kEplEventSinkPdokCal:
        {
            Ret = EplPdokCalProcess(pEvent_p);
            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
            {
                EventSource = kEplEventSourcePdok;

                // Error event for API layer
                EplEventkPostError(kEplEventSourceEventk,
                                Ret,
                                sizeof(EventSource),
                                &EventSource);
            }
            break;
        }
#endif

#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
        // events for Error handler module
        case kEplEventSinkErrk:
        {
            // only call error handler if DLL is present
            Ret = EplErrorHandlerkProcess(pEvent_p);
            if ((Ret != kEplSuccessful) && (Ret != kEplShutdown))
            {
                EventSource = kEplEventSourceErrk;

                // Error event for API layer
                EplEventkPostError(kEplEventSourceEventk,
                                Ret,
                                sizeof(EventSource),
                                &EventSource);
            }
            break;
        }
#endif

        // unknown sink
        default:
        {
            Ret = kEplEventUnknownSink;

            // Error event for API layer
            EplEventkPostError(kEplEventSourceEventk,
                            Ret,
                            sizeof(pEvent_p->m_EventSink),
                            &pEvent_p->m_EventSink);
        }

    } // end of switch(pEvent_p->m_EventSink)

#if (EPL_USE_SHAREDBUFF != FALSE) \
    && (EPL_EVENT_USE_KERNEL_QUEUE != FALSE)
Exit:
#endif
    return Ret;

}
示例#3
0
tEplKernel EplEventkProcess(tEplEvent *pEvent_p)
{
	tEplKernel Ret;
	tEplEventSource EventSource;

	Ret = kEplSuccessful;

	// error handling if event queue is full
	if (EplEventkInstance_g.m_uiUserToKernelFullCount > 0) {	// UserToKernel event queue has run out of space -> kEplNmtEventInternComError
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
		tEplEvent Event;
		tEplNmtEvent NmtEvent;
#endif
#ifndef EPL_NO_FIFO
		tShbError ShbError;
#endif

		// directly call NMTk process function, because event queue is full
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
		NmtEvent = kEplNmtEventInternComError;
		Event.m_EventSink = kEplEventSinkNmtk;
		Event.m_NetTime.m_dwNanoSec = 0;
		Event.m_NetTime.m_dwSec = 0;
		Event.m_EventType = kEplEventTypeNmtEvent;
		Event.m_pArg = &NmtEvent;
		Event.m_uiSize = sizeof(NmtEvent);
		Ret = EplNmtkProcess(&Event);
#endif

		// NMT state machine changed to reset (i.e. NMT_GS_RESET_COMMUNICATION)
		// now, it is safe to reset the counter and empty the event queue
#ifndef EPL_NO_FIFO
		ShbError =
		    ShbCirResetBuffer(EplEventkInstance_g.
				      m_pShbUserToKernelInstance, 1000, NULL);
#endif

		EplEventkInstance_g.m_uiUserToKernelFullCount = 0;
		TGT_DBG_SIGNAL_TRACE_POINT(22);

		// also discard the current event (it doesn't matter if we lose another event)
		goto Exit;
	}
	// check m_EventSink
	switch (pEvent_p->m_EventSink) {
	case kEplEventSinkSync:
		{
			if (EplEventkInstance_g.m_pfnCbSync != NULL) {
				Ret = EplEventkInstance_g.m_pfnCbSync();
				if (Ret == kEplSuccessful) {
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
					// mark TPDOs as valid
					Ret = EplPdokCalSetTpdosValid(TRUE);
#endif
				} else if ((Ret != kEplReject)
					   && (Ret != kEplShutdown)) {
					EventSource = kEplEventSourceSyncCb;

					// Error event for API layer
					EplEventkPostError
					    (kEplEventSourceEventk, Ret,
					     sizeof(EventSource), &EventSource);
				}
			}
			break;
		}

		// NMT-Kernel-Modul
	case kEplEventSinkNmtk:
		{
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
			Ret = EplNmtkProcess(pEvent_p);
			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
				EventSource = kEplEventSourceNmtk;

				// Error event for API layer
				EplEventkPostError(kEplEventSourceEventk,
						   Ret,
						   sizeof(EventSource),
						   &EventSource);
			}
#endif
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
			if ((pEvent_p->m_EventType == kEplEventTypeNmtEvent)
			    &&
			    ((*((tEplNmtEvent *) pEvent_p->m_pArg) ==
			      kEplNmtEventDllCeSoa)
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
			     || (*((tEplNmtEvent *) pEvent_p->m_pArg) ==
				 kEplNmtEventDllMeSoaSent)
#endif
			    )) {	// forward SoA event to error handler
				Ret = EplErrorHandlerkProcess(pEvent_p);
				if ((Ret != kEplSuccessful)
				    && (Ret != kEplShutdown)) {
					EventSource = kEplEventSourceErrk;

					// Error event for API layer
					EplEventkPostError
					    (kEplEventSourceEventk, Ret,
					     sizeof(EventSource), &EventSource);
				}
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
				// forward SoA event to PDO module
				pEvent_p->m_EventType = kEplEventTypePdoSoa;
				Ret = EplPdokProcess(pEvent_p);
				if ((Ret != kEplSuccessful)
				    && (Ret != kEplShutdown)) {
					EventSource = kEplEventSourcePdok;

					// Error event for API layer
					EplEventkPostError
					    (kEplEventSourceEventk, Ret,
					     sizeof(EventSource), &EventSource);
				}
#endif

			}
			break;
#endif
		}

		// events for Dllk module
	case kEplEventSinkDllk:
		{
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
			Ret = EplDllkProcess(pEvent_p);
			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
				EventSource = kEplEventSourceDllk;

				// Error event for API layer
				EplEventkPostError(kEplEventSourceEventk,
						   Ret,
						   sizeof(EventSource),
						   &EventSource);
			}
#endif
			break;
		}

		// events for DllkCal module
	case kEplEventSinkDllkCal:
		{
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
			Ret = EplDllkCalProcess(pEvent_p);
			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
				EventSource = kEplEventSourceDllk;

				// Error event for API layer
				EplEventkPostError(kEplEventSourceEventk,
						   Ret,
						   sizeof(EventSource),
						   &EventSource);
			}
#endif
			break;
		}

		//
	case kEplEventSinkPdok:
		{
			// PDO-Module
#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
			Ret = EplPdokProcess(pEvent_p);
			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
				EventSource = kEplEventSourcePdok;

				// Error event for API layer
				EplEventkPostError(kEplEventSourceEventk,
						   Ret,
						   sizeof(EventSource),
						   &EventSource);
			}
#endif
			break;
		}

		// events for Error handler module
	case kEplEventSinkErrk:
		{
			// only call error handler if DLL is present
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
			Ret = EplErrorHandlerkProcess(pEvent_p);
			if ((Ret != kEplSuccessful) && (Ret != kEplShutdown)) {
				EventSource = kEplEventSourceErrk;

				// Error event for API layer
				EplEventkPostError(kEplEventSourceEventk,
						   Ret,
						   sizeof(EventSource),
						   &EventSource);
			}
			break;
#endif
		}

		// unknown sink
	default:
		{
			Ret = kEplEventUnknownSink;
		}

	}			// end of switch(pEvent_p->m_EventSink)

      Exit:
	return Ret;

}