blob: 4ed0b6ce487c8820e8064d5a9a9c360bb509625f [file] [log] [blame]
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001/****************************************************************************
2
3 (c) SYSTEC electronic GmbH, D-07973 Greiz, August-Bebel-Str. 29
4 www.systec-electronic.com
5
6 Project: openPOWERLINK
7
8 Description: source file for NMT-MN-Module
9
10 License:
11
12 Redistribution and use in source and binary forms, with or without
13 modification, are permitted provided that the following conditions
14 are met:
15
16 1. Redistributions of source code must retain the above copyright
17 notice, this list of conditions and the following disclaimer.
18
19 2. Redistributions in binary form must reproduce the above copyright
20 notice, this list of conditions and the following disclaimer in the
21 documentation and/or other materials provided with the distribution.
22
23 3. Neither the name of SYSTEC electronic GmbH nor the names of its
24 contributors may be used to endorse or promote products derived
25 from this software without prior written permission. For written
26 permission, please contact info@systec-electronic.com.
27
28 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
29 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
30 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32 COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
33 INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
34 BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
36 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
37 LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
38 ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 POSSIBILITY OF SUCH DAMAGE.
40
41 Severability Clause:
42
43 If a provision of this License is or becomes illegal, invalid or
44 unenforceable in any jurisdiction, that shall not affect:
45 1. the validity or enforceability in that jurisdiction of any other
46 provision of this License; or
47 2. the validity or enforceability in other jurisdictions of that or
48 any other provision of this License.
49
50 -------------------------------------------------------------------------
51
52 $RCSfile: EplNmtMnu.c,v $
53
54 $Author: D.Krueger $
55
56 $Revision: 1.18 $ $Date: 2008/11/19 09:52:24 $
57
58 $State: Exp $
59
60 Build Environment:
61 GCC V3.4
62
63 -------------------------------------------------------------------------
64
65 Revision History:
66
67 2006/06/09 k.t.: start of the implementation
68
69****************************************************************************/
70
71#include "user/EplNmtMnu.h"
72#include "user/EplTimeru.h"
73#include "user/EplIdentu.h"
74#include "user/EplStatusu.h"
75#include "user/EplObdu.h"
76#include "user/EplDlluCal.h"
77#include "Benchmark.h"
78
79#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
80
81#if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDU)) == 0) && (EPL_OBD_USE_KERNEL == FALSE)
82#error "EPL NmtMnu module needs EPL module OBDU or OBDK!"
83#endif
84
85//=========================================================================//
86// //
87// P R I V A T E D E F I N I T I O N S //
88// //
89//=========================================================================//
90
91//---------------------------------------------------------------------------
92// const defines
93//---------------------------------------------------------------------------
94
95// TracePoint support for realtime-debugging
96#ifdef _DBG_TRACE_POINTS_
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -080097void PUBLIC TgtDbgSignalTracePoint(BYTE bTracePointNumber_p);
98void PUBLIC TgtDbgPostTraceValue(DWORD dwTraceValue_p);
99#define TGT_DBG_SIGNAL_TRACE_POINT(p) TgtDbgSignalTracePoint(p)
100#define TGT_DBG_POST_TRACE_VALUE(v) TgtDbgPostTraceValue(v)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800101#else
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800102#define TGT_DBG_SIGNAL_TRACE_POINT(p)
103#define TGT_DBG_POST_TRACE_VALUE(v)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800104#endif
105#define EPL_NMTMNU_DBG_POST_TRACE_VALUE(Event_p, uiNodeId_p, wErrorCode_p) \
106 TGT_DBG_POST_TRACE_VALUE((kEplEventSinkNmtMnu << 28) | (Event_p << 24) \
107 | (uiNodeId_p << 16) | wErrorCode_p)
108
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800109// defines for flags in node info structure
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800110#define EPL_NMTMNU_NODE_FLAG_ISOCHRON 0x0001 // CN is being accessed isochronously
111#define EPL_NMTMNU_NODE_FLAG_NOT_SCANNED 0x0002 // CN was not scanned once -> decrement SignalCounter and reset flag
112#define EPL_NMTMNU_NODE_FLAG_HALTED 0x0004 // boot process for this CN is halted
113#define EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED 0x0008 // NMT command was just issued, wrong NMT states will be tolerated
114#define EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ 0x0300 // counter for StatusRequest timer handle
115#define EPL_NMTMNU_NODE_FLAG_COUNT_LONGER 0x0C00 // counter for longer timeouts timer handle
116#define EPL_NMTMNU_NODE_FLAG_INC_STATREQ 0x0100 // increment for StatusRequest timer handle
117#define EPL_NMTMNU_NODE_FLAG_INC_LONGER 0x0400 // increment for longer timeouts timer handle
118 // These counters will be incremented at every timer start
119 // and copied to timerarg. When the timer event occures
120 // both will be compared and if unequal the timer event
121 // will be discarded, because it is an old one.
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800122
123// defines for timer arguments to draw a distinction between serveral events
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800124#define EPL_NMTMNU_TIMERARG_NODE_MASK 0x000000FFL // mask that contains the node-ID
125#define EPL_NMTMNU_TIMERARG_IDENTREQ 0x00010000L // timer event is for IdentRequest
126#define EPL_NMTMNU_TIMERARG_STATREQ 0x00020000L // timer event is for StatusRequest
127#define EPL_NMTMNU_TIMERARG_LONGER 0x00040000L // timer event is for longer timeouts
128#define EPL_NMTMNU_TIMERARG_STATE_MON 0x00080000L // timer event for StatusRequest to monitor execution of NMT state changes
129#define EPL_NMTMNU_TIMERARG_COUNT_SR 0x00000300L // counter for StatusRequest
130#define EPL_NMTMNU_TIMERARG_COUNT_LO 0x00000C00L // counter for longer timeouts
131 // The counters must have the same position as in the node flags above.
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800132
133#define EPL_NMTMNU_SET_FLAGS_TIMERARG_STATREQ(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
134 pNodeInfo_p->m_wFlags = \
135 ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \
136 & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \
137 | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
138 TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_STATREQ | uiNodeId_p | \
139 (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
140 TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;
141
142#define EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
143 pNodeInfo_p->m_wFlags = \
144 ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \
145 & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \
146 | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
147 TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_IDENTREQ | uiNodeId_p | \
148 (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
149 TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;
150
151#define EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
152 pNodeInfo_p->m_wFlags = \
153 ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_LONGER) \
154 & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER) \
155 | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_LONGER); \
156 TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p | \
157 (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER); \
158 TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;
159
160#define EPL_NMTMNU_SET_FLAGS_TIMERARG_STATE_MON(pNodeInfo_p, uiNodeId_p, TimerArg_p) \
161 pNodeInfo_p->m_wFlags = \
162 ((pNodeInfo_p->m_wFlags + EPL_NMTMNU_NODE_FLAG_INC_STATREQ) \
163 & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) \
164 | (pNodeInfo_p->m_wFlags & ~EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
165 TimerArg_p.m_ulArg = EPL_NMTMNU_TIMERARG_STATE_MON | uiNodeId_p | \
166 (pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ); \
167 TimerArg_p.m_EventSink = kEplEventSinkNmtMnu;
168
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800169// defines for global flags
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800170#define EPL_NMTMNU_FLAG_HALTED 0x0001 // boot process is halted
171#define EPL_NMTMNU_FLAG_APP_INFORMED 0x0002 // application was informed about possible NMT state change
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800172
173// return pointer to node info structure for specified node ID
174// d.k. may be replaced by special (hash) function if node ID array is smaller than 254
175#define EPL_NMTMNU_GET_NODEINFO(uiNodeId_p) (&EplNmtMnuInstance_g.m_aNodeInfo[uiNodeId_p - 1])
176
177//---------------------------------------------------------------------------
178// local types
179//---------------------------------------------------------------------------
180
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800181typedef enum {
182 kEplNmtMnuIntNodeEventNoIdentResponse = 0x00,
183 kEplNmtMnuIntNodeEventIdentResponse = 0x01,
184 kEplNmtMnuIntNodeEventBoot = 0x02,
185 kEplNmtMnuIntNodeEventExecReset = 0x03,
186 kEplNmtMnuIntNodeEventConfigured = 0x04,
187 kEplNmtMnuIntNodeEventNoStatusResponse = 0x05,
188 kEplNmtMnuIntNodeEventStatusResponse = 0x06,
189 kEplNmtMnuIntNodeEventHeartbeat = 0x07,
190 kEplNmtMnuIntNodeEventNmtCmdSent = 0x08,
191 kEplNmtMnuIntNodeEventTimerIdentReq = 0x09,
192 kEplNmtMnuIntNodeEventTimerStatReq = 0x0A,
193 kEplNmtMnuIntNodeEventTimerStateMon = 0x0B,
194 kEplNmtMnuIntNodeEventTimerLonger = 0x0C,
195 kEplNmtMnuIntNodeEventError = 0x0D,
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800196
197} tEplNmtMnuIntNodeEvent;
198
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800199typedef enum {
200 kEplNmtMnuNodeStateUnknown = 0x00,
201 kEplNmtMnuNodeStateIdentified = 0x01,
202 kEplNmtMnuNodeStateResetConf = 0x02, // CN reset after configuration update
203 kEplNmtMnuNodeStateConfigured = 0x03, // BootStep1 completed
204 kEplNmtMnuNodeStateReadyToOp = 0x04, // BootStep2 completed
205 kEplNmtMnuNodeStateComChecked = 0x05, // Communication checked successfully
206 kEplNmtMnuNodeStateOperational = 0x06, // CN is in NMT state OPERATIONAL
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800207
208} tEplNmtMnuNodeState;
209
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800210typedef struct {
211 tEplTimerHdl m_TimerHdlStatReq; // timer to delay StatusRequests and IdentRequests
212 tEplTimerHdl m_TimerHdlLonger; // 2nd timer for NMT command EnableReadyToOp and CheckCommunication
213 tEplNmtMnuNodeState m_NodeState; // internal node state (kind of sub state of NMT state)
214 DWORD m_dwNodeCfg; // subindex from 0x1F81
215 WORD m_wFlags; // flags: CN is being accessed isochronously
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800216
217} tEplNmtMnuNodeInfo;
218
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800219typedef struct {
220 tEplNmtMnuNodeInfo m_aNodeInfo[EPL_NMT_MAX_NODE_ID];
221 tEplTimerHdl m_TimerHdlNmtState; // timeout for stay in NMT state
222 unsigned int m_uiMandatorySlaveCount;
223 unsigned int m_uiSignalSlaveCount;
224 unsigned long m_ulStatusRequestDelay; // in [ms] (object 0x1006 * EPL_C_NMT_STATREQ_CYCLE)
225 unsigned long m_ulTimeoutReadyToOp; // in [ms] (object 0x1F89/5)
226 unsigned long m_ulTimeoutCheckCom; // in [ms] (object 0x1006 * MultiplexedCycleCount)
227 WORD m_wFlags; // global flags
228 DWORD m_dwNmtStartup; // object 0x1F80 NMT_StartUp_U32
229 tEplNmtMnuCbNodeEvent m_pfnCbNodeEvent;
230 tEplNmtMnuCbBootEvent m_pfnCbBootEvent;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800231
232} tEplNmtMnuInstance;
233
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800234//---------------------------------------------------------------------------
235// local vars
236//---------------------------------------------------------------------------
237
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800238static tEplNmtMnuInstance EplNmtMnuInstance_g;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800239
240//---------------------------------------------------------------------------
241// local function prototypes
242//---------------------------------------------------------------------------
243
244static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p);
245
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800246static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
247 tEplIdentResponse *
248 pIdentResponse_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800249
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800250static tEplKernel PUBLIC EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
251 tEplStatusResponse *
252 pStatusResponse_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800253
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800254static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
255 tEplNmtMnuNodeInfo * pNodeInfo_p,
256 tEplNmtState NodeNmtState_p,
257 WORD wErrorCode_p,
258 tEplNmtState LocalNmtState_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800259
260static tEplKernel EplNmtMnuStartBootStep1(void);
261
262static tEplKernel EplNmtMnuStartBootStep2(void);
263
264static tEplKernel EplNmtMnuStartCheckCom(void);
265
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800266static tEplKernel EplNmtMnuNodeBootStep2(unsigned int uiNodeId_p,
267 tEplNmtMnuNodeInfo * pNodeInfo_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800268
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800269static tEplKernel EplNmtMnuNodeCheckCom(unsigned int uiNodeId_p,
270 tEplNmtMnuNodeInfo * pNodeInfo_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800271
272static tEplKernel EplNmtMnuStartNodes(void);
273
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800274static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
275 tEplNmtState NodeNmtState_p,
276 WORD wErrorCode_p,
277 tEplNmtMnuIntNodeEvent
278 NodeEvent_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800279
280static tEplKernel EplNmtMnuReset(void);
281
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800282//=========================================================================//
283// //
284// P U B L I C F U N C T I O N S //
285// //
286//=========================================================================//
287
288//---------------------------------------------------------------------------
289//
290// Function: EplNmtMnuInit
291//
292// Description: init first instance of the module
293//
294//
295//
296// Parameters:
297//
298//
299// Returns: tEplKernel = errorcode
300//
301//
302// State:
303//
304//---------------------------------------------------------------------------
305
306tEplKernel EplNmtMnuInit(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800307 tEplNmtMnuCbBootEvent pfnCbBootEvent_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800308{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800309 tEplKernel Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800310
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800311 Ret = EplNmtMnuAddInstance(pfnCbNodeEvent_p, pfnCbBootEvent_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800312
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800313 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800314}
315
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800316//---------------------------------------------------------------------------
317//
318// Function: EplNmtMnuAddInstance
319//
320// Description: init other instances of the module
321//
322//
323//
324// Parameters:
325//
326//
327// Returns: tEplKernel = errorcode
328//
329//
330// State:
331//
332//---------------------------------------------------------------------------
333
334tEplKernel EplNmtMnuAddInstance(tEplNmtMnuCbNodeEvent pfnCbNodeEvent_p,
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800335 tEplNmtMnuCbBootEvent pfnCbBootEvent_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800336{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800337 tEplKernel Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800338
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800339 Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800340
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800341 // reset instance structure
342 EPL_MEMSET(&EplNmtMnuInstance_g, 0, sizeof(EplNmtMnuInstance_g));
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800343
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800344 if ((pfnCbNodeEvent_p == NULL) || (pfnCbBootEvent_p == NULL)) {
345 Ret = kEplNmtInvalidParam;
346 goto Exit;
347 }
348 EplNmtMnuInstance_g.m_pfnCbNodeEvent = pfnCbNodeEvent_p;
349 EplNmtMnuInstance_g.m_pfnCbBootEvent = pfnCbBootEvent_p;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800350
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800351 // initialize StatusRequest delay
352 EplNmtMnuInstance_g.m_ulStatusRequestDelay = 5000L;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800353
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800354 // register NmtMnResponse callback function
355 Ret =
356 EplDlluCalRegAsndService(kEplDllAsndNmtRequest,
357 EplNmtMnuCbNmtRequest,
358 kEplDllAsndFilterLocal);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800359
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800360 Exit:
361 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800362
363}
364
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800365//---------------------------------------------------------------------------
366//
367// Function: EplNmtMnuDelInstance
368//
369// Description: delete instance
370//
371//
372//
373// Parameters:
374//
375//
376// Returns: tEplKernel = errorcode
377//
378//
379// State:
380//
381//---------------------------------------------------------------------------
382
383tEplKernel EplNmtMnuDelInstance()
384{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800385 tEplKernel Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800386
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800387 Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800388
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800389 // deregister NmtMnResponse callback function
390 Ret =
391 EplDlluCalRegAsndService(kEplDllAsndNmtRequest, NULL,
392 kEplDllAsndFilterNone);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800393
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800394 Ret = EplNmtMnuReset();
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800395
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800396 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800397
398}
399
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800400//---------------------------------------------------------------------------
401//
402// Function: EplNmtMnuSendNmtCommandEx
403//
404// Description: sends the specified NMT command to the specified node.
405//
406// Parameters: uiNodeId_p = node ID to which the NMT command will be sent
407// NmtCommand_p = NMT command
408//
409// Returns: tEplKernel = error code
410//
411// State:
412//
413//---------------------------------------------------------------------------
414
415tEplKernel EplNmtMnuSendNmtCommandEx(unsigned int uiNodeId_p,
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800416 tEplNmtCommand NmtCommand_p,
417 void *pNmtCommandData_p,
418 unsigned int uiDataSize_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800419{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800420 tEplKernel Ret = kEplSuccessful;
421 tEplFrameInfo FrameInfo;
422 BYTE abBuffer[EPL_C_DLL_MINSIZE_NMTCMDEXT];
423 tEplFrame *pFrame = (tEplFrame *) abBuffer;
424 BOOL fSoftDeleteNode = FALSE;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800425
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800426 if ((uiNodeId_p == 0) || (uiNodeId_p > EPL_C_ADR_BROADCAST)) { // invalid node ID specified
427 Ret = kEplInvalidNodeId;
428 goto Exit;
429 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800430
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800431 if ((pNmtCommandData_p != NULL)
432 && (uiDataSize_p >
433 (EPL_C_DLL_MINSIZE_NMTCMDEXT - EPL_C_DLL_MINSIZE_NMTCMD))) {
434 Ret = kEplNmtInvalidParam;
435 goto Exit;
436 }
437 // $$$ d.k. may be check in future versions if the caller wants to perform prohibited state transitions
438 // the CN should not perform these transitions, but the expected NMT state will be changed and never fullfilled.
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800439
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800440 // build frame
441 EPL_MEMSET(pFrame, 0x00, sizeof(abBuffer));
442 AmiSetByteToLe(&pFrame->m_le_bDstNodeId, (BYTE) uiNodeId_p);
443 AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_le_bServiceId,
444 (BYTE) kEplDllAsndNmtCommand);
445 AmiSetByteToLe(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.
446 m_le_bNmtCommandId, (BYTE) NmtCommand_p);
447 if ((pNmtCommandData_p != NULL) && (uiDataSize_p > 0)) { // copy command data to frame
448 EPL_MEMCPY(&pFrame->m_Data.m_Asnd.m_Payload.m_NmtCommandService.
449 m_le_abNmtCommandData[0], pNmtCommandData_p,
450 uiDataSize_p);
451 }
452 // build info structure
453 FrameInfo.m_NetTime.m_dwNanoSec = 0;
454 FrameInfo.m_NetTime.m_dwSec = 0;
455 FrameInfo.m_pFrame = pFrame;
456 FrameInfo.m_uiFrameSize = sizeof(abBuffer);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800457
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800458 // send NMT-Request
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800459#if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800460 Ret = EplDlluCalAsyncSend(&FrameInfo, // pointer to frameinfo
461 kEplDllAsyncReqPrioNmt); // priority
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800462#endif
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800463 if (Ret != kEplSuccessful) {
464 goto Exit;
465 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800466
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800467 EPL_DBGLVL_NMTMN_TRACE2("NMTCmd(%02X->%02X)\n", NmtCommand_p,
468 uiNodeId_p);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800469
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800470 switch (NmtCommand_p) {
471 case kEplNmtCmdStartNode:
472 case kEplNmtCmdEnterPreOperational2:
473 case kEplNmtCmdEnableReadyToOperate:
474 {
475 // nothing left to do,
476 // because any further processing is done
477 // when the NMT command is actually sent
478 goto Exit;
479 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800480
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800481 case kEplNmtCmdStopNode:
482 {
483 fSoftDeleteNode = TRUE;
484 break;
485 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800486
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800487 case kEplNmtCmdResetNode:
488 case kEplNmtCmdResetCommunication:
489 case kEplNmtCmdResetConfiguration:
490 case kEplNmtCmdSwReset:
491 {
492 break;
493 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800494
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800495 default:
496 goto Exit;
497 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800498
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800499 // remove CN from isochronous phase;
500 // This must be done here and not when NMT command is actually sent
501 // because it will be too late and may cause unwanted errors
502 if (uiNodeId_p != EPL_C_ADR_BROADCAST) {
503 if (fSoftDeleteNode == FALSE) { // remove CN immediately from isochronous phase
504 Ret = EplDlluCalDeleteNode(uiNodeId_p);
505 } else { // remove CN from isochronous phase softly
506 Ret = EplDlluCalSoftDeleteNode(uiNodeId_p);
507 }
508 } else { // do it for all active CNs
509 for (uiNodeId_p = 1;
510 uiNodeId_p <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
511 uiNodeId_p++) {
512 if ((EPL_NMTMNU_GET_NODEINFO(uiNodeId_p)->
513 m_dwNodeCfg & (EPL_NODEASSIGN_NODE_IS_CN |
514 EPL_NODEASSIGN_NODE_EXISTS)) != 0) {
515 if (fSoftDeleteNode == FALSE) { // remove CN immediately from isochronous phase
516 Ret = EplDlluCalDeleteNode(uiNodeId_p);
517 } else { // remove CN from isochronous phase softly
518 Ret =
519 EplDlluCalSoftDeleteNode
520 (uiNodeId_p);
521 }
522 }
523 }
524 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800525
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800526 Exit:
527 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800528}
529
530//---------------------------------------------------------------------------
531//
532// Function: EplNmtMnuSendNmtCommand
533//
534// Description: sends the specified NMT command to the specified node.
535//
536// Parameters: uiNodeId_p = node ID to which the NMT command will be sent
537// NmtCommand_p = NMT command
538//
539// Returns: tEplKernel = error code
540//
541// State:
542//
543//---------------------------------------------------------------------------
544
545tEplKernel EplNmtMnuSendNmtCommand(unsigned int uiNodeId_p,
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800546 tEplNmtCommand NmtCommand_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800547{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800548 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800549
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800550 Ret = EplNmtMnuSendNmtCommandEx(uiNodeId_p, NmtCommand_p, NULL, 0);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800551
552//Exit:
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800553 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800554}
555
556//---------------------------------------------------------------------------
557//
558// Function: EplNmtMnuTriggerStateChange
559//
560// Description: triggers the specified node command for the specified node.
561//
562// Parameters: uiNodeId_p = node ID for which the node command will be executed
563// NodeCommand_p = node command
564//
565// Returns: tEplKernel = error code
566//
567// State:
568//
569//---------------------------------------------------------------------------
570
571tEplKernel EplNmtMnuTriggerStateChange(unsigned int uiNodeId_p,
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800572 tEplNmtNodeCommand NodeCommand_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800573{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800574 tEplKernel Ret = kEplSuccessful;
575 tEplNmtMnuIntNodeEvent NodeEvent;
576 tEplObdSize ObdSize;
577 BYTE bNmtState;
578 WORD wErrorCode = EPL_E_NO_ERROR;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800579
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800580 if ((uiNodeId_p == 0) || (uiNodeId_p >= EPL_C_ADR_BROADCAST)) {
581 Ret = kEplInvalidNodeId;
582 goto Exit;
583 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800584
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800585 switch (NodeCommand_p) {
586 case kEplNmtNodeCommandBoot:
587 {
588 NodeEvent = kEplNmtMnuIntNodeEventBoot;
589 break;
590 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800591
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800592 case kEplNmtNodeCommandConfOk:
593 {
594 NodeEvent = kEplNmtMnuIntNodeEventConfigured;
595 break;
596 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800597
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800598 case kEplNmtNodeCommandConfErr:
599 {
600 NodeEvent = kEplNmtMnuIntNodeEventError;
601 wErrorCode = EPL_E_NMT_BPO1_CF_VERIFY;
602 break;
603 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800604
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800605 case kEplNmtNodeCommandConfReset:
606 {
607 NodeEvent = kEplNmtMnuIntNodeEventExecReset;
608 break;
609 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800610
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800611 default:
612 { // invalid node command
613 goto Exit;
614 }
615 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800616
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800617 // fetch current NMT state
618 ObdSize = 1;
619 Ret = EplObduReadEntry(0x1F8E, uiNodeId_p, &bNmtState, &ObdSize);
620 if (Ret != kEplSuccessful) {
621 goto Exit;
622 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800623
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800624 Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
625 (tEplNmtState) (bNmtState |
626 EPL_NMT_TYPE_CS),
627 wErrorCode, NodeEvent);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800628
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800629 Exit:
630 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800631}
632
633//---------------------------------------------------------------------------
634//
635// Function: EplNmtMnuCbNmtStateChange
636//
637// Description: callback function for NMT state changes
638//
639// Parameters: NmtStateChange_p = NMT state change event
640//
641// Returns: tEplKernel = error code
642//
643//
644// State:
645//
646//---------------------------------------------------------------------------
647
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800648tEplKernel PUBLIC EplNmtMnuCbNmtStateChange(tEplEventNmtStateChange
649 NmtStateChange_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800650{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800651 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800652
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800653 // do work which must be done in that state
654 switch (NmtStateChange_p.m_NewNmtState) {
655 // EPL stack is not running
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800656/* case kEplNmtGsOff:
657 break;
658
659 // first init of the hardware
660 case kEplNmtGsInitialising:
661 break;
662
663 // init of the manufacturer-specific profile area and the
664 // standardised device profile area
665 case kEplNmtGsResetApplication:
666 {
667 break;
668 }
669
670 // init of the communication profile area
671 case kEplNmtGsResetCommunication:
672 {
673 break;
674 }
675*/
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800676 // build the configuration with infos from OD
677 case kEplNmtGsResetConfiguration:
678 {
679 DWORD dwTimeout;
680 tEplObdSize ObdSize;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800681
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800682 // read object 0x1F80 NMT_StartUp_U32
683 ObdSize = 4;
684 Ret =
685 EplObduReadEntry(0x1F80, 0,
686 &EplNmtMnuInstance_g.
687 m_dwNmtStartup, &ObdSize);
688 if (Ret != kEplSuccessful) {
689 break;
690 }
691 // compute StatusReqDelay = object 0x1006 * EPL_C_NMT_STATREQ_CYCLE
692 ObdSize = sizeof(dwTimeout);
693 Ret = EplObduReadEntry(0x1006, 0, &dwTimeout, &ObdSize);
694 if (Ret != kEplSuccessful) {
695 break;
696 }
697 if (dwTimeout != 0L) {
698 EplNmtMnuInstance_g.m_ulStatusRequestDelay =
699 dwTimeout * EPL_C_NMT_STATREQ_CYCLE / 1000L;
700 if (EplNmtMnuInstance_g.
701 m_ulStatusRequestDelay == 0L) {
702 EplNmtMnuInstance_g.m_ulStatusRequestDelay = 1L; // at least 1 ms
703 }
704 // $$$ fetch and use MultiplexedCycleCount from OD
705 EplNmtMnuInstance_g.m_ulTimeoutCheckCom =
706 dwTimeout * EPL_C_NMT_STATREQ_CYCLE / 1000L;
707 if (EplNmtMnuInstance_g.m_ulTimeoutCheckCom ==
708 0L) {
709 EplNmtMnuInstance_g.m_ulTimeoutCheckCom = 1L; // at least 1 ms
710 }
711 }
712 // fetch ReadyToOp Timeout from OD
713 ObdSize = sizeof(dwTimeout);
714 Ret = EplObduReadEntry(0x1F89, 5, &dwTimeout, &ObdSize);
715 if (Ret != kEplSuccessful) {
716 break;
717 }
718 if (dwTimeout != 0L) {
719 // convert [us] to [ms]
720 dwTimeout /= 1000L;
721 if (dwTimeout == 0L) {
722 dwTimeout = 1L; // at least 1 ms
723 }
724 EplNmtMnuInstance_g.m_ulTimeoutReadyToOp =
725 dwTimeout;
726 } else {
727 EplNmtMnuInstance_g.m_ulTimeoutReadyToOp = 0L;
728 }
729 break;
730 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800731/*
732 //-----------------------------------------------------------
733 // CN part of the state machine
734
735 // node liste for EPL-Frames and check timeout
736 case kEplNmtCsNotActive:
737 {
738 break;
739 }
740
741 // node process only async frames
742 case kEplNmtCsPreOperational1:
743 {
744 break;
745 }
746
747 // node process isochronus and asynchronus frames
748 case kEplNmtCsPreOperational2:
749 {
750 break;
751 }
752
753 // node should be configured und application is ready
754 case kEplNmtCsReadyToOperate:
755 {
756 break;
757 }
758
759 // normal work state
760 case kEplNmtCsOperational:
761 {
762 break;
763 }
764
765 // node stopped by MN
766 // -> only process asynchronus frames
767 case kEplNmtCsStopped:
768 {
769 break;
770 }
771
772 // no EPL cycle
773 // -> normal ethernet communication
774 case kEplNmtCsBasicEthernet:
775 {
776 break;
777 }
778*/
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800779 //-----------------------------------------------------------
780 // MN part of the state machine
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800781
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800782 // node listens for EPL-Frames and check timeout
783 case kEplNmtMsNotActive:
784 {
785 break;
786 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800787
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800788 // node processes only async frames
789 case kEplNmtMsPreOperational1:
790 {
791 DWORD dwTimeout;
792 tEplTimerArg TimerArg;
793 tEplObdSize ObdSize;
794 tEplEvent Event;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800795
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800796 // clear global flags, e.g. reenable boot process
797 EplNmtMnuInstance_g.m_wFlags = 0;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800798
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800799 // reset IdentResponses and running IdentRequests and StatusRequests
800 Ret = EplIdentuReset();
801 Ret = EplStatusuReset();
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800802
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800803 // reset timers
804 Ret = EplNmtMnuReset();
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800805
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800806 // 2008/11/18 d.k. reset internal node info is not necessary,
807 // because timer flags are important and other
808 // things are reset by EplNmtMnuStartBootStep1().
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800809/*
810 EPL_MEMSET(EplNmtMnuInstance_g.m_aNodeInfo,
811 0,
812 sizeof (EplNmtMnuInstance_g.m_aNodeInfo));
813*/
814
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800815 // inform DLL about NMT state change,
816 // so that it can clear the asynchonous queues and start the reduced cycle
817 Event.m_EventSink = kEplEventSinkDllk;
818 Event.m_EventType = kEplEventTypeDllkStartReducedCycle;
819 EPL_MEMSET(&Event.m_NetTime, 0x00,
820 sizeof(Event.m_NetTime));
821 Event.m_pArg = NULL;
822 Event.m_uiSize = 0;
823 Ret = EplEventuPost(&Event);
824 if (Ret != kEplSuccessful) {
825 break;
826 }
827 // reset all nodes
828 // d.k.: skip this step if was just done before, e.g. because of a ResetNode command from a diagnostic node
829 if (NmtStateChange_p.m_NmtEvent ==
830 kEplNmtEventTimerMsPreOp1) {
831 BENCHMARK_MOD_07_TOGGLE(9);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800832
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800833 EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
834 EPL_C_ADR_BROADCAST,
835 kEplNmtCmdResetNode);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800836
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800837 Ret =
838 EplNmtMnuSendNmtCommand(EPL_C_ADR_BROADCAST,
839 kEplNmtCmdResetNode);
840 if (Ret != kEplSuccessful) {
841 break;
842 }
843 }
844 // start network scan
845 Ret = EplNmtMnuStartBootStep1();
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800846
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800847 // start timer for 0x1F89/2 MNTimeoutPreOp1_U32
848 ObdSize = sizeof(dwTimeout);
849 Ret = EplObduReadEntry(0x1F89, 2, &dwTimeout, &ObdSize);
850 if (Ret != kEplSuccessful) {
851 break;
852 }
853 if (dwTimeout != 0L) {
854 dwTimeout /= 1000L;
855 if (dwTimeout == 0L) {
856 dwTimeout = 1L; // at least 1 ms
857 }
858 TimerArg.m_EventSink = kEplEventSinkNmtMnu;
859 TimerArg.m_ulArg = 0;
860 Ret =
861 EplTimeruModifyTimerMs(&EplNmtMnuInstance_g.
862 m_TimerHdlNmtState,
863 dwTimeout, TimerArg);
864 }
865 break;
866 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800867
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800868 // node processes isochronous and asynchronous frames
869 case kEplNmtMsPreOperational2:
870 {
871 // add identified CNs to isochronous phase
872 // send EnableReadyToOp to all identified CNs
873 Ret = EplNmtMnuStartBootStep2();
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800874
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800875 // wait for NMT state change of CNs
876 break;
877 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800878
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800879 // node should be configured und application is ready
880 case kEplNmtMsReadyToOperate:
881 {
882 // check if PRes of CNs are OK
883 // d.k. that means wait CycleLength * MultiplexCycleCount (i.e. start timer)
884 // because Dllk checks PRes of CNs automatically in ReadyToOp
885 Ret = EplNmtMnuStartCheckCom();
886 break;
887 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800888
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800889 // normal work state
890 case kEplNmtMsOperational:
891 {
892 // send StartNode to CNs
893 // wait for NMT state change of CNs
894 Ret = EplNmtMnuStartNodes();
895 break;
896 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800897
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800898 // no EPL cycle
899 // -> normal ethernet communication
900 case kEplNmtMsBasicEthernet:
901 {
902 break;
903 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800904
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800905 default:
906 {
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800907// TRACE0("EplNmtMnuCbNmtStateChange(): unhandled NMT state\n");
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800908 }
909 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800910
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800911 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800912}
913
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800914//---------------------------------------------------------------------------
915//
916// Function: EplNmtMnuCbCheckEvent
917//
918// Description: callback funktion for NMT events before they are actually executed.
919// The EPL API layer must forward NMT events from NmtCnu module.
920// This module will reject some NMT commands while MN.
921//
922// Parameters: NmtEvent_p = outstanding NMT event for approval
923//
924// Returns: tEplKernel = error code
925// kEplReject = reject the NMT event
926//
927// State:
928//
929//---------------------------------------------------------------------------
930
931tEplKernel PUBLIC EplNmtMnuCbCheckEvent(tEplNmtEvent NmtEvent_p)
932{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800933 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800934
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800935 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800936}
937
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800938//---------------------------------------------------------------------------
939//
940// Function: EplNmtuProcessEvent
941//
942// Description: processes events from event queue
943//
944// Parameters: pEvent_p = pointer to event
945//
946// Returns: tEplKernel = errorcode
947//
948// State:
949//
950//---------------------------------------------------------------------------
951
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800952EPLDLLEXPORT tEplKernel PUBLIC EplNmtMnuProcessEvent(tEplEvent * pEvent_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800953{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800954 tEplKernel Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800955
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800956 Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800957
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800958 // process event
959 switch (pEvent_p->m_EventType) {
960 // timer event
961 case kEplEventTypeTimer:
962 {
963 tEplTimerEventArg *pTimerEventArg =
964 (tEplTimerEventArg *) pEvent_p->m_pArg;
965 unsigned int uiNodeId;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800966
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800967 uiNodeId =
968 (unsigned int)(pTimerEventArg->
969 m_ulArg &
970 EPL_NMTMNU_TIMERARG_NODE_MASK);
971 if (uiNodeId != 0) {
972 tEplObdSize ObdSize;
973 BYTE bNmtState;
974 tEplNmtMnuNodeInfo *pNodeInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800975
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800976 pNodeInfo = EPL_NMTMNU_GET_NODEINFO(uiNodeId);
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800977
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800978 ObdSize = 1;
979 Ret =
980 EplObduReadEntry(0x1F8E, uiNodeId,
981 &bNmtState, &ObdSize);
982 if (Ret != kEplSuccessful) {
983 break;
984 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -0800985
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -0800986 if ((pTimerEventArg->
987 m_ulArg & EPL_NMTMNU_TIMERARG_IDENTREQ) !=
988 0L) {
989 if ((pNodeInfo->
990 m_wFlags &
991 EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ)
992 != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR)) { // this is an old (already deleted or modified) timer
993 // but not the current timer
994 // so discard it
995 EPL_NMTMNU_DBG_POST_TRACE_VALUE
996 (kEplNmtMnuIntNodeEventTimerIdentReq,
997 uiNodeId,
998 ((pNodeInfo->
999 m_NodeState << 8)
1000 | 0xFF));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001001
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001002 break;
1003 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001004/*
1005 EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerIdentReq,
1006 uiNodeId,
1007 ((pNodeInfo->m_NodeState << 8)
1008 | 0x80
1009 | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
1010 | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
1011*/
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001012 Ret =
1013 EplNmtMnuProcessInternalEvent
1014 (uiNodeId,
1015 (tEplNmtState) (bNmtState |
1016 EPL_NMT_TYPE_CS),
1017 EPL_E_NO_ERROR,
1018 kEplNmtMnuIntNodeEventTimerIdentReq);
1019 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001020
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001021 else if ((pTimerEventArg->
1022 m_ulArg & EPL_NMTMNU_TIMERARG_STATREQ)
1023 != 0L) {
1024 if ((pNodeInfo->
1025 m_wFlags &
1026 EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ)
1027 != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR)) { // this is an old (already deleted or modified) timer
1028 // but not the current timer
1029 // so discard it
1030 EPL_NMTMNU_DBG_POST_TRACE_VALUE
1031 (kEplNmtMnuIntNodeEventTimerStatReq,
1032 uiNodeId,
1033 ((pNodeInfo->
1034 m_NodeState << 8)
1035 | 0xFF));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001036
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001037 break;
1038 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001039/*
1040 EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerStatReq,
1041 uiNodeId,
1042 ((pNodeInfo->m_NodeState << 8)
1043 | 0x80
1044 | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
1045 | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
1046*/
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001047 Ret =
1048 EplNmtMnuProcessInternalEvent
1049 (uiNodeId,
1050 (tEplNmtState) (bNmtState |
1051 EPL_NMT_TYPE_CS),
1052 EPL_E_NO_ERROR,
1053 kEplNmtMnuIntNodeEventTimerStatReq);
1054 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001055
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001056 else if ((pTimerEventArg->
1057 m_ulArg &
1058 EPL_NMTMNU_TIMERARG_STATE_MON) !=
1059 0L) {
1060 if ((pNodeInfo->
1061 m_wFlags &
1062 EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ)
1063 != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR)) { // this is an old (already deleted or modified) timer
1064 // but not the current timer
1065 // so discard it
1066 EPL_NMTMNU_DBG_POST_TRACE_VALUE
1067 (kEplNmtMnuIntNodeEventTimerStateMon,
1068 uiNodeId,
1069 ((pNodeInfo->
1070 m_NodeState << 8)
1071 | 0xFF));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001072
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001073 break;
1074 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001075/*
1076 EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerStatReq,
1077 uiNodeId,
1078 ((pNodeInfo->m_NodeState << 8)
1079 | 0x80
1080 | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
1081 | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
1082*/
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001083 Ret =
1084 EplNmtMnuProcessInternalEvent
1085 (uiNodeId,
1086 (tEplNmtState) (bNmtState |
1087 EPL_NMT_TYPE_CS),
1088 EPL_E_NO_ERROR,
1089 kEplNmtMnuIntNodeEventTimerStateMon);
1090 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001091
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001092 else if ((pTimerEventArg->
1093 m_ulArg & EPL_NMTMNU_TIMERARG_LONGER)
1094 != 0L) {
1095 if ((pNodeInfo->
1096 m_wFlags &
1097 EPL_NMTMNU_NODE_FLAG_COUNT_LONGER)
1098 != (pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_LO)) { // this is an old (already deleted or modified) timer
1099 // but not the current timer
1100 // so discard it
1101 EPL_NMTMNU_DBG_POST_TRACE_VALUE
1102 (kEplNmtMnuIntNodeEventTimerLonger,
1103 uiNodeId,
1104 ((pNodeInfo->
1105 m_NodeState << 8)
1106 | 0xFF));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001107
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001108 break;
1109 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001110/*
1111 EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventTimerLonger,
1112 uiNodeId,
1113 ((pNodeInfo->m_NodeState << 8)
1114 | 0x80
1115 | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_LONGER) >> 6)
1116 | ((pTimerEventArg->m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_LO) >> 8)));
1117*/
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001118 Ret =
1119 EplNmtMnuProcessInternalEvent
1120 (uiNodeId,
1121 (tEplNmtState) (bNmtState |
1122 EPL_NMT_TYPE_CS),
1123 EPL_E_NO_ERROR,
1124 kEplNmtMnuIntNodeEventTimerLonger);
1125 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001126
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001127 } else { // global timer event
1128 }
1129 break;
1130 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001131
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001132 case kEplEventTypeHeartbeat:
1133 {
1134 tEplHeartbeatEvent *pHeartbeatEvent =
1135 (tEplHeartbeatEvent *) pEvent_p->m_pArg;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001136
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001137 Ret =
1138 EplNmtMnuProcessInternalEvent(pHeartbeatEvent->
1139 m_uiNodeId,
1140 pHeartbeatEvent->
1141 m_NmtState,
1142 pHeartbeatEvent->
1143 m_wErrorCode,
1144 kEplNmtMnuIntNodeEventHeartbeat);
1145 break;
1146 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001147
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001148 case kEplEventTypeNmtMnuNmtCmdSent:
1149 {
1150 tEplFrame *pFrame = (tEplFrame *) pEvent_p->m_pArg;
1151 unsigned int uiNodeId;
1152 tEplNmtCommand NmtCommand;
1153 BYTE bNmtState;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001154
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001155 uiNodeId = AmiGetByteFromLe(&pFrame->m_le_bDstNodeId);
1156 NmtCommand =
1157 (tEplNmtCommand) AmiGetByteFromLe(&pFrame->m_Data.
1158 m_Asnd.m_Payload.
1159 m_NmtCommandService.
1160 m_le_bNmtCommandId);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001161
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001162 switch (NmtCommand) {
1163 case kEplNmtCmdStartNode:
1164 bNmtState =
1165 (BYTE) (kEplNmtCsOperational & 0xFF);
1166 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001167
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001168 case kEplNmtCmdStopNode:
1169 bNmtState = (BYTE) (kEplNmtCsStopped & 0xFF);
1170 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001171
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001172 case kEplNmtCmdEnterPreOperational2:
1173 bNmtState =
1174 (BYTE) (kEplNmtCsPreOperational2 & 0xFF);
1175 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001176
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001177 case kEplNmtCmdEnableReadyToOperate:
1178 // d.k. do not change expected node state, because of DS 1.0.0 7.3.1.2.1 Plain NMT State Command
1179 // and because node may not change NMT state within EPL_C_NMT_STATE_TOLERANCE
1180 bNmtState =
1181 (BYTE) (kEplNmtCsPreOperational2 & 0xFF);
1182 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001183
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001184 case kEplNmtCmdResetNode:
1185 case kEplNmtCmdResetCommunication:
1186 case kEplNmtCmdResetConfiguration:
1187 case kEplNmtCmdSwReset:
1188 bNmtState = (BYTE) (kEplNmtCsNotActive & 0xFF);
1189 // EplNmtMnuProcessInternalEvent() sets internal node state to kEplNmtMnuNodeStateUnknown
1190 // after next unresponded IdentRequest/StatusRequest
1191 break;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001192
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001193 default:
1194 goto Exit;
1195 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001196
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001197 // process as internal event which update expected NMT state in OD
1198 if (uiNodeId != EPL_C_ADR_BROADCAST) {
1199 Ret = EplNmtMnuProcessInternalEvent(uiNodeId,
1200 (tEplNmtState)
1201 (bNmtState |
1202 EPL_NMT_TYPE_CS),
1203 0,
1204 kEplNmtMnuIntNodeEventNmtCmdSent);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001205
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001206 } else { // process internal event for all active nodes (except myself)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001207
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001208 for (uiNodeId = 1;
1209 uiNodeId <=
1210 tabentries(EplNmtMnuInstance_g.
1211 m_aNodeInfo); uiNodeId++) {
1212 if ((EPL_NMTMNU_GET_NODEINFO(uiNodeId)->
1213 m_dwNodeCfg &
1214 (EPL_NODEASSIGN_NODE_IS_CN |
1215 EPL_NODEASSIGN_NODE_EXISTS)) !=
1216 0) {
1217 Ret =
1218 EplNmtMnuProcessInternalEvent
1219 (uiNodeId,
1220 (tEplNmtState) (bNmtState |
1221 EPL_NMT_TYPE_CS),
1222 0,
1223 kEplNmtMnuIntNodeEventNmtCmdSent);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001224
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001225 if (Ret != kEplSuccessful) {
1226 goto Exit;
1227 }
1228 }
1229 }
1230 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001231
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001232 break;
1233 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001234
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001235 default:
1236 {
1237 Ret = kEplNmtInvalidEvent;
1238 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001239
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001240 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001241
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001242 Exit:
1243 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001244}
1245
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001246//---------------------------------------------------------------------------
1247//
1248// Function: EplNmtMnuGetRunningTimerStatReq
1249//
1250// Description: returns a bit field with running StatReq timers
1251// just for debugging purposes
1252//
1253// Parameters: (none)
1254//
1255// Returns: tEplKernel = error code
1256//
1257// State:
1258//
1259//---------------------------------------------------------------------------
1260
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001261tEplKernel PUBLIC EplNmtMnuGetDiagnosticInfo(unsigned int
1262 *puiMandatorySlaveCount_p,
1263 unsigned int
1264 *puiSignalSlaveCount_p,
1265 WORD * pwFlags_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001266{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001267 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001268
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001269 if ((puiMandatorySlaveCount_p == NULL)
1270 || (puiSignalSlaveCount_p == NULL)
1271 || (pwFlags_p == NULL)) {
1272 Ret = kEplNmtInvalidParam;
1273 goto Exit;
1274 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001275
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001276 *puiMandatorySlaveCount_p = EplNmtMnuInstance_g.m_uiMandatorySlaveCount;
1277 *puiSignalSlaveCount_p = EplNmtMnuInstance_g.m_uiSignalSlaveCount;
1278 *pwFlags_p = EplNmtMnuInstance_g.m_wFlags;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001279
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001280 Exit:
1281 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001282}
1283
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001284//---------------------------------------------------------------------------
1285//
1286// Function: EplNmtMnuGetRunningTimerStatReq
1287//
1288// Description: returns a bit field with running StatReq timers
1289// just for debugging purposes
1290//
1291// Parameters: (none)
1292//
1293// Returns: tEplKernel = error code
1294//
1295// State:
1296//
1297//---------------------------------------------------------------------------
1298/*
1299DWORD EplNmtMnuGetRunningTimerStatReq(void)
1300{
1301tEplKernel Ret = kEplSuccessful;
1302unsigned int uiIndex;
1303tEplNmtMnuNodeInfo* pNodeInfo;
1304
1305 pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
1306 for (uiIndex = 1; uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo); uiIndex++, pNodeInfo++)
1307 {
1308 if (pNodeInfo->m_NodeState == kEplNmtMnuNodeStateConfigured)
1309 {
1310 // reset flag "scanned once"
1311 pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_SCANNED;
1312
1313 Ret = EplNmtMnuNodeBootStep2(uiIndex, pNodeInfo);
1314 if (Ret != kEplSuccessful)
1315 {
1316 goto Exit;
1317 }
1318 EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
1319 // signal slave counter shall be decremented if StatusRequest was sent once to a CN
1320 // mandatory slave counter shall be decremented if mandatory CN is ReadyToOp
1321 }
1322 }
1323
1324Exit:
1325 return Ret;
1326}
1327*/
1328
1329//=========================================================================//
1330// //
1331// P R I V A T E F U N C T I O N S //
1332// //
1333//=========================================================================//
1334
1335//---------------------------------------------------------------------------
1336//
1337// Function: EplNmtMnuCbNmtRequest
1338//
1339// Description: callback funktion for NmtRequest
1340//
1341// Parameters: pFrameInfo_p = Frame with the NmtRequest
1342//
1343// Returns: tEplKernel = error code
1344//
1345//
1346// State:
1347//
1348//---------------------------------------------------------------------------
1349
1350static tEplKernel PUBLIC EplNmtMnuCbNmtRequest(tEplFrameInfo * pFrameInfo_p)
1351{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001352 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001353
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001354 // $$$ perform NMTRequest
1355 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001356}
1357
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001358//---------------------------------------------------------------------------
1359//
1360// Function: EplNmtMnuCbIdentResponse
1361//
1362// Description: callback funktion for IdentResponse
1363//
1364// Parameters: uiNodeId_p = node ID for which IdentReponse was received
1365// pIdentResponse_p = pointer to IdentResponse
1366// is NULL if node did not answer
1367//
1368// Returns: tEplKernel = error code
1369//
1370// State:
1371//
1372//---------------------------------------------------------------------------
1373
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001374static tEplKernel PUBLIC EplNmtMnuCbIdentResponse(unsigned int uiNodeId_p,
1375 tEplIdentResponse *
1376 pIdentResponse_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001377{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001378 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001379
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001380 if (pIdentResponse_p == NULL) { // node did not answer
1381 Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p, kEplNmtCsNotActive, EPL_E_NMT_NO_IDENT_RES, // was EPL_E_NO_ERROR
1382 kEplNmtMnuIntNodeEventNoIdentResponse);
1383 } else { // node answered IdentRequest
1384 tEplObdSize ObdSize;
1385 DWORD dwDevType;
1386 WORD wErrorCode = EPL_E_NO_ERROR;
1387 tEplNmtState NmtState =
1388 (tEplNmtState) (AmiGetByteFromLe
1389 (&pIdentResponse_p->
1390 m_le_bNmtStatus) | EPL_NMT_TYPE_CS);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001391
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001392 // check IdentResponse $$$ move to ProcessIntern, because this function may be called also if CN
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001393
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001394 // check DeviceType (0x1F84)
1395 ObdSize = 4;
1396 Ret =
1397 EplObduReadEntry(0x1F84, uiNodeId_p, &dwDevType, &ObdSize);
1398 if (Ret != kEplSuccessful) {
1399 goto Exit;
1400 }
1401 if (dwDevType != 0L) { // actually compare it with DeviceType from IdentResponse
1402 if (AmiGetDwordFromLe(&pIdentResponse_p->m_le_dwDeviceType) != dwDevType) { // wrong DeviceType
1403 NmtState = kEplNmtCsNotActive;
1404 wErrorCode = EPL_E_NMT_BPO1_DEVICE_TYPE;
1405 }
1406 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001407
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001408 Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
1409 NmtState,
1410 wErrorCode,
1411 kEplNmtMnuIntNodeEventIdentResponse);
1412 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001413
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001414 Exit:
1415 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001416}
1417
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001418//---------------------------------------------------------------------------
1419//
1420// Function: EplNmtMnuCbStatusResponse
1421//
1422// Description: callback funktion for StatusResponse
1423//
1424// Parameters: uiNodeId_p = node ID for which IdentReponse was received
1425// pIdentResponse_p = pointer to IdentResponse
1426// is NULL if node did not answer
1427//
1428// Returns: tEplKernel = error code
1429//
1430// State:
1431//
1432//---------------------------------------------------------------------------
1433
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001434static tEplKernel PUBLIC EplNmtMnuCbStatusResponse(unsigned int uiNodeId_p,
1435 tEplStatusResponse *
1436 pStatusResponse_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001437{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001438 tEplKernel Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001439
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001440 if (pStatusResponse_p == NULL) { // node did not answer
1441 Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p, kEplNmtCsNotActive, EPL_E_NMT_NO_STATUS_RES, // was EPL_E_NO_ERROR
1442 kEplNmtMnuIntNodeEventNoStatusResponse);
1443 } else { // node answered StatusRequest
1444 Ret = EplNmtMnuProcessInternalEvent(uiNodeId_p,
1445 (tEplNmtState)
1446 (AmiGetByteFromLe
1447 (&pStatusResponse_p->
1448 m_le_bNmtStatus) |
1449 EPL_NMT_TYPE_CS),
1450 EPL_E_NO_ERROR,
1451 kEplNmtMnuIntNodeEventStatusResponse);
1452 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001453
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001454 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001455}
1456
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001457//---------------------------------------------------------------------------
1458//
1459// Function: EplNmtMnuStartBootStep1
1460//
1461// Description: starts BootStep1
1462//
1463// Parameters: (none)
1464//
1465// Returns: tEplKernel = error code
1466//
1467// State:
1468//
1469//---------------------------------------------------------------------------
1470
1471static tEplKernel EplNmtMnuStartBootStep1(void)
1472{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001473 tEplKernel Ret = kEplSuccessful;
1474 unsigned int uiSubIndex;
1475 unsigned int uiLocalNodeId;
1476 DWORD dwNodeCfg;
1477 tEplObdSize ObdSize;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001478
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001479 // $$$ d.k.: save current time for 0x1F89/2 MNTimeoutPreOp1_U32
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001480
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001481 // start network scan
1482 EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
1483 EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
1484 // check 0x1F81
1485 uiLocalNodeId = EplObduGetNodeId();
1486 for (uiSubIndex = 1; uiSubIndex <= 254; uiSubIndex++) {
1487 ObdSize = 4;
1488 Ret =
1489 EplObduReadEntry(0x1F81, uiSubIndex, &dwNodeCfg, &ObdSize);
1490 if (Ret != kEplSuccessful) {
1491 goto Exit;
1492 }
1493 if (uiSubIndex != uiLocalNodeId) {
1494 // reset flags "not scanned" and "isochronous"
1495 EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_wFlags &=
1496 ~(EPL_NMTMNU_NODE_FLAG_ISOCHRON |
1497 EPL_NMTMNU_NODE_FLAG_NOT_SCANNED);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001498
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001499 if (uiSubIndex == EPL_C_ADR_DIAG_DEF_NODE_ID) { // diagnostic node must be scanned by MN in any case
1500 dwNodeCfg |=
1501 (EPL_NODEASSIGN_NODE_IS_CN |
1502 EPL_NODEASSIGN_NODE_EXISTS);
1503 // and it must be isochronously accessed
1504 dwNodeCfg &= ~EPL_NODEASSIGN_ASYNCONLY_NODE;
1505 }
1506 // save node config in local node info structure
1507 EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_dwNodeCfg =
1508 dwNodeCfg;
1509 EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_NodeState =
1510 kEplNmtMnuNodeStateUnknown;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001511
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001512 if ((dwNodeCfg & (EPL_NODEASSIGN_NODE_IS_CN | EPL_NODEASSIGN_NODE_EXISTS)) != 0) { // node is configured as CN
1513 // identify the node
1514 Ret =
1515 EplIdentuRequestIdentResponse(uiSubIndex,
1516 EplNmtMnuCbIdentResponse);
1517 if (Ret != kEplSuccessful) {
1518 goto Exit;
1519 }
1520 // set flag "not scanned"
1521 EPL_NMTMNU_GET_NODEINFO(uiSubIndex)->m_wFlags |=
1522 EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
1523 EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
1524 // signal slave counter shall be decremented if IdentRequest was sent once to a CN
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001525
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001526 if ((dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // node is a mandatory CN
1527 EplNmtMnuInstance_g.
1528 m_uiMandatorySlaveCount++;
1529 // mandatory slave counter shall be decremented if mandatory CN was configured successfully
1530 }
1531 }
1532 } else { // subindex of MN
1533 if ((dwNodeCfg & (EPL_NODEASSIGN_MN_PRES | EPL_NODEASSIGN_NODE_EXISTS)) != 0) { // MN shall send PRes
1534 tEplDllNodeInfo DllNodeInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001535
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001536 EPL_MEMSET(&DllNodeInfo, 0,
1537 sizeof(DllNodeInfo));
1538 DllNodeInfo.m_uiNodeId = uiLocalNodeId;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001539
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001540 Ret = EplDlluCalAddNode(&DllNodeInfo);
1541 }
1542 }
1543 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001544
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001545 Exit:
1546 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001547}
1548
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001549//---------------------------------------------------------------------------
1550//
1551// Function: EplNmtMnuStartBootStep2
1552//
1553// Description: starts BootStep2.
1554// That means add nodes to isochronous phase and send
1555// NMT EnableReadyToOp.
1556//
1557// Parameters: (none)
1558//
1559// Returns: tEplKernel = error code
1560//
1561// State:
1562//
1563//---------------------------------------------------------------------------
1564
1565static tEplKernel EplNmtMnuStartBootStep2(void)
1566{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001567 tEplKernel Ret = kEplSuccessful;
1568 unsigned int uiIndex;
1569 tEplNmtMnuNodeInfo *pNodeInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001570
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001571 if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0) { // boot process is not halted
1572 // add nodes to isochronous phase and send NMT EnableReadyToOp
1573 EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
1574 EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
1575 // reset flag that application was informed about possible state change
1576 EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001577
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001578 pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
1579 for (uiIndex = 1;
1580 uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
1581 uiIndex++, pNodeInfo++) {
1582 if (pNodeInfo->m_NodeState ==
1583 kEplNmtMnuNodeStateConfigured) {
1584 Ret =
1585 EplNmtMnuNodeBootStep2(uiIndex, pNodeInfo);
1586 if (Ret != kEplSuccessful) {
1587 goto Exit;
1588 }
1589 // set flag "not scanned"
1590 pNodeInfo->m_wFlags |=
1591 EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001592
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001593 EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
1594 // signal slave counter shall be decremented if StatusRequest was sent once to a CN
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001595
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001596 if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // node is a mandatory CN
1597 EplNmtMnuInstance_g.
1598 m_uiMandatorySlaveCount++;
1599 }
1600 // mandatory slave counter shall be decremented if mandatory CN is ReadyToOp
1601 }
1602 }
1603 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001604
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001605 Exit:
1606 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001607}
1608
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001609//---------------------------------------------------------------------------
1610//
1611// Function: EplNmtMnuNodeBootStep2
1612//
1613// Description: starts BootStep2 for the specified node.
1614// This means the CN is added to isochronous phase if not
1615// async-only and it gets the NMT command EnableReadyToOp.
1616// The CN must be in node state Configured, when it enters
1617// BootStep2. When BootStep2 finishes, the CN is in node state
1618// ReadyToOp.
1619// If TimeoutReadyToOp in object 0x1F89/5 is configured,
1620// TimerHdlLonger will be started with this timeout.
1621//
1622// Parameters: uiNodeId_p = node ID
1623// pNodeInfo_p = pointer to internal node info structure
1624//
1625// Returns: tEplKernel = error code
1626//
1627// State:
1628//
1629//---------------------------------------------------------------------------
1630
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001631static tEplKernel EplNmtMnuNodeBootStep2(unsigned int uiNodeId_p,
1632 tEplNmtMnuNodeInfo * pNodeInfo_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001633{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001634 tEplKernel Ret = kEplSuccessful;
1635 tEplDllNodeInfo DllNodeInfo;
1636 DWORD dwNodeCfg;
1637 tEplObdSize ObdSize;
1638 tEplTimerArg TimerArg;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001639
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001640 dwNodeCfg = pNodeInfo_p->m_dwNodeCfg;
1641 if ((dwNodeCfg & EPL_NODEASSIGN_ASYNCONLY_NODE) == 0) { // add node to isochronous phase
1642 DllNodeInfo.m_uiNodeId = uiNodeId_p;
1643 ObdSize = 4;
1644 Ret =
1645 EplObduReadEntry(0x1F92, uiNodeId_p,
1646 &DllNodeInfo.m_dwPresTimeout, &ObdSize);
1647 if (Ret != kEplSuccessful) {
1648 goto Exit;
1649 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001650
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001651 ObdSize = 2;
1652 Ret =
1653 EplObduReadEntry(0x1F8B, uiNodeId_p,
1654 &DllNodeInfo.m_wPreqPayloadLimit,
1655 &ObdSize);
1656 if (Ret != kEplSuccessful) {
1657 goto Exit;
1658 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001659
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001660 ObdSize = 2;
1661 Ret =
1662 EplObduReadEntry(0x1F8D, uiNodeId_p,
1663 &DllNodeInfo.m_wPresPayloadLimit,
1664 &ObdSize);
1665 if (Ret != kEplSuccessful) {
1666 goto Exit;
1667 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001668
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001669 pNodeInfo_p->m_wFlags |= EPL_NMTMNU_NODE_FLAG_ISOCHRON;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001670
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001671 Ret = EplDlluCalAddNode(&DllNodeInfo);
1672 if (Ret != kEplSuccessful) {
1673 goto Exit;
1674 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001675
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001676 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001677
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001678 EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
1679 uiNodeId_p,
1680 kEplNmtCmdEnableReadyToOperate);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001681
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001682 Ret =
1683 EplNmtMnuSendNmtCommand(uiNodeId_p, kEplNmtCmdEnableReadyToOperate);
1684 if (Ret != kEplSuccessful) {
1685 goto Exit;
1686 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001687
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001688 if (EplNmtMnuInstance_g.m_ulTimeoutReadyToOp != 0L) { // start timer
1689 // when the timer expires the CN must be ReadyToOp
1690 EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(pNodeInfo_p, uiNodeId_p,
1691 TimerArg);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001692// TimerArg.m_EventSink = kEplEventSinkNmtMnu;
1693// TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p;
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001694 Ret =
1695 EplTimeruModifyTimerMs(&pNodeInfo_p->m_TimerHdlLonger,
1696 EplNmtMnuInstance_g.
1697 m_ulTimeoutReadyToOp, TimerArg);
1698 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001699
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001700 Exit:
1701 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001702}
1703
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001704//---------------------------------------------------------------------------
1705//
1706// Function: EplNmtMnuStartCheckCom
1707//
1708// Description: starts CheckCommunication
1709//
1710// Parameters: (none)
1711//
1712// Returns: tEplKernel = error code
1713//
1714// State:
1715//
1716//---------------------------------------------------------------------------
1717
1718static tEplKernel EplNmtMnuStartCheckCom(void)
1719{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001720 tEplKernel Ret = kEplSuccessful;
1721 unsigned int uiIndex;
1722 tEplNmtMnuNodeInfo *pNodeInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001723
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001724 if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0) { // boot process is not halted
1725 // wait some time and check that no communication error occurs
1726 EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
1727 EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
1728 // reset flag that application was informed about possible state change
1729 EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001730
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001731 pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
1732 for (uiIndex = 1;
1733 uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
1734 uiIndex++, pNodeInfo++) {
1735 if (pNodeInfo->m_NodeState ==
1736 kEplNmtMnuNodeStateReadyToOp) {
1737 Ret = EplNmtMnuNodeCheckCom(uiIndex, pNodeInfo);
1738 if (Ret == kEplReject) { // timer was started
1739 // wait until it expires
1740 if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // node is a mandatory CN
1741 EplNmtMnuInstance_g.
1742 m_uiMandatorySlaveCount++;
1743 }
1744 } else if (Ret != kEplSuccessful) {
1745 goto Exit;
1746 }
1747 // set flag "not scanned"
1748 pNodeInfo->m_wFlags |=
1749 EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001750
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001751 EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
1752 // signal slave counter shall be decremented if timeout elapsed and regardless of an error
1753 // mandatory slave counter shall be decremented if timeout elapsed and no error occured
1754 }
1755 }
1756 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001757
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001758 Ret = kEplSuccessful;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001759
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001760 Exit:
1761 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001762}
1763
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001764//---------------------------------------------------------------------------
1765//
1766// Function: EplNmtMnuNodeCheckCom
1767//
1768// Description: checks communication of the specified node.
1769// That means wait some time and if no error occured everything
1770// is OK.
1771//
1772// Parameters: uiNodeId_p = node ID
1773// pNodeInfo_p = pointer to internal node info structure
1774//
1775// Returns: tEplKernel = error code
1776//
1777// State:
1778//
1779//---------------------------------------------------------------------------
1780
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001781static tEplKernel EplNmtMnuNodeCheckCom(unsigned int uiNodeId_p,
1782 tEplNmtMnuNodeInfo * pNodeInfo_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001783{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001784 tEplKernel Ret = kEplSuccessful;
1785 DWORD dwNodeCfg;
1786 tEplTimerArg TimerArg;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001787
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001788 dwNodeCfg = pNodeInfo_p->m_dwNodeCfg;
1789 if (((dwNodeCfg & EPL_NODEASSIGN_ASYNCONLY_NODE) == 0)
1790 && (EplNmtMnuInstance_g.m_ulTimeoutCheckCom != 0L)) { // CN is not async-only and timeout for CheckCom was set
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001791
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001792 // check communication,
1793 // that means wait some time and if no error occured everything is OK;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001794
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001795 // start timer (when the timer expires the CN must be still ReadyToOp)
1796 EPL_NMTMNU_SET_FLAGS_TIMERARG_LONGER(pNodeInfo_p, uiNodeId_p,
1797 TimerArg);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001798// TimerArg.m_EventSink = kEplEventSinkNmtMnu;
1799// TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_LONGER | uiNodeId_p;
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001800 Ret =
1801 EplTimeruModifyTimerMs(&pNodeInfo_p->m_TimerHdlLonger,
1802 EplNmtMnuInstance_g.
1803 m_ulTimeoutCheckCom, TimerArg);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001804
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001805 // update mandatory slave counter, because timer was started
1806 if (Ret == kEplSuccessful) {
1807 Ret = kEplReject;
1808 }
1809 } else { // timer was not started
1810 // assume everything is OK
1811 pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateComChecked;
1812 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001813
1814//Exit:
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001815 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001816}
1817
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001818//---------------------------------------------------------------------------
1819//
1820// Function: EplNmtMnuStartNodes
1821//
1822// Description: really starts all nodes which are ReadyToOp and CheckCom did not fail
1823//
1824// Parameters: (none)
1825//
1826// Returns: tEplKernel = error code
1827//
1828// State:
1829//
1830//---------------------------------------------------------------------------
1831
1832static tEplKernel EplNmtMnuStartNodes(void)
1833{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001834 tEplKernel Ret = kEplSuccessful;
1835 unsigned int uiIndex;
1836 tEplNmtMnuNodeInfo *pNodeInfo;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001837
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001838 if ((EplNmtMnuInstance_g.m_wFlags & EPL_NMTMNU_FLAG_HALTED) == 0) { // boot process is not halted
1839 // send NMT command Start Node
1840 EplNmtMnuInstance_g.m_uiMandatorySlaveCount = 0;
1841 EplNmtMnuInstance_g.m_uiSignalSlaveCount = 0;
1842 // reset flag that application was informed about possible state change
1843 EplNmtMnuInstance_g.m_wFlags &= ~EPL_NMTMNU_FLAG_APP_INFORMED;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001844
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001845 pNodeInfo = EplNmtMnuInstance_g.m_aNodeInfo;
1846 for (uiIndex = 1;
1847 uiIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
1848 uiIndex++, pNodeInfo++) {
1849 if (pNodeInfo->m_NodeState ==
1850 kEplNmtMnuNodeStateComChecked) {
1851 if ((EplNmtMnuInstance_g.
1852 m_dwNmtStartup & EPL_NMTST_STARTALLNODES)
1853 == 0) {
1854 EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
1855 uiIndex,
1856 kEplNmtCmdStartNode);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001857
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001858 Ret =
1859 EplNmtMnuSendNmtCommand(uiIndex,
1860 kEplNmtCmdStartNode);
1861 if (Ret != kEplSuccessful) {
1862 goto Exit;
1863 }
1864 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001865
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001866 if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // node is a mandatory CN
1867 EplNmtMnuInstance_g.
1868 m_uiMandatorySlaveCount++;
1869 }
1870 // set flag "not scanned"
1871 pNodeInfo->m_wFlags |=
1872 EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001873
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001874 EplNmtMnuInstance_g.m_uiSignalSlaveCount++;
1875 // signal slave counter shall be decremented if StatusRequest was sent once to a CN
1876 // mandatory slave counter shall be decremented if mandatory CN is OPERATIONAL
1877 }
1878 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001879
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001880 // $$$ inform application if EPL_NMTST_NO_STARTNODE is set
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001881
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001882 if ((EplNmtMnuInstance_g.
1883 m_dwNmtStartup & EPL_NMTST_STARTALLNODES) != 0) {
1884 EPL_NMTMNU_DBG_POST_TRACE_VALUE(0, EPL_C_ADR_BROADCAST,
1885 kEplNmtCmdStartNode);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001886
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001887 Ret =
1888 EplNmtMnuSendNmtCommand(EPL_C_ADR_BROADCAST,
1889 kEplNmtCmdStartNode);
1890 if (Ret != kEplSuccessful) {
1891 goto Exit;
1892 }
1893 }
1894 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001895
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001896 Exit:
1897 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001898}
1899
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001900//---------------------------------------------------------------------------
1901//
1902// Function: EplNmtMnuProcessInternalEvent
1903//
1904// Description: processes internal node events
1905//
1906// Parameters: uiNodeId_p = node ID
1907// NodeNmtState_p = NMT state of CN
1908// NodeEvent_p = occured events
1909//
1910// Returns: tEplKernel = error code
1911//
1912//
1913// State:
1914//
1915//---------------------------------------------------------------------------
1916
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001917static tEplKernel EplNmtMnuProcessInternalEvent(unsigned int uiNodeId_p,
1918 tEplNmtState NodeNmtState_p,
1919 WORD wErrorCode_p,
1920 tEplNmtMnuIntNodeEvent
1921 NodeEvent_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001922{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001923 tEplKernel Ret = kEplSuccessful;
1924 tEplNmtState NmtState;
1925 tEplNmtMnuNodeInfo *pNodeInfo;
1926 tEplTimerArg TimerArg;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001927
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001928 pNodeInfo = EPL_NMTMNU_GET_NODEINFO(uiNodeId_p);
1929 NmtState = EplNmtuGetNmtState();
1930 if (NmtState <= kEplNmtMsNotActive) { // MN is not active
1931 goto Exit;
1932 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001933
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001934 switch (NodeEvent_p) {
1935 case kEplNmtMnuIntNodeEventIdentResponse:
1936 {
1937 BYTE bNmtState;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001938
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001939 EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
1940 uiNodeId_p,
1941 pNodeInfo->m_NodeState);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001942
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001943 if (pNodeInfo->m_NodeState !=
1944 kEplNmtMnuNodeStateResetConf) {
1945 pNodeInfo->m_NodeState =
1946 kEplNmtMnuNodeStateIdentified;
1947 }
1948 // reset flags ISOCHRON and NMT_CMD_ISSUED
1949 pNodeInfo->m_wFlags &= ~(EPL_NMTMNU_NODE_FLAG_ISOCHRON
1950 |
1951 EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001952
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001953 if ((NmtState == kEplNmtMsPreOperational1)
1954 &&
1955 ((pNodeInfo->
1956 m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) !=
1957 0)) {
1958 // decrement only signal slave count
1959 EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
1960 pNodeInfo->m_wFlags &=
1961 ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
1962 }
1963 // update object 0x1F8F NMT_MNNodeExpState_AU8 to PreOp1 (even if local state >= PreOp2)
1964 bNmtState = (BYTE) (kEplNmtCsPreOperational1 & 0xFF);
1965 Ret =
1966 EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState,
1967 1);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001968
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001969 // check NMT state of CN
1970 Ret =
1971 EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
1972 NodeNmtState_p, wErrorCode_p,
1973 NmtState);
1974 if (Ret != kEplSuccessful) {
1975 if (Ret == kEplReject) {
1976 Ret = kEplSuccessful;
1977 }
1978 break;
1979 }
1980 // request StatusResponse immediately,
1981 // because we want a fast boot-up of CNs
1982 Ret =
1983 EplStatusuRequestStatusResponse(uiNodeId_p,
1984 EplNmtMnuCbStatusResponse);
1985 if (Ret != kEplSuccessful) {
1986 EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
1987 uiNodeId_p,
1988 Ret);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001989
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08001990 if (Ret == kEplInvalidOperation) { // the only situation when this should happen is, when
1991 // StatusResponse was already requested from within
1992 // the StatReq timer event.
1993 // so ignore this error.
1994 Ret = kEplSuccessful;
1995 } else {
1996 break;
1997 }
1998 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08001999
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002000 if (pNodeInfo->m_NodeState !=
2001 kEplNmtMnuNodeStateResetConf) {
2002 // inform application
2003 Ret =
2004 EplNmtMnuInstance_g.
2005 m_pfnCbNodeEvent(uiNodeId_p,
2006 kEplNmtNodeEventFound,
2007 NodeNmtState_p,
2008 EPL_E_NO_ERROR,
2009 (pNodeInfo->
2010 m_dwNodeCfg &
2011 EPL_NODEASSIGN_MANDATORY_CN)
2012 != 0);
2013 if (Ret == kEplReject) { // interrupt boot process on user request
2014 EPL_NMTMNU_DBG_POST_TRACE_VALUE
2015 (NodeEvent_p, uiNodeId_p,
2016 ((pNodeInfo->m_NodeState << 8)
2017 | Ret));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002018
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002019 Ret = kEplSuccessful;
2020 break;
2021 } else if (Ret != kEplSuccessful) {
2022 EPL_NMTMNU_DBG_POST_TRACE_VALUE
2023 (NodeEvent_p, uiNodeId_p,
2024 ((pNodeInfo->m_NodeState << 8)
2025 | Ret));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002026
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002027 break;
2028 }
2029 }
2030 // continue BootStep1
2031 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002032
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002033 case kEplNmtMnuIntNodeEventBoot:
2034 {
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002035
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002036 // $$$ check identification (vendor ID, product code, revision no, serial no)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002037
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002038 if (pNodeInfo->m_NodeState ==
2039 kEplNmtMnuNodeStateIdentified) {
2040 // $$$ check software
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002041
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002042 // check/start configuration
2043 // inform application
2044 Ret =
2045 EplNmtMnuInstance_g.
2046 m_pfnCbNodeEvent(uiNodeId_p,
2047 kEplNmtNodeEventCheckConf,
2048 NodeNmtState_p,
2049 EPL_E_NO_ERROR,
2050 (pNodeInfo->
2051 m_dwNodeCfg &
2052 EPL_NODEASSIGN_MANDATORY_CN)
2053 != 0);
2054 if (Ret == kEplReject) { // interrupt boot process on user request
2055 EPL_NMTMNU_DBG_POST_TRACE_VALUE
2056 (kEplNmtMnuIntNodeEventBoot,
2057 uiNodeId_p,
2058 ((pNodeInfo->m_NodeState << 8)
2059 | Ret));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002060
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002061 Ret = kEplSuccessful;
2062 break;
2063 } else if (Ret != kEplSuccessful) {
2064 EPL_NMTMNU_DBG_POST_TRACE_VALUE
2065 (kEplNmtMnuIntNodeEventBoot,
2066 uiNodeId_p,
2067 ((pNodeInfo->m_NodeState << 8)
2068 | Ret));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002069
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002070 break;
2071 }
2072 } else if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateResetConf) { // wrong CN state
2073 // ignore event
2074 break;
2075 }
2076 // $$$ d.k.: currently we assume configuration is OK
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002077
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002078 // continue BootStep1
2079 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002080
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002081 case kEplNmtMnuIntNodeEventConfigured:
2082 {
2083 if ((pNodeInfo->m_NodeState !=
2084 kEplNmtMnuNodeStateIdentified)
2085 && (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateResetConf)) { // wrong CN state
2086 // ignore event
2087 break;
2088 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002089
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002090 pNodeInfo->m_NodeState = kEplNmtMnuNodeStateConfigured;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002091
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002092 if (NmtState == kEplNmtMsPreOperational1) {
2093 if ((pNodeInfo->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // decrement mandatory CN counter
2094 EplNmtMnuInstance_g.
2095 m_uiMandatorySlaveCount--;
2096 }
2097 } else {
2098 // put optional node to next step (BootStep2)
2099 Ret =
2100 EplNmtMnuNodeBootStep2(uiNodeId_p,
2101 pNodeInfo);
2102 }
2103 break;
2104 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002105
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002106 case kEplNmtMnuIntNodeEventNoIdentResponse:
2107 {
2108 if ((NmtState == kEplNmtMsPreOperational1)
2109 &&
2110 ((pNodeInfo->
2111 m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) !=
2112 0)) {
2113 // decrement only signal slave count
2114 EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
2115 pNodeInfo->m_wFlags &=
2116 ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
2117 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002118
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002119 if (pNodeInfo->m_NodeState !=
2120 kEplNmtMnuNodeStateResetConf) {
2121 pNodeInfo->m_NodeState =
2122 kEplNmtMnuNodeStateUnknown;
2123 }
2124 // $$$ d.k. check start time for 0x1F89/2 MNTimeoutPreOp1_U32
2125 // $$$ d.k. check individual timeout 0x1F89/6 MNIdentificationTimeout_U32
2126 // if mandatory node and timeout elapsed -> halt boot procedure
2127 // trigger IdentRequest again (if >= PreOp2, after delay)
2128 if (NmtState >= kEplNmtMsPreOperational2) { // start timer
2129 EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ
2130 (pNodeInfo, uiNodeId_p, TimerArg);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002131// TimerArg.m_EventSink = kEplEventSinkNmtMnu;
2132// TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_IDENTREQ | uiNodeId_p;
2133/*
2134 EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventNoIdentResponse,
2135 uiNodeId_p,
2136 ((pNodeInfo->m_NodeState << 8)
2137 | 0x80
2138 | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
2139 | ((TimerArg.m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
2140*/
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002141 Ret =
2142 EplTimeruModifyTimerMs(&pNodeInfo->
2143 m_TimerHdlStatReq,
2144 EplNmtMnuInstance_g.
2145 m_ulStatusRequestDelay,
2146 TimerArg);
2147 } else { // trigger IdentRequest immediately
2148 Ret =
2149 EplIdentuRequestIdentResponse(uiNodeId_p,
2150 EplNmtMnuCbIdentResponse);
2151 }
2152 break;
2153 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002154
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002155 case kEplNmtMnuIntNodeEventStatusResponse:
2156 {
2157 if ((NmtState >= kEplNmtMsPreOperational2)
2158 &&
2159 ((pNodeInfo->
2160 m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) !=
2161 0)) {
2162 // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
2163 EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
2164 pNodeInfo->m_wFlags &=
2165 ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
2166 }
2167 // check NMT state of CN
2168 Ret =
2169 EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
2170 NodeNmtState_p, wErrorCode_p,
2171 NmtState);
2172 if (Ret != kEplSuccessful) {
2173 if (Ret == kEplReject) {
2174 Ret = kEplSuccessful;
2175 }
2176 break;
2177 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002178
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002179 if (NmtState == kEplNmtMsPreOperational1) {
2180 // request next StatusResponse immediately
2181 Ret =
2182 EplStatusuRequestStatusResponse(uiNodeId_p,
2183 EplNmtMnuCbStatusResponse);
2184 if (Ret != kEplSuccessful) {
2185 EPL_NMTMNU_DBG_POST_TRACE_VALUE
2186 (NodeEvent_p, uiNodeId_p, Ret);
2187 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002188
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002189 } else if ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_ISOCHRON) == 0) { // start timer
2190 // not isochronously accessed CN (e.g. async-only or stopped CN)
2191 EPL_NMTMNU_SET_FLAGS_TIMERARG_STATREQ(pNodeInfo,
2192 uiNodeId_p,
2193 TimerArg);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002194// TimerArg.m_EventSink = kEplEventSinkNmtMnu;
2195// TimerArg.m_ulArg = EPL_NMTMNU_TIMERARG_STATREQ | uiNodeId_p;
2196/*
2197 EPL_NMTMNU_DBG_POST_TRACE_VALUE(kEplNmtMnuIntNodeEventStatusResponse,
2198 uiNodeId_p,
2199 ((pNodeInfo->m_NodeState << 8)
2200 | 0x80
2201 | ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_COUNT_STATREQ) >> 6)
2202 | ((TimerArg.m_ulArg & EPL_NMTMNU_TIMERARG_COUNT_SR) >> 8)));
2203*/
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002204 Ret =
2205 EplTimeruModifyTimerMs(&pNodeInfo->
2206 m_TimerHdlStatReq,
2207 EplNmtMnuInstance_g.
2208 m_ulStatusRequestDelay,
2209 TimerArg);
2210 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002211
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002212 break;
2213 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002214
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002215 case kEplNmtMnuIntNodeEventNoStatusResponse:
2216 {
2217 // function CheckNmtState sets node state to unknown if necessary
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002218/*
2219 if ((NmtState >= kEplNmtMsPreOperational2)
2220 && ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0))
2221 {
2222 // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
2223 EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
2224 pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
2225 }
2226*/
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002227 // check NMT state of CN
2228 Ret =
2229 EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
2230 NodeNmtState_p, wErrorCode_p,
2231 NmtState);
2232 if (Ret != kEplSuccessful) {
2233 if (Ret == kEplReject) {
2234 Ret = kEplSuccessful;
2235 }
2236 break;
2237 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002238
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002239 break;
2240 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002241
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002242 case kEplNmtMnuIntNodeEventError:
2243 { // currently only issued on kEplNmtNodeCommandConfErr
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002244
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002245 if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateIdentified) { // wrong CN state
2246 // ignore event
2247 break;
2248 }
2249 // check NMT state of CN
2250 Ret =
2251 EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
2252 kEplNmtCsNotActive,
2253 wErrorCode_p, NmtState);
2254 if (Ret != kEplSuccessful) {
2255 if (Ret == kEplReject) {
2256 Ret = kEplSuccessful;
2257 }
2258 break;
2259 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002260
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002261 break;
2262 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002263
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002264 case kEplNmtMnuIntNodeEventExecReset:
2265 {
2266 if (pNodeInfo->m_NodeState != kEplNmtMnuNodeStateIdentified) { // wrong CN state
2267 // ignore event
2268 break;
2269 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002270
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002271 pNodeInfo->m_NodeState = kEplNmtMnuNodeStateResetConf;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002272
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002273 EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
2274 uiNodeId_p,
2275 (((NodeNmtState_p &
2276 0xFF) << 8)
2277 |
2278 kEplNmtCmdResetConfiguration));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002279
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002280 // send NMT reset configuration to CN for activation of configuration
2281 Ret =
2282 EplNmtMnuSendNmtCommand(uiNodeId_p,
2283 kEplNmtCmdResetConfiguration);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002284
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002285 break;
2286 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002287
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002288 case kEplNmtMnuIntNodeEventHeartbeat:
2289 {
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002290/*
2291 if ((NmtState >= kEplNmtMsPreOperational2)
2292 && ((pNodeInfo->m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0))
2293 {
2294 // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
2295 EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
2296 pNodeInfo->m_wFlags &= ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
2297 }
2298*/
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002299 // check NMT state of CN
2300 Ret =
2301 EplNmtMnuCheckNmtState(uiNodeId_p, pNodeInfo,
2302 NodeNmtState_p, wErrorCode_p,
2303 NmtState);
2304 if (Ret != kEplSuccessful) {
2305 if (Ret == kEplReject) {
2306 Ret = kEplSuccessful;
2307 }
2308 break;
2309 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002310
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002311 break;
2312 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002313
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002314 case kEplNmtMnuIntNodeEventTimerIdentReq:
2315 {
2316 EPL_DBGLVL_NMTMN_TRACE1
2317 ("TimerStatReq->IdentReq(%02X)\n", uiNodeId_p);
2318 // trigger IdentRequest again
2319 Ret =
2320 EplIdentuRequestIdentResponse(uiNodeId_p,
2321 EplNmtMnuCbIdentResponse);
2322 if (Ret != kEplSuccessful) {
2323 EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
2324 uiNodeId_p,
2325 (((NodeNmtState_p & 0xFF) << 8)
2326 | Ret));
2327 if (Ret == kEplInvalidOperation) { // this can happen because of a bug in EplTimeruLinuxKernel.c
2328 // so ignore this error.
2329 Ret = kEplSuccessful;
2330 }
2331 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002332
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002333 break;
2334 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002335
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002336 case kEplNmtMnuIntNodeEventTimerStateMon:
2337 {
2338 // reset NMT state change flag
2339 // because from now on the CN must have the correct NMT state
2340 pNodeInfo->m_wFlags &=
2341 ~EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002342
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002343 // continue with normal StatReq processing
2344 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002345
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002346 case kEplNmtMnuIntNodeEventTimerStatReq:
2347 {
2348 EPL_DBGLVL_NMTMN_TRACE1("TimerStatReq->StatReq(%02X)\n",
2349 uiNodeId_p);
2350 // request next StatusResponse
2351 Ret =
2352 EplStatusuRequestStatusResponse(uiNodeId_p,
2353 EplNmtMnuCbStatusResponse);
2354 if (Ret != kEplSuccessful) {
2355 EPL_NMTMNU_DBG_POST_TRACE_VALUE(NodeEvent_p,
2356 uiNodeId_p,
2357 (((NodeNmtState_p & 0xFF) << 8)
2358 | Ret));
2359 if (Ret == kEplInvalidOperation) { // the only situation when this should happen is, when
2360 // StatusResponse was already requested while processing
2361 // event IdentResponse.
2362 // so ignore this error.
2363 Ret = kEplSuccessful;
2364 }
2365 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002366
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002367 break;
2368 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002369
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002370 case kEplNmtMnuIntNodeEventTimerLonger:
2371 {
2372 switch (pNodeInfo->m_NodeState) {
2373 case kEplNmtMnuNodeStateConfigured:
2374 { // node should be ReadyToOp but it is not
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002375
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002376 // check NMT state which shall be intentionally wrong, so that ERROR_TREATMENT will be started
2377 Ret =
2378 EplNmtMnuCheckNmtState(uiNodeId_p,
2379 pNodeInfo,
2380 kEplNmtCsNotActive,
2381 EPL_E_NMT_BPO2,
2382 NmtState);
2383 if (Ret != kEplSuccessful) {
2384 if (Ret == kEplReject) {
2385 Ret = kEplSuccessful;
2386 }
2387 break;
2388 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002389
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002390 break;
2391 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002392
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002393 case kEplNmtMnuNodeStateReadyToOp:
2394 { // CheckCom finished successfully
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002395
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002396 pNodeInfo->m_NodeState =
2397 kEplNmtMnuNodeStateComChecked;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002398
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002399 if ((pNodeInfo->
2400 m_wFlags &
2401 EPL_NMTMNU_NODE_FLAG_NOT_SCANNED)
2402 != 0) {
2403 // decrement only signal slave count if checked once for ReadyToOp, CheckCom, Operational
2404 EplNmtMnuInstance_g.
2405 m_uiSignalSlaveCount--;
2406 pNodeInfo->m_wFlags &=
2407 ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
2408 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002409
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002410 if ((pNodeInfo->
2411 m_dwNodeCfg &
2412 EPL_NODEASSIGN_MANDATORY_CN) !=
2413 0) {
2414 // decrement mandatory slave counter
2415 EplNmtMnuInstance_g.
2416 m_uiMandatorySlaveCount--;
2417 }
2418 if (NmtState != kEplNmtMsReadyToOperate) {
2419 EPL_NMTMNU_DBG_POST_TRACE_VALUE
2420 (NodeEvent_p, uiNodeId_p,
2421 (((NodeNmtState_p & 0xFF)
2422 << 8)
2423 | kEplNmtCmdStartNode));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002424
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002425 // start optional CN
2426 Ret =
2427 EplNmtMnuSendNmtCommand
2428 (uiNodeId_p,
2429 kEplNmtCmdStartNode);
2430 }
2431 break;
2432 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002433
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002434 default:
2435 {
2436 break;
2437 }
2438 }
2439 break;
2440 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002441
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002442 case kEplNmtMnuIntNodeEventNmtCmdSent:
2443 {
2444 BYTE bNmtState;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002445
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002446 // update expected NMT state with the one that results
2447 // from the sent NMT command
2448 bNmtState = (BYTE) (NodeNmtState_p & 0xFF);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002449
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002450 // write object 0x1F8F NMT_MNNodeExpState_AU8
2451 Ret =
2452 EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState,
2453 1);
2454 if (Ret != kEplSuccessful) {
2455 goto Exit;
2456 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002457
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002458 if (NodeNmtState_p == kEplNmtCsNotActive) { // restart processing with IdentRequest
2459 EPL_NMTMNU_SET_FLAGS_TIMERARG_IDENTREQ
2460 (pNodeInfo, uiNodeId_p, TimerArg);
2461 } else { // monitor NMT state change with StatusRequest after
2462 // the corresponding delay;
2463 // until then wrong NMT states will be ignored
2464 EPL_NMTMNU_SET_FLAGS_TIMERARG_STATE_MON
2465 (pNodeInfo, uiNodeId_p, TimerArg);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002466
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002467 // set NMT state change flag
2468 pNodeInfo->m_wFlags |=
2469 EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED;
2470 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002471
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002472 Ret =
2473 EplTimeruModifyTimerMs(&pNodeInfo->
2474 m_TimerHdlStatReq,
2475 EplNmtMnuInstance_g.
2476 m_ulStatusRequestDelay,
2477 TimerArg);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002478
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002479 // finish processing, because NmtState_p is the expected and not the current state
2480 goto Exit;
2481 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002482
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002483 default:
2484 {
2485 break;
2486 }
2487 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002488
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002489 // check if network is ready to change local NMT state and this was not done before
2490 if ((EplNmtMnuInstance_g.m_wFlags & (EPL_NMTMNU_FLAG_HALTED | EPL_NMTMNU_FLAG_APP_INFORMED)) == 0) { // boot process is not halted
2491 switch (NmtState) {
2492 case kEplNmtMsPreOperational1:
2493 {
2494 if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount ==
2495 0)
2496 && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) { // all optional CNs scanned once and all mandatory CNs configured successfully
2497 EplNmtMnuInstance_g.m_wFlags |=
2498 EPL_NMTMNU_FLAG_APP_INFORMED;
2499 // inform application
2500 Ret =
2501 EplNmtMnuInstance_g.
2502 m_pfnCbBootEvent
2503 (kEplNmtBootEventBootStep1Finish,
2504 NmtState, EPL_E_NO_ERROR);
2505 if (Ret != kEplSuccessful) {
2506 if (Ret == kEplReject) {
2507 // wait for application
2508 Ret = kEplSuccessful;
2509 }
2510 break;
2511 }
2512 // enter PreOp2
2513 Ret =
2514 EplNmtuNmtEvent
2515 (kEplNmtEventAllMandatoryCNIdent);
2516 }
2517 break;
2518 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002519
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002520 case kEplNmtMsPreOperational2:
2521 {
2522 if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount ==
2523 0)
2524 && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) { // all optional CNs checked once for ReadyToOp and all mandatory CNs are ReadyToOp
2525 EplNmtMnuInstance_g.m_wFlags |=
2526 EPL_NMTMNU_FLAG_APP_INFORMED;
2527 // inform application
2528 Ret =
2529 EplNmtMnuInstance_g.
2530 m_pfnCbBootEvent
2531 (kEplNmtBootEventBootStep2Finish,
2532 NmtState, EPL_E_NO_ERROR);
2533 if (Ret != kEplSuccessful) {
2534 if (Ret == kEplReject) {
2535 // wait for application
2536 Ret = kEplSuccessful;
2537 }
2538 break;
2539 }
2540 // enter ReadyToOp
2541 Ret =
2542 EplNmtuNmtEvent
2543 (kEplNmtEventEnterReadyToOperate);
2544 }
2545 break;
2546 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002547
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002548 case kEplNmtMsReadyToOperate:
2549 {
2550 if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount ==
2551 0)
2552 && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) { // all CNs checked for errorless communication
2553 EplNmtMnuInstance_g.m_wFlags |=
2554 EPL_NMTMNU_FLAG_APP_INFORMED;
2555 // inform application
2556 Ret =
2557 EplNmtMnuInstance_g.
2558 m_pfnCbBootEvent
2559 (kEplNmtBootEventCheckComFinish,
2560 NmtState, EPL_E_NO_ERROR);
2561 if (Ret != kEplSuccessful) {
2562 if (Ret == kEplReject) {
2563 // wait for application
2564 Ret = kEplSuccessful;
2565 }
2566 break;
2567 }
2568 // enter Operational
2569 Ret =
2570 EplNmtuNmtEvent
2571 (kEplNmtEventEnterMsOperational);
2572 }
2573 break;
2574 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002575
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002576 case kEplNmtMsOperational:
2577 {
2578 if ((EplNmtMnuInstance_g.m_uiSignalSlaveCount ==
2579 0)
2580 && (EplNmtMnuInstance_g.m_uiMandatorySlaveCount == 0)) { // all optional CNs scanned once and all mandatory CNs are OPERATIONAL
2581 EplNmtMnuInstance_g.m_wFlags |=
2582 EPL_NMTMNU_FLAG_APP_INFORMED;
2583 // inform application
2584 Ret =
2585 EplNmtMnuInstance_g.
2586 m_pfnCbBootEvent
2587 (kEplNmtBootEventOperational,
2588 NmtState, EPL_E_NO_ERROR);
2589 if (Ret != kEplSuccessful) {
2590 if (Ret == kEplReject) {
2591 // ignore error code
2592 Ret = kEplSuccessful;
2593 }
2594 break;
2595 }
2596 }
2597 break;
2598 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002599
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002600 default:
2601 {
2602 break;
2603 }
2604 }
2605 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002606
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002607 Exit:
2608 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002609}
2610
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002611//---------------------------------------------------------------------------
2612//
2613// Function: EplNmtMnuCheckNmtState
2614//
2615// Description: checks the NMT state, i.e. evaluates it with object 0x1F8F
2616// NMT_MNNodeExpState_AU8 and updates object 0x1F8E
2617// NMT_MNNodeCurrState_AU8.
2618// It manipulates m_NodeState in internal node info structure.
2619//
2620// Parameters: uiNodeId_p = node ID
2621// NodeNmtState_p = NMT state of CN
2622//
2623// Returns: tEplKernel = error code
2624// kEplReject = CN was in wrong state and has been reset
2625//
2626// State:
2627//
2628//---------------------------------------------------------------------------
2629
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002630static tEplKernel EplNmtMnuCheckNmtState(unsigned int uiNodeId_p,
2631 tEplNmtMnuNodeInfo * pNodeInfo_p,
2632 tEplNmtState NodeNmtState_p,
2633 WORD wErrorCode_p,
2634 tEplNmtState LocalNmtState_p)
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002635{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002636 tEplKernel Ret = kEplSuccessful;
2637 tEplObdSize ObdSize;
2638 BYTE bNmtState;
2639 BYTE bNmtStatePrev;
2640 tEplNmtState ExpNmtState;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002641
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002642 ObdSize = 1;
2643 // read object 0x1F8F NMT_MNNodeExpState_AU8
2644 Ret = EplObduReadEntry(0x1F8F, uiNodeId_p, &bNmtState, &ObdSize);
2645 if (Ret != kEplSuccessful) {
2646 goto Exit;
2647 }
2648 // compute expected NMT state
2649 ExpNmtState = (tEplNmtState) (bNmtState | EPL_NMT_TYPE_CS);
2650 // compute BYTE of current NMT state
2651 bNmtState = ((BYTE) NodeNmtState_p & 0xFF);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002652
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002653 if (ExpNmtState == kEplNmtCsNotActive) { // ignore the current state, because the CN shall be not active
2654 Ret = kEplReject;
2655 goto Exit;
2656 } else if ((ExpNmtState == kEplNmtCsPreOperational2)
2657 && (NodeNmtState_p == kEplNmtCsReadyToOperate)) { // CN switched to ReadyToOp
2658 // delete timer for timeout handling
2659 Ret = EplTimeruDeleteTimer(&pNodeInfo_p->m_TimerHdlLonger);
2660 if (Ret != kEplSuccessful) {
2661 goto Exit;
2662 }
2663 pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateReadyToOp;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002664
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002665 // update object 0x1F8F NMT_MNNodeExpState_AU8 to ReadyToOp
2666 Ret = EplObduWriteEntry(0x1F8F, uiNodeId_p, &bNmtState, 1);
2667 if (Ret != kEplSuccessful) {
2668 goto Exit;
2669 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002670
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002671 if ((pNodeInfo_p->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // node is a mandatory CN -> decrement counter
2672 EplNmtMnuInstance_g.m_uiMandatorySlaveCount--;
2673 }
2674 if (LocalNmtState_p >= kEplNmtMsReadyToOperate) { // start procedure CheckCommunication for this node
2675 Ret = EplNmtMnuNodeCheckCom(uiNodeId_p, pNodeInfo_p);
2676 if (Ret != kEplSuccessful) {
2677 goto Exit;
2678 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002679
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002680 if ((LocalNmtState_p == kEplNmtMsOperational)
2681 && (pNodeInfo_p->m_NodeState ==
2682 kEplNmtMnuNodeStateComChecked)) {
2683 EPL_NMTMNU_DBG_POST_TRACE_VALUE(0, uiNodeId_p,
2684 (((NodeNmtState_p & 0xFF) << 8)
2685 |
2686 kEplNmtCmdStartNode));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002687
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002688 // immediately start optional CN, because communication is always OK (e.g. async-only CN)
2689 Ret =
2690 EplNmtMnuSendNmtCommand(uiNodeId_p,
2691 kEplNmtCmdStartNode);
2692 if (Ret != kEplSuccessful) {
2693 goto Exit;
2694 }
2695 }
2696 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002697
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002698 } else if ((ExpNmtState == kEplNmtCsReadyToOperate)
2699 && (NodeNmtState_p == kEplNmtCsOperational)) { // CN switched to OPERATIONAL
2700 pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateOperational;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002701
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002702 if ((pNodeInfo_p->m_dwNodeCfg & EPL_NODEASSIGN_MANDATORY_CN) != 0) { // node is a mandatory CN -> decrement counter
2703 EplNmtMnuInstance_g.m_uiMandatorySlaveCount--;
2704 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002705
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002706 } else if ((ExpNmtState != NodeNmtState_p)
2707 && !((ExpNmtState == kEplNmtCsPreOperational1)
2708 && (NodeNmtState_p == kEplNmtCsPreOperational2))) { // CN is not in expected NMT state (without the exceptions above)
2709 WORD wbeErrorCode;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002710
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002711 if ((pNodeInfo_p->
2712 m_wFlags & EPL_NMTMNU_NODE_FLAG_NOT_SCANNED) != 0) {
2713 // decrement only signal slave count if checked once
2714 EplNmtMnuInstance_g.m_uiSignalSlaveCount--;
2715 pNodeInfo_p->m_wFlags &=
2716 ~EPL_NMTMNU_NODE_FLAG_NOT_SCANNED;
2717 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002718
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002719 if (pNodeInfo_p->m_NodeState == kEplNmtMnuNodeStateUnknown) { // CN is already in state unknown, which means that it got
2720 // NMT reset command earlier
2721 goto Exit;
2722 }
2723 // -> CN is in wrong NMT state
2724 pNodeInfo_p->m_NodeState = kEplNmtMnuNodeStateUnknown;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002725
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002726 if (wErrorCode_p == 0) { // assume wrong NMT state error
2727 if ((pNodeInfo_p->m_wFlags & EPL_NMTMNU_NODE_FLAG_NMT_CMD_ISSUED) != 0) { // NMT command has been just issued;
2728 // ignore wrong NMT state until timer expires;
2729 // other errors like LOSS_PRES_TH are still processed
2730 goto Exit;
2731 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002732
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002733 wErrorCode_p = EPL_E_NMT_WRONG_STATE;
2734 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002735
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002736 BENCHMARK_MOD_07_TOGGLE(9);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002737
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002738 // $$$ start ERROR_TREATMENT and inform application
2739 Ret = EplNmtMnuInstance_g.m_pfnCbNodeEvent(uiNodeId_p,
2740 kEplNmtNodeEventError,
2741 NodeNmtState_p,
2742 wErrorCode_p,
2743 (pNodeInfo_p->
2744 m_dwNodeCfg &
2745 EPL_NODEASSIGN_MANDATORY_CN)
2746 != 0);
2747 if (Ret != kEplSuccessful) {
2748 goto Exit;
2749 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002750
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002751 EPL_NMTMNU_DBG_POST_TRACE_VALUE(0,
2752 uiNodeId_p,
2753 (((NodeNmtState_p & 0xFF) << 8)
2754 | kEplNmtCmdResetNode));
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002755
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002756 // reset CN
2757 // store error code in NMT command data for diagnostic purpose
2758 AmiSetWordToLe(&wbeErrorCode, wErrorCode_p);
2759 Ret =
2760 EplNmtMnuSendNmtCommandEx(uiNodeId_p, kEplNmtCmdResetNode,
2761 &wbeErrorCode,
2762 sizeof(wbeErrorCode));
2763 if (Ret == kEplSuccessful) {
2764 Ret = kEplReject;
2765 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002766
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002767 goto Exit;
2768 }
2769 // check if NMT_MNNodeCurrState_AU8 has to be changed
2770 ObdSize = 1;
2771 Ret = EplObduReadEntry(0x1F8E, uiNodeId_p, &bNmtStatePrev, &ObdSize);
2772 if (Ret != kEplSuccessful) {
2773 goto Exit;
2774 }
2775 if (bNmtState != bNmtStatePrev) {
2776 // update object 0x1F8E NMT_MNNodeCurrState_AU8
2777 Ret = EplObduWriteEntry(0x1F8E, uiNodeId_p, &bNmtState, 1);
2778 if (Ret != kEplSuccessful) {
2779 goto Exit;
2780 }
2781 Ret = EplNmtMnuInstance_g.m_pfnCbNodeEvent(uiNodeId_p,
2782 kEplNmtNodeEventNmtState,
2783 NodeNmtState_p,
2784 wErrorCode_p,
2785 (pNodeInfo_p->
2786 m_dwNodeCfg &
2787 EPL_NODEASSIGN_MANDATORY_CN)
2788 != 0);
2789 if (Ret != kEplSuccessful) {
2790 goto Exit;
2791 }
2792 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002793
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002794 Exit:
2795 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002796}
2797
2798//---------------------------------------------------------------------------
2799//
2800// Function: EplNmtMnuReset
2801//
2802// Description: reset internal structures, e.g. timers
2803//
2804// Parameters: void
2805//
2806// Returns: tEplKernel = error code
2807//
2808// State:
2809//
2810//---------------------------------------------------------------------------
2811
2812static tEplKernel EplNmtMnuReset(void)
2813{
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002814 tEplKernel Ret;
2815 int iIndex;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002816
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002817 Ret = EplTimeruDeleteTimer(&EplNmtMnuInstance_g.m_TimerHdlNmtState);
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002818
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002819 for (iIndex = 1; iIndex <= tabentries(EplNmtMnuInstance_g.m_aNodeInfo);
2820 iIndex++) {
2821 // delete timer handles
2822 Ret =
2823 EplTimeruDeleteTimer(&EPL_NMTMNU_GET_NODEINFO(iIndex)->
2824 m_TimerHdlStatReq);
2825 Ret =
2826 EplTimeruDeleteTimer(&EPL_NMTMNU_GET_NODEINFO(iIndex)->
2827 m_TimerHdlLonger);
2828 }
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002829
Greg Kroah-Hartman833dfbe2008-12-19 17:11:52 -08002830 return Ret;
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002831}
2832
Daniel Krueger9d7164c2008-12-19 11:41:57 -08002833#endif // #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
2834
2835// EOF