/****************************************************************************

  (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
      www.systec-electronic.com

  Project:      openPOWERLINK

  Description:  source file for NMT-MN-Module

  License:

    Redistribution and use in source and binary forms, with or without
    modification, are permitted provided that the following conditions
    are met:

    1. Redistributions of source code must retain the above copyright
       notice, this list of conditions and the following disclaimer.

    2. Redistributions in binary form must reproduce the above copyright
       notice, this list of conditions and the following disclaimer in the
       documentation and/or other materials provided with the distribution.

    3. Neither the name of SYSTEC electronic GmbH nor the names of its
       contributors may be used to endorse or promote products derived
       from this software without prior written permission. For written
       permission, please contact info@systec-electronic.com.

    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
    FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
    COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
    INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
    BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
    CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
    LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
    ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
    POSSIBILITY OF SUCH DAMAGE.

    Severability Clause:

        If a provision of this License is or becomes illegal, invalid or
        unenforceable in any jurisdiction, that shall not affect:
        1. the validity or enforceability in that jurisdiction of any other
           provision of this License; or
        2. the validity or enforceability in other jurisdictions of that or
           any other provision of this License.

  -------------------------------------------------------------------------

                $RCSfile: EplNmtMnu.c,v $

                $Author: D.Krueger $

                $Revision: 1.18 $  $Date: 2008/11/19 09:52:24 $

                $State: Exp $

                Build Environment:
                    GCC V3.4

  -------------------------------------------------------------------------

  Revision History:

  2006/06/09 k.t.:   start of the implementation

****************************************************************************/

#include "user/EplNmtMnu.h"
#include "user/EplTimeru.h"
#include "user/EplIdentu.h"
#include "user/EplStatusu.h"
#include "user/EplObdu.h"
#include "user/EplDlluCal.h"
#include "Benchmark.h"

#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)

#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE)
#error "EPL NmtMnu module needs EPL module OBDU or OBDK!"
#endif

//=========================================================================//
//                                                                         //
//          P R I V A T E   D E F I N I T I O N S                          //
//                                                                         //
//=========================================================================//

//---------------------------------------------------------------------------
// const defines
//---------------------------------------------------------------------------

// TracePoint support for realtime-debugging
#ifdef _DBG_TRACE_POINTS_
void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
#define TGT_DBG_SIGNAL_TRACE_POINT(p)   TgtDbgSignalTracePoint(p)
#define TGT_DBG_POST_TRACE_VALUE(v)     TgtDbgPostTraceValue(v)
#else
#define TGT_DBG_SIGNAL_TRACE_POINT(p)
#define TGT_DBG_POST_TRACE_VALUE(v)
#endif
#define EPL_NMTMNU_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \
    TGT_DBG_POST_TRACE_VALUE((kEplEventSinkNmtMnu << 28) | (Event_p << 24) \
                             | (uiNodeId_p << 16) | wErrorCode_p)

// defines for flags in node info structure
#define EPL_NMTMNU_NODE_FLAG_ISOCHRON       0x0001	// CN is being accessed isochronously
#define EPL_NMTMNU_NODE_FLAG_NOT_SCANNED    0x0002	// CN was not scanned once -> decrement SignalCounter and reset flag
#define EPL_NMTMNU_NODE_FLAG_HALTED         0x0004	// boot process for this CN is halted
#define EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED 0x0008	// NMT command was just issued, wrong NMT states will be tolerated
#define EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ  0x0300	// counter for StatusRequest timer handle
#define EPL_NMTMNU_NODE_FLAG_COUNT_LONGER   0x0C00	// counter for longer timeouts timer handle
#define EPL_NMTMNU_NODE_FLAG_INC_STATREQ    0x0100	// increment for StatusRequest timer handle
#define EPL_NMTMNU_NODE_FLAG_INC_LONGER     0x0400	// increment for longer timeouts timer handle
		    // These counters will be incremented at every timer start
		    // and copied to timerarg. When the timer event occures
		    // both will be compared and if unequal the timer event
		    // will be discarded, because it is an old one.

// defines for timer arguments to draw a distinction between serveral events
#define EPL_NMTMNU_TIMERARG_NODE_MASK   0x000000FFL	// mask that contains the node-ID
#define EPL_NMTMNU_TIMERARG_IDENTREQ    0x00010000L	// timer event is for IdentRequest
#define EPL_NMTMNU_TIMERARG_STATREQ     0x00020000L	// timer event is for StatusRequest
#define EPL_NMTMNU_TIMERARG_LONGER      0x00040000L	// timer event is for longer timeouts
#define EPL_NMTMNU_TIMERARG_STATE_MON   0x00080000L	// timer event for StatusRequest to monitor execution of NMT state changes
#define EPL_NMTMNU_TIMERARG_COUNT_SR    0x00000300L	// counter for StatusRequest
#define EPL_NMTMNU_TIMERARG_COUNT_LO    0x00000C00L	// counter for longer timeouts
		    // The counters must have the same position as in the node flags above.

#define EPL_NMTMNU_SET_FLAGS_TIMERARG_STATREQ(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
    pNodeInfo_p->m_wFlags = \
        ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \
         & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \
        | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
    TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_STATREQ | uiNodeId_p | \
        (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
    TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;

#define EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
    pNodeInfo_p->m_wFlags = \
        ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \
         & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \
        | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
    TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_IDENTREQ | uiNodeId_p | \
        (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
    TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;

#define EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
    pNodeInfo_p->m_wFlags = \
        ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_LONGER) \
         & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER) \
        | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_LONGER); \
    TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p | \
        (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER); \
    TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;

#define EPL_NMTMNU_SET_FLAGS_TIMERARG_STATE_MON(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
    pNodeInfo_p->m_wFlags = \
        ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \
         & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \
        | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
    TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_STATE_MON | uiNodeId_p | \
        (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
    TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;

// defines for global flags
#define EPL_NMTMNU_FLAG_HALTED          0x0001	// boot process is halted
#define EPL_NMTMNU_FLAG_APP_INFORMED    0x0002	// application was informed about possible NMT state change

// return pointer to node info structure for specified node ID
// d.k. may be replaced by special (hash) function if node ID array is smaller than 254
#define EPL_NMTMNU_GET_NODEINFO(uiNodeId_p) (&EplNmtMnuInstance_g.m_aNodeInfo[uiNodeId_p - 1])

//---------------------------------------------------------------------------
// local types
//---------------------------------------------------------------------------

typedef enum {
	kEplNmtMnuIntNodeEventNoIdentResponse = 0x00,
	kEplNmtMnuIntNodeEventIdentResponse = 0x01,
	kEplNmtMnuIntNodeEventBoot = 0x02,
	kEplNmtMnuIntNodeEventExecReset = 0x03,
	kEplNmtMnuIntNodeEventConfigured = 0x04,
	kEplNmtMnuIntNodeEventNoStatusResponse = 0x05,
	kEplNmtMnuIntNodeEventStatusResponse = 0x06,
	kEplNmtMnuIntNodeEventHeartbeat = 0x07,
	kEplNmtMnuIntNodeEventNmtCmdSent = 0x08,
	kEplNmtMnuIntNodeEventTimerIdentReq = 0x09,
	kEplNmtMnuIntNodeEventTimerStatReq = 0x0A,
	kEplNmtMnuIntNodeEventTimerStateMon = 0x0B,
	kEplNmtMnuIntNodeEventTimerLonger = 0x0C,
	kEplNmtMnuIntNodeEventError = 0x0D,

} tEplNmtMnuIntNodeEvent;

typedef enum {
	kEplNmtMnuNodeStateUnknown = 0x00,
	kEplNmtMnuNodeStateIdentified = 0x01,
	kEplNmtMnuNodeStateResetConf = 0x02,	// CN reset after configuration update
	kEplNmtMnuNodeStateConfigured = 0x03,	// BootStep1 completed
	kEplNmtMnuNodeStateReadyToOp = 0x04,	// BootStep2 completed
	kEplNmtMnuNodeStateComChecked = 0x05,	// Communication checked successfully
	kEplNmtMnuNodeStateOperational = 0x06,	// CN is in NMT state OPERATIONAL

} tEplNmtMnuNodeState;

typedef struct {
	tEplTimerHdl m_TimerHdlStatReq;	// timer to delay StatusRequests and IdentRequests
	tEplTimerHdl m_TimerHdlLonger;	// 2nd timer for NMT command EnableReadyToOp and CheckCommunication
	tEplNmtMnuNodeState m_NodeState;	// internal node state (kind of sub state of NMT state)
	DWORD m_dwNodeCfg;	// subindex from 0x1F81
	WORD m_wFlags;		// flags: CN is being accessed isochronously

} tEplNmtMnuNodeInfo;

typedef struct {
	tEplNmtMnuNodeInfo m_aNodeInfo[EPL_NMT_MAX_NODE_ID];
	tEplTimerHdl m_TimerHdlNmtState;	// timeout for stay in NMT state
	unsigned int m_uiMandatorySlaveCount;
	unsigned int m_uiSignalSlaveCount;
	unsigned long m_ulStatusRequestDelay;	// in [ms] (object 0x1006 * EPL_C_NMT_STATREQ_CYCLE)
	unsigned long m_ulTimeoutReadyToOp;	// in [ms] (object 0x1F89/5)
	unsigned long m_ulTimeoutCheckCom;	// in [ms] (object 0x1006 * MultiplexedCycleCount)
	WORD m_wFlags;		// global flags
	DWORD m_dwNmtStartup;	// object 0x1F80 NMT_StartUp_U32
	tEplNmtMnuCbNodeEvent m_pfnCbNodeEvent;
	tEplNmtMnuCbBootEvent m_pfnCbBootEvent;

} tEplNmtMnuInstance;

//---------------------------------------------------------------------------
// local vars
//---------------------------------------------------------------------------

static tEplNmtMnuInstance EplNmtMnuInstance_g;

//---------------------------------------------------------------------------
// local function prototypes
//---------------------------------------------------------------------------

static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p);

static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
						  tEplIdentResponse *
						  pIdentResponse_p);

static tEplKernel PUBLIC EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
						   tEplStatusResponse *
						   pStatusResponse_p);

static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
					 tEplNmtMnuNodeInfo * pNodeInfo_p,
					 tEplNmtState NodeNmtState_p,
					 WORD wErrorCode_p,
					 tEplNmtState LocalNmtState_p);

static tEplKernel EplNmtMnuStartBootStep1(void);

static tEplKernel EplNmtMnuStartBootStep2(void);

static tEplKernel EplNmtMnuStartCheckCom(void);

static tEplKernel EplNmtMnuNodeBootStep2(unsigned int uiNodeId_p,
					 tEplNmtMnuNodeInfo * pNodeInfo_p);

static tEplKernel EplNmtMnuNodeCheckCom(unsigned int uiNodeId_p,
					tEplNmtMnuNodeInfo * pNodeInfo_p);

static tEplKernel EplNmtMnuStartNodes(void);

static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
						tEplNmtState NodeNmtState_p,
						WORD wErrorCode_p,
						tEplNmtMnuIntNodeEvent
						NodeEvent_p);

static tEplKernel EplNmtMnuReset(void);

//=========================================================================//
//                                                                         //
//          P U B L I C   F U N C T I O N S                                //
//                                                                         //
//=========================================================================//

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuInit
//
// Description: init first instance of the module
//
//
//
// Parameters:
//
//
// Returns:     tEplKernel  = errorcode
//
//
// State:
//
//---------------------------------------------------------------------------

tEplKernel EplNmtMnuInit(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
			 tEplNmtMnuCbBootEvent pfnCbBootEvent_p)
{
	tEplKernel Ret;

	Ret = EplNmtMnuAddInstance(pfnCbNodeEvent_p, pfnCbBootEvent_p);

	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuAddInstance
//
// Description: init other instances of the module
//
//
//
// Parameters:
//
//
// Returns:     tEplKernel  = errorcode
//
//
// State:
//
//---------------------------------------------------------------------------

tEplKernel EplNmtMnuAddInstance(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
				tEplNmtMnuCbBootEvent pfnCbBootEvent_p)
{
	tEplKernel Ret;

	Ret = kEplSuccessful;

	// reset instance structure
	EPL_MEMSET(&EplNmtMnuInstance_g, 0, sizeof(EplNmtMnuInstance_g));

	if ((pfnCbNodeEvent_p == NULL) || (pfnCbBootEvent_p == NULL)) {
		Ret = kEplNmtInvalidParam;
		goto Exit;
	}
	EplNmtMnuInstance_g.m_pfnCbNodeEvent = pfnCbNodeEvent_p;
	EplNmtMnuInstance_g.m_pfnCbBootEvent = pfnCbBootEvent_p;

	// initialize StatusRequest delay
	EplNmtMnuInstance_g.m_ulStatusRequestDelay = 5000L;

	// register NmtMnResponse callback function
	Ret =
	    EplDlluCalRegAsndService(kEplDllAsndNmtRequest,
				     EplNmtMnuCbNmtRequest,
				     kEplDllAsndFilterLocal);

      Exit:
	return Ret;

}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuDelInstance
//
// Description: delete instance
//
//
//
// Parameters:
//
//
// Returns:     tEplKernel  = errorcode
//
//
// State:
//
//---------------------------------------------------------------------------

tEplKernel EplNmtMnuDelInstance()
{
	tEplKernel Ret;

	Ret = kEplSuccessful;

	// deregister NmtMnResponse callback function
	Ret =
	    EplDlluCalRegAsndService(kEplDllAsndNmtRequest, NULL,
				     kEplDllAsndFilterNone);

	Ret = EplNmtMnuReset();

	return Ret;

}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuSendNmtCommandEx
//
// Description: sends the specified NMT command to the specified node.
//
// Parameters:  uiNodeId_p              = node ID to which the NMT command will be sent
//              NmtCommand_p            = NMT command
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------

tEplKernel EplNmtMnuSendNmtCommandEx(unsigned int uiNodeId_p,
				     tEplNmtCommand NmtCommand_p,
				     void *pNmtCommandData_p,
				     unsigned int uiDataSize_p)
{
	tEplKernel Ret = kEplSuccessful;
	tEplFrameInfo FrameInfo;
	BYTE abBuffer[EPL_C_DLL_MINSIZE_NMTCMDEXT];
	tEplFrame *pFrame = (tEplFrame *) abBuffer;
	BOOL fSoftDeleteNode = FALSE;

	if ((uiNodeId_p == 0) || (uiNodeId_p > EPL_C_ADR_BROADCAST)) {	// invalid node ID specified
		Ret = kEplInvalidNodeId;
		goto Exit;
	}

	if ((pNmtCommandData_p != NULL)
	    && (uiDataSize_p >
		(EPL_C_DLL_MINSIZE_NMTCMDEXT - EPL_C_DLL_MINSIZE_NMTCMD))) {
		Ret = kEplNmtInvalidParam;
		goto Exit;
	}
	// $$$ d.k. may be check in future versions if the caller wants to perform prohibited state transitions
	//     the CN should not perform these transitions, but the expected NMT state will be changed and never fullfilled.

	// build frame
	EPL_MEMSET(pFrame, 0x00, sizeof(abBuffer));
	AmiSetByteToLe(&pFrame->m_le_bDstNodeId, (BYTE) uiNodeId_p);
	AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId,
		       (BYTE) kEplDllAsndNmtCommand);
	AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.
		       m_le_bNmtCommandId, (BYTE) NmtCommand_p);
	if ((pNmtCommandData_p != NULL) && (uiDataSize_p > 0)) {	// copy command data to frame
		EPL_MEMCPY(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.
			   m_le_abNmtCommandData[0], pNmtCommandData_p,
			   uiDataSize_p);
	}
	// build info structure
	FrameInfo.m_NetTime.m_dwNanoSec = 0;
	FrameInfo.m_NetTime.m_dwSec = 0;
	FrameInfo.m_pFrame = pFrame;
	FrameInfo.m_uiFrameSize = sizeof(abBuffer);

	// send NMT-Request
#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
	Ret = EplDlluCalAsyncSend(&FrameInfo,	// pointer to frameinfo
				  kEplDllAsyncReqPrioNmt);	// priority
#endif
	if (Ret != kEplSuccessful) {
		goto Exit;
	}

	EPL_DBGLVL_NMTMN_TRACE2("NMTCmd(%02X->%02X)\n", NmtCommand_p,
				uiNodeId_p);

	switch (NmtCommand_p) {
	case kEplNmtCmdStartNode:
	case kEplNmtCmdEnterPreOperational2:
	case kEplNmtCmdEnableReadyToOperate:
		{
			// nothing left to do,
			// because any further processing is done
			// when the NMT command is actually sent
			goto Exit;
		}

	case kEplNmtCmdStopNode:
		{
			fSoftDeleteNode = TRUE;
			break;
		}

	case kEplNmtCmdResetNode:
	case kEplNmtCmdResetCommunication:
	case kEplNmtCmdResetConfiguration:
	case kEplNmtCmdSwReset:
		{
			break;
		}

	default:
		goto Exit;
	}

	// remove CN from isochronous phase;
	// This must be done here and not when NMT command is actually sent
	// because it will be too late and may cause unwanted errors
	if (uiNodeId_p != EPL_C_ADR_BROADCAST) {
		if (fSoftDeleteNode == FALSE) {	// remove CN immediately from isochronous phase
			Ret = EplDlluCalDeleteNode(uiNodeId_p);
		} else {	// remove CN from isochronous phase softly
			Ret = EplDlluCalSoftDeleteNode(uiNodeId_p);
		}
	} else {		// do it for all active CNs
		for (uiNodeId_p = 1;
		     uiNodeId_p <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
		     uiNodeId_p++) {
			if ((EPL_NMTMNU_GET_NODEINFO(uiNodeId_p)->
			     m_dwNodeCfg & (EPL_NODEASSIGN_NODE_IS_CN |
					    EPL_NODEASSIGN_NODE_EXISTS)) != 0) {
				if (fSoftDeleteNode == FALSE) {	// remove CN immediately from isochronous phase
					Ret = EplDlluCalDeleteNode(uiNodeId_p);
				} else {	// remove CN from isochronous phase softly
					Ret =
					    EplDlluCalSoftDeleteNode
					    (uiNodeId_p);
				}
			}
		}
	}

      Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuSendNmtCommand
//
// Description: sends the specified NMT command to the specified node.
//
// Parameters:  uiNodeId_p              = node ID to which the NMT command will be sent
//              NmtCommand_p            = NMT command
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------

tEplKernel EplNmtMnuSendNmtCommand(unsigned int uiNodeId_p,
				   tEplNmtCommand NmtCommand_p)
{
	tEplKernel Ret = kEplSuccessful;

	Ret = EplNmtMnuSendNmtCommandEx(uiNodeId_p, NmtCommand_p, NULL, 0);

//Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuTriggerStateChange
//
// Description: triggers the specified node command for the specified node.
//
// Parameters:  uiNodeId_p              = node ID for which the node command will be executed
//              NodeCommand_p           = node command
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------

tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p,
				       tEplNmtNodeCommand NodeCommand_p)
{
	tEplKernel Ret = kEplSuccessful;
	tEplNmtMnuIntNodeEvent NodeEvent;
	tEplObdSize ObdSize;
	BYTE bNmtState;
	WORD wErrorCode = EPL_E_NO_ERROR;

	if ((uiNodeId_p == 0) || (uiNodeId_p >= EPL_C_ADR_BROADCAST)) {
		Ret = kEplInvalidNodeId;
		goto Exit;
	}

	switch (NodeCommand_p) {
	case kEplNmtNodeCommandBoot:
		{
			NodeEvent = kEplNmtMnuIntNodeEventBoot;
			break;
		}

	case kEplNmtNodeCommandConfOk:
		{
			NodeEvent = kEplNmtMnuIntNodeEventConfigured;
			break;
		}

	case kEplNmtNodeCommandConfErr:
		{
			NodeEvent = kEplNmtMnuIntNodeEventError;
			wErrorCode = EPL_E_NMT_BPO1_CF_VERIFY;
			break;
		}

	case kEplNmtNodeCommandConfReset:
		{
			NodeEvent = kEplNmtMnuIntNodeEventExecReset;
			break;
		}

	default:
		{		// invalid node command
			goto Exit;
		}
	}

	// fetch current NMT state
	ObdSize = 1;
	Ret = EplObduReadEntry(0x1F8E, uiNodeId_p, &bNmtState, &ObdSize);
	if (Ret != kEplSuccessful) {
		goto Exit;
	}

	Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
					    (tEplNmtState) (bNmtState |
							    EPL_NMT_TYPE_CS),
					    wErrorCode, NodeEvent);

      Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuCbNmtStateChange
//
// Description: callback function for NMT state changes
//
// Parameters:  NmtStateChange_p        = NMT state change event
//
// Returns:     tEplKernel              = error code
//
//
// State:
//
//---------------------------------------------------------------------------

tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
					    NmtStateChange_p)
{
	tEplKernel Ret = kEplSuccessful;

	// do work which must be done in that state
	switch (NmtStateChange_p.m_NewNmtState) {
		// EPL stack is not running
/*        case kEplNmtGsOff:
            break;

        // first init of the hardware
        case kEplNmtGsInitialising:
            break;

        // init of the manufacturer-specific profile area and the
        // standardised device profile area
        case kEplNmtGsResetApplication:
        {
            break;
        }

        // init of the communication profile area
        case kEplNmtGsResetCommunication:
        {
            break;
        }
*/
		// build the configuration with infos from OD
	case kEplNmtGsResetConfiguration:
		{
			DWORD dwTimeout;
			tEplObdSize ObdSize;

			// read object 0x1F80 NMT_StartUp_U32
			ObdSize = 4;
			Ret =
			    EplObduReadEntry(0x1F80, 0,
					     &EplNmtMnuInstance_g.
					     m_dwNmtStartup, &ObdSize);
			if (Ret != kEplSuccessful) {
				break;
			}
			// compute StatusReqDelay = object 0x1006 * EPL_C_NMT_STATREQ_CYCLE
			ObdSize = sizeof(dwTimeout);
			Ret = EplObduReadEntry(0x1006, 0, &dwTimeout, &ObdSize);
			if (Ret != kEplSuccessful) {
				break;
			}
			if (dwTimeout != 0L) {
				EplNmtMnuInstance_g.m_ulStatusRequestDelay =
				    dwTimeout * EPL_C_NMT_STATREQ_CYCLE / 1000L;
				if (EplNmtMnuInstance_g.
				    m_ulStatusRequestDelay == 0L) {
					EplNmtMnuInstance_g.m_ulStatusRequestDelay = 1L;	// at least 1 ms
				}
				// $$$ fetch and use MultiplexedCycleCount from OD
				EplNmtMnuInstance_g.m_ulTimeoutCheckCom =
				    dwTimeout * EPL_C_NMT_STATREQ_CYCLE / 1000L;
				if (EplNmtMnuInstance_g.m_ulTimeoutCheckCom ==
				    0L) {
					EplNmtMnuInstance_g.m_ulTimeoutCheckCom = 1L;	// at least 1 ms
				}
			}
			// fetch ReadyToOp Timeout from OD
			ObdSize = sizeof(dwTimeout);
			Ret = EplObduReadEntry(0x1F89, 5, &dwTimeout, &ObdSize);
			if (Ret != kEplSuccessful) {
				break;
			}
			if (dwTimeout != 0L) {
				// convert [us] to [ms]
				dwTimeout /= 1000L;
				if (dwTimeout == 0L) {
					dwTimeout = 1L;	// at least 1 ms
				}
				EplNmtMnuInstance_g.m_ulTimeoutReadyToOp =
				    dwTimeout;
			} else {
				EplNmtMnuInstance_g.m_ulTimeoutReadyToOp = 0L;
			}
			break;
		}
/*
        //-----------------------------------------------------------
        // CN part of the state machine

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

        // node process only async frames
        case kEplNmtCsPreOperational1:
        {
            break;
        }

        // node process isochronus and asynchronus frames
        case kEplNmtCsPreOperational2:
        {
            break;
        }

        // node should be configured und application is ready
        case kEplNmtCsReadyToOperate:
        {
            break;
        }

        // normal work state
        case kEplNmtCsOperational:
        {
            break;
        }

        // node stopped by MN
        // -> only process asynchronus frames
        case kEplNmtCsStopped:
        {
            break;
        }

        // no EPL cycle
        // -> normal ethernet communication
        case kEplNmtCsBasicEthernet:
        {
            break;
        }
*/
		//-----------------------------------------------------------
		// MN part of the state machine

		// node listens for EPL-Frames and check timeout
	case kEplNmtMsNotActive:
		{
			break;
		}

		// node processes only async frames
	case kEplNmtMsPreOperational1:
		{
			DWORD dwTimeout;
			tEplTimerArg TimerArg;
			tEplObdSize ObdSize;
			tEplEvent Event;

			// clear global flags, e.g. reenable boot process
			EplNmtMnuInstance_g.m_wFlags = 0;

			// reset IdentResponses and running IdentRequests and StatusRequests
			Ret = EplIdentuReset();
			Ret = EplStatusuReset();

			// reset timers
			Ret = EplNmtMnuReset();

			// 2008/11/18 d.k. reset internal node info is not necessary,
			//                 because timer flags are important and other
			//                 things are reset by EplNmtMnuStartBootStep1().
/*
            EPL_MEMSET(EplNmtMnuInstance_g.m_aNodeInfo,
                       0,
                       sizeof (EplNmtMnuInstance_g.m_aNodeInfo));
*/

			// inform DLL about NMT state change,
			// so that it can clear the asynchonous queues and start the reduced cycle
			Event.m_EventSink = kEplEventSinkDllk;
			Event.m_EventType = kEplEventTypeDllkStartReducedCycle;
			EPL_MEMSET(&Event.m_NetTime, 0x00,
				   sizeof(Event.m_NetTime));
			Event.m_pArg = NULL;
			Event.m_uiSize = 0;
			Ret = EplEventuPost(&Event);
			if (Ret != kEplSuccessful) {
				break;
			}
			// reset all nodes
			// d.k.: skip this step if was just done before, e.g. because of a ResetNode command from a diagnostic node
			if (NmtStateChange_p.m_NmtEvent ==
			    kEplNmtEventTimerMsPreOp1) {
				BENCHMARK_MOD_07_TOGGLE(9);

				EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
								EPL_C_ADR_BROADCAST,
								kEplNmtCmdResetNode);

				Ret =
				    EplNmtMnuSendNmtCommand(EPL_C_ADR_BROADCAST,
							    kEplNmtCmdResetNode);
				if (Ret != kEplSuccessful) {
					break;
				}
			}
			// start network scan
			Ret = EplNmtMnuStartBootStep1();

			// start timer for 0x1F89/2 MNTimeoutPreOp1_U32
			ObdSize = sizeof(dwTimeout);
			Ret = EplObduReadEntry(0x1F89, 2, &dwTimeout, &ObdSize);
			if (Ret != kEplSuccessful) {
				break;
			}
			if (dwTimeout != 0L) {
				dwTimeout /= 1000L;
				if (dwTimeout == 0L) {
					dwTimeout = 1L;	// at least 1 ms
				}
				TimerArg.m_EventSink = kEplEventSinkNmtMnu;
				TimerArg.m_ulArg = 0;
				Ret =
				    EplTimeruModifyTimerMs(&EplNmtMnuInstance_g.
							   m_TimerHdlNmtState,
							   dwTimeout, TimerArg);
			}
			break;
		}

		// node processes isochronous and asynchronous frames
	case kEplNmtMsPreOperational2:
		{
			// add identified CNs to isochronous phase
			// send EnableReadyToOp to all identified CNs
			Ret = EplNmtMnuStartBootStep2();

			// wait for NMT state change of CNs
			break;
		}

		// node should be configured und application is ready
	case kEplNmtMsReadyToOperate:
		{
			// check if PRes of CNs are OK
			// d.k. that means wait CycleLength * MultiplexCycleCount (i.e. start timer)
			//      because Dllk checks PRes of CNs automatically in ReadyToOp
			Ret = EplNmtMnuStartCheckCom();
			break;
		}

		// normal work state
	case kEplNmtMsOperational:
		{
			// send StartNode to CNs
			// wait for NMT state change of CNs
			Ret = EplNmtMnuStartNodes();
			break;
		}

		// no EPL cycle
		// -> normal ethernet communication
	case kEplNmtMsBasicEthernet:
		{
			break;
		}

	default:
		{
//            TRACE0("EplNmtMnuCbNmtStateChange(): unhandled NMT state\n");
		}
	}

	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuCbCheckEvent
//
// Description: callback funktion for NMT events before they are actually executed.
//              The EPL API layer must forward NMT events from NmtCnu module.
//              This module will reject some NMT commands while MN.
//
// Parameters:  NmtEvent_p              = outstanding NMT event for approval
//
// Returns:     tEplKernel              = error code
//                      kEplReject      = reject the NMT event
//
// State:
//
//---------------------------------------------------------------------------

tEplKernel PUBLIC EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p)
{
	tEplKernel Ret = kEplSuccessful;

	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtuProcessEvent
//
// Description: processes events from event queue
//
// Parameters:  pEvent_p        = pointer to event
//
// Returns:     tEplKernel      = errorcode
//
// State:
//
//---------------------------------------------------------------------------

EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p)
{
	tEplKernel Ret;

	Ret = kEplSuccessful;

	// process event
	switch (pEvent_p->m_EventType) {
		// timer event
	case kEplEventTypeTimer:
		{
			tEplTimerEventArg *pTimerEventArg =
			    (tEplTimerEventArg *) pEvent_p->m_pArg;
			unsigned int uiNodeId;

			uiNodeId =
			    (unsigned int)(pTimerEventArg->
					   m_ulArg &
					   EPL_NMTMNU_TIMERARG_NODE_MASK);
			if (uiNodeId != 0) {
				tEplObdSize ObdSize;
				BYTE bNmtState;
				tEplNmtMnuNodeInfo *pNodeInfo;

				pNodeInfo = EPL_NMTMNU_GET_NODEINFO(uiNodeId);

				ObdSize = 1;
				Ret =
				    EplObduReadEntry(0x1F8E, uiNodeId,
						     &bNmtState, &ObdSize);
				if (Ret != kEplSuccessful) {
					break;
				}

				if ((pTimerEventArg->
				     m_ulArg & EPL_NMTMNU_TIMERARG_IDENTREQ) !=
				    0L) {
					if ((pNodeInfo->
					     m_wFlags &
					     EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ)
					    != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR)) {	// this is an old (already deleted or modified) timer
						// but not the current timer
						// so discard it
						EPL_NMTMNU_DBG_POST_TRACE_VALUE
						    (kEplNmtMnuIntNodeEventTimerIdentReq,
						     uiNodeId,
						     ((pNodeInfo->
						       m_NodeState << 8)
						      | 0xFF));

						break;
					}
/*
                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerIdentReq,
                                                    uiNodeId,
                                                    ((pNodeInfo->m_NodeState << 8)
                                                     | 0x80
                                                     | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
                                                     | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
*/
					Ret =
					    EplNmtMnuProcessInternalEvent
					    (uiNodeId,
					     (tEplNmtState) (bNmtState |
							     EPL_NMT_TYPE_CS),
					     EPL_E_NO_ERROR,
					     kEplNmtMnuIntNodeEventTimerIdentReq);
				}

				else if ((pTimerEventArg->
					  m_ulArg & EPL_NMTMNU_TIMERARG_STATREQ)
					 != 0L) {
					if ((pNodeInfo->
					     m_wFlags &
					     EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ)
					    != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR)) {	// this is an old (already deleted or modified) timer
						// but not the current timer
						// so discard it
						EPL_NMTMNU_DBG_POST_TRACE_VALUE
						    (kEplNmtMnuIntNodeEventTimerStatReq,
						     uiNodeId,
						     ((pNodeInfo->
						       m_NodeState << 8)
						      | 0xFF));

						break;
					}
/*
                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerStatReq,
                                                    uiNodeId,
                                                    ((pNodeInfo->m_NodeState << 8)
                                                     | 0x80
                                                     | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
                                                     | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
*/
					Ret =
					    EplNmtMnuProcessInternalEvent
					    (uiNodeId,
					     (tEplNmtState) (bNmtState |
							     EPL_NMT_TYPE_CS),
					     EPL_E_NO_ERROR,
					     kEplNmtMnuIntNodeEventTimerStatReq);
				}

				else if ((pTimerEventArg->
					  m_ulArg &
					  EPL_NMTMNU_TIMERARG_STATE_MON) !=
					 0L) {
					if ((pNodeInfo->
					     m_wFlags &
					     EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ)
					    != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR)) {	// this is an old (already deleted or modified) timer
						// but not the current timer
						// so discard it
						EPL_NMTMNU_DBG_POST_TRACE_VALUE
						    (kEplNmtMnuIntNodeEventTimerStateMon,
						     uiNodeId,
						     ((pNodeInfo->
						       m_NodeState << 8)
						      | 0xFF));

						break;
					}
/*
                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerStatReq,
                                                    uiNodeId,
                                                    ((pNodeInfo->m_NodeState << 8)
                                                     | 0x80
                                                     | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
                                                     | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
*/
					Ret =
					    EplNmtMnuProcessInternalEvent
					    (uiNodeId,
					     (tEplNmtState) (bNmtState |
							     EPL_NMT_TYPE_CS),
					     EPL_E_NO_ERROR,
					     kEplNmtMnuIntNodeEventTimerStateMon);
				}

				else if ((pTimerEventArg->
					  m_ulArg & EPL_NMTMNU_TIMERARG_LONGER)
					 != 0L) {
					if ((pNodeInfo->
					     m_wFlags &
					     EPL_NMTMNU_NODE_FLAG_COUNT_LONGER)
					    != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_LO)) {	// this is an old (already deleted or modified) timer
						// but not the current timer
						// so discard it
						EPL_NMTMNU_DBG_POST_TRACE_VALUE
						    (kEplNmtMnuIntNodeEventTimerLonger,
						     uiNodeId,
						     ((pNodeInfo->
						       m_NodeState << 8)
						      | 0xFF));

						break;
					}
/*
                    EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerLonger,
                                                    uiNodeId,
                                                    ((pNodeInfo->m_NodeState << 8)
                                                     | 0x80
                                                     | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER) >> 6)
                                                     | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_LO) >> 8)));
*/
					Ret =
					    EplNmtMnuProcessInternalEvent
					    (uiNodeId,
					     (tEplNmtState) (bNmtState |
							     EPL_NMT_TYPE_CS),
					     EPL_E_NO_ERROR,
					     kEplNmtMnuIntNodeEventTimerLonger);
				}

			} else {	// global timer event
			}
			break;
		}

	case kEplEventTypeHeartbeat:
		{
			tEplHeartbeatEvent *pHeartbeatEvent =
			    (tEplHeartbeatEvent *) pEvent_p->m_pArg;

			Ret =
			    EplNmtMnuProcessInternalEvent(pHeartbeatEvent->
							  m_uiNodeId,
							  pHeartbeatEvent->
							  m_NmtState,
							  pHeartbeatEvent->
							  m_wErrorCode,
							  kEplNmtMnuIntNodeEventHeartbeat);
			break;
		}

	case kEplEventTypeNmtMnuNmtCmdSent:
		{
			tEplFrame *pFrame = (tEplFrame *) pEvent_p->m_pArg;
			unsigned int uiNodeId;
			tEplNmtCommand NmtCommand;
			BYTE bNmtState;

			uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bDstNodeId);
			NmtCommand =
			    (tEplNmtCommand) AmiGetByteFromLe(&pFrame->m_Data.
							      m_Asnd.m_Payload.
							      m_NmtCommandService.
							      m_le_bNmtCommandId);

			switch (NmtCommand) {
			case kEplNmtCmdStartNode:
				bNmtState =
				    (BYTE) (kEplNmtCsOperational & 0xFF);
				break;

			case kEplNmtCmdStopNode:
				bNmtState = (BYTE) (kEplNmtCsStopped & 0xFF);
				break;

			case kEplNmtCmdEnterPreOperational2:
				bNmtState =
				    (BYTE) (kEplNmtCsPreOperational2 & 0xFF);
				break;

			case kEplNmtCmdEnableReadyToOperate:
				// d.k. do not change expected node state, because of DS 1.0.0 7.3.1.2.1 Plain NMT State Command
				//      and because node may not change NMT state within EPL_C_NMT_STATE_TOLERANCE
				bNmtState =
				    (BYTE) (kEplNmtCsPreOperational2 & 0xFF);
				break;

			case kEplNmtCmdResetNode:
			case kEplNmtCmdResetCommunication:
			case kEplNmtCmdResetConfiguration:
			case kEplNmtCmdSwReset:
				bNmtState = (BYTE) (kEplNmtCsNotActive & 0xFF);
				// EplNmtMnuProcessInternalEvent() sets internal node state to kEplNmtMnuNodeStateUnknown
				// after next unresponded IdentRequest/StatusRequest
				break;

			default:
				goto Exit;
			}

			// process as internal event which update expected NMT state in OD
			if (uiNodeId != EPL_C_ADR_BROADCAST) {
				Ret = EplNmtMnuProcessInternalEvent(uiNodeId,
								    (tEplNmtState)
								    (bNmtState |
								     EPL_NMT_TYPE_CS),
								    0,
								    kEplNmtMnuIntNodeEventNmtCmdSent);

			} else {	// process internal event for all active nodes (except myself)

				for (uiNodeId = 1;
				     uiNodeId <=
				     tabentries(EplNmtMnuInstance_g.
						m_aNodeInfo); uiNodeId++) {
					if ((EPL_NMTMNU_GET_NODEINFO(uiNodeId)->
					     m_dwNodeCfg &
					     (EPL_NODEASSIGN_NODE_IS_CN |
					      EPL_NODEASSIGN_NODE_EXISTS)) !=
					    0) {
						Ret =
						    EplNmtMnuProcessInternalEvent
						    (uiNodeId,
						     (tEplNmtState) (bNmtState |
								     EPL_NMT_TYPE_CS),
						     0,
						     kEplNmtMnuIntNodeEventNmtCmdSent);

						if (Ret != kEplSuccessful) {
							goto Exit;
						}
					}
				}
			}

			break;
		}

	default:
		{
			Ret = kEplNmtInvalidEvent;
		}

	}

      Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuGetRunningTimerStatReq
//
// Description: returns a bit field with running StatReq timers
//              just for debugging purposes
//
// Parameters:  (none)
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------

tEplKernel PUBLIC EplNmtMnuGetDiagnosticInfo(unsigned int
					     *puiMandatorySlaveCount_p,
					     unsigned int
					     *puiSignalSlaveCount_p,
					     WORD * pwFlags_p)
{
	tEplKernel Ret = kEplSuccessful;

	if ((puiMandatorySlaveCount_p == NULL)
	    || (puiSignalSlaveCount_p == NULL)
	    || (pwFlags_p == NULL)) {
		Ret = kEplNmtInvalidParam;
		goto Exit;
	}

	*puiMandatorySlaveCount_p = EplNmtMnuInstance_g.m_uiMandatorySlaveCount;
	*puiSignalSlaveCount_p = EplNmtMnuInstance_g.m_uiSignalSlaveCount;
	*pwFlags_p = EplNmtMnuInstance_g.m_wFlags;

      Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuGetRunningTimerStatReq
//
// Description: returns a bit field with running StatReq timers
//              just for debugging purposes
//
// Parameters:  (none)
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------
/*
DWORD EplNmtMnuGetRunningTimerStatReq(void)
{
tEplKernel      Ret = kEplSuccessful;
unsigned int    uiIndex;
tEplNmtMnuNodeInfo* pNodeInfo;

    pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
    for (uiIndex = 1; uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); uiIndex++, pNodeInfo++)
    {
        if (pNodeInfo->m_NodeState == kEplNmtMnuNodeStateConfigured)
        {
            // reset flag "scanned once"
            pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_SCANNED;

            Ret = EplNmtMnuNodeBootStep2(uiIndex, pNodeInfo);
            if (Ret != kEplSuccessful)
            {
                goto Exit;
            }
            EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
            // signal slave counter shall be decremented if StatusRequest was sent once to a CN
            // mandatory slave counter shall be decremented if mandatory CN is ReadyToOp
        }
    }

Exit:
    return Ret;
}
*/

//=========================================================================//
//                                                                         //
//          P R I V A T E   F U N C T I O N S                              //
//                                                                         //
//=========================================================================//

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuCbNmtRequest
//
// Description: callback funktion for NmtRequest
//
// Parameters:  pFrameInfo_p            = Frame with the NmtRequest
//
// Returns:     tEplKernel              = error code
//
//
// State:
//
//---------------------------------------------------------------------------

static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p)
{
	tEplKernel Ret = kEplSuccessful;

	// $$$ perform NMTRequest
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuCbIdentResponse
//
// Description: callback funktion for IdentResponse
//
// Parameters:  uiNodeId_p              = node ID for which IdentReponse was received
//              pIdentResponse_p        = pointer to IdentResponse
//                                        is NULL if node did not answer
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------

static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
						  tEplIdentResponse *
						  pIdentResponse_p)
{
	tEplKernel Ret = kEplSuccessful;

	if (pIdentResponse_p == NULL) {	// node did not answer
		Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p, kEplNmtCsNotActive, EPL_E_NMT_NO_IDENT_RES,	// was EPL_E_NO_ERROR
						    kEplNmtMnuIntNodeEventNoIdentResponse);
	} else {		// node answered IdentRequest
		tEplObdSize ObdSize;
		DWORD dwDevType;
		WORD wErrorCode = EPL_E_NO_ERROR;
		tEplNmtState NmtState =
		    (tEplNmtState) (AmiGetByteFromLe
				    (&pIdentResponse_p->
				     m_le_bNmtStatus) | EPL_NMT_TYPE_CS);

		// check IdentResponse $$$ move to ProcessIntern, because this function may be called also if CN

		// check DeviceType (0x1F84)
		ObdSize = 4;
		Ret =
		    EplObduReadEntry(0x1F84, uiNodeId_p, &dwDevType, &ObdSize);
		if (Ret != kEplSuccessful) {
			goto Exit;
		}
		if (dwDevType != 0L) {	// actually compare it with DeviceType from IdentResponse
			if (AmiGetDwordFromLe(&pIdentResponse_p->m_le_dwDeviceType) != dwDevType) {	// wrong DeviceType
				NmtState = kEplNmtCsNotActive;
				wErrorCode = EPL_E_NMT_BPO1_DEVICE_TYPE;
			}
		}

		Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
						    NmtState,
						    wErrorCode,
						    kEplNmtMnuIntNodeEventIdentResponse);
	}

      Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuCbStatusResponse
//
// Description: callback funktion for StatusResponse
//
// Parameters:  uiNodeId_p              = node ID for which IdentReponse was received
//              pIdentResponse_p        = pointer to IdentResponse
//                                        is NULL if node did not answer
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------

static tEplKernel PUBLIC EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
						   tEplStatusResponse *
						   pStatusResponse_p)
{
	tEplKernel Ret = kEplSuccessful;

	if (pStatusResponse_p == NULL) {	// node did not answer
		Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p, kEplNmtCsNotActive, EPL_E_NMT_NO_STATUS_RES,	// was EPL_E_NO_ERROR
						    kEplNmtMnuIntNodeEventNoStatusResponse);
	} else {		// node answered StatusRequest
		Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
						    (tEplNmtState)
						    (AmiGetByteFromLe
						     (&pStatusResponse_p->
						      m_le_bNmtStatus) |
						     EPL_NMT_TYPE_CS),
						    EPL_E_NO_ERROR,
						    kEplNmtMnuIntNodeEventStatusResponse);
	}

	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuStartBootStep1
//
// Description: starts BootStep1
//
// Parameters:  (none)
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------

static tEplKernel EplNmtMnuStartBootStep1(void)
{
	tEplKernel Ret = kEplSuccessful;
	unsigned int uiSubIndex;
	unsigned int uiLocalNodeId;
	DWORD dwNodeCfg;
	tEplObdSize ObdSize;

	// $$$ d.k.: save current time for 0x1F89/2 MNTimeoutPreOp1_U32

	// start network scan
	EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
	EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
	// check 0x1F81
	uiLocalNodeId = EplObduGetNodeId();
	for (uiSubIndex = 1; uiSubIndex <= 254; uiSubIndex++) {
		ObdSize = 4;
		Ret =
		    EplObduReadEntry(0x1F81, uiSubIndex, &dwNodeCfg, &ObdSize);
		if (Ret != kEplSuccessful) {
			goto Exit;
		}
		if (uiSubIndex != uiLocalNodeId) {
			// reset flags "not scanned" and "isochronous"
			EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_wFlags &=
			    ~(EPL_NMTMNU_NODE_FLAG_ISOCHRON |
			      EPL_NMTMNU_NODE_FLAG_NOT_SCANNED);

			if (uiSubIndex == EPL_C_ADR_DIAG_DEF_NODE_ID) {	// diagnostic node must be scanned by MN in any case
				dwNodeCfg |=
				    (EPL_NODEASSIGN_NODE_IS_CN |
				     EPL_NODEASSIGN_NODE_EXISTS);
				// and it must be isochronously accessed
				dwNodeCfg &= ~EPL_NODEASSIGN_ASYNCONLY_NODE;
			}
			// save node config in local node info structure
			EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_dwNodeCfg =
			    dwNodeCfg;
			EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_NodeState =
			    kEplNmtMnuNodeStateUnknown;

			if ((dwNodeCfg & (EPL_NODEASSIGN_NODE_IS_CN | EPL_NODEASSIGN_NODE_EXISTS)) != 0) {	// node is configured as CN
				// identify the node
				Ret =
				    EplIdentuRequestIdentResponse(uiSubIndex,
								  EplNmtMnuCbIdentResponse);
				if (Ret != kEplSuccessful) {
					goto Exit;
				}
				// set flag "not scanned"
				EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_wFlags |=
				    EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
				EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
				// signal slave counter shall be decremented if IdentRequest was sent once to a CN

				if ((dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// node is a mandatory CN
					EplNmtMnuInstance_g.
					    m_uiMandatorySlaveCount++;
					// mandatory slave counter shall be decremented if mandatory CN was configured successfully
				}
			}
		} else {	// subindex of MN
			if ((dwNodeCfg & (EPL_NODEASSIGN_MN_PRES | EPL_NODEASSIGN_NODE_EXISTS)) != 0) {	// MN shall send PRes
				tEplDllNodeInfo DllNodeInfo;

				EPL_MEMSET(&DllNodeInfo, 0,
					   sizeof(DllNodeInfo));
				DllNodeInfo.m_uiNodeId = uiLocalNodeId;

				Ret = EplDlluCalAddNode(&DllNodeInfo);
			}
		}
	}

      Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuStartBootStep2
//
// Description: starts BootStep2.
//              That means add nodes to isochronous phase and send
//              NMT EnableReadyToOp.
//
// Parameters:  (none)
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------

static tEplKernel EplNmtMnuStartBootStep2(void)
{
	tEplKernel Ret = kEplSuccessful;
	unsigned int uiIndex;
	tEplNmtMnuNodeInfo *pNodeInfo;

	if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0) {	// boot process is not halted
		// add nodes to isochronous phase and send NMT EnableReadyToOp
		EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
		EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
		// reset flag that application was informed about possible state change
		EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED;

		pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
		for (uiIndex = 1;
		     uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
		     uiIndex++, pNodeInfo++) {
			if (pNodeInfo->m_NodeState ==
			    kEplNmtMnuNodeStateConfigured) {
				Ret =
				    EplNmtMnuNodeBootStep2(uiIndex, pNodeInfo);
				if (Ret != kEplSuccessful) {
					goto Exit;
				}
				// set flag "not scanned"
				pNodeInfo->m_wFlags |=
				    EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;

				EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
				// signal slave counter shall be decremented if StatusRequest was sent once to a CN

				if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// node is a mandatory CN
					EplNmtMnuInstance_g.
					    m_uiMandatorySlaveCount++;
				}
				// mandatory slave counter shall be decremented if mandatory CN is ReadyToOp
			}
		}
	}

      Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuNodeBootStep2
//
// Description: starts BootStep2 for the specified node.
//              This means the CN is added to isochronous phase if not
//              async-only and it gets the NMT command EnableReadyToOp.
//              The CN must be in node state Configured, when it enters
//              BootStep2. When BootStep2 finishes, the CN is in node state
//              ReadyToOp.
//              If TimeoutReadyToOp in object 0x1F89/5 is configured,
//              TimerHdlLonger will be started with this timeout.
//
// Parameters:  uiNodeId_p              = node ID
//              pNodeInfo_p             = pointer to internal node info structure
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------

static tEplKernel EplNmtMnuNodeBootStep2(unsigned int uiNodeId_p,
					 tEplNmtMnuNodeInfo * pNodeInfo_p)
{
	tEplKernel Ret = kEplSuccessful;
	tEplDllNodeInfo DllNodeInfo;
	DWORD dwNodeCfg;
	tEplObdSize ObdSize;
	tEplTimerArg TimerArg;

	dwNodeCfg = pNodeInfo_p->m_dwNodeCfg;
	if ((dwNodeCfg & EPL_NODEASSIGN_ASYNCONLY_NODE) == 0) {	// add node to isochronous phase
		DllNodeInfo.m_uiNodeId = uiNodeId_p;
		ObdSize = 4;
		Ret =
		    EplObduReadEntry(0x1F92, uiNodeId_p,
				     &DllNodeInfo.m_dwPresTimeout, &ObdSize);
		if (Ret != kEplSuccessful) {
			goto Exit;
		}

		ObdSize = 2;
		Ret =
		    EplObduReadEntry(0x1F8B, uiNodeId_p,
				     &DllNodeInfo.m_wPreqPayloadLimit,
				     &ObdSize);
		if (Ret != kEplSuccessful) {
			goto Exit;
		}

		ObdSize = 2;
		Ret =
		    EplObduReadEntry(0x1F8D, uiNodeId_p,
				     &DllNodeInfo.m_wPresPayloadLimit,
				     &ObdSize);
		if (Ret != kEplSuccessful) {
			goto Exit;
		}

		pNodeInfo_p->m_wFlags |= EPL_NMTMNU_NODE_FLAG_ISOCHRON;

		Ret = EplDlluCalAddNode(&DllNodeInfo);
		if (Ret != kEplSuccessful) {
			goto Exit;
		}

	}

	EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
					uiNodeId_p,
					kEplNmtCmdEnableReadyToOperate);

	Ret =
	    EplNmtMnuSendNmtCommand(uiNodeId_p, kEplNmtCmdEnableReadyToOperate);
	if (Ret != kEplSuccessful) {
		goto Exit;
	}

	if (EplNmtMnuInstance_g.m_ulTimeoutReadyToOp != 0L) {	// start timer
		// when the timer expires the CN must be ReadyToOp
		EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(pNodeInfo_p, uiNodeId_p,
						     TimerArg);
//        TimerArg.m_EventSink = kEplEventSinkNmtMnu;
//        TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p;
		Ret =
		    EplTimeruModifyTimerMs(&pNodeInfo_p->m_TimerHdlLonger,
					   EplNmtMnuInstance_g.
					   m_ulTimeoutReadyToOp, TimerArg);
	}

      Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuStartCheckCom
//
// Description: starts CheckCommunication
//
// Parameters:  (none)
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------

static tEplKernel EplNmtMnuStartCheckCom(void)
{
	tEplKernel Ret = kEplSuccessful;
	unsigned int uiIndex;
	tEplNmtMnuNodeInfo *pNodeInfo;

	if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0) {	// boot process is not halted
		// wait some time and check that no communication error occurs
		EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
		EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
		// reset flag that application was informed about possible state change
		EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED;

		pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
		for (uiIndex = 1;
		     uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
		     uiIndex++, pNodeInfo++) {
			if (pNodeInfo->m_NodeState ==
			    kEplNmtMnuNodeStateReadyToOp) {
				Ret = EplNmtMnuNodeCheckCom(uiIndex, pNodeInfo);
				if (Ret == kEplReject) {	// timer was started
					// wait until it expires
					if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// node is a mandatory CN
						EplNmtMnuInstance_g.
						    m_uiMandatorySlaveCount++;
					}
				} else if (Ret != kEplSuccessful) {
					goto Exit;
				}
				// set flag "not scanned"
				pNodeInfo->m_wFlags |=
				    EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;

				EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
				// signal slave counter shall be decremented if timeout elapsed and regardless of an error
				// mandatory slave counter shall be decremented if timeout elapsed and no error occured
			}
		}
	}

	Ret = kEplSuccessful;

      Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuNodeCheckCom
//
// Description: checks communication of the specified node.
//              That means wait some time and if no error occured everything
//              is OK.
//
// Parameters:  uiNodeId_p              = node ID
//              pNodeInfo_p             = pointer to internal node info structure
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------

static tEplKernel EplNmtMnuNodeCheckCom(unsigned int uiNodeId_p,
					tEplNmtMnuNodeInfo * pNodeInfo_p)
{
	tEplKernel Ret = kEplSuccessful;
	DWORD dwNodeCfg;
	tEplTimerArg TimerArg;

	dwNodeCfg = pNodeInfo_p->m_dwNodeCfg;
	if (((dwNodeCfg & EPL_NODEASSIGN_ASYNCONLY_NODE) == 0)
	    && (EplNmtMnuInstance_g.m_ulTimeoutCheckCom != 0L)) {	// CN is not async-only and timeout for CheckCom was set

		// check communication,
		// that means wait some time and if no error occured everything is OK;

		// start timer (when the timer expires the CN must be still ReadyToOp)
		EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(pNodeInfo_p, uiNodeId_p,
						     TimerArg);
//        TimerArg.m_EventSink = kEplEventSinkNmtMnu;
//        TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p;
		Ret =
		    EplTimeruModifyTimerMs(&pNodeInfo_p->m_TimerHdlLonger,
					   EplNmtMnuInstance_g.
					   m_ulTimeoutCheckCom, TimerArg);

		// update mandatory slave counter, because timer was started
		if (Ret == kEplSuccessful) {
			Ret = kEplReject;
		}
	} else {		// timer was not started
		// assume everything is OK
		pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateComChecked;
	}

//Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuStartNodes
//
// Description: really starts all nodes which are ReadyToOp and CheckCom did not fail
//
// Parameters:  (none)
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------

static tEplKernel EplNmtMnuStartNodes(void)
{
	tEplKernel Ret = kEplSuccessful;
	unsigned int uiIndex;
	tEplNmtMnuNodeInfo *pNodeInfo;

	if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0) {	// boot process is not halted
		// send NMT command Start Node
		EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
		EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
		// reset flag that application was informed about possible state change
		EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED;

		pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
		for (uiIndex = 1;
		     uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
		     uiIndex++, pNodeInfo++) {
			if (pNodeInfo->m_NodeState ==
			    kEplNmtMnuNodeStateComChecked) {
				if ((EplNmtMnuInstance_g.
				     m_dwNmtStartup & EPL_NMTST_STARTALLNODES)
				    == 0) {
					EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
									uiIndex,
									kEplNmtCmdStartNode);

					Ret =
					    EplNmtMnuSendNmtCommand(uiIndex,
								    kEplNmtCmdStartNode);
					if (Ret != kEplSuccessful) {
						goto Exit;
					}
				}

				if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// node is a mandatory CN
					EplNmtMnuInstance_g.
					    m_uiMandatorySlaveCount++;
				}
				// set flag "not scanned"
				pNodeInfo->m_wFlags |=
				    EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;

				EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
				// signal slave counter shall be decremented if StatusRequest was sent once to a CN
				// mandatory slave counter shall be decremented if mandatory CN is OPERATIONAL
			}
		}

		// $$$ inform application if EPL_NMTST_NO_STARTNODE is set

		if ((EplNmtMnuInstance_g.
		     m_dwNmtStartup & EPL_NMTST_STARTALLNODES) != 0) {
			EPL_NMTMNU_DBG_POST_TRACE_VALUE(0, EPL_C_ADR_BROADCAST,
							kEplNmtCmdStartNode);

			Ret =
			    EplNmtMnuSendNmtCommand(EPL_C_ADR_BROADCAST,
						    kEplNmtCmdStartNode);
			if (Ret != kEplSuccessful) {
				goto Exit;
			}
		}
	}

      Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuProcessInternalEvent
//
// Description: processes internal node events
//
// Parameters:  uiNodeId_p              = node ID
//              NodeNmtState_p          = NMT state of CN
//              NodeEvent_p             = occured events
//
// Returns:     tEplKernel              = error code
//
//
// State:
//
//---------------------------------------------------------------------------

static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
						tEplNmtState NodeNmtState_p,
						WORD wErrorCode_p,
						tEplNmtMnuIntNodeEvent
						NodeEvent_p)
{
	tEplKernel Ret = kEplSuccessful;
	tEplNmtState NmtState;
	tEplNmtMnuNodeInfo *pNodeInfo;
	tEplTimerArg TimerArg;

	pNodeInfo = EPL_NMTMNU_GET_NODEINFO(uiNodeId_p);
	NmtState = EplNmtuGetNmtState();
	if (NmtState <= kEplNmtMsNotActive) {	// MN is not active
		goto Exit;
	}

	switch (NodeEvent_p) {
	case kEplNmtMnuIntNodeEventIdentResponse:
		{
			BYTE bNmtState;

			EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
							uiNodeId_p,
							pNodeInfo->m_NodeState);

			if (pNodeInfo->m_NodeState !=
			    kEplNmtMnuNodeStateResetConf) {
				pNodeInfo->m_NodeState =
				    kEplNmtMnuNodeStateIdentified;
			}
			// reset flags ISOCHRON and NMT_CMD_ISSUED
			pNodeInfo->m_wFlags &= ~(EPL_NMTMNU_NODE_FLAG_ISOCHRON
						 |
						 EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED);

			if ((NmtState == kEplNmtMsPreOperational1)
			    &&
			    ((pNodeInfo->
			      m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) !=
			     0)) {
				// decrement only signal slave count
				EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
				pNodeInfo->m_wFlags &=
				    ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
			}
			// update object 0x1F8F NMT_MNNodeExpState_AU8 to PreOp1 (even if local state >= PreOp2)
			bNmtState = (BYTE) (kEplNmtCsPreOperational1 & 0xFF);
			Ret =
			    EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState,
					      1);

			// check NMT state of CN
			Ret =
			    EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
						   NodeNmtState_p, wErrorCode_p,
						   NmtState);
			if (Ret != kEplSuccessful) {
				if (Ret == kEplReject) {
					Ret = kEplSuccessful;
				}
				break;
			}
			// request StatusResponse immediately,
			// because we want a fast boot-up of CNs
			Ret =
			    EplStatusuRequestStatusResponse(uiNodeId_p,
							    EplNmtMnuCbStatusResponse);
			if (Ret != kEplSuccessful) {
				EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
								uiNodeId_p,
								Ret);

				if (Ret == kEplInvalidOperation) {	// the only situation when this should happen is, when
					// StatusResponse was already requested from within
					// the StatReq timer event.
					// so ignore this error.
					Ret = kEplSuccessful;
				} else {
					break;
				}
			}

			if (pNodeInfo->m_NodeState !=
			    kEplNmtMnuNodeStateResetConf) {
				// inform application
				Ret =
				    EplNmtMnuInstance_g.
				    m_pfnCbNodeEvent(uiNodeId_p,
						     kEplNmtNodeEventFound,
						     NodeNmtState_p,
						     EPL_E_NO_ERROR,
						     (pNodeInfo->
						      m_dwNodeCfg &
						      EPL_NODEASSIGN_MANDATORY_CN)
						     != 0);
				if (Ret == kEplReject) {	// interrupt boot process on user request
					EPL_NMTMNU_DBG_POST_TRACE_VALUE
					    (NodeEvent_p, uiNodeId_p,
					     ((pNodeInfo->m_NodeState << 8)
					      | Ret));

					Ret = kEplSuccessful;
					break;
				} else if (Ret != kEplSuccessful) {
					EPL_NMTMNU_DBG_POST_TRACE_VALUE
					    (NodeEvent_p, uiNodeId_p,
					     ((pNodeInfo->m_NodeState << 8)
					      | Ret));

					break;
				}
			}
			// continue BootStep1
		}

	case kEplNmtMnuIntNodeEventBoot:
		{

			// $$$ check identification (vendor ID, product code, revision no, serial no)

			if (pNodeInfo->m_NodeState ==
			    kEplNmtMnuNodeStateIdentified) {
				// $$$ check software

				// check/start configuration
				// inform application
				Ret =
				    EplNmtMnuInstance_g.
				    m_pfnCbNodeEvent(uiNodeId_p,
						     kEplNmtNodeEventCheckConf,
						     NodeNmtState_p,
						     EPL_E_NO_ERROR,
						     (pNodeInfo->
						      m_dwNodeCfg &
						      EPL_NODEASSIGN_MANDATORY_CN)
						     != 0);
				if (Ret == kEplReject) {	// interrupt boot process on user request
					EPL_NMTMNU_DBG_POST_TRACE_VALUE
					    (kEplNmtMnuIntNodeEventBoot,
					     uiNodeId_p,
					     ((pNodeInfo->m_NodeState << 8)
					      | Ret));

					Ret = kEplSuccessful;
					break;
				} else if (Ret != kEplSuccessful) {
					EPL_NMTMNU_DBG_POST_TRACE_VALUE
					    (kEplNmtMnuIntNodeEventBoot,
					     uiNodeId_p,
					     ((pNodeInfo->m_NodeState << 8)
					      | Ret));

					break;
				}
			} else if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateResetConf) {	// wrong CN state
				// ignore event
				break;
			}
			// $$$ d.k.: currently we assume configuration is OK

			// continue BootStep1
		}

	case kEplNmtMnuIntNodeEventConfigured:
		{
			if ((pNodeInfo->m_NodeState !=
			     kEplNmtMnuNodeStateIdentified)
			    && (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateResetConf)) {	// wrong CN state
				// ignore event
				break;
			}

			pNodeInfo->m_NodeState = kEplNmtMnuNodeStateConfigured;

			if (NmtState == kEplNmtMsPreOperational1) {
				if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// decrement mandatory CN counter
					EplNmtMnuInstance_g.
					    m_uiMandatorySlaveCount--;
				}
			} else {
				// put optional node to next step (BootStep2)
				Ret =
				    EplNmtMnuNodeBootStep2(uiNodeId_p,
							   pNodeInfo);
			}
			break;
		}

	case kEplNmtMnuIntNodeEventNoIdentResponse:
		{
			if ((NmtState == kEplNmtMsPreOperational1)
			    &&
			    ((pNodeInfo->
			      m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) !=
			     0)) {
				// decrement only signal slave count
				EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
				pNodeInfo->m_wFlags &=
				    ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
			}

			if (pNodeInfo->m_NodeState !=
			    kEplNmtMnuNodeStateResetConf) {
				pNodeInfo->m_NodeState =
				    kEplNmtMnuNodeStateUnknown;
			}
			// $$$ d.k. check start time for 0x1F89/2 MNTimeoutPreOp1_U32
			// $$$ d.k. check individual timeout 0x1F89/6 MNIdentificationTimeout_U32
			// if mandatory node and timeout elapsed -> halt boot procedure
			// trigger IdentRequest again (if >= PreOp2, after delay)
			if (NmtState >= kEplNmtMsPreOperational2) {	// start timer
				EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ
				    (pNodeInfo, uiNodeId_p, TimerArg);
//                TimerArg.m_EventSink = kEplEventSinkNmtMnu;
//                TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_IDENTREQ | uiNodeId_p;
/*
                EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventNoIdentResponse,
                                                uiNodeId_p,
                                                ((pNodeInfo->m_NodeState << 8)
                                                 | 0x80
                                                 | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
                                                 | ((TimerArg.m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
*/
				Ret =
				    EplTimeruModifyTimerMs(&pNodeInfo->
							   m_TimerHdlStatReq,
							   EplNmtMnuInstance_g.
							   m_ulStatusRequestDelay,
							   TimerArg);
			} else {	// trigger IdentRequest immediately
				Ret =
				    EplIdentuRequestIdentResponse(uiNodeId_p,
								  EplNmtMnuCbIdentResponse);
			}
			break;
		}

	case kEplNmtMnuIntNodeEventStatusResponse:
		{
			if ((NmtState >= kEplNmtMsPreOperational2)
			    &&
			    ((pNodeInfo->
			      m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) !=
			     0)) {
				// decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
				EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
				pNodeInfo->m_wFlags &=
				    ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
			}
			// check NMT state of CN
			Ret =
			    EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
						   NodeNmtState_p, wErrorCode_p,
						   NmtState);
			if (Ret != kEplSuccessful) {
				if (Ret == kEplReject) {
					Ret = kEplSuccessful;
				}
				break;
			}

			if (NmtState == kEplNmtMsPreOperational1) {
				// request next StatusResponse immediately
				Ret =
				    EplStatusuRequestStatusResponse(uiNodeId_p,
								    EplNmtMnuCbStatusResponse);
				if (Ret != kEplSuccessful) {
					EPL_NMTMNU_DBG_POST_TRACE_VALUE
					    (NodeEvent_p, uiNodeId_p, Ret);
				}

			} else if ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_ISOCHRON) == 0) {	// start timer
				// not isochronously accessed CN (e.g. async-only or stopped CN)
				EPL_NMTMNU_SET_FLAGS_TIMERARG_STATREQ(pNodeInfo,
								      uiNodeId_p,
								      TimerArg);
//                TimerArg.m_EventSink = kEplEventSinkNmtMnu;
//                TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_STATREQ | uiNodeId_p;
/*
                EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventStatusResponse,
                                                uiNodeId_p,
                                                ((pNodeInfo->m_NodeState << 8)
                                                 | 0x80
                                                 | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
                                                 | ((TimerArg.m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
*/
				Ret =
				    EplTimeruModifyTimerMs(&pNodeInfo->
							   m_TimerHdlStatReq,
							   EplNmtMnuInstance_g.
							   m_ulStatusRequestDelay,
							   TimerArg);
			}

			break;
		}

	case kEplNmtMnuIntNodeEventNoStatusResponse:
		{
			// function CheckNmtState sets node state to unknown if necessary
/*
            if ((NmtState >= kEplNmtMsPreOperational2)
                && ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0))
            {
                // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
                EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
                pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
            }
*/
			// check NMT state of CN
			Ret =
			    EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
						   NodeNmtState_p, wErrorCode_p,
						   NmtState);
			if (Ret != kEplSuccessful) {
				if (Ret == kEplReject) {
					Ret = kEplSuccessful;
				}
				break;
			}

			break;
		}

	case kEplNmtMnuIntNodeEventError:
		{		// currently only issued on kEplNmtNodeCommandConfErr

			if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateIdentified) {	// wrong CN state
				// ignore event
				break;
			}
			// check NMT state of CN
			Ret =
			    EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
						   kEplNmtCsNotActive,
						   wErrorCode_p, NmtState);
			if (Ret != kEplSuccessful) {
				if (Ret == kEplReject) {
					Ret = kEplSuccessful;
				}
				break;
			}

			break;
		}

	case kEplNmtMnuIntNodeEventExecReset:
		{
			if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateIdentified) {	// wrong CN state
				// ignore event
				break;
			}

			pNodeInfo->m_NodeState = kEplNmtMnuNodeStateResetConf;

			EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
							uiNodeId_p,
							(((NodeNmtState_p &
							   0xFF) << 8)
							 |
							 kEplNmtCmdResetConfiguration));

			// send NMT reset configuration to CN for activation of configuration
			Ret =
			    EplNmtMnuSendNmtCommand(uiNodeId_p,
						    kEplNmtCmdResetConfiguration);

			break;
		}

	case kEplNmtMnuIntNodeEventHeartbeat:
		{
/*
            if ((NmtState >= kEplNmtMsPreOperational2)
                && ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0))
            {
                // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
                EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
                pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
            }
*/
			// check NMT state of CN
			Ret =
			    EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
						   NodeNmtState_p, wErrorCode_p,
						   NmtState);
			if (Ret != kEplSuccessful) {
				if (Ret == kEplReject) {
					Ret = kEplSuccessful;
				}
				break;
			}

			break;
		}

	case kEplNmtMnuIntNodeEventTimerIdentReq:
		{
			EPL_DBGLVL_NMTMN_TRACE1
			    ("TimerStatReq->IdentReq(%02X)\n", uiNodeId_p);
			// trigger IdentRequest again
			Ret =
			    EplIdentuRequestIdentResponse(uiNodeId_p,
							  EplNmtMnuCbIdentResponse);
			if (Ret != kEplSuccessful) {
				EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
								uiNodeId_p,
								(((NodeNmtState_p & 0xFF) << 8)
								 | Ret));
				if (Ret == kEplInvalidOperation) {	// this can happen because of a bug in EplTimeruLinuxKernel.c
					// so ignore this error.
					Ret = kEplSuccessful;
				}
			}

			break;
		}

	case kEplNmtMnuIntNodeEventTimerStateMon:
		{
			// reset NMT state change flag
			// because from now on the CN must have the correct NMT state
			pNodeInfo->m_wFlags &=
			    ~EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED;

			// continue with normal StatReq processing
		}

	case kEplNmtMnuIntNodeEventTimerStatReq:
		{
			EPL_DBGLVL_NMTMN_TRACE1("TimerStatReq->StatReq(%02X)\n",
						uiNodeId_p);
			// request next StatusResponse
			Ret =
			    EplStatusuRequestStatusResponse(uiNodeId_p,
							    EplNmtMnuCbStatusResponse);
			if (Ret != kEplSuccessful) {
				EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
								uiNodeId_p,
								(((NodeNmtState_p & 0xFF) << 8)
								 | Ret));
				if (Ret == kEplInvalidOperation) {	// the only situation when this should happen is, when
					// StatusResponse was already requested while processing
					// event IdentResponse.
					// so ignore this error.
					Ret = kEplSuccessful;
				}
			}

			break;
		}

	case kEplNmtMnuIntNodeEventTimerLonger:
		{
			switch (pNodeInfo->m_NodeState) {
			case kEplNmtMnuNodeStateConfigured:
				{	// node should be ReadyToOp but it is not

					// check NMT state which shall be intentionally wrong, so that ERROR_TREATMENT will be started
					Ret =
					    EplNmtMnuCheckNmtState(uiNodeId_p,
								   pNodeInfo,
								   kEplNmtCsNotActive,
								   EPL_E_NMT_BPO2,
								   NmtState);
					if (Ret != kEplSuccessful) {
						if (Ret == kEplReject) {
							Ret = kEplSuccessful;
						}
						break;
					}

					break;
				}

			case kEplNmtMnuNodeStateReadyToOp:
				{	// CheckCom finished successfully

					pNodeInfo->m_NodeState =
					    kEplNmtMnuNodeStateComChecked;

					if ((pNodeInfo->
					     m_wFlags &
					     EPL_NMTMNU_NODE_FLAG_NOT_SCANNED)
					    != 0) {
						// decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
						EplNmtMnuInstance_g.
						    m_uiSignalSlaveCount--;
						pNodeInfo->m_wFlags &=
						    ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
					}

					if ((pNodeInfo->
					     m_dwNodeCfg &
					     EPL_NODEASSIGN_MANDATORY_CN) !=
					    0) {
						// decrement mandatory slave counter
						EplNmtMnuInstance_g.
						    m_uiMandatorySlaveCount--;
					}
					if (NmtState != kEplNmtMsReadyToOperate) {
						EPL_NMTMNU_DBG_POST_TRACE_VALUE
						    (NodeEvent_p, uiNodeId_p,
						     (((NodeNmtState_p & 0xFF)
						       << 8)
						      | kEplNmtCmdStartNode));

						// start optional CN
						Ret =
						    EplNmtMnuSendNmtCommand
						    (uiNodeId_p,
						     kEplNmtCmdStartNode);
					}
					break;
				}

			default:
				{
					break;
				}
			}
			break;
		}

	case kEplNmtMnuIntNodeEventNmtCmdSent:
		{
			BYTE bNmtState;

			// update expected NMT state with the one that results
			// from the sent NMT command
			bNmtState = (BYTE) (NodeNmtState_p & 0xFF);

			// write object 0x1F8F NMT_MNNodeExpState_AU8
			Ret =
			    EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState,
					      1);
			if (Ret != kEplSuccessful) {
				goto Exit;
			}

			if (NodeNmtState_p == kEplNmtCsNotActive) {	// restart processing with IdentRequest
				EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ
				    (pNodeInfo, uiNodeId_p, TimerArg);
			} else {	// monitor NMT state change with StatusRequest after
				// the corresponding delay;
				// until then wrong NMT states will be ignored
				EPL_NMTMNU_SET_FLAGS_TIMERARG_STATE_MON
				    (pNodeInfo, uiNodeId_p, TimerArg);

				// set NMT state change flag
				pNodeInfo->m_wFlags |=
				    EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED;
			}

			Ret =
			    EplTimeruModifyTimerMs(&pNodeInfo->
						   m_TimerHdlStatReq,
						   EplNmtMnuInstance_g.
						   m_ulStatusRequestDelay,
						   TimerArg);

			// finish processing, because NmtState_p is the expected and not the current state
			goto Exit;
		}

	default:
		{
			break;
		}
	}

	// check if network is ready to change local NMT state and this was not done before
	if ((EplNmtMnuInstance_g.m_wFlags & (EPL_NMTMNU_FLAG_HALTED | EPL_NMTMNU_FLAG_APP_INFORMED)) == 0) {	// boot process is not halted
		switch (NmtState) {
		case kEplNmtMsPreOperational1:
			{
				if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount ==
				     0)
				    && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) {	// all optional CNs scanned once and all mandatory CNs configured successfully
					EplNmtMnuInstance_g.m_wFlags |=
					    EPL_NMTMNU_FLAG_APP_INFORMED;
					// inform application
					Ret =
					    EplNmtMnuInstance_g.
					    m_pfnCbBootEvent
					    (kEplNmtBootEventBootStep1Finish,
					     NmtState, EPL_E_NO_ERROR);
					if (Ret != kEplSuccessful) {
						if (Ret == kEplReject) {
							// wait for application
							Ret = kEplSuccessful;
						}
						break;
					}
					// enter PreOp2
					Ret =
					    EplNmtuNmtEvent
					    (kEplNmtEventAllMandatoryCNIdent);
				}
				break;
			}

		case kEplNmtMsPreOperational2:
			{
				if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount ==
				     0)
				    && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) {	// all optional CNs checked once for ReadyToOp and all mandatory CNs are ReadyToOp
					EplNmtMnuInstance_g.m_wFlags |=
					    EPL_NMTMNU_FLAG_APP_INFORMED;
					// inform application
					Ret =
					    EplNmtMnuInstance_g.
					    m_pfnCbBootEvent
					    (kEplNmtBootEventBootStep2Finish,
					     NmtState, EPL_E_NO_ERROR);
					if (Ret != kEplSuccessful) {
						if (Ret == kEplReject) {
							// wait for application
							Ret = kEplSuccessful;
						}
						break;
					}
					// enter ReadyToOp
					Ret =
					    EplNmtuNmtEvent
					    (kEplNmtEventEnterReadyToOperate);
				}
				break;
			}

		case kEplNmtMsReadyToOperate:
			{
				if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount ==
				     0)
				    && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) {	// all CNs checked for errorless communication
					EplNmtMnuInstance_g.m_wFlags |=
					    EPL_NMTMNU_FLAG_APP_INFORMED;
					// inform application
					Ret =
					    EplNmtMnuInstance_g.
					    m_pfnCbBootEvent
					    (kEplNmtBootEventCheckComFinish,
					     NmtState, EPL_E_NO_ERROR);
					if (Ret != kEplSuccessful) {
						if (Ret == kEplReject) {
							// wait for application
							Ret = kEplSuccessful;
						}
						break;
					}
					// enter Operational
					Ret =
					    EplNmtuNmtEvent
					    (kEplNmtEventEnterMsOperational);
				}
				break;
			}

		case kEplNmtMsOperational:
			{
				if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount ==
				     0)
				    && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) {	// all optional CNs scanned once and all mandatory CNs are OPERATIONAL
					EplNmtMnuInstance_g.m_wFlags |=
					    EPL_NMTMNU_FLAG_APP_INFORMED;
					// inform application
					Ret =
					    EplNmtMnuInstance_g.
					    m_pfnCbBootEvent
					    (kEplNmtBootEventOperational,
					     NmtState, EPL_E_NO_ERROR);
					if (Ret != kEplSuccessful) {
						if (Ret == kEplReject) {
							// ignore error code
							Ret = kEplSuccessful;
						}
						break;
					}
				}
				break;
			}

		default:
			{
				break;
			}
		}
	}

      Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuCheckNmtState
//
// Description: checks the NMT state, i.e. evaluates it with object 0x1F8F
//              NMT_MNNodeExpState_AU8 and updates object 0x1F8E
//              NMT_MNNodeCurrState_AU8.
//              It manipulates m_NodeState in internal node info structure.
//
// Parameters:  uiNodeId_p              = node ID
//              NodeNmtState_p          = NMT state of CN
//
// Returns:     tEplKernel              = error code
//                  kEplReject          = CN was in wrong state and has been reset
//
// State:
//
//---------------------------------------------------------------------------

static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
					 tEplNmtMnuNodeInfo * pNodeInfo_p,
					 tEplNmtState NodeNmtState_p,
					 WORD wErrorCode_p,
					 tEplNmtState LocalNmtState_p)
{
	tEplKernel Ret = kEplSuccessful;
	tEplObdSize ObdSize;
	BYTE bNmtState;
	BYTE bNmtStatePrev;
	tEplNmtState ExpNmtState;

	ObdSize = 1;
	// read object 0x1F8F NMT_MNNodeExpState_AU8
	Ret = EplObduReadEntry(0x1F8F, uiNodeId_p, &bNmtState, &ObdSize);
	if (Ret != kEplSuccessful) {
		goto Exit;
	}
	// compute expected NMT state
	ExpNmtState = (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS);
	// compute BYTE of current NMT state
	bNmtState = ((BYTE) NodeNmtState_p & 0xFF);

	if (ExpNmtState == kEplNmtCsNotActive) {	// ignore the current state, because the CN shall be not active
		Ret = kEplReject;
		goto Exit;
	} else if ((ExpNmtState == kEplNmtCsPreOperational2)
		   && (NodeNmtState_p == kEplNmtCsReadyToOperate)) {	// CN switched to ReadyToOp
		// delete timer for timeout handling
		Ret = EplTimeruDeleteTimer(&pNodeInfo_p->m_TimerHdlLonger);
		if (Ret != kEplSuccessful) {
			goto Exit;
		}
		pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateReadyToOp;

		// update object 0x1F8F NMT_MNNodeExpState_AU8 to ReadyToOp
		Ret = EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState, 1);
		if (Ret != kEplSuccessful) {
			goto Exit;
		}

		if ((pNodeInfo_p->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// node is a mandatory CN -> decrement counter
			EplNmtMnuInstance_g.m_uiMandatorySlaveCount--;
		}
		if (LocalNmtState_p >= kEplNmtMsReadyToOperate) {	// start procedure CheckCommunication for this node
			Ret = EplNmtMnuNodeCheckCom(uiNodeId_p, pNodeInfo_p);
			if (Ret != kEplSuccessful) {
				goto Exit;
			}

			if ((LocalNmtState_p == kEplNmtMsOperational)
			    && (pNodeInfo_p->m_NodeState ==
				kEplNmtMnuNodeStateComChecked)) {
				EPL_NMTMNU_DBG_POST_TRACE_VALUE(0, uiNodeId_p,
								(((NodeNmtState_p & 0xFF) << 8)
								 |
								 kEplNmtCmdStartNode));

				// immediately start optional CN, because communication is always OK (e.g. async-only CN)
				Ret =
				    EplNmtMnuSendNmtCommand(uiNodeId_p,
							    kEplNmtCmdStartNode);
				if (Ret != kEplSuccessful) {
					goto Exit;
				}
			}
		}

	} else if ((ExpNmtState == kEplNmtCsReadyToOperate)
		   && (NodeNmtState_p == kEplNmtCsOperational)) {	// CN switched to OPERATIONAL
		pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateOperational;

		if ((pNodeInfo_p->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) {	// node is a mandatory CN -> decrement counter
			EplNmtMnuInstance_g.m_uiMandatorySlaveCount--;
		}

	} else if ((ExpNmtState != NodeNmtState_p)
		   && !((ExpNmtState == kEplNmtCsPreOperational1)
			&& (NodeNmtState_p == kEplNmtCsPreOperational2))) {	// CN is not in expected NMT state (without the exceptions above)
		WORD wbeErrorCode;

		if ((pNodeInfo_p->
		     m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0) {
			// decrement only signal slave count if checked once
			EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
			pNodeInfo_p->m_wFlags &=
			    ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
		}

		if (pNodeInfo_p->m_NodeState == kEplNmtMnuNodeStateUnknown) {	// CN is already in state unknown, which means that it got
			// NMT reset command earlier
			goto Exit;
		}
		// -> CN is in wrong NMT state
		pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateUnknown;

		if (wErrorCode_p == 0) {	// assume wrong NMT state error
			if ((pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED) != 0) {	// NMT command has been just issued;
				// ignore wrong NMT state until timer expires;
				// other errors like LOSS_PRES_TH are still processed
				goto Exit;
			}

			wErrorCode_p = EPL_E_NMT_WRONG_STATE;
		}

		BENCHMARK_MOD_07_TOGGLE(9);

		// $$$ start ERROR_TREATMENT and inform application
		Ret = EplNmtMnuInstance_g.m_pfnCbNodeEvent(uiNodeId_p,
							   kEplNmtNodeEventError,
							   NodeNmtState_p,
							   wErrorCode_p,
							   (pNodeInfo_p->
							    m_dwNodeCfg &
							    EPL_NODEASSIGN_MANDATORY_CN)
							   != 0);
		if (Ret != kEplSuccessful) {
			goto Exit;
		}

		EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
						uiNodeId_p,
						(((NodeNmtState_p & 0xFF) << 8)
						 | kEplNmtCmdResetNode));

		// reset CN
		// store error code in NMT command data for diagnostic purpose
		AmiSetWordToLe(&wbeErrorCode, wErrorCode_p);
		Ret =
		    EplNmtMnuSendNmtCommandEx(uiNodeId_p, kEplNmtCmdResetNode,
					      &wbeErrorCode,
					      sizeof(wbeErrorCode));
		if (Ret == kEplSuccessful) {
			Ret = kEplReject;
		}

		goto Exit;
	}
	// check if NMT_MNNodeCurrState_AU8 has to be changed
	ObdSize = 1;
	Ret = EplObduReadEntry(0x1F8E, uiNodeId_p, &bNmtStatePrev, &ObdSize);
	if (Ret != kEplSuccessful) {
		goto Exit;
	}
	if (bNmtState != bNmtStatePrev) {
		// update object 0x1F8E NMT_MNNodeCurrState_AU8
		Ret = EplObduWriteEntry(0x1F8E, uiNodeId_p, &bNmtState, 1);
		if (Ret != kEplSuccessful) {
			goto Exit;
		}
		Ret = EplNmtMnuInstance_g.m_pfnCbNodeEvent(uiNodeId_p,
							   kEplNmtNodeEventNmtState,
							   NodeNmtState_p,
							   wErrorCode_p,
							   (pNodeInfo_p->
							    m_dwNodeCfg &
							    EPL_NODEASSIGN_MANDATORY_CN)
							   != 0);
		if (Ret != kEplSuccessful) {
			goto Exit;
		}
	}

      Exit:
	return Ret;
}

//---------------------------------------------------------------------------
//
// Function:    EplNmtMnuReset
//
// Description: reset internal structures, e.g. timers
//
// Parameters:  void
//
// Returns:     tEplKernel              = error code
//
// State:
//
//---------------------------------------------------------------------------

static tEplKernel EplNmtMnuReset(void)
{
	tEplKernel Ret;
	int iIndex;

	Ret = EplTimeruDeleteTimer(&EplNmtMnuInstance_g.m_TimerHdlNmtState);

	for (iIndex = 1; iIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
	     iIndex++) {
		// delete timer handles
		Ret =
		    EplTimeruDeleteTimer(&EPL_NMTMNU_GET_NODEINFO(iIndex)->
					 m_TimerHdlStatReq);
		Ret =
		    EplTimeruDeleteTimer(&EPL_NMTMNU_GET_NODEINFO(iIndex)->
					 m_TimerHdlLonger);
	}

	return Ret;
}

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

// EOF
