pty: Narrow the race on ldisc locking
[pandora-kernel.git] / drivers / staging / epl / EplApiGeneric.c
1 /****************************************************************************
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 generic EPL API 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: EplApiGeneric.c,v $
53
54                 $Author: D.Krueger $
55
56                 $Revision: 1.21 $  $Date: 2008/11/21 09:00:38 $
57
58                 $State: Exp $
59
60                 Build Environment:
61                     GCC V3.4
62
63   -------------------------------------------------------------------------
64
65   Revision History:
66
67   2006/09/05 d.k.:   start of the implementation, version 1.00
68
69 ****************************************************************************/
70
71 #include "Epl.h"
72 #include "kernel/EplDllk.h"
73 #include "kernel/EplErrorHandlerk.h"
74 #include "kernel/EplEventk.h"
75 #include "kernel/EplNmtk.h"
76 #include "kernel/EplObdk.h"
77 #include "kernel/EplTimerk.h"
78 #include "kernel/EplDllkCal.h"
79 #include "kernel/EplPdokCal.h"
80 #include "user/EplDlluCal.h"
81 #include "user/EplLedu.h"
82 #include "user/EplNmtCnu.h"
83 #include "user/EplNmtMnu.h"
84 #include "user/EplSdoComu.h"
85 #include "user/EplIdentu.h"
86 #include "user/EplStatusu.h"
87
88 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
89 #include "kernel/EplPdok.h"
90 #endif
91
92 #include "SharedBuff.h"
93
94 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) == 0)
95 #error "EPL API layer needs EPL module OBDK!"
96 #endif
97
98 /***************************************************************************/
99 /*                                                                         */
100 /*                                                                         */
101 /*          G L O B A L   D E F I N I T I O N S                            */
102 /*                                                                         */
103 /*                                                                         */
104 /***************************************************************************/
105
106 //---------------------------------------------------------------------------
107 // const defines
108 //---------------------------------------------------------------------------
109
110 //---------------------------------------------------------------------------
111 // local types
112 //---------------------------------------------------------------------------
113
114 //---------------------------------------------------------------------------
115 // modul globale vars
116 //---------------------------------------------------------------------------
117
118 //---------------------------------------------------------------------------
119 // local function prototypes
120 //---------------------------------------------------------------------------
121
122 /***************************************************************************/
123 /*                                                                         */
124 /*                                                                         */
125 /*          C L A S S  EplApi                                              */
126 /*                                                                         */
127 /*                                                                         */
128 /***************************************************************************/
129 //
130 // Description:
131 //
132 //
133 /***************************************************************************/
134
135 //=========================================================================//
136 //                                                                         //
137 //          P R I V A T E   D E F I N I T I O N S                          //
138 //                                                                         //
139 //=========================================================================//
140
141 //---------------------------------------------------------------------------
142 // const defines
143 //---------------------------------------------------------------------------
144
145 //---------------------------------------------------------------------------
146 // local types
147 //---------------------------------------------------------------------------
148
149 typedef struct {
150         tEplApiInitParam m_InitParam;
151
152 } tEplApiInstance;
153
154 //---------------------------------------------------------------------------
155 // local vars
156 //---------------------------------------------------------------------------
157
158 static tEplApiInstance EplApiInstance_g;
159
160 //---------------------------------------------------------------------------
161 // local function prototypes
162 //---------------------------------------------------------------------------
163
164 // NMT state change event callback function
165 static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p);
166
167 // update DLL configuration from OD
168 static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p);
169
170 // update OD from init param
171 static tEplKernel EplApiUpdateObd(void);
172
173 // process events from user event queue
174 static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p);
175
176 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
177 // callback function of SDO module
178 static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p);
179 #endif
180
181 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
182 // callback functions of NmtMnu module
183 static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p,
184                                     tEplNmtNodeEvent NodeEvent_p,
185                                     tEplNmtState NmtState_p,
186                                     u16 wErrorCode_p, BOOL fMandatory_p);
187
188 static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
189                                     tEplNmtState NmtState_p,
190                                     u16 wErrorCode_p);
191 #endif
192
193 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
194 // callback function of Ledu module
195 static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p);
196 #endif
197
198 // OD initialization function (implemented in Objdict.c)
199 tEplKernel EplObdInitRam(tEplObdInitParam *pInitParam_p);
200
201 //=========================================================================//
202 //                                                                         //
203 //          P U B L I C   F U N C T I O N S                                //
204 //                                                                         //
205 //=========================================================================//
206
207 //---------------------------------------------------------------------------
208 //
209 // Function:    EplApiInitialize()
210 //
211 // Description: add and initialize new instance of EPL stack.
212 //              After return from this function the application must start
213 //              the NMT state machine via
214 //              EplApiExecNmtCommand(kEplNmtEventSwReset)
215 //              and thereby the whole EPL stack :-)
216 //
217 // Parameters:  pInitParam_p            = initialisation parameters
218 //
219 // Returns:     tEplKernel              = error code
220 //
221 //
222 // State:
223 //
224 //---------------------------------------------------------------------------
225
226 tEplKernel EplApiInitialize(tEplApiInitParam *pInitParam_p)
227 {
228         tEplKernel Ret = kEplSuccessful;
229         tEplObdInitParam ObdInitParam;
230         tEplDllkInitParam DllkInitParam;
231 #ifndef EPL_NO_FIFO
232         tShbError ShbError;
233 #endif
234
235         // reset instance structure
236         EPL_MEMSET(&EplApiInstance_g, 0, sizeof(EplApiInstance_g));
237
238         EPL_MEMCPY(&EplApiInstance_g.m_InitParam, pInitParam_p,
239                    min(sizeof(tEplApiInitParam),
240                        pInitParam_p->m_uiSizeOfStruct));
241
242         // check event callback function pointer
243         if (EplApiInstance_g.m_InitParam.m_pfnCbEvent == NULL) {        // application must always have an event callback function
244                 Ret = kEplApiInvalidParam;
245                 goto Exit;
246         }
247 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
248         // init OD
249 // FIXME
250 //    Ret = EplObdInitRam(&ObdInitParam);
251 //    if (Ret != kEplSuccessful)
252 //    {
253 //        goto Exit;
254 //    }
255
256         // initialize EplObd module
257         Ret = EplObdInit(&ObdInitParam);
258         if (Ret != kEplSuccessful) {
259                 goto Exit;
260         }
261 #endif
262
263 #ifndef EPL_NO_FIFO
264         ShbError = ShbInit();
265         if (ShbError != kShbOk) {
266                 Ret = kEplNoResource;
267                 goto Exit;
268         }
269 #endif
270
271         // initialize EplEventk module
272         Ret = EplEventkInit(EplApiInstance_g.m_InitParam.m_pfnCbSync);
273         if (Ret != kEplSuccessful) {
274                 goto Exit;
275         }
276         // initialize EplEventu module
277         Ret = EplEventuInit(EplApiProcessEvent);
278         if (Ret != kEplSuccessful) {
279                 goto Exit;
280         }
281         // init EplTimerk module
282         Ret = EplTimerkInit();
283         if (Ret != kEplSuccessful) {
284                 goto Exit;
285         }
286         // initialize EplNmtk module before DLL
287 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
288         Ret = EplNmtkInit();
289         if (Ret != kEplSuccessful) {
290                 goto Exit;
291         }
292 #endif
293
294         // initialize EplDllk module
295 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
296         EPL_MEMCPY(DllkInitParam.m_be_abSrcMac,
297                    EplApiInstance_g.m_InitParam.m_abMacAddress, 6);
298         Ret = EplDllkAddInstance(&DllkInitParam);
299         if (Ret != kEplSuccessful) {
300                 goto Exit;
301         }
302         // initialize EplErrorHandlerk module
303         Ret = EplErrorHandlerkInit();
304         if (Ret != kEplSuccessful) {
305                 goto Exit;
306         }
307         // initialize EplDllkCal module
308         Ret = EplDllkCalAddInstance();
309         if (Ret != kEplSuccessful) {
310                 goto Exit;
311         }
312 #endif
313
314         // initialize EplDlluCal module
315 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
316         Ret = EplDlluCalAddInstance();
317         if (Ret != kEplSuccessful) {
318                 goto Exit;
319         }
320 #endif
321
322         // initialize EplPdok module
323 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_PDOK)) != 0)
324         Ret = EplPdokAddInstance();
325         if (Ret != kEplSuccessful) {
326                 goto Exit;
327         }
328
329         Ret = EplPdokCalAddInstance();
330         if (Ret != kEplSuccessful) {
331                 goto Exit;
332         }
333 #endif
334
335         // initialize EplNmtCnu module
336 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
337         Ret = EplNmtCnuAddInstance(EplApiInstance_g.m_InitParam.m_uiNodeId);
338         if (Ret != kEplSuccessful) {
339                 goto Exit;
340         }
341 #endif
342
343         // initialize EplNmtu module
344 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
345         Ret = EplNmtuInit();
346         if (Ret != kEplSuccessful) {
347                 goto Exit;
348         }
349         // register NMT event callback function
350         Ret = EplNmtuRegisterStateChangeCb(EplApiCbNmtStateChange);
351         if (Ret != kEplSuccessful) {
352                 goto Exit;
353         }
354 #endif
355
356 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
357         // initialize EplNmtMnu module
358         Ret = EplNmtMnuInit(EplApiCbNodeEvent, EplApiCbBootEvent);
359         if (Ret != kEplSuccessful) {
360                 goto Exit;
361         }
362         // initialize EplIdentu module
363         Ret = EplIdentuInit();
364         if (Ret != kEplSuccessful) {
365                 goto Exit;
366         }
367         // initialize EplStatusu module
368         Ret = EplStatusuInit();
369         if (Ret != kEplSuccessful) {
370                 goto Exit;
371         }
372 #endif
373
374         // initialize EplLedu module
375 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
376         Ret = EplLeduInit(EplApiCbLedStateChange);
377         if (Ret != kEplSuccessful) {
378                 goto Exit;
379         }
380 #endif
381
382         // init SDO module
383 #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \
384      (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0))
385         // init sdo command layer
386         Ret = EplSdoComInit();
387         if (Ret != kEplSuccessful) {
388                 goto Exit;
389         }
390 #endif
391
392         // the application must start NMT state machine
393         // via EplApiExecNmtCommand(kEplNmtEventSwReset)
394         // and thereby the whole EPL stack
395
396       Exit:
397         return Ret;
398 }
399
400 //---------------------------------------------------------------------------
401 //
402 // Function:    EplApiShutdown()
403 //
404 // Description: deletes an instance of EPL stack
405 //
406 // Parameters:  (none)
407 //
408 // Returns:     tEplKernel              = error code
409 //
410 //
411 // State:
412 //
413 //---------------------------------------------------------------------------
414
415 tEplKernel EplApiShutdown(void)
416 {
417         tEplKernel Ret = kEplSuccessful;
418
419         // $$$ d.k.: check if NMT state is NMT_GS_OFF
420
421         // $$$ d.k.: maybe delete event queues at first, but this implies that
422         //           no other module must not use the event queues for communication
423         //           during shutdown.
424
425         // delete instance for all modules
426
427         // deinitialize EplSdoCom module
428 #if ((((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOS)) != 0) || \
429      (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0))
430         Ret = EplSdoComDelInstance();
431 //    PRINTF1("EplSdoComDelInstance():  0x%X\n", Ret);
432 #endif
433
434         // deinitialize EplLedu module
435 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
436         Ret = EplLeduDelInstance();
437 //    PRINTF1("EplLeduDelInstance():    0x%X\n", Ret);
438 #endif
439
440 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
441         // deinitialize EplNmtMnu module
442         Ret = EplNmtMnuDelInstance();
443 //    PRINTF1("EplNmtMnuDelInstance():  0x%X\n", Ret);
444
445         // deinitialize EplIdentu module
446         Ret = EplIdentuDelInstance();
447 //    PRINTF1("EplIdentuDelInstance():  0x%X\n", Ret);
448
449         // deinitialize EplStatusu module
450         Ret = EplStatusuDelInstance();
451 //    PRINTF1("EplStatusuDelInstance():  0x%X\n", Ret);
452 #endif
453
454         // deinitialize EplNmtCnu module
455 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_CN)) != 0)
456         Ret = EplNmtCnuDelInstance();
457 //    PRINTF1("EplNmtCnuDelInstance():  0x%X\n", Ret);
458 #endif
459
460         // deinitialize EplNmtu module
461 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
462         Ret = EplNmtuDelInstance();
463 //    PRINTF1("EplNmtuDelInstance():    0x%X\n", Ret);
464 #endif
465
466         // deinitialize EplDlluCal module
467 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLU)) != 0)
468         Ret = EplDlluCalDelInstance();
469 //    PRINTF1("EplDlluCalDelInstance(): 0x%X\n", Ret);
470
471 #endif
472
473         // deinitialize EplEventu module
474         Ret = EplEventuDelInstance();
475 //    PRINTF1("EplEventuDelInstance():  0x%X\n", Ret);
476
477         // deinitialize EplNmtk module
478 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTK)) != 0)
479         Ret = EplNmtkDelInstance();
480 //    PRINTF1("EplNmtkDelInstance():    0x%X\n", Ret);
481 #endif
482
483         // deinitialize EplDllk module
484 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_DLLK)) != 0)
485         Ret = EplDllkDelInstance();
486 //    PRINTF1("EplDllkDelInstance():    0x%X\n", Ret);
487
488         // deinitialize EplDllkCal module
489         Ret = EplDllkCalDelInstance();
490 //    PRINTF1("EplDllkCalDelInstance(): 0x%X\n", Ret);
491 #endif
492
493         // deinitialize EplEventk module
494         Ret = EplEventkDelInstance();
495 //    PRINTF1("EplEventkDelInstance():  0x%X\n", Ret);
496
497         // deinitialize EplTimerk module
498         Ret = EplTimerkDelInstance();
499 //    PRINTF1("EplTimerkDelInstance():  0x%X\n", Ret);
500
501 #ifndef EPL_NO_FIFO
502         ShbExit();
503 #endif
504
505         return Ret;
506 }
507
508 //----------------------------------------------------------------------------
509 // Function:    EplApiExecNmtCommand()
510 //
511 // Description: executes a NMT command, i.e. post the NMT command/event to the
512 //              NMTk module. NMT commands which are not appropriate in the current
513 //              NMT state are silently ignored. Please keep in mind that the
514 //              NMT state may change until the NMT command is actually executed.
515 //
516 // Parameters:  NmtEvent_p              = NMT command/event
517 //
518 // Returns:     tEplKernel              = error code
519 //
520 // State:
521 //----------------------------------------------------------------------------
522
523 tEplKernel EplApiExecNmtCommand(tEplNmtEvent NmtEvent_p)
524 {
525         tEplKernel Ret = kEplSuccessful;
526
527 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
528         Ret = EplNmtuNmtEvent(NmtEvent_p);
529 #endif
530
531         return Ret;
532 }
533
534 //----------------------------------------------------------------------------
535 // Function:    EplApiLinkObject()
536 //
537 // Description: Function maps array of application variables onto specified object in OD
538 //
539 // Parameters:  uiObjIndex_p            = Function maps variables for this object index
540 //              pVar_p                  = Pointer to data memory area for the specified object
541 //              puiVarEntries_p         = IN: pointer to number of entries to map
542 //                                        OUT: pointer to number of actually used entries
543 //              pEntrySize_p            = IN: pointer to size of one entry;
544 //                                            if size is zero, the actual size will be read from OD
545 //                                        OUT: pointer to entire size of all entries mapped
546 //              uiFirstSubindex_p       = This is the first subindex to be mapped.
547 //
548 // Returns:     tEplKernel              = error code
549 //
550 // State:
551 //----------------------------------------------------------------------------
552
553 tEplKernel EplApiLinkObject(unsigned int uiObjIndex_p,
554                             void *pVar_p,
555                             unsigned int *puiVarEntries_p,
556                             tEplObdSize *pEntrySize_p,
557                             unsigned int uiFirstSubindex_p)
558 {
559         u8 bVarEntries;
560         u8 bIndexEntries;
561         u8 *pbData;
562         unsigned int uiSubindex;
563         tEplVarParam VarParam;
564         tEplObdSize EntrySize;
565         tEplObdSize UsedSize;
566
567         tEplKernel RetCode = kEplSuccessful;
568
569         if ((pVar_p == NULL)
570             || (puiVarEntries_p == NULL)
571             || (*puiVarEntries_p == 0)
572             || (pEntrySize_p == NULL)) {
573                 RetCode = kEplApiInvalidParam;
574                 goto Exit;
575         }
576
577         pbData = (u8 *)pVar_p;
578         bVarEntries = (u8) * puiVarEntries_p;
579         UsedSize = 0;
580
581         // init VarParam structure with default values
582         VarParam.m_uiIndex = uiObjIndex_p;
583         VarParam.m_ValidFlag = kVarValidAll;
584
585         if (uiFirstSubindex_p != 0) {   // check if object exists by reading subindex 0x00,
586                 // because user wants to link a variable to a subindex unequal 0x00
587                 // read number of entries
588                 EntrySize = (tEplObdSize) sizeof(bIndexEntries);
589                 RetCode = EplObdReadEntry(uiObjIndex_p,
590                                           0x00,
591                                           (void *)&bIndexEntries,
592                                           &EntrySize);
593
594                 if ((RetCode != kEplSuccessful) || (bIndexEntries == 0x00)) {
595                         // Object doesn't exist or invalid entry number
596                         RetCode = kEplObdIndexNotExist;
597                         goto Exit;
598                 }
599         } else {                // user wants to link a variable to subindex 0x00
600                 // that's OK
601                 bIndexEntries = 0;
602         }
603
604         // Correct number of entries if number read from OD is greater
605         // than the specified number.
606         // This is done, so that we do not set more entries than subindexes the
607         // object actually has.
608         if ((bIndexEntries > (bVarEntries + uiFirstSubindex_p - 1)) &&
609             (bVarEntries != 0x00)) {
610                 bIndexEntries = (u8) (bVarEntries + uiFirstSubindex_p - 1);
611         }
612         // map entries
613         for (uiSubindex = uiFirstSubindex_p; uiSubindex <= bIndexEntries;
614              uiSubindex++) {
615                 // if passed entry size is 0, then get size from OD
616                 if (*pEntrySize_p == 0x00) {
617                         // read entry size
618                         EntrySize = EplObdGetDataSize(uiObjIndex_p, uiSubindex);
619
620                         if (EntrySize == 0x00) {
621                                 // invalid entry size (maybe object doesn't exist or entry of type DOMAIN is empty)
622                                 RetCode = kEplObdSubindexNotExist;
623                                 break;
624                         }
625                 } else {        // use passed entry size
626                         EntrySize = *pEntrySize_p;
627                 }
628
629                 VarParam.m_uiSubindex = uiSubindex;
630
631                 // set pointer to user var
632                 VarParam.m_Size = EntrySize;
633                 VarParam.m_pData = pbData;
634
635                 UsedSize += EntrySize;
636                 pbData += EntrySize;
637
638                 RetCode = EplObdDefineVar(&VarParam);
639                 if (RetCode != kEplSuccessful) {
640                         break;
641                 }
642         }
643
644         // set number of mapped entries and entry size
645         *puiVarEntries_p = ((bIndexEntries - uiFirstSubindex_p) + 1);
646         *pEntrySize_p = UsedSize;
647
648       Exit:
649
650         return (RetCode);
651
652 }
653
654 // ----------------------------------------------------------------------------
655 //
656 // Function:    EplApiReadObject()
657 //
658 // Description: reads the specified entry from the OD of the specified node.
659 //              If this node is a remote node, it performs a SDO transfer, which
660 //              means this function returns kEplApiTaskDeferred and the application
661 //              is informed via the event callback function when the task is completed.
662 //
663 // Parameters:  pSdoComConHdl_p         = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access)
664 //              uiNodeId_p              = IN: node ID (0 = itself)
665 //              uiIndex_p               = IN: index of object in OD
666 //              uiSubindex_p            = IN: sub-index of object in OD
667 //              pDstData_le_p           = OUT: pointer to data in little endian
668 //              puiSize_p               = INOUT: pointer to size of data
669 //              SdoType_p               = IN: type of SDO transfer
670 //              pUserArg_p              = IN: user-definable argument pointer,
671 //                                            which will be passed to the event callback function
672 //
673 // Return:      tEplKernel              = error code
674 //
675 // ----------------------------------------------------------------------------
676
677 tEplKernel EplApiReadObject(tEplSdoComConHdl *pSdoComConHdl_p,
678                             unsigned int uiNodeId_p,
679                             unsigned int uiIndex_p,
680                             unsigned int uiSubindex_p,
681                             void *pDstData_le_p,
682                             unsigned int *puiSize_p,
683                             tEplSdoType SdoType_p, void *pUserArg_p)
684 {
685         tEplKernel Ret = kEplSuccessful;
686
687         if ((uiIndex_p == 0) || (pDstData_le_p == NULL) || (puiSize_p == NULL)
688             || (*puiSize_p == 0)) {
689                 Ret = kEplApiInvalidParam;
690                 goto Exit;
691         }
692
693         if (uiNodeId_p == 0 || uiNodeId_p == EplObdGetNodeId()) {       // local OD access can be performed
694                 tEplObdSize ObdSize;
695
696                 ObdSize = (tEplObdSize) * puiSize_p;
697                 Ret =
698                     EplObdReadEntryToLe(uiIndex_p, uiSubindex_p, pDstData_le_p,
699                                         &ObdSize);
700                 *puiSize_p = (unsigned int)ObdSize;
701         } else {                // perform SDO transfer
702 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
703                 tEplSdoComTransParamByIndex TransParamByIndex;
704 //    tEplSdoComConHdl            SdoComConHdl;
705
706                 // check if application provides space for handle
707                 if (pSdoComConHdl_p == NULL) {
708                         Ret = kEplApiInvalidParam;
709                         goto Exit;
710 //            pSdoComConHdl_p = &SdoComConHdl;
711                 }
712                 // init command layer connection
713                 Ret = EplSdoComDefineCon(pSdoComConHdl_p, uiNodeId_p,   // target node id
714                                          SdoType_p);    // SDO type
715                 if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) {
716                         goto Exit;
717                 }
718                 TransParamByIndex.m_pData = pDstData_le_p;
719                 TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeRead;
720                 TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p;
721                 TransParamByIndex.m_uiDataSize = *puiSize_p;
722                 TransParamByIndex.m_uiIndex = uiIndex_p;
723                 TransParamByIndex.m_uiSubindex = uiSubindex_p;
724                 TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon;
725                 TransParamByIndex.m_pUserArg = pUserArg_p;
726
727                 Ret = EplSdoComInitTransferByIndex(&TransParamByIndex);
728                 if (Ret != kEplSuccessful) {
729                         goto Exit;
730                 }
731                 Ret = kEplApiTaskDeferred;
732
733 #else
734                 Ret = kEplApiInvalidParam;
735 #endif
736         }
737
738       Exit:
739         return Ret;
740 }
741
742 // ----------------------------------------------------------------------------
743 //
744 // Function:    EplApiWriteObject()
745 //
746 // Description: writes the specified entry to the OD of the specified node.
747 //              If this node is a remote node, it performs a SDO transfer, which
748 //              means this function returns kEplApiTaskDeferred and the application
749 //              is informed via the event callback function when the task is completed.
750 //
751 // Parameters:  pSdoComConHdl_p         = INOUT: pointer to SDO connection handle (may be NULL in case of local OD access)
752 //              uiNodeId_p              = IN: node ID (0 = itself)
753 //              uiIndex_p               = IN: index of object in OD
754 //              uiSubindex_p            = IN: sub-index of object in OD
755 //              pSrcData_le_p           = IN: pointer to data in little endian
756 //              uiSize_p                = IN: size of data in bytes
757 //              SdoType_p               = IN: type of SDO transfer
758 //              pUserArg_p              = IN: user-definable argument pointer,
759 //                                            which will be passed to the event callback function
760 //
761 // Return:      tEplKernel              = error code
762 //
763 // ----------------------------------------------------------------------------
764
765 tEplKernel EplApiWriteObject(tEplSdoComConHdl *pSdoComConHdl_p,
766                              unsigned int uiNodeId_p,
767                              unsigned int uiIndex_p,
768                              unsigned int uiSubindex_p,
769                              void *pSrcData_le_p,
770                              unsigned int uiSize_p,
771                              tEplSdoType SdoType_p, void *pUserArg_p)
772 {
773         tEplKernel Ret = kEplSuccessful;
774
775         if ((uiIndex_p == 0) || (pSrcData_le_p == NULL) || (uiSize_p == 0)) {
776                 Ret = kEplApiInvalidParam;
777                 goto Exit;
778         }
779
780         if (uiNodeId_p == 0 || uiNodeId_p == EplObdGetNodeId()) {       // local OD access can be performed
781
782                 Ret =
783                     EplObdWriteEntryFromLe(uiIndex_p, uiSubindex_p,
784                                            pSrcData_le_p, uiSize_p);
785         } else {                // perform SDO transfer
786 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
787                 tEplSdoComTransParamByIndex TransParamByIndex;
788 //    tEplSdoComConHdl            SdoComConHdl;
789
790                 // check if application provides space for handle
791                 if (pSdoComConHdl_p == NULL) {
792                         Ret = kEplApiInvalidParam;
793                         goto Exit;
794 //            pSdoComConHdl_p = &SdoComConHdl;
795                 }
796                 // d.k.: How to recycle command layer connection?
797                 //       Try to redefine it, which will return kEplSdoComHandleExists
798                 //       and the existing command layer handle.
799                 //       If the returned handle is busy, EplSdoComInitTransferByIndex()
800                 //       will return with error.
801                 // $$$ d.k.: Collisions may occur with Configuration Manager, if both the application and
802                 //           Configuration Manager, are trying to communicate with the very same node.
803                 //     possible solution: disallow communication by application if Configuration Manager is busy
804
805                 // init command layer connection
806                 Ret = EplSdoComDefineCon(pSdoComConHdl_p, uiNodeId_p,   // target node id
807                                          SdoType_p);    // SDO type
808                 if ((Ret != kEplSuccessful) && (Ret != kEplSdoComHandleExists)) {
809                         goto Exit;
810                 }
811                 TransParamByIndex.m_pData = pSrcData_le_p;
812                 TransParamByIndex.m_SdoAccessType = kEplSdoAccessTypeWrite;
813                 TransParamByIndex.m_SdoComConHdl = *pSdoComConHdl_p;
814                 TransParamByIndex.m_uiDataSize = uiSize_p;
815                 TransParamByIndex.m_uiIndex = uiIndex_p;
816                 TransParamByIndex.m_uiSubindex = uiSubindex_p;
817                 TransParamByIndex.m_pfnSdoFinishedCb = EplApiCbSdoCon;
818                 TransParamByIndex.m_pUserArg = pUserArg_p;
819
820                 Ret = EplSdoComInitTransferByIndex(&TransParamByIndex);
821                 if (Ret != kEplSuccessful) {
822                         goto Exit;
823                 }
824                 Ret = kEplApiTaskDeferred;
825
826 #else
827                 Ret = kEplApiInvalidParam;
828 #endif
829         }
830
831       Exit:
832         return Ret;
833 }
834
835 // ----------------------------------------------------------------------------
836 //
837 // Function:    EplApiFreeSdoChannel()
838 //
839 // Description: frees the specified SDO channel.
840 //              This function must be called after each call to EplApiReadObject()/EplApiWriteObject()
841 //              which returns kEplApiTaskDeferred and the application
842 //              is informed via the event callback function when the task is completed.
843 //
844 // Parameters:  SdoComConHdl_p          = IN: SDO connection handle
845 //
846 // Return:      tEplKernel              = error code
847 //
848 // ----------------------------------------------------------------------------
849
850 tEplKernel EplApiFreeSdoChannel(tEplSdoComConHdl SdoComConHdl_p)
851 {
852         tEplKernel Ret = kEplSuccessful;
853
854 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
855
856         // init command layer connection
857         Ret = EplSdoComUndefineCon(SdoComConHdl_p);
858
859 #else
860         Ret = kEplApiInvalidParam;
861 #endif
862
863         return Ret;
864 }
865
866 // ----------------------------------------------------------------------------
867 //
868 // Function:    EplApiReadLocalObject()
869 //
870 // Description: reads the specified entry from the local OD.
871 //
872 // Parameters:  uiIndex_p               = IN: index of object in OD
873 //              uiSubindex_p            = IN: sub-index of object in OD
874 //              pDstData_p              = OUT: pointer to data in platform byte order
875 //              puiSize_p               = INOUT: pointer to size of data
876 //
877 // Return:      tEplKernel              = error code
878 //
879 // ----------------------------------------------------------------------------
880
881 tEplKernel EplApiReadLocalObject(unsigned int uiIndex_p,
882                                  unsigned int uiSubindex_p,
883                                  void *pDstData_p, unsigned int *puiSize_p)
884 {
885         tEplKernel Ret = kEplSuccessful;
886         tEplObdSize ObdSize;
887
888         ObdSize = (tEplObdSize) * puiSize_p;
889         Ret = EplObdReadEntry(uiIndex_p, uiSubindex_p, pDstData_p, &ObdSize);
890         *puiSize_p = (unsigned int)ObdSize;
891
892         return Ret;
893 }
894
895 // ----------------------------------------------------------------------------
896 //
897 // Function:    EplApiWriteLocalObject()
898 //
899 // Description: writes the specified entry to the local OD.
900 //
901 // Parameters:  uiIndex_p               = IN: index of object in OD
902 //              uiSubindex_p            = IN: sub-index of object in OD
903 //              pSrcData_p              = IN: pointer to data in platform byte order
904 //              uiSize_p                = IN: size of data in bytes
905 //
906 // Return:      tEplKernel              = error code
907 //
908 // ----------------------------------------------------------------------------
909
910 tEplKernel EplApiWriteLocalObject(unsigned int uiIndex_p,
911                                   unsigned int uiSubindex_p,
912                                   void *pSrcData_p,
913                                   unsigned int uiSize_p)
914 {
915         tEplKernel Ret = kEplSuccessful;
916
917         Ret =
918             EplObdWriteEntry(uiIndex_p, uiSubindex_p, pSrcData_p,
919                              (tEplObdSize) uiSize_p);
920
921         return Ret;
922 }
923
924 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
925 // ----------------------------------------------------------------------------
926 //
927 // Function:    EplApiMnTriggerStateChange()
928 //
929 // Description: triggers the specified node command for the specified node.
930 //
931 // Parameters:  uiNodeId_p              = node ID for which the node command will be executed
932 //              NodeCommand_p           = node command
933 //
934 // Return:      tEplKernel              = error code
935 //
936 // ----------------------------------------------------------------------------
937
938 tEplKernel EplApiMnTriggerStateChange(unsigned int uiNodeId_p,
939                                       tEplNmtNodeCommand NodeCommand_p)
940 {
941         tEplKernel Ret = kEplSuccessful;
942
943         Ret = EplNmtMnuTriggerStateChange(uiNodeId_p, NodeCommand_p);
944
945         return Ret;
946 }
947
948 #endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
949
950 //---------------------------------------------------------------------------
951 //
952 // Function:    EplApiCbObdAccess
953 //
954 // Description: callback function for OD accesses
955 //
956 // Parameters:  pParam_p                = OBD parameter
957 //
958 // Returns:     tEplKernel              = error code
959 //
960 //
961 // State:
962 //
963 //---------------------------------------------------------------------------
964
965 tEplKernel EplApiCbObdAccess(tEplObdCbParam *pParam_p)
966 {
967         tEplKernel Ret = kEplSuccessful;
968
969 #if (EPL_API_OBD_FORWARD_EVENT != FALSE)
970         tEplApiEventArg EventArg;
971
972         // call user callback
973         // must be disabled for EplApiLinuxKernel.c, because of reentrancy problem
974         // for local OD access. This is not so bad as user callback function in
975         // application does not use OD callbacks at the moment.
976         EventArg.m_ObdCbParam = *pParam_p;
977         Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventObdAccess,
978                                                         &EventArg,
979                                                         EplApiInstance_g.
980                                                         m_InitParam.
981                                                         m_pEventUserArg);
982 #endif
983
984         switch (pParam_p->m_uiIndex) {
985                 //case 0x1006:    // NMT_CycleLen_U32 (valid on reset)
986         case 0x1C14:            // DLL_LossOfFrameTolerance_U32
987                 //case 0x1F98:    // NMT_CycleTiming_REC (valid on reset)
988                 {
989                         if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) {
990                                 // update DLL configuration
991                                 Ret = EplApiUpdateDllConfig(FALSE);
992                         }
993                         break;
994                 }
995
996         case 0x1020:            // CFM_VerifyConfiguration_REC.ConfId_U32 != 0
997                 {
998                         if ((pParam_p->m_ObdEvent == kEplObdEvPostWrite)
999                             && (pParam_p->m_uiSubIndex == 3)
1000                             && (*((u32 *) pParam_p->m_pArg) != 0)) {
1001                                 u32 dwVerifyConfInvalid = 0;
1002                                 // set CFM_VerifyConfiguration_REC.VerifyConfInvalid_U32 to 0
1003                                 Ret =
1004                                     EplObdWriteEntry(0x1020, 4,
1005                                                      &dwVerifyConfInvalid, 4);
1006                                 // ignore any error because this objekt is optional
1007                                 Ret = kEplSuccessful;
1008                         }
1009                         break;
1010                 }
1011
1012         case 0x1F9E:            // NMT_ResetCmd_U8
1013                 {
1014                         if (pParam_p->m_ObdEvent == kEplObdEvPreWrite) {
1015                                 u8 bNmtCommand;
1016
1017                                 bNmtCommand = *((u8 *) pParam_p->m_pArg);
1018                                 // check value range
1019                                 switch ((tEplNmtCommand) bNmtCommand) {
1020                                 case kEplNmtCmdResetNode:
1021                                 case kEplNmtCmdResetCommunication:
1022                                 case kEplNmtCmdResetConfiguration:
1023                                 case kEplNmtCmdSwReset:
1024                                 case kEplNmtCmdInvalidService:
1025                                         // valid command identifier specified
1026                                         break;
1027
1028                                 default:
1029                                         pParam_p->m_dwAbortCode =
1030                                             EPL_SDOAC_VALUE_RANGE_EXCEEDED;
1031                                         Ret = kEplObdAccessViolation;
1032                                         break;
1033                                 }
1034                         } else if (pParam_p->m_ObdEvent == kEplObdEvPostWrite) {
1035                                 u8 bNmtCommand;
1036
1037                                 bNmtCommand = *((u8 *) pParam_p->m_pArg);
1038                                 // check value range
1039                                 switch ((tEplNmtCommand) bNmtCommand) {
1040                                 case kEplNmtCmdResetNode:
1041 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1042                                         Ret =
1043                                             EplNmtuNmtEvent
1044                                             (kEplNmtEventResetNode);
1045 #endif
1046                                         break;
1047
1048                                 case kEplNmtCmdResetCommunication:
1049 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1050                                         Ret =
1051                                             EplNmtuNmtEvent
1052                                             (kEplNmtEventResetCom);
1053 #endif
1054                                         break;
1055
1056                                 case kEplNmtCmdResetConfiguration:
1057 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1058                                         Ret =
1059                                             EplNmtuNmtEvent
1060                                             (kEplNmtEventResetConfig);
1061 #endif
1062                                         break;
1063
1064                                 case kEplNmtCmdSwReset:
1065 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMTU)) != 0)
1066                                         Ret =
1067                                             EplNmtuNmtEvent
1068                                             (kEplNmtEventSwReset);
1069 #endif
1070                                         break;
1071
1072                                 case kEplNmtCmdInvalidService:
1073                                         break;
1074
1075                                 default:
1076                                         pParam_p->m_dwAbortCode =
1077                                             EPL_SDOAC_VALUE_RANGE_EXCEEDED;
1078                                         Ret = kEplObdAccessViolation;
1079                                         break;
1080                                 }
1081                         }
1082                         break;
1083                 }
1084
1085         default:
1086                 break;
1087         }
1088
1089 //Exit:
1090         return Ret;
1091 }
1092
1093 //=========================================================================//
1094 //                                                                         //
1095 //          P R I V A T E   F U N C T I O N S                              //
1096 //                                                                         //
1097 //=========================================================================//
1098
1099 //---------------------------------------------------------------------------
1100 //
1101 // Function:    EplApiProcessEvent
1102 //
1103 // Description: processes events from event queue and forwards these to
1104 //              the application's event callback function
1105 //
1106 // Parameters:  pEplEvent_p =   pointer to event
1107 //
1108 // Returns:     tEplKernel  = errorcode
1109 //
1110 // State:
1111 //
1112 //---------------------------------------------------------------------------
1113
1114 static tEplKernel EplApiProcessEvent(tEplEvent *pEplEvent_p)
1115 {
1116         tEplKernel Ret;
1117         tEplEventError *pEventError;
1118         tEplApiEventType EventType;
1119
1120         Ret = kEplSuccessful;
1121
1122         // process event
1123         switch (pEplEvent_p->m_EventType) {
1124                 // error event
1125         case kEplEventTypeError:
1126                 {
1127                         pEventError = (tEplEventError *) pEplEvent_p->m_pArg;
1128                         switch (pEventError->m_EventSource) {
1129                                 // treat the errors from the following sources as critical
1130                         case kEplEventSourceEventk:
1131                         case kEplEventSourceEventu:
1132                         case kEplEventSourceDllk:
1133                                 {
1134                                         EventType = kEplApiEventCriticalError;
1135                                         // halt the stack by entering NMT state Off
1136                                         Ret =
1137                                             EplNmtuNmtEvent
1138                                             (kEplNmtEventCriticalError);
1139                                         break;
1140                                 }
1141
1142                                 // the other errors are just warnings
1143                         default:
1144                                 {
1145                                         EventType = kEplApiEventWarning;
1146                                         break;
1147                                 }
1148                         }
1149
1150                         // call user callback
1151                         Ret =
1152                             EplApiInstance_g.m_InitParam.m_pfnCbEvent(EventType,
1153                                                                       (tEplApiEventArg
1154                                                                        *)
1155                                                                       pEventError,
1156                                                                       EplApiInstance_g.
1157                                                                       m_InitParam.
1158                                                                       m_pEventUserArg);
1159                         // discard error from callback function, because this could generate an endless loop
1160                         Ret = kEplSuccessful;
1161                         break;
1162                 }
1163
1164                 // at present, there are no other events for this module
1165         default:
1166                 break;
1167         }
1168
1169         return Ret;
1170 }
1171
1172 //---------------------------------------------------------------------------
1173 //
1174 // Function:    EplApiCbNmtStateChange
1175 //
1176 // Description: callback function for NMT state changes
1177 //
1178 // Parameters:  NmtStateChange_p        = NMT state change event
1179 //
1180 // Returns:     tEplKernel              = error code
1181 //
1182 //
1183 // State:
1184 //
1185 //---------------------------------------------------------------------------
1186
1187 static tEplKernel EplApiCbNmtStateChange(tEplEventNmtStateChange NmtStateChange_p)
1188 {
1189         tEplKernel Ret = kEplSuccessful;
1190         u8 bNmtState;
1191         tEplApiEventArg EventArg;
1192
1193         // save NMT state in OD
1194         bNmtState = (u8) NmtStateChange_p.m_NewNmtState;
1195         Ret = EplObdWriteEntry(0x1F8C, 0, &bNmtState, 1);
1196         if (Ret != kEplSuccessful) {
1197                 goto Exit;
1198         }
1199         // do work which must be done in that state
1200         switch (NmtStateChange_p.m_NewNmtState) {
1201                 // EPL stack is not running
1202         case kEplNmtGsOff:
1203                 break;
1204
1205                 // first init of the hardware
1206         case kEplNmtGsInitialising:
1207 #if 0
1208 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDO_UDP)) != 0)
1209                 // configure SDO via UDP (i.e. bind it to the EPL ethernet interface)
1210                 Ret =
1211                     EplSdoUdpuConfig(EplApiInstance_g.m_InitParam.m_dwIpAddress,
1212                                      EPL_C_SDO_EPL_PORT);
1213                 if (Ret != kEplSuccessful) {
1214                         goto Exit;
1215                 }
1216 #endif
1217 #endif
1218
1219                 break;
1220
1221                 // init of the manufacturer-specific profile area and the
1222                 // standardised device profile area
1223         case kEplNmtGsResetApplication:
1224                 {
1225                         // reset application part of OD
1226                         Ret = EplObdAccessOdPart(kEplObdPartApp,
1227                                                  kEplObdDirLoad);
1228                         if (Ret != kEplSuccessful) {
1229                                 goto Exit;
1230                         }
1231
1232                         break;
1233                 }
1234
1235                 // init of the communication profile area
1236         case kEplNmtGsResetCommunication:
1237                 {
1238                         // reset communication part of OD
1239                         Ret = EplObdAccessOdPart(kEplObdPartGen,
1240                                                  kEplObdDirLoad);
1241
1242                         if (Ret != kEplSuccessful) {
1243                                 goto Exit;
1244                         }
1245                         // $$$ d.k.: update OD only if OD was not loaded from non-volatile memory
1246                         Ret = EplApiUpdateObd();
1247                         if (Ret != kEplSuccessful) {
1248                                 goto Exit;
1249                         }
1250
1251                         break;
1252                 }
1253
1254                 // build the configuration with infos from OD
1255         case kEplNmtGsResetConfiguration:
1256                 {
1257
1258                         Ret = EplApiUpdateDllConfig(TRUE);
1259                         if (Ret != kEplSuccessful) {
1260                                 goto Exit;
1261                         }
1262
1263                         break;
1264                 }
1265
1266                 //-----------------------------------------------------------
1267                 // CN part of the state machine
1268
1269                 // node liste for EPL-Frames and check timeout
1270         case kEplNmtCsNotActive:
1271                 {
1272                         // indicate completion of reset in NMT_ResetCmd_U8
1273                         bNmtState = (u8) kEplNmtCmdInvalidService;
1274                         Ret = EplObdWriteEntry(0x1F9E, 0, &bNmtState, 1);
1275                         if (Ret != kEplSuccessful) {
1276                                 goto Exit;
1277                         }
1278
1279                         break;
1280                 }
1281
1282                 // node process only async frames
1283         case kEplNmtCsPreOperational1:
1284                 {
1285                         break;
1286                 }
1287
1288                 // node process isochronus and asynchronus frames
1289         case kEplNmtCsPreOperational2:
1290                 {
1291                         break;
1292                 }
1293
1294                 // node should be configured und application is ready
1295         case kEplNmtCsReadyToOperate:
1296                 {
1297                         break;
1298                 }
1299
1300                 // normal work state
1301         case kEplNmtCsOperational:
1302                 {
1303                         break;
1304                 }
1305
1306                 // node stopped by MN
1307                 // -> only process asynchronus frames
1308         case kEplNmtCsStopped:
1309                 {
1310                         break;
1311                 }
1312
1313                 // no EPL cycle
1314                 // -> normal ethernet communication
1315         case kEplNmtCsBasicEthernet:
1316                 {
1317                         break;
1318                 }
1319
1320                 //-----------------------------------------------------------
1321                 // MN part of the state machine
1322
1323                 // node listens for EPL-Frames and check timeout
1324         case kEplNmtMsNotActive:
1325                 {
1326                         break;
1327                 }
1328
1329                 // node processes only async frames
1330         case kEplNmtMsPreOperational1:
1331                 {
1332                         break;
1333                 }
1334
1335                 // node processes isochronous and asynchronous frames
1336         case kEplNmtMsPreOperational2:
1337                 {
1338                         break;
1339                 }
1340
1341                 // node should be configured und application is ready
1342         case kEplNmtMsReadyToOperate:
1343                 {
1344                         break;
1345                 }
1346
1347                 // normal work state
1348         case kEplNmtMsOperational:
1349                 {
1350                         break;
1351                 }
1352
1353                 // no EPL cycle
1354                 // -> normal ethernet communication
1355         case kEplNmtMsBasicEthernet:
1356                 {
1357                         break;
1358                 }
1359
1360         default:
1361                 {
1362                         TRACE0
1363                             ("EplApiCbNmtStateChange(): unhandled NMT state\n");
1364                 }
1365         }
1366
1367 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
1368         // forward event to Led module
1369         Ret = EplLeduCbNmtStateChange(NmtStateChange_p);
1370         if (Ret != kEplSuccessful) {
1371                 goto Exit;
1372         }
1373 #endif
1374
1375 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1376         // forward event to NmtMn module
1377         Ret = EplNmtMnuCbNmtStateChange(NmtStateChange_p);
1378         if (Ret != kEplSuccessful) {
1379                 goto Exit;
1380         }
1381 #endif
1382
1383         // call user callback
1384         EventArg.m_NmtStateChange = NmtStateChange_p;
1385         Ret =
1386             EplApiInstance_g.m_InitParam.
1387             m_pfnCbEvent(kEplApiEventNmtStateChange, &EventArg,
1388                          EplApiInstance_g.m_InitParam.m_pEventUserArg);
1389
1390       Exit:
1391         return Ret;
1392 }
1393
1394 //---------------------------------------------------------------------------
1395 //
1396 // Function:    EplApiUpdateDllConfig
1397 //
1398 // Description: update configuration of DLL
1399 //
1400 // Parameters:  fUpdateIdentity_p       = TRUE, if identity must be updated
1401 //
1402 // Returns:     tEplKernel              = error code
1403 //
1404 //
1405 // State:
1406 //
1407 //---------------------------------------------------------------------------
1408
1409 static tEplKernel EplApiUpdateDllConfig(BOOL fUpdateIdentity_p)
1410 {
1411         tEplKernel Ret = kEplSuccessful;
1412         tEplDllConfigParam DllConfigParam;
1413         tEplDllIdentParam DllIdentParam;
1414         tEplObdSize ObdSize;
1415         u16 wTemp;
1416         u8 bTemp;
1417
1418         // configure Dll
1419         EPL_MEMSET(&DllConfigParam, 0, sizeof(DllConfigParam));
1420         DllConfigParam.m_uiNodeId = EplObdGetNodeId();
1421
1422         // Cycle Length (0x1006: NMT_CycleLen_U32) in [us]
1423         ObdSize = 4;
1424         Ret =
1425             EplObdReadEntry(0x1006, 0, &DllConfigParam.m_dwCycleLen, &ObdSize);
1426         if (Ret != kEplSuccessful) {
1427                 goto Exit;
1428         }
1429         // 0x1F82: NMT_FeatureFlags_U32
1430         ObdSize = 4;
1431         Ret =
1432             EplObdReadEntry(0x1F82, 0, &DllConfigParam.m_dwFeatureFlags,
1433                             &ObdSize);
1434         if (Ret != kEplSuccessful) {
1435                 goto Exit;
1436         }
1437         // d.k. There is no dependance between FeatureFlags and async-only CN
1438         DllConfigParam.m_fAsyncOnly = EplApiInstance_g.m_InitParam.m_fAsyncOnly;
1439
1440         // 0x1C14: DLL_LossOfFrameTolerance_U32 in [ns]
1441         ObdSize = 4;
1442         Ret =
1443             EplObdReadEntry(0x1C14, 0, &DllConfigParam.m_dwLossOfFrameTolerance,
1444                             &ObdSize);
1445         if (Ret != kEplSuccessful) {
1446                 goto Exit;
1447         }
1448         // 0x1F98: NMT_CycleTiming_REC
1449         // 0x1F98.1: IsochrTxMaxPayload_U16
1450         ObdSize = 2;
1451         Ret = EplObdReadEntry(0x1F98, 1, &wTemp, &ObdSize);
1452         if (Ret != kEplSuccessful) {
1453                 goto Exit;
1454         }
1455         DllConfigParam.m_uiIsochrTxMaxPayload = wTemp;
1456
1457         // 0x1F98.2: IsochrRxMaxPayload_U16
1458         ObdSize = 2;
1459         Ret = EplObdReadEntry(0x1F98, 2, &wTemp, &ObdSize);
1460         if (Ret != kEplSuccessful) {
1461                 goto Exit;
1462         }
1463         DllConfigParam.m_uiIsochrRxMaxPayload = wTemp;
1464
1465         // 0x1F98.3: PResMaxLatency_U32
1466         ObdSize = 4;
1467         Ret =
1468             EplObdReadEntry(0x1F98, 3, &DllConfigParam.m_dwPresMaxLatency,
1469                             &ObdSize);
1470         if (Ret != kEplSuccessful) {
1471                 goto Exit;
1472         }
1473         // 0x1F98.4: PReqActPayloadLimit_U16
1474         ObdSize = 2;
1475         Ret = EplObdReadEntry(0x1F98, 4, &wTemp, &ObdSize);
1476         if (Ret != kEplSuccessful) {
1477                 goto Exit;
1478         }
1479         DllConfigParam.m_uiPreqActPayloadLimit = wTemp;
1480
1481         // 0x1F98.5: PResActPayloadLimit_U16
1482         ObdSize = 2;
1483         Ret = EplObdReadEntry(0x1F98, 5, &wTemp, &ObdSize);
1484         if (Ret != kEplSuccessful) {
1485                 goto Exit;
1486         }
1487         DllConfigParam.m_uiPresActPayloadLimit = wTemp;
1488
1489         // 0x1F98.6: ASndMaxLatency_U32
1490         ObdSize = 4;
1491         Ret =
1492             EplObdReadEntry(0x1F98, 6, &DllConfigParam.m_dwAsndMaxLatency,
1493                             &ObdSize);
1494         if (Ret != kEplSuccessful) {
1495                 goto Exit;
1496         }
1497         // 0x1F98.7: MultiplCycleCnt_U8
1498         ObdSize = 1;
1499         Ret = EplObdReadEntry(0x1F98, 7, &bTemp, &ObdSize);
1500         if (Ret != kEplSuccessful) {
1501                 goto Exit;
1502         }
1503         DllConfigParam.m_uiMultiplCycleCnt = bTemp;
1504
1505         // 0x1F98.8: AsyncMTU_U16
1506         ObdSize = 2;
1507         Ret = EplObdReadEntry(0x1F98, 8, &wTemp, &ObdSize);
1508         if (Ret != kEplSuccessful) {
1509                 goto Exit;
1510         }
1511         DllConfigParam.m_uiAsyncMtu = wTemp;
1512
1513         // $$$ Prescaler
1514
1515 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1516         // 0x1F8A.1: WaitSoCPReq_U32 in [ns]
1517         ObdSize = 4;
1518         Ret =
1519             EplObdReadEntry(0x1F8A, 1, &DllConfigParam.m_dwWaitSocPreq,
1520                             &ObdSize);
1521         if (Ret != kEplSuccessful) {
1522                 goto Exit;
1523         }
1524         // 0x1F8A.2: AsyncSlotTimeout_U32 in [ns] (optional)
1525         ObdSize = 4;
1526         Ret =
1527             EplObdReadEntry(0x1F8A, 2, &DllConfigParam.m_dwAsyncSlotTimeout,
1528                             &ObdSize);
1529 /*    if(Ret != kEplSuccessful)
1530     {
1531         goto Exit;
1532     }*/
1533 #endif
1534
1535         DllConfigParam.m_uiSizeOfStruct = sizeof(DllConfigParam);
1536         Ret = EplDllkConfig(&DllConfigParam);
1537         if (Ret != kEplSuccessful) {
1538                 goto Exit;
1539         }
1540
1541         if (fUpdateIdentity_p != FALSE) {
1542                 // configure Identity
1543                 EPL_MEMSET(&DllIdentParam, 0, sizeof(DllIdentParam));
1544                 ObdSize = 4;
1545                 Ret =
1546                     EplObdReadEntry(0x1000, 0, &DllIdentParam.m_dwDeviceType,
1547                                     &ObdSize);
1548                 if (Ret != kEplSuccessful) {
1549                         goto Exit;
1550                 }
1551
1552                 ObdSize = 4;
1553                 Ret =
1554                     EplObdReadEntry(0x1018, 1, &DllIdentParam.m_dwVendorId,
1555                                     &ObdSize);
1556                 if (Ret != kEplSuccessful) {
1557                         goto Exit;
1558                 }
1559                 ObdSize = 4;
1560                 Ret =
1561                     EplObdReadEntry(0x1018, 2, &DllIdentParam.m_dwProductCode,
1562                                     &ObdSize);
1563                 if (Ret != kEplSuccessful) {
1564                         goto Exit;
1565                 }
1566                 ObdSize = 4;
1567                 Ret =
1568                     EplObdReadEntry(0x1018, 3,
1569                                     &DllIdentParam.m_dwRevisionNumber,
1570                                     &ObdSize);
1571                 if (Ret != kEplSuccessful) {
1572                         goto Exit;
1573                 }
1574                 ObdSize = 4;
1575                 Ret =
1576                     EplObdReadEntry(0x1018, 4, &DllIdentParam.m_dwSerialNumber,
1577                                     &ObdSize);
1578                 if (Ret != kEplSuccessful) {
1579                         goto Exit;
1580                 }
1581
1582                 DllIdentParam.m_dwIpAddress =
1583                     EplApiInstance_g.m_InitParam.m_dwIpAddress;
1584                 DllIdentParam.m_dwSubnetMask =
1585                     EplApiInstance_g.m_InitParam.m_dwSubnetMask;
1586                 EPL_MEMCPY(DllIdentParam.m_sHostname,
1587                            EplApiInstance_g.m_InitParam.m_sHostname,
1588                            sizeof(DllIdentParam.m_sHostname));
1589
1590                 ObdSize = 4;
1591                 Ret =
1592                     EplObdReadEntry(0x1020, 1,
1593                                     &DllIdentParam.m_dwVerifyConfigurationDate,
1594                                     &ObdSize);
1595                 // ignore any error, because this object is optional
1596
1597                 ObdSize = 4;
1598                 Ret =
1599                     EplObdReadEntry(0x1020, 2,
1600                                     &DllIdentParam.m_dwVerifyConfigurationTime,
1601                                     &ObdSize);
1602                 // ignore any error, because this object is optional
1603
1604                 // $$$ d.k.: fill rest of ident structure
1605
1606                 DllIdentParam.m_uiSizeOfStruct = sizeof(DllIdentParam);
1607                 Ret = EplDllkSetIdentity(&DllIdentParam);
1608                 if (Ret != kEplSuccessful) {
1609                         goto Exit;
1610                 }
1611         }
1612
1613       Exit:
1614         return Ret;
1615 }
1616
1617 //---------------------------------------------------------------------------
1618 //
1619 // Function:    EplApiUpdateObd
1620 //
1621 // Description: update OD from init param
1622 //
1623 // Parameters:  (none)
1624 //
1625 // Returns:     tEplKernel              = error code
1626 //
1627 //
1628 // State:
1629 //
1630 //---------------------------------------------------------------------------
1631
1632 static tEplKernel EplApiUpdateObd(void)
1633 {
1634         tEplKernel Ret = kEplSuccessful;
1635         u16 wTemp;
1636         u8 bTemp;
1637
1638         // set node id in OD
1639         Ret = EplObdSetNodeId(EplApiInstance_g.m_InitParam.m_uiNodeId,  // node id
1640                               kEplObdNodeIdHardware);   // set by hardware
1641         if (Ret != kEplSuccessful) {
1642                 goto Exit;
1643         }
1644
1645         if (EplApiInstance_g.m_InitParam.m_dwCycleLen != -1) {
1646                 Ret =
1647                     EplObdWriteEntry(0x1006, 0,
1648                                      &EplApiInstance_g.m_InitParam.m_dwCycleLen,
1649                                      4);
1650 /*    if(Ret != kEplSuccessful)
1651     {
1652         goto Exit;
1653     }*/
1654         }
1655
1656         if (EplApiInstance_g.m_InitParam.m_dwLossOfFrameTolerance != -1) {
1657                 Ret =
1658                     EplObdWriteEntry(0x1C14, 0,
1659                                      &EplApiInstance_g.m_InitParam.
1660                                      m_dwLossOfFrameTolerance, 4);
1661                 /*        if(Ret != kEplSuccessful)
1662                    {
1663                    goto Exit;
1664                    } */
1665         }
1666         // d.k. There is no dependance between FeatureFlags and async-only CN.
1667         if (EplApiInstance_g.m_InitParam.m_dwFeatureFlags != -1) {
1668                 Ret =
1669                     EplObdWriteEntry(0x1F82, 0,
1670                                      &EplApiInstance_g.m_InitParam.
1671                                      m_dwFeatureFlags, 4);
1672                 /*    if(Ret != kEplSuccessful)
1673                    {
1674                    goto Exit;
1675                    } */
1676         }
1677
1678         wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrTxMaxPayload;
1679         Ret = EplObdWriteEntry(0x1F98, 1, &wTemp, 2);
1680 /*    if(Ret != kEplSuccessful)
1681     {
1682         goto Exit;
1683     }*/
1684
1685         wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiIsochrRxMaxPayload;
1686         Ret = EplObdWriteEntry(0x1F98, 2, &wTemp, 2);
1687 /*    if(Ret != kEplSuccessful)
1688     {
1689         goto Exit;
1690     }*/
1691
1692         Ret =
1693             EplObdWriteEntry(0x1F98, 3,
1694                              &EplApiInstance_g.m_InitParam.m_dwPresMaxLatency,
1695                              4);
1696 /*    if(Ret != kEplSuccessful)
1697     {
1698         goto Exit;
1699     }*/
1700
1701         if (EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit <=
1702             EPL_C_DLL_ISOCHR_MAX_PAYL) {
1703                 wTemp =
1704                     (u16) EplApiInstance_g.m_InitParam.m_uiPreqActPayloadLimit;
1705                 Ret = EplObdWriteEntry(0x1F98, 4, &wTemp, 2);
1706 /*    if(Ret != kEplSuccessful)
1707     {
1708         goto Exit;
1709     }*/
1710         }
1711
1712         if (EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit <=
1713             EPL_C_DLL_ISOCHR_MAX_PAYL) {
1714                 wTemp =
1715                     (u16) EplApiInstance_g.m_InitParam.m_uiPresActPayloadLimit;
1716                 Ret = EplObdWriteEntry(0x1F98, 5, &wTemp, 2);
1717 /*    if(Ret != kEplSuccessful)
1718     {
1719         goto Exit;
1720     }*/
1721         }
1722
1723         Ret =
1724             EplObdWriteEntry(0x1F98, 6,
1725                              &EplApiInstance_g.m_InitParam.m_dwAsndMaxLatency,
1726                              4);
1727 /*    if(Ret != kEplSuccessful)
1728     {
1729         goto Exit;
1730     }*/
1731
1732         if (EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt <= 0xFF) {
1733                 bTemp = (u8) EplApiInstance_g.m_InitParam.m_uiMultiplCycleCnt;
1734                 Ret = EplObdWriteEntry(0x1F98, 7, &bTemp, 1);
1735 /*    if(Ret != kEplSuccessful)
1736     {
1737         goto Exit;
1738     }*/
1739         }
1740
1741         if (EplApiInstance_g.m_InitParam.m_uiAsyncMtu <=
1742             EPL_C_DLL_MAX_ASYNC_MTU) {
1743                 wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiAsyncMtu;
1744                 Ret = EplObdWriteEntry(0x1F98, 8, &wTemp, 2);
1745 /*    if(Ret != kEplSuccessful)
1746     {
1747         goto Exit;
1748     }*/
1749         }
1750
1751         if (EplApiInstance_g.m_InitParam.m_uiPrescaler <= 1000) {
1752                 wTemp = (u16) EplApiInstance_g.m_InitParam.m_uiPrescaler;
1753                 Ret = EplObdWriteEntry(0x1F98, 9, &wTemp, 2);
1754                 // ignore return code
1755                 Ret = kEplSuccessful;
1756         }
1757 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1758         if (EplApiInstance_g.m_InitParam.m_dwWaitSocPreq != -1) {
1759                 Ret =
1760                     EplObdWriteEntry(0x1F8A, 1,
1761                                      &EplApiInstance_g.m_InitParam.
1762                                      m_dwWaitSocPreq, 4);
1763                 /*        if(Ret != kEplSuccessful)
1764                    {
1765                    goto Exit;
1766                    } */
1767         }
1768
1769         if ((EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != 0)
1770             && (EplApiInstance_g.m_InitParam.m_dwAsyncSlotTimeout != -1)) {
1771                 Ret =
1772                     EplObdWriteEntry(0x1F8A, 2,
1773                                      &EplApiInstance_g.m_InitParam.
1774                                      m_dwAsyncSlotTimeout, 4);
1775                 /*        if(Ret != kEplSuccessful)
1776                    {
1777                    goto Exit;
1778                    } */
1779         }
1780 #endif
1781
1782         // configure Identity
1783         if (EplApiInstance_g.m_InitParam.m_dwDeviceType != -1) {
1784                 Ret =
1785                     EplObdWriteEntry(0x1000, 0,
1786                                      &EplApiInstance_g.m_InitParam.
1787                                      m_dwDeviceType, 4);
1788 /*        if(Ret != kEplSuccessful)
1789         {
1790             goto Exit;
1791         }*/
1792         }
1793
1794         if (EplApiInstance_g.m_InitParam.m_dwVendorId != -1) {
1795                 Ret =
1796                     EplObdWriteEntry(0x1018, 1,
1797                                      &EplApiInstance_g.m_InitParam.m_dwVendorId,
1798                                      4);
1799 /*        if(Ret != kEplSuccessful)
1800         {
1801             goto Exit;
1802         }*/
1803         }
1804
1805         if (EplApiInstance_g.m_InitParam.m_dwProductCode != -1) {
1806                 Ret =
1807                     EplObdWriteEntry(0x1018, 2,
1808                                      &EplApiInstance_g.m_InitParam.
1809                                      m_dwProductCode, 4);
1810 /*        if(Ret != kEplSuccessful)
1811         {
1812             goto Exit;
1813         }*/
1814         }
1815
1816         if (EplApiInstance_g.m_InitParam.m_dwRevisionNumber != -1) {
1817                 Ret =
1818                     EplObdWriteEntry(0x1018, 3,
1819                                      &EplApiInstance_g.m_InitParam.
1820                                      m_dwRevisionNumber, 4);
1821 /*        if(Ret != kEplSuccessful)
1822         {
1823             goto Exit;
1824         }*/
1825         }
1826
1827         if (EplApiInstance_g.m_InitParam.m_dwSerialNumber != -1) {
1828                 Ret =
1829                     EplObdWriteEntry(0x1018, 4,
1830                                      &EplApiInstance_g.m_InitParam.
1831                                      m_dwSerialNumber, 4);
1832 /*        if(Ret != kEplSuccessful)
1833         {
1834             goto Exit;
1835         }*/
1836         }
1837
1838         if (EplApiInstance_g.m_InitParam.m_pszDevName != NULL) {
1839                 // write Device Name (0x1008)
1840                 Ret =
1841                     EplObdWriteEntry(0x1008, 0,
1842                                      (void *)EplApiInstance_g.
1843                                      m_InitParam.m_pszDevName,
1844                                      (tEplObdSize) strlen(EplApiInstance_g.
1845                                                           m_InitParam.
1846                                                           m_pszDevName));
1847 /*        if (Ret != kEplSuccessful)
1848         {
1849             goto Exit;
1850         }*/
1851         }
1852
1853         if (EplApiInstance_g.m_InitParam.m_pszHwVersion != NULL) {
1854                 // write Hardware version (0x1009)
1855                 Ret =
1856                     EplObdWriteEntry(0x1009, 0,
1857                                      (void *)EplApiInstance_g.
1858                                      m_InitParam.m_pszHwVersion,
1859                                      (tEplObdSize) strlen(EplApiInstance_g.
1860                                                           m_InitParam.
1861                                                           m_pszHwVersion));
1862 /*        if (Ret != kEplSuccessful)
1863         {
1864             goto Exit;
1865         }*/
1866         }
1867
1868         if (EplApiInstance_g.m_InitParam.m_pszSwVersion != NULL) {
1869                 // write Software version (0x100A)
1870                 Ret =
1871                     EplObdWriteEntry(0x100A, 0,
1872                                      (void *)EplApiInstance_g.
1873                                      m_InitParam.m_pszSwVersion,
1874                                      (tEplObdSize) strlen(EplApiInstance_g.
1875                                                           m_InitParam.
1876                                                           m_pszSwVersion));
1877 /*        if (Ret != kEplSuccessful)
1878         {
1879             goto Exit;
1880         }*/
1881         }
1882
1883       Exit:
1884         return Ret;
1885 }
1886
1887 //---------------------------------------------------------------------------
1888 //
1889 // Function:    EplApiCbSdoCon
1890 //
1891 // Description: callback function for SDO transfers
1892 //
1893 // Parameters:  pSdoComFinished_p       = SDO parameter
1894 //
1895 // Returns:     tEplKernel              = error code
1896 //
1897 //
1898 // State:
1899 //
1900 //---------------------------------------------------------------------------
1901
1902 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_SDOC)) != 0)
1903 static tEplKernel EplApiCbSdoCon(tEplSdoComFinished *pSdoComFinished_p)
1904 {
1905         tEplKernel Ret;
1906         tEplApiEventArg EventArg;
1907
1908         Ret = kEplSuccessful;
1909
1910         // call user callback
1911         EventArg.m_Sdo = *pSdoComFinished_p;
1912         Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventSdo,
1913                                                         &EventArg,
1914                                                         EplApiInstance_g.
1915                                                         m_InitParam.
1916                                                         m_pEventUserArg);
1917
1918         return Ret;
1919
1920 }
1921 #endif
1922
1923 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
1924
1925 //---------------------------------------------------------------------------
1926 //
1927 // Function:    EplApiCbNodeEvent
1928 //
1929 // Description: callback function for node events
1930 //
1931 // Parameters:  uiNodeId_p              = node ID of the CN
1932 //              NodeEvent_p             = event from the specified CN
1933 //              NmtState_p              = current NMT state of the CN
1934 //              wErrorCode_p            = EPL error code if NodeEvent_p==kEplNmtNodeEventError
1935 //              fMandatory_p            = flag if CN is mandatory
1936 //
1937 // Returns:     tEplKernel              = error code
1938 //
1939 //
1940 // State:
1941 //
1942 //---------------------------------------------------------------------------
1943
1944 static tEplKernel EplApiCbNodeEvent(unsigned int uiNodeId_p,
1945                                     tEplNmtNodeEvent NodeEvent_p,
1946                                     tEplNmtState NmtState_p,
1947                                     u16 wErrorCode_p, BOOL fMandatory_p)
1948 {
1949         tEplKernel Ret;
1950         tEplApiEventArg EventArg;
1951
1952         Ret = kEplSuccessful;
1953
1954         // call user callback
1955         EventArg.m_Node.m_uiNodeId = uiNodeId_p;
1956         EventArg.m_Node.m_NodeEvent = NodeEvent_p;
1957         EventArg.m_Node.m_NmtState = NmtState_p;
1958         EventArg.m_Node.m_wErrorCode = wErrorCode_p;
1959         EventArg.m_Node.m_fMandatory = fMandatory_p;
1960
1961         Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventNode,
1962                                                         &EventArg,
1963                                                         EplApiInstance_g.
1964                                                         m_InitParam.
1965                                                         m_pEventUserArg);
1966
1967         return Ret;
1968
1969 }
1970
1971 //---------------------------------------------------------------------------
1972 //
1973 // Function:    EplApiCbBootEvent
1974 //
1975 // Description: callback function for boot events
1976 //
1977 // Parameters:  BootEvent_p             = event from the boot-up process
1978 //              NmtState_p              = current local NMT state
1979 //              wErrorCode_p            = EPL error code if BootEvent_p==kEplNmtBootEventError
1980 //
1981 // Returns:     tEplKernel              = error code
1982 //
1983 //
1984 // State:
1985 //
1986 //---------------------------------------------------------------------------
1987
1988 static tEplKernel EplApiCbBootEvent(tEplNmtBootEvent BootEvent_p,
1989                                     tEplNmtState NmtState_p,
1990                                     u16 wErrorCode_p)
1991 {
1992         tEplKernel Ret;
1993         tEplApiEventArg EventArg;
1994
1995         Ret = kEplSuccessful;
1996
1997         // call user callback
1998         EventArg.m_Boot.m_BootEvent = BootEvent_p;
1999         EventArg.m_Boot.m_NmtState = NmtState_p;
2000         EventArg.m_Boot.m_wErrorCode = wErrorCode_p;
2001
2002         Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventBoot,
2003                                                         &EventArg,
2004                                                         EplApiInstance_g.
2005                                                         m_InitParam.
2006                                                         m_pEventUserArg);
2007
2008         return Ret;
2009
2010 }
2011
2012 #endif // (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_NMT_MN)) != 0)
2013
2014 #if (((EPL_MODULE_INTEGRATION) & (EPL_MODULE_LEDU)) != 0)
2015
2016 //---------------------------------------------------------------------------
2017 //
2018 // Function:    EplApiCbLedStateChange
2019 //
2020 // Description: callback function for LED change events.
2021 //
2022 // Parameters:  LedType_p       = type of LED
2023 //              fOn_p           = state of LED
2024 //
2025 // Returns:     tEplKernel      = errorcode
2026 //
2027 // State:
2028 //
2029 //---------------------------------------------------------------------------
2030
2031 static tEplKernel EplApiCbLedStateChange(tEplLedType LedType_p, BOOL fOn_p)
2032 {
2033         tEplKernel Ret;
2034         tEplApiEventArg EventArg;
2035
2036         Ret = kEplSuccessful;
2037
2038         // call user callback
2039         EventArg.m_Led.m_LedType = LedType_p;
2040         EventArg.m_Led.m_fOn = fOn_p;
2041
2042         Ret = EplApiInstance_g.m_InitParam.m_pfnCbEvent(kEplApiEventLed,
2043                                                         &EventArg,
2044                                                         EplApiInstance_g.
2045                                                         m_InitParam.
2046                                                         m_pEventUserArg);
2047
2048         return Ret;
2049
2050 }
2051
2052 #endif
2053
2054 // EOF