Staging: add epl stack
[platform/kernel/linux-starfive.git] / drivers / staging / epl / EplObd.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 api function of EplOBD-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: EplObd.c,v $
53
54                 $Author: D.Krueger $
55
56                 $Revision: 1.12 $  $Date: 2008/10/17 15:32:32 $
57
58                 $State: Exp $
59
60                 Build Environment:
61                 Microsoft VC7
62
63   -------------------------------------------------------------------------
64
65   Revision History:
66
67   2006/06/02 k.t.:   start of the implementation, version 1.00
68                      ->based on CANopen OBD-Modul
69
70 ****************************************************************************/
71
72 #include "EplInc.h"
73 #include "kernel/EplObdk.h"         // function prototyps of the EplOBD-Modul
74
75 #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
76
77 /***************************************************************************/
78 /*                                                                         */
79 /*                                                                         */
80 /*          G L O B A L   D E F I N I T I O N S                            */
81 /*                                                                         */
82 /*                                                                         */
83 /***************************************************************************/
84
85 //---------------------------------------------------------------------------
86 // const defines
87 //---------------------------------------------------------------------------
88
89 // float definitions and macros
90 #define _SHIFTED_EXPONENT_MASK_SP   0xff
91 #define _BIAS_SP                    126
92 #define T_SP                        23
93 #define EXPONENT_DENORM_SP          (-_BIAS_SP)
94 #define BASE_TO_THE_T_SP            ((float) 8388608.0)
95 #define GET_EXPONENT_SP(x)          ((((x) >> T_SP) & _SHIFTED_EXPONENT_MASK_SP) - _BIAS_SP)
96
97
98 //---------------------------------------------------------------------------
99 // local types
100 //---------------------------------------------------------------------------
101
102 // struct for instance table
103 INSTANCE_TYPE_BEGIN
104
105     EPL_MCO_DECL_INSTANCE_MEMBER ()
106
107     STATIC      tEplObdInitParam               INST_FAR    m_ObdInitParam;
108     STATIC      tEplObdStoreLoadObjCallback    INST_NEAR   m_fpStoreLoadObjCallback;
109
110 INSTANCE_TYPE_END
111
112 // decomposition of float
113 typedef union
114 {
115     tEplObdReal32   m_flRealPart;
116     int             m_nIntegerPart;
117
118 } tEplObdRealParts;
119
120
121 //---------------------------------------------------------------------------
122 // modul globale vars
123 //---------------------------------------------------------------------------
124
125 // This macro replace the unspecific pointer to an instance through
126 // the modul specific type for the local instance table. This macro
127 // must defined in each modul.
128 //#define tEplPtrInstance             tEplInstanceInfo MEM*
129
130 EPL_MCO_DECL_INSTANCE_VAR ()
131
132 BYTE MEM            abEplObdTrashObject_g[8];
133
134
135 //---------------------------------------------------------------------------
136 // local function prototypes
137 //---------------------------------------------------------------------------
138
139 EPL_MCO_DEFINE_INSTANCE_FCT ()
140
141 static tEplKernel EplObdCallObjectCallback (EPL_MCO_DECL_INSTANCE_PTR_
142     tEplObdCallback     fpCallback_p,
143     tEplObdCbParam MEM* pCbParam_p);
144
145 static tEplObdSize EplObdGetDataSizeIntern (tEplObdSubEntryPtr pSubIndexEntry_p);
146
147 static tEplObdSize EplObdGetStrLen (void* pObjData_p,
148                                     tEplObdSize ObjLen_p,
149                                     tEplObdType ObjType_p);
150
151 #if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
152 static tEplKernel EplObdCheckObjectRange (
153             tEplObdSubEntryPtr pSubindexEntry_p,
154             void * pData_p);
155 #endif
156
157 static tEplKernel EplObdGetVarEntry (
158             tEplObdSubEntryPtr    pSubindexEntry_p,
159             tEplObdVarEntry MEM** ppVarEntry_p);
160
161 static tEplKernel  EplObdGetEntry (EPL_MCO_DECL_INSTANCE_PTR_
162             unsigned int          uiIndex_p,
163             unsigned int          uiSubindex_p,
164             tEplObdEntryPtr*      ppObdEntry_p,
165             tEplObdSubEntryPtr*   ppObdSubEntry_p);
166
167 static tEplObdSize EplObdGetObjectSize (tEplObdSubEntryPtr pSubIndexEntry_p);
168
169 static tEplKernel EplObdGetIndexIntern (
170     tEplObdInitParam MEM*     pInitParam_p,
171     unsigned int              uiIndex_p,
172     tEplObdEntryPtr*          ppObdEntry_p);
173
174 static tEplKernel EplObdGetSubindexIntern (
175     tEplObdEntryPtr           pObdEntry_p,
176     unsigned int              uiSubIndex_p,
177     tEplObdSubEntryPtr*       ppObdSubEntry_p);
178
179 static tEplKernel EplObdAccessOdPartIntern (EPL_MCO_DECL_INSTANCE_PTR_
180                             tEplObdPart     CurrentOdPart_p,
181                             tEplObdEntryPtr pObdEnty_p,
182                             tEplObdDir      Direction_p);
183
184 static void *   EplObdGetObjectDefaultPtr (tEplObdSubEntryPtr pSubIndexEntry_p);
185 static void MEM*       EplObdGetObjectCurrentPtr (tEplObdSubEntryPtr pSubIndexEntry_p);
186
187 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
188
189     static tEplKernel EplObdCallStoreCallback (EPL_MCO_DECL_INSTANCE_PTR_
190         tEplObdCbStoreParam MEM* pCbStoreParam_p);
191
192 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
193
194 static void EplObdCopyObjectData (
195                         void MEM*       pDstData_p,
196                         void *   pSrcData_p,
197                         tEplObdSize     ObjSize_p,
198                         tEplObdType     ObjType_p);
199
200 void * EplObdGetObjectDataPtrIntern (tEplObdSubEntryPtr pSubindexEntry_p);
201
202 static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
203                                         BOOL*         pfEntryNumerical_p);
204
205 static tEplKernel PUBLIC EplObdWriteEntryPre (EPL_MCO_DECL_INSTANCE_PTR_
206     unsigned int  uiIndex_p,
207     unsigned int  uiSubIndex_p,
208     void * pSrcData_p,
209     void** ppDstData_p,
210     tEplObdSize   Size_p,
211     tEplObdEntryPtr*        ppObdEntry_p,
212     tEplObdSubEntryPtr*     ppSubEntry_p,
213     tEplObdCbParam MEM*     pCbParam_p,
214     tEplObdSize*  pObdSize_p);
215
216 static tEplKernel PUBLIC EplObdWriteEntryPost (EPL_MCO_DECL_INSTANCE_PTR_
217     tEplObdEntryPtr         pObdEntry_p,
218     tEplObdSubEntryPtr      pSubEntry_p,
219     tEplObdCbParam MEM*     pCbParam_p,
220     void * pSrcData_p,
221     void * pDstData_p,
222     tEplObdSize   ObdSize_p);
223
224
225
226 //=========================================================================//
227 //                                                                         //
228 //          P U B L I C   F U N C T I O N S                                //
229 //                                                                         //
230 //=========================================================================//
231
232 //---------------------------------------------------------------------------
233 //
234 // Function:    EplObdInit()
235 //
236 // Description: initializes the first instance
237 //
238 // Parameters:  pInitParam_p    = init parameter
239 //
240 // Return:      tEplKernel      =   errorcode
241 //
242 // State:
243 //
244 //---------------------------------------------------------------------------
245
246 EPLDLLEXPORT tEplKernel PUBLIC EplObdInit (EPL_MCO_DECL_PTR_INSTANCE_PTR_
247                     tEplObdInitParam MEM* pInitParam_p)
248 {
249
250 tEplKernel Ret;
251 EPL_MCO_DELETE_INSTANCE_TABLE ();
252
253     if (pInitParam_p == NULL)
254     {
255         Ret = kEplSuccessful;
256         goto Exit;
257     }
258
259     Ret = EplObdAddInstance (EPL_MCO_PTR_INSTANCE_PTR_
260         pInitParam_p);
261
262 Exit:
263     return Ret;
264
265 }
266
267
268 //---------------------------------------------------------------------------
269 //
270 // Function:    EplObdAddInstance()
271 //
272 // Description: adds a new instance
273 //
274 // Parameters:  pInitParam_p
275 //
276 // Return:      tEplKernel
277 //
278 // State:
279 //
280 //---------------------------------------------------------------------------
281
282 EPLDLLEXPORT tEplKernel PUBLIC EplObdAddInstance (EPL_MCO_DECL_PTR_INSTANCE_PTR_
283     tEplObdInitParam MEM* pInitParam_p)
284 {
285
286 EPL_MCO_DECL_INSTANCE_PTR_LOCAL
287 tEplKernel Ret;
288
289     // check if pointer to instance pointer valid
290     // get free instance and set the globale instance pointer
291     // set also the instance addr to parameterlist
292     EPL_MCO_CHECK_PTR_INSTANCE_PTR ();
293     EPL_MCO_GET_FREE_INSTANCE_PTR ();
294     EPL_MCO_SET_PTR_INSTANCE_PTR ();
295
296     // save init parameters
297     EPL_MEMCPY (&EPL_MCO_GLB_VAR (m_ObdInitParam), pInitParam_p, sizeof (tEplObdInitParam));
298
299     // clear callback function for command LOAD and STORE
300     EPL_MCO_GLB_VAR (m_fpStoreLoadObjCallback) = NULL;
301
302     // sign instance as used
303     EPL_MCO_WRITE_INSTANCE_STATE (kStateUsed);
304
305     // initialize object dictionary
306     // so all all VarEntries will be initialized to trash object and default values will be set to current data
307     Ret = EplObdAccessOdPart (EPL_MCO_INSTANCE_PTR_
308         kEplObdPartAll, kEplObdDirInit);
309
310     return Ret;
311
312 }
313
314
315 //---------------------------------------------------------------------------
316 //
317 // Function:    EplObdDeleteInstance()
318 //
319 // Description: delete instance
320 //
321 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR
322 //
323 // Return:      tEplKernel
324 //
325 // State:
326 //
327 //---------------------------------------------------------------------------
328 #if (EPL_USE_DELETEINST_FUNC != FALSE)
329 EPLDLLEXPORT tEplKernel PUBLIC EplObdDeleteInstance (EPL_MCO_DECL_INSTANCE_PTR)
330 {
331     // check for all API function if instance is valid
332     EPL_MCO_CHECK_INSTANCE_STATE ();
333
334     // sign instance as unused
335     EPL_MCO_WRITE_INSTANCE_STATE (kStateUnused);
336
337     return kEplSuccessful;
338
339 }
340 #endif // (EPL_USE_DELETEINST_FUNC != FALSE)
341
342
343 //---------------------------------------------------------------------------
344 //
345 // Function:    EplObdWriteEntry()
346 //
347 // Description: Function writes data to an OBD entry. Strings
348 //              are stored with added '\0' character.
349 //
350 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
351 //              uiIndex_p       =   Index of the OD entry
352 //              uiSubIndex_p    =   Subindex of the OD Entry
353 //              pSrcData_p      =   Pointer to the data to write
354 //              Size_p          =   Size of the data in Byte
355 //
356 // Return:      tEplKernel      =   Errorcode
357 //
358 //
359 // State:
360 //
361 //---------------------------------------------------------------------------
362
363 EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntry (EPL_MCO_DECL_INSTANCE_PTR_
364     unsigned int  uiIndex_p,
365     unsigned int  uiSubIndex_p,
366     void * pSrcData_p,
367     tEplObdSize   Size_p)
368 {
369
370 tEplKernel              Ret;
371 tEplObdEntryPtr         pObdEntry;
372 tEplObdSubEntryPtr      pSubEntry;
373 tEplObdCbParam MEM      CbParam;
374 void MEM*               pDstData;
375 tEplObdSize             ObdSize;
376
377
378     Ret = EplObdWriteEntryPre (EPL_MCO_INSTANCE_PTR_
379                                uiIndex_p,
380                                uiSubIndex_p,
381                                pSrcData_p,
382                                &pDstData,
383                                Size_p,
384                                &pObdEntry,
385                                &pSubEntry,
386                                &CbParam,
387                                &ObdSize);
388     if (Ret != kEplSuccessful)
389     {
390         goto Exit;
391     }
392
393     Ret = EplObdWriteEntryPost (EPL_MCO_INSTANCE_PTR_
394                                 pObdEntry,
395                                 pSubEntry,
396                                 &CbParam,
397                                 pSrcData_p,
398                                 pDstData,
399                                 ObdSize);
400     if (Ret != kEplSuccessful)
401     {
402         goto Exit;
403     }
404
405 Exit:
406
407     return Ret;
408
409 }
410
411
412 //---------------------------------------------------------------------------
413 //
414 // Function:    EplObdReadEntry()
415 //
416 // Description: The function reads an object entry. The application
417 //              can always read the data even if attrib kEplObdAccRead
418 //              is not set. The attrib is only checked up for SDO transfer.
419 //
420 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
421 //              uiIndex_p       = Index oof the OD entry to read
422 //              uiSubIndex_p    = Subindex to read
423 //              pDstData_p      = pointer to the buffer for data
424 //              Offset_p        = offset in data for read access
425 //              pSize_p         = IN: Size of the buffer
426 //                                OUT: number of readed Bytes
427 //
428 // Return:      tEplKernel
429 //
430 // State:
431 //
432 //---------------------------------------------------------------------------
433
434 EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntry (EPL_MCO_DECL_INSTANCE_PTR_
435                                                 unsigned int        uiIndex_p,
436                                                 unsigned int        uiSubIndex_p,
437                                                 void *              pDstData_p,
438                                                 tEplObdSize *       pSize_p)
439 {
440
441 tEplKernel                      Ret;
442 tEplObdEntryPtr                 pObdEntry;
443 tEplObdSubEntryPtr              pSubEntry;
444 tEplObdCbParam  MEM             CbParam;
445 void *                          pSrcData;
446 tEplObdSize                     ObdSize;
447
448     // check for all API function if instance is valid
449     EPL_MCO_CHECK_INSTANCE_STATE ();
450
451     ASSERT (pDstData_p != NULL);
452     ASSERT (pSize_p != NULL);
453
454     // get address of index and subindex entry
455     Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_
456         uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
457     if (Ret != kEplSuccessful)
458     {
459         goto Exit;
460     }
461
462     // get pointer to object data
463      pSrcData = EplObdGetObjectDataPtrIntern (pSubEntry);
464
465     // check source pointer
466     if (pSrcData == NULL)
467     {
468         Ret = kEplObdReadViolation;
469         goto Exit;
470     }
471
472     //------------------------------------------------------------------------
473     // address of source data to structure of callback parameters
474     // so callback function can change this data before reading
475     CbParam.m_uiIndex   = uiIndex_p;
476     CbParam.m_uiSubIndex= uiSubIndex_p;
477     CbParam.m_pArg      = pSrcData;
478     CbParam.m_ObdEvent  = kEplObdEvPreRead;
479     Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
480         pObdEntry->m_fpCallback, &CbParam);
481     if (Ret != kEplSuccessful)
482     {
483         goto Exit;
484     }
485
486     // get size of data and check if application has reserved enough memory
487     ObdSize = EplObdGetDataSizeIntern (pSubEntry);
488     // check if offset given and calc correct number of bytes to read
489     if (*pSize_p < ObdSize)
490     {
491         Ret = kEplObdValueLengthError;
492         goto Exit;
493     }
494
495     // read value from object
496     EPL_MEMCPY (pDstData_p, pSrcData, ObdSize);
497     *pSize_p = ObdSize;
498
499     // write address of destination data to structure of callback parameters
500     // so callback function can change this data after reading
501     CbParam.m_pArg     = pDstData_p;
502     CbParam.m_ObdEvent = kEplObdEvPostRead;
503     Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
504         pObdEntry->m_fpCallback, &CbParam);
505
506 Exit:
507
508     return Ret;
509
510 }
511
512 //---------------------------------------------------------------------------
513 //
514 // Function:    EplObdAccessOdPart()
515 //
516 // Description: restores default values of one part of OD
517 //
518 // Parameters:  ObdPart_p
519 //              Direction_p
520 //
521 // Return:      tEplKernel
522 //
523 // State:
524 //
525 //---------------------------------------------------------------------------
526
527 EPLDLLEXPORT tEplKernel PUBLIC EplObdAccessOdPart (EPL_MCO_DECL_INSTANCE_PTR_
528     tEplObdPart ObdPart_p,
529     tEplObdDir  Direction_p)
530 {
531
532 tEplKernel      Ret = kEplSuccessful;
533 BOOL            fPartFount;
534 tEplObdEntryPtr pObdEntry;
535
536     // check for all API function if instance is valid
537     EPL_MCO_CHECK_INSTANCE_STATE ();
538
539     //  part always has to be unequal to NULL
540     pObdEntry = EPL_MCO_GLB_VAR (m_ObdInitParam.m_pPart);
541     ASSERTMSG (pObdEntry != NULL, "EplObdAccessOdPart(): no  OD part is defined!\n");
542
543     // if ObdPart_p is not valid fPartFound keeps FALSE and function returns kEplObdIllegalPart
544     fPartFount = FALSE;
545
546     // access to  part
547     if ((ObdPart_p & kEplObdPartGen) != 0)
548     {
549         fPartFount = TRUE;
550
551         Ret = EplObdAccessOdPartIntern (EPL_MCO_INSTANCE_PTR_
552             kEplObdPartGen, pObdEntry, Direction_p);
553         if (Ret != kEplSuccessful)
554         {
555             goto Exit;
556         }
557     }
558
559     // access to manufacturer part
560     pObdEntry = EPL_MCO_GLB_VAR (m_ObdInitParam.m_pManufacturerPart);
561
562     if ( ((ObdPart_p & kEplObdPartMan) != 0) &&
563          (pObdEntry != NULL) )
564     {
565         fPartFount = TRUE;
566
567         Ret = EplObdAccessOdPartIntern (EPL_MCO_INSTANCE_PTR_
568             kEplObdPartMan, pObdEntry, Direction_p);
569         if (Ret != kEplSuccessful)
570         {
571             goto Exit;
572         }
573     }
574
575     // access to device part
576     pObdEntry = EPL_MCO_GLB_VAR (m_ObdInitParam.m_pDevicePart);
577
578     if ( ((ObdPart_p & kEplObdPartDev) != 0) &&
579          (pObdEntry != NULL) )
580     {
581         fPartFount = TRUE;
582
583         Ret = EplObdAccessOdPartIntern (EPL_MCO_INSTANCE_PTR_
584             kEplObdPartDev, pObdEntry, Direction_p);
585         if (Ret != kEplSuccessful)
586         {
587             goto Exit;
588         }
589     }
590
591     #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
592     {
593         // access to user part
594         pObdEntry = EPL_MCO_GLB_VAR (m_ObdInitParam.m_pUserPart);
595
596         if ( ((ObdPart_p & kEplObdPartUsr) != 0) &&
597              (pObdEntry != NULL) )
598         {
599             fPartFount = TRUE;
600
601             Ret = EplObdAccessOdPartIntern (EPL_MCO_INSTANCE_PTR_
602                 kEplObdPartUsr, pObdEntry, Direction_p);
603             if (Ret != kEplSuccessful)
604             {
605                 goto Exit;
606             }
607         }
608     }
609     #endif
610
611     // no access to an OD part was done? illegal OD part was specified!
612     if (fPartFount == FALSE)
613     {
614         Ret = kEplObdIllegalPart;
615     }
616
617 Exit:
618
619     return Ret;
620
621 }
622
623
624 //---------------------------------------------------------------------------
625 //
626 // Function:    EplObdDefineVar()
627 //
628 // Description: defines a variable in OD
629 //
630 // Parameters:  pEplVarParam_p
631 //
632 // Return:      tEplKernel
633 //
634 // State:
635 //
636 //---------------------------------------------------------------------------
637
638 EPLDLLEXPORT tEplKernel PUBLIC EplObdDefineVar (EPL_MCO_DECL_INSTANCE_PTR_
639     tEplVarParam MEM* pVarParam_p)
640 {
641
642 tEplKernel              Ret;
643 tEplObdVarEntry MEM*    pVarEntry;
644 tEplVarParamValid       VarValid;
645 tEplObdSubEntryPtr      pSubindexEntry;
646
647     // check for all API function if instance is valid
648     EPL_MCO_CHECK_INSTANCE_STATE ();
649
650     ASSERT (pVarParam_p != NULL);   // is not allowed to be NULL
651
652     // get address of subindex entry
653     Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_
654         pVarParam_p->m_uiIndex,
655         pVarParam_p->m_uiSubindex,
656         NULL, &pSubindexEntry);
657     if (Ret != kEplSuccessful)
658     {
659         goto Exit;
660     }
661
662     // get var entry
663     Ret = EplObdGetVarEntry (pSubindexEntry, &pVarEntry);
664     if (Ret != kEplSuccessful)
665     {
666         goto Exit;
667     }
668
669     VarValid =  pVarParam_p->m_ValidFlag;
670
671     // copy only this values, which valid flag is set
672     if ((VarValid & kVarValidSize) != 0)
673     {
674         if (pSubindexEntry->m_Type != kEplObdTypDomain)
675         {
676         tEplObdSize DataSize;
677
678             // check passed size parameter
679             DataSize = EplObdGetObjectSize(pSubindexEntry);
680             if (DataSize != pVarParam_p->m_Size)
681             {   // size of variable does not match
682                 Ret = kEplObdValueLengthError;
683                 goto Exit;
684             }
685         }
686         else
687         {   // size can be set only for objects of type DOMAIN
688             pVarEntry->m_Size = pVarParam_p->m_Size;
689         }
690     }
691
692     if ((VarValid & kVarValidData) != 0)
693     {
694        pVarEntry->m_pData = pVarParam_p->m_pData;
695     }
696 /*
697     #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
698     {
699         if ((VarValid & kVarValidCallback) != 0)
700         {
701            pVarEntry->m_fpCallback = pVarParam_p->m_fpCallback;
702         }
703
704         if ((VarValid & kVarValidArg) != 0)
705         {
706            pVarEntry->m_pArg = pVarParam_p->m_pArg;
707         }
708     }
709     #endif
710 */
711     // Ret is already set to kEplSuccessful from ObdGetVarIntern()
712
713 Exit:
714
715     return Ret;
716
717 }
718
719
720 //---------------------------------------------------------------------------
721 //
722 // Function:    EplObdGetObjectDataPtr()
723 //
724 // Description: It returnes the current data pointer. But if object is an
725 //              constant object it returnes the default pointer.
726 //
727 // Parameters:  uiIndex_p    =   Index of the entry
728 //              uiSubindex_p =   Subindex of the entry
729 //
730 // Return:      void *    = pointer to object data
731 //
732 // State:
733 //
734 //---------------------------------------------------------------------------
735
736 EPLDLLEXPORT void * PUBLIC EplObdGetObjectDataPtr (EPL_MCO_DECL_INSTANCE_PTR_
737                                         unsigned int uiIndex_p,
738                                         unsigned int uiSubIndex_p)
739  {
740 tEplKernel          Ret;
741 void *       pData;
742 tEplObdEntryPtr     pObdEntry;
743 tEplObdSubEntryPtr  pObdSubEntry;
744
745
746     // get pointer to index structure
747     Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam),
748                                 uiIndex_p,
749                                 &pObdEntry);
750     if(Ret != kEplSuccessful)
751     {
752         pData = NULL;
753         goto Exit;
754     }
755
756     // get pointer to subindex structure
757     Ret = EplObdGetSubindexIntern (pObdEntry,
758                                 uiSubIndex_p,
759                                 &pObdSubEntry);
760     if(Ret != kEplSuccessful)
761     {
762         pData = NULL;
763         goto Exit;
764     }
765     // get Datapointer
766     pData = EplObdGetObjectDataPtrIntern(pObdSubEntry);
767
768 Exit:
769     return pData;
770
771 }
772
773
774 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
775
776 //---------------------------------------------------------------------------
777 //
778 // Function:    EplObdRegisterUserOd()
779 //
780 // Description: function registers the user OD
781 //
782 // Parameters:  pUserOd_p   =pointer to user ODd
783 //
784 // Return:     tEplKernel = errorcode
785 //
786 // State:
787 //
788 //---------------------------------------------------------------------------
789 EPLDLLEXPORT tEplKernel PUBLIC EplObdRegisterUserOd (EPL_MCO_DECL_INSTANCE_PTR_
790     tEplObdEntryPtr pUserOd_p)
791 {
792
793     EPL_MCO_CHECK_INSTANCE_STATE ();
794
795     EPL_MCO_GLB_VAR (m_ObdInitParam.m_pUserPart) = pUserOd_p;
796
797     return kEplSuccessful;
798
799 }
800
801 #endif
802
803
804 //---------------------------------------------------------------------------
805 //
806 // Function:    EplObdInitVarEntry()
807 //
808 // Description: function to initialize VarEntry dependened on object type
809 //
810 // Parameters:  pVarEntry_p = pointer to var entry structure
811 //              Type_p      = object type
812 //              ObdSize_p   = size of object data
813 //
814 // Returns:     none
815 //
816 // State:
817 //
818 //---------------------------------------------------------------------------
819
820 EPLDLLEXPORT void PUBLIC EplObdInitVarEntry (EPL_MCO_DECL_INSTANCE_PTR_
821                                              tEplObdVarEntry MEM* pVarEntry_p,
822                                              tEplObdType Type_p, tEplObdSize ObdSize_p)
823 {
824 /*
825     #if (EPL_PDO_USE_STATIC_MAPPING == FALSE)
826     {
827         // reset pointer to VAR callback and argument
828         pVarEntry_p->m_fpCallback  = NULL;
829         pVarEntry_p->m_pArg = NULL;
830     }
831     #endif
832 */
833
834 // 10-dec-2004 r.d.: this function will not be used for strings
835     if ((Type_p == kEplObdTypDomain))
836 //         (bType_p == kEplObdTypVString) /* ||
837 //         (bType_p == kEplObdTypOString) ||
838 //         (bType_p == kEplObdTypUString)    */ )
839     {
840         // variables which are defined as DOMAIN or VSTRING should not point to
841         // trash object, because this trash object contains only 8 bytes. DOMAINS or
842         // STRINGS can be longer.
843         pVarEntry_p->m_pData = NULL;
844         pVarEntry_p->m_Size  = 0;
845     }
846     else
847     {
848         // set address to variable data to trash object
849         // This prevents an access violation if user forgets to call EplObdDefineVar()
850         // for this variable but mappes it in a PDO.
851         pVarEntry_p->m_pData = &abEplObdTrashObject_g[0];
852         pVarEntry_p->m_Size  = ObdSize_p;
853     }
854
855 }
856
857
858 //---------------------------------------------------------------------------
859 //
860 // Function:    EplObdGetDataSize()
861 //
862 // Description: function to initialize VarEntry dependened on object type
863 //
864 //              gets the data size of an object
865 //              for string objects it returnes the string length
866 //
867 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
868 //              uiIndex_p   =   Index
869 //              uiSubIndex_p=   Subindex
870 //
871 // Return:      tEplObdSize
872 //
873 // State:
874 //
875 //---------------------------------------------------------------------------
876 EPLDLLEXPORT tEplObdSize PUBLIC EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_
877                                                   unsigned int uiIndex_p,
878                                                   unsigned int uiSubIndex_p)
879 {
880 tEplKernel          Ret;
881 tEplObdSize         ObdSize;
882 tEplObdEntryPtr     pObdEntry;
883 tEplObdSubEntryPtr  pObdSubEntry;
884
885
886     // get pointer to index structure
887     Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam),
888                                 uiIndex_p,
889                                 &pObdEntry);
890     if(Ret != kEplSuccessful)
891     {
892         ObdSize = 0;
893         goto Exit;
894     }
895
896     // get pointer to subindex structure
897     Ret = EplObdGetSubindexIntern (pObdEntry,
898                                 uiSubIndex_p,
899                                 &pObdSubEntry);
900     if(Ret != kEplSuccessful)
901     {
902         ObdSize = 0;
903         goto Exit;
904     }
905
906     // get size
907     ObdSize = EplObdGetDataSizeIntern (pObdSubEntry);
908 Exit:
909     return ObdSize;
910 }
911 //---------------------------------------------------------------------------
912 //
913 // Function:    EplObdGetNodeId()
914 //
915 // Description: function returns nodeid from entry 0x1F93
916 //
917 //
918 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR = Instancepointer
919 //
920 // Return:      unsigned int = Node Id
921 //
922 // State:
923 //
924 //---------------------------------------------------------------------------
925 EPLDLLEXPORT unsigned int PUBLIC EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)
926 {
927 tEplKernel      Ret;
928 tEplObdSize     ObdSize;
929 BYTE            bNodeId;
930
931     bNodeId = 0;
932     ObdSize = sizeof(bNodeId);
933     Ret = EplObdReadEntry(EPL_MCO_PTR_INSTANCE_PTR_
934                             EPL_OBD_NODE_ID_INDEX,
935                             EPL_OBD_NODE_ID_SUBINDEX,
936                             &bNodeId,
937                             &ObdSize);
938     if(Ret != kEplSuccessful)
939     {
940         bNodeId = EPL_C_ADR_INVALID;
941         goto Exit;
942     }
943
944 Exit:
945     return (unsigned int) bNodeId;
946
947 }
948
949
950 //---------------------------------------------------------------------------
951 //
952 // Function:    EplObdSetNodeId()
953 //
954 // Description: function sets nodeid in entry 0x1F93
955 //
956 //
957 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
958 //              uiNodeId_p  =   Node Id to set
959 //              NodeIdType_p=   Type on which way the Node Id was set
960 //
961 // Return:      tEplKernel = Errorcode
962 //
963 // State:
964 //
965 //---------------------------------------------------------------------------
966 EPLDLLEXPORT tEplKernel PUBLIC EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_
967                                          unsigned int uiNodeId_p,
968                                          tEplObdNodeIdType NodeIdType_p)
969 {
970 tEplKernel  Ret;
971 tEplObdSize ObdSize;
972 BYTE        fHwBool;
973 BYTE        bNodeId;
974
975     // check Node Id
976     if(uiNodeId_p == EPL_C_ADR_INVALID)
977     {
978         Ret = kEplInvalidNodeId;
979         goto Exit;
980     }
981     bNodeId = (BYTE)uiNodeId_p;
982     ObdSize = sizeof(BYTE);
983     // write NodeId to OD entry
984     Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR_
985                             EPL_OBD_NODE_ID_INDEX,
986                             EPL_OBD_NODE_ID_SUBINDEX,
987                             &bNodeId,
988                             ObdSize);
989     if(Ret != kEplSuccessful)
990     {
991         goto Exit;
992     }
993
994     // set HWBOOL-Flag in Subindex EPL_OBD_NODE_ID_HWBOOL_SUBINDEX
995     switch (NodeIdType_p)
996     {
997         // type unknown
998         case kEplObdNodeIdUnknown:
999         {
1000             fHwBool = OBD_FALSE;
1001             break;
1002         }
1003
1004         case kEplObdNodeIdSoftware:
1005         {
1006             fHwBool = OBD_FALSE;
1007             break;
1008         }
1009
1010         case kEplObdNodeIdHardware:
1011         {
1012             fHwBool = OBD_TRUE;
1013             break;
1014         }
1015
1016         default:
1017         {
1018             fHwBool = OBD_FALSE;
1019         }
1020
1021     }   // end of switch (NodeIdType_p)
1022
1023     // write flag
1024     ObdSize = sizeof(fHwBool);
1025     Ret = EplObdWriteEntry(EPL_MCO_PTR_INSTANCE_PTR
1026                             EPL_OBD_NODE_ID_INDEX,
1027                             EPL_OBD_NODE_ID_HWBOOL_SUBINDEX,
1028                             &fHwBool,
1029                             ObdSize);
1030     if(Ret != kEplSuccessful)
1031     {
1032         goto Exit;
1033     }
1034
1035 Exit:
1036     return Ret;
1037 }
1038
1039 //---------------------------------------------------------------------------
1040 //
1041 // Function:    EplObdIsNumerical()
1042 //
1043 // Description: function checks if a entry is numerical or not
1044 //
1045 //
1046 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
1047 //              uiIndex_p           = Index
1048 //              uiSubIndex_p        = Subindex
1049 //              pfEntryNumerical_p  = pointer to BOOL for returnvalue
1050 //                                  -> TRUE if entry a numerical value
1051 //                                  -> FALSE if entry not a numerical value
1052 //
1053 // Return:      tEplKernel = Errorcode
1054 //
1055 // State:
1056 //
1057 //---------------------------------------------------------------------------
1058 EPLDLLEXPORT tEplKernel PUBLIC EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_
1059                                         unsigned int  uiIndex_p,
1060                                         unsigned int  uiSubIndex_p,
1061                                         BOOL*         pfEntryNumerical_p)
1062 {
1063 tEplKernel          Ret;
1064 tEplObdEntryPtr     pObdEntry;
1065 tEplObdSubEntryPtr  pObdSubEntry;
1066
1067
1068     // get pointer to index structure
1069     Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam),
1070                                 uiIndex_p,
1071                                 &pObdEntry);
1072     if(Ret != kEplSuccessful)
1073     {
1074         goto Exit;
1075     }
1076
1077     // get pointer to subindex structure
1078     Ret = EplObdGetSubindexIntern (pObdEntry,
1079                                 uiSubIndex_p,
1080                                 &pObdSubEntry);
1081     if(Ret != kEplSuccessful)
1082     {
1083         goto Exit;
1084     }
1085
1086     Ret = EplObdIsNumericalIntern(pObdSubEntry, pfEntryNumerical_p);
1087
1088
1089 Exit:
1090     return Ret;
1091
1092 }
1093
1094 //---------------------------------------------------------------------------
1095 //
1096 // Function:    EplObdReadEntryToLe()
1097 //
1098 // Description: The function reads an object entry from the byteoder
1099 //              of the system to the little endian byteorder for numerical values.
1100 //              For other types a normal read will be processed. This is usefull for
1101 //              the PDO and SDO module. The application
1102 //              can always read the data even if attrib kEplObdAccRead
1103 //              is not set. The attrib is only checked up for SDO transfer.
1104 //
1105 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
1106 //              uiIndex_p       = Index of the OD entry to read
1107 //              uiSubIndex_p    = Subindex to read
1108 //              pDstData_p      = pointer to the buffer for data
1109 //              Offset_p        = offset in data for read access
1110 //              pSize_p         = IN: Size of the buffer
1111 //                                OUT: number of readed Bytes
1112 //
1113 // Return:      tEplKernel
1114 //
1115 // State:
1116 //
1117 //---------------------------------------------------------------------------
1118 EPLDLLEXPORT tEplKernel PUBLIC EplObdReadEntryToLe (EPL_MCO_DECL_INSTANCE_PTR_
1119                                         unsigned int        uiIndex_p,
1120                                         unsigned int        uiSubIndex_p,
1121                                         void *              pDstData_p,
1122                                         tEplObdSize *       pSize_p)
1123 {
1124 tEplKernel                      Ret;
1125 tEplObdEntryPtr                 pObdEntry;
1126 tEplObdSubEntryPtr              pSubEntry;
1127 tEplObdCbParam  MEM             CbParam;
1128 void *                          pSrcData;
1129 tEplObdSize                     ObdSize;
1130
1131     // check for all API function if instance is valid
1132     EPL_MCO_CHECK_INSTANCE_STATE ();
1133
1134     ASSERT (pDstData_p != NULL);
1135     ASSERT (pSize_p != NULL);
1136
1137     // get address of index and subindex entry
1138     Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_
1139         uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
1140     if (Ret != kEplSuccessful)
1141     {
1142         goto Exit;
1143     }
1144
1145     // get pointer to object data
1146      pSrcData = EplObdGetObjectDataPtrIntern (pSubEntry);
1147
1148     // check source pointer
1149     if (pSrcData == NULL)
1150     {
1151         Ret = kEplObdReadViolation;
1152         goto Exit;
1153     }
1154
1155     //------------------------------------------------------------------------
1156     // address of source data to structure of callback parameters
1157     // so callback function can change this data before reading
1158     CbParam.m_uiIndex   = uiIndex_p;
1159     CbParam.m_uiSubIndex= uiSubIndex_p;
1160     CbParam.m_pArg      = pSrcData;
1161     CbParam.m_ObdEvent  = kEplObdEvPreRead;
1162     Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
1163         pObdEntry->m_fpCallback, &CbParam);
1164     if (Ret != kEplSuccessful)
1165     {
1166         goto Exit;
1167     }
1168
1169     // get size of data and check if application has reserved enough memory
1170     ObdSize = EplObdGetDataSizeIntern (pSubEntry);
1171     // check if offset given and calc correct number of bytes to read
1172     if (*pSize_p < ObdSize)
1173     {
1174         Ret = kEplObdValueLengthError;
1175         goto Exit;
1176     }
1177
1178     // check if numerical type
1179     switch(pSubEntry->m_Type)
1180     {
1181         //-----------------------------------------------
1182         // types without ami
1183         case kEplObdTypVString:
1184         case kEplObdTypOString:
1185         case kEplObdTypDomain:
1186         default:
1187         {
1188             // read value from object
1189             EPL_MEMCPY (pDstData_p, pSrcData, ObdSize);
1190             break;
1191         }
1192
1193         //-----------------------------------------------
1194         // numerical type which needs ami-write
1195         // 8 bit or smaller values
1196         case kEplObdTypBool:
1197         case kEplObdTypInt8:
1198         case kEplObdTypUInt8:
1199         {
1200             AmiSetByteToLe(pDstData_p, *((BYTE*)pSrcData));
1201             break;
1202         }
1203
1204         // 16 bit values
1205         case kEplObdTypInt16:
1206         case kEplObdTypUInt16:
1207         {
1208             AmiSetWordToLe(pDstData_p, *((WORD*)pSrcData));
1209             break;
1210         }
1211
1212         // 24 bit values
1213         case kEplObdTypInt24:
1214         case kEplObdTypUInt24:
1215         {
1216             AmiSetDword24ToLe(pDstData_p, *((DWORD*)pSrcData));
1217             break;
1218         }
1219
1220         // 32 bit values
1221         case kEplObdTypInt32:
1222         case kEplObdTypUInt32:
1223         case kEplObdTypReal32:
1224         {
1225             AmiSetDwordToLe(pDstData_p, *((DWORD*)pSrcData));
1226             break;
1227         }
1228
1229         // 40 bit values
1230         case kEplObdTypInt40:
1231         case kEplObdTypUInt40:
1232         {
1233             AmiSetQword40ToLe(pDstData_p, *((QWORD*)pSrcData));
1234             break;
1235         }
1236
1237         // 48 bit values
1238         case kEplObdTypInt48:
1239         case kEplObdTypUInt48:
1240         {
1241             AmiSetQword48ToLe(pDstData_p, *((QWORD*)pSrcData));
1242             break;
1243         }
1244
1245         // 56 bit values
1246         case kEplObdTypInt56:
1247         case kEplObdTypUInt56:
1248         {
1249             AmiSetQword56ToLe(pDstData_p, *((QWORD*)pSrcData));
1250             break;
1251         }
1252
1253         // 64 bit values
1254         case kEplObdTypInt64:
1255         case kEplObdTypUInt64:
1256         case kEplObdTypReal64:
1257         {
1258             AmiSetQword64ToLe(pDstData_p, *((QWORD*)pSrcData));
1259             break;
1260         }
1261
1262         // time of day
1263         case kEplObdTypTimeOfDay:
1264         case kEplObdTypTimeDiff:
1265         {
1266             AmiSetTimeOfDay(pDstData_p, ((tTimeOfDay*)pSrcData));
1267             break;
1268         }
1269
1270     }// end of switch(pSubEntry->m_Type)
1271
1272     *pSize_p = ObdSize;
1273
1274
1275     // write address of destination data to structure of callback parameters
1276     // so callback function can change this data after reading
1277     CbParam.m_pArg     = pDstData_p;
1278     CbParam.m_ObdEvent = kEplObdEvPostRead;
1279     Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
1280         pObdEntry->m_fpCallback, &CbParam);
1281
1282 Exit:
1283
1284     return Ret;
1285
1286 }
1287
1288 //---------------------------------------------------------------------------
1289 //
1290 // Function:    EplObdWriteEntryFromLe()
1291 //
1292 // Description: Function writes data to an OBD entry from a source with
1293 //              little endian byteorder to the od with system specuific
1294 //              byteorder. Not numerical values will only by copied. Strings
1295 //              are stored with added '\0' character.
1296 //
1297 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
1298 //              uiIndex_p       =   Index of the OD entry
1299 //              uiSubIndex_p    =   Subindex of the OD Entry
1300 //              pSrcData_p      =   Pointer to the data to write
1301 //              Size_p          =   Size of the data in Byte
1302 //
1303 // Return:      tEplKernel      =   Errorcode
1304 //
1305 //
1306 // State:
1307 //
1308 //---------------------------------------------------------------------------
1309 EPLDLLEXPORT tEplKernel PUBLIC EplObdWriteEntryFromLe (EPL_MCO_DECL_INSTANCE_PTR_
1310                                         unsigned int  uiIndex_p,
1311                                         unsigned int  uiSubIndex_p,
1312                                         void *        pSrcData_p,
1313                                         tEplObdSize   Size_p)
1314 {
1315 tEplKernel              Ret;
1316 tEplObdEntryPtr         pObdEntry;
1317 tEplObdSubEntryPtr      pSubEntry;
1318 tEplObdCbParam MEM      CbParam;
1319 void MEM*               pDstData;
1320 tEplObdSize             ObdSize;
1321 QWORD                   qwBuffer;
1322 void*                   pBuffer = &qwBuffer;
1323
1324
1325     Ret = EplObdWriteEntryPre (EPL_MCO_INSTANCE_PTR_
1326                                uiIndex_p,
1327                                uiSubIndex_p,
1328                                pSrcData_p,
1329                                &pDstData,
1330                                Size_p,
1331                                &pObdEntry,
1332                                &pSubEntry,
1333                                &CbParam,
1334                                &ObdSize);
1335     if (Ret != kEplSuccessful)
1336     {
1337         goto Exit;
1338     }
1339
1340
1341     // check if numerical type
1342     switch(pSubEntry->m_Type)
1343     {
1344         //-----------------------------------------------
1345         // types without ami
1346         default:
1347         {   // do nothing, i.e. use the given source pointer
1348             pBuffer = pSrcData_p;
1349             break;
1350         }
1351
1352         //-----------------------------------------------
1353         // numerical type which needs ami-write
1354         // 8 bit or smaller values
1355         case kEplObdTypBool:
1356         case kEplObdTypInt8:
1357         case kEplObdTypUInt8:
1358         {
1359             *((BYTE*)pBuffer) = AmiGetByteFromLe(pSrcData_p);
1360             break;
1361         }
1362
1363         // 16 bit values
1364         case kEplObdTypInt16:
1365         case kEplObdTypUInt16:
1366         {
1367             *((WORD*)pBuffer) = AmiGetWordFromLe(pSrcData_p);
1368             break;
1369         }
1370
1371         // 24 bit values
1372         case kEplObdTypInt24:
1373         case kEplObdTypUInt24:
1374         {
1375             *((DWORD*)pBuffer) = AmiGetDword24FromLe(pSrcData_p);
1376             break;
1377         }
1378
1379         // 32 bit values
1380         case kEplObdTypInt32:
1381         case kEplObdTypUInt32:
1382         case kEplObdTypReal32:
1383         {
1384             *((DWORD*)pBuffer) = AmiGetDwordFromLe(pSrcData_p);
1385             break;
1386         }
1387
1388         // 40 bit values
1389         case kEplObdTypInt40:
1390         case kEplObdTypUInt40:
1391         {
1392             *((QWORD*)pBuffer) = AmiGetQword40FromLe(pSrcData_p);
1393             break;
1394         }
1395
1396         // 48 bit values
1397         case kEplObdTypInt48:
1398         case kEplObdTypUInt48:
1399         {
1400             *((QWORD*)pBuffer) = AmiGetQword48FromLe(pSrcData_p);
1401             break;
1402         }
1403
1404         // 56 bit values
1405         case kEplObdTypInt56:
1406         case kEplObdTypUInt56:
1407         {
1408             *((QWORD*)pBuffer) = AmiGetQword56FromLe(pSrcData_p);
1409             break;
1410         }
1411
1412         // 64 bit values
1413         case kEplObdTypInt64:
1414         case kEplObdTypUInt64:
1415         case kEplObdTypReal64:
1416         {
1417             *((QWORD*)pBuffer) = AmiGetQword64FromLe(pSrcData_p);
1418             break;
1419         }
1420
1421         // time of day
1422         case kEplObdTypTimeOfDay:
1423         case kEplObdTypTimeDiff:
1424         {
1425             AmiGetTimeOfDay(pBuffer, ((tTimeOfDay*)pSrcData_p));
1426             break;
1427         }
1428
1429     }// end of switch(pSubEntry->m_Type)
1430
1431
1432     Ret = EplObdWriteEntryPost (EPL_MCO_INSTANCE_PTR_
1433                                 pObdEntry,
1434                                 pSubEntry,
1435                                 &CbParam,
1436                                 pBuffer,
1437                                 pDstData,
1438                                 ObdSize);
1439     if (Ret != kEplSuccessful)
1440     {
1441         goto Exit;
1442     }
1443
1444 Exit:
1445
1446     return Ret;
1447
1448 }
1449
1450 //---------------------------------------------------------------------------
1451 //
1452 // Function:    EplObdGetAccessType()
1453 //
1454 // Description: Function returns accesstype of the entry
1455 //
1456 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
1457 //              uiIndex_p       =   Index of the OD entry
1458 //              uiSubIndex_p    =   Subindex of the OD Entry
1459 //              pAccessTyp_p    =   pointer to buffer to store accesstype
1460 //
1461 // Return:      tEplKernel     =   errorcode
1462 //
1463 //
1464 // State:
1465 //
1466 //---------------------------------------------------------------------------
1467 EPLDLLEXPORT tEplKernel PUBLIC EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_
1468                                         unsigned int uiIndex_p,
1469                                         unsigned int uiSubIndex_p,
1470                                         tEplObdAccess* pAccessTyp_p)
1471
1472 {
1473 tEplKernel          Ret;
1474 tEplObdEntryPtr     pObdEntry;
1475 tEplObdSubEntryPtr  pObdSubEntry;
1476
1477
1478     // get pointer to index structure
1479     Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam),
1480                                 uiIndex_p,
1481                                 &pObdEntry);
1482     if(Ret != kEplSuccessful)
1483     {
1484         goto Exit;
1485     }
1486
1487     // get pointer to subindex structure
1488     Ret = EplObdGetSubindexIntern (pObdEntry,
1489                                 uiSubIndex_p,
1490                                 &pObdSubEntry);
1491     if(Ret != kEplSuccessful)
1492     {
1493         goto Exit;
1494     }
1495
1496     // get accessType
1497     *pAccessTyp_p = pObdSubEntry->m_Access;
1498
1499
1500 Exit:
1501     return Ret;
1502 }
1503
1504 //---------------------------------------------------------------------------
1505 //
1506 // Function:    EplObdSearchVarEntry()
1507 //
1508 // Description: gets variable from OD
1509 //
1510 // Parameters:  uiIndex_p       =   index of the var entry to search
1511 //              uiSubindex_p    =   subindex of var entry to search
1512 //              ppVarEntry_p    =   pointer to the pointer to the varentry
1513 //
1514 // Return:      tEplKernel
1515 //
1516 // State:
1517 //
1518 //---------------------------------------------------------------------------
1519
1520 tEplKernel PUBLIC EplObdSearchVarEntry (EPL_MCO_DECL_INSTANCE_PTR_
1521     unsigned int            uiIndex_p,
1522     unsigned int            uiSubindex_p,
1523     tEplObdVarEntry MEM**   ppVarEntry_p)
1524 {
1525
1526 tEplKernel           Ret;
1527 tEplObdSubEntryPtr   pSubindexEntry;
1528
1529     // check for all API function if instance is valid
1530     EPL_MCO_CHECK_INSTANCE_STATE ();
1531
1532     // get address of subindex entry
1533     Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_
1534         uiIndex_p, uiSubindex_p, NULL, &pSubindexEntry);
1535     if (Ret == kEplSuccessful)
1536     {
1537         // get var entry
1538         Ret = EplObdGetVarEntry (pSubindexEntry, ppVarEntry_p);
1539     }
1540
1541     return Ret;
1542
1543 }
1544 //=========================================================================//
1545 //                                                                         //
1546 //          P R I V A T E   D E F I N I T I O N S                          //
1547 //                                                                         //
1548 //=========================================================================//
1549
1550 EPL_MCO_DECL_INSTANCE_FCT ()
1551 //---------------------------------------------------------------------------
1552 //
1553 // Function:    EplObdCallObjectCallback()
1554 //
1555 // Description: calls callback function of an object or of a variable
1556 //
1557 // Parameters:  fpCallback_p
1558 //              pCbParam_p
1559 //
1560 // Return:      tEplKernel
1561 //
1562 // State:
1563 //
1564 //---------------------------------------------------------------------------
1565
1566 static tEplKernel EplObdCallObjectCallback (EPL_MCO_DECL_INSTANCE_PTR_
1567     tEplObdCallback fpCallback_p,
1568     tEplObdCbParam MEM* pCbParam_p)
1569 {
1570
1571 tEplKernel           Ret;
1572 tEplObdCallback MEM  fpCallback;
1573
1574     // check for all API function if instance is valid
1575     EPL_MCO_CHECK_INSTANCE_STATE ();
1576
1577     ASSERT (pCbParam_p != NULL);
1578
1579     Ret = kEplSuccessful;
1580
1581     // check address of callback function before calling it
1582     if (fpCallback_p != NULL)
1583     {
1584         // KEIL C51 V6.01 has a bug.
1585         // Therefore the parameter fpCallback_p has to be copied in local variable fpCallback.
1586         fpCallback = fpCallback_p;
1587
1588         // call callback function for this object
1589         Ret = fpCallback (EPL_MCO_INSTANCE_PARAM_IDX_()
1590             pCbParam_p);
1591     }
1592
1593     return Ret;
1594 }
1595
1596 //---------------------------------------------------------------------------
1597 //
1598 // Function:    EplObdGetDataSizeIntern()
1599 //
1600 // Description: gets the data size of an object
1601 //              for string objects it returnes the string length
1602 //
1603 // Parameters:  pSubIndexEntry_p
1604 //
1605 // Return:      tEplObdSize
1606 //
1607 // State:
1608 //
1609 //---------------------------------------------------------------------------
1610
1611 static tEplObdSize EplObdGetDataSizeIntern (tEplObdSubEntryPtr pSubIndexEntry_p)
1612 {
1613
1614 tEplObdSize DataSize;
1615 void MEM*   pData;
1616
1617     // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
1618     // then the current pointer is always NULL. The function
1619     // returns the length of default string.
1620     DataSize = EplObdGetObjectSize (pSubIndexEntry_p);
1621
1622     if (pSubIndexEntry_p->m_Type == kEplObdTypVString)
1623     {
1624         // The pointer to current value can be received from EplObdGetObjectCurrentPtr()
1625         pData = ((void MEM*) EplObdGetObjectCurrentPtr (pSubIndexEntry_p));
1626         if (pData != NULL)
1627         {
1628             DataSize = EplObdGetStrLen ((void *) pData, DataSize, pSubIndexEntry_p->m_Type);
1629         }
1630
1631     }
1632
1633     return DataSize;
1634
1635 }
1636
1637
1638 //---------------------------------------------------------------------------
1639 //
1640 // Function:    EplObdGetStrLen()
1641 //
1642 // Description: The function calculates the length of string. The '\0'
1643 //              character is included!!
1644 //
1645 // Parameters:  pObjData_p          = pointer to string
1646 //              ObjLen_p            = max. length of objectr entry
1647 //              bObjType_p          = object type (VSTRING, ...)
1648 //
1649 // Returns:     string length + 1
1650 //
1651 // State:
1652 //
1653 //---------------------------------------------------------------------------
1654
1655 static tEplObdSize EplObdGetStrLen (void * pObjData_p,
1656                                  tEplObdSize ObjLen_p,
1657                                  tEplObdType ObjType_p)
1658 {
1659
1660 tEplObdSize    StrLen = 0;
1661 BYTE *  pbString;
1662
1663     if (pObjData_p == NULL)
1664     {
1665         goto Exit;
1666     }
1667
1668     //----------------------------------------
1669     // Visible String: data format byte
1670     if (ObjType_p == kEplObdTypVString)
1671     {
1672         pbString = pObjData_p;
1673
1674         for (StrLen = 0; StrLen < ObjLen_p; StrLen++)
1675         {
1676             if (*pbString == '\0')
1677             {
1678                 StrLen++;
1679                 break;
1680             }
1681
1682             pbString++;
1683         }
1684     }
1685
1686     //----------------------------------------
1687     // other string types ...
1688
1689 Exit:
1690     return (StrLen);
1691
1692 }
1693
1694
1695
1696 #if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
1697
1698 //---------------------------------------------------------------------------
1699 //
1700 // Function:    EplObdCheckObjectRange()
1701 //
1702 // Description: function to check value range of object data
1703 //
1704 // NOTICE: The pointer of data (pData_p) must point out to an even address,
1705 //         if ObjType is unequal to kEplObdTypInt8 or kEplObdTypUInt8! But it is
1706 //         always realiced because pointer m_pDefault points always to an
1707 //         array of the SPECIFIED type.
1708 //
1709 // Parameters:  pSubindexEntry_p
1710 //              pData_p
1711 //
1712 // Return:      tEplKernel
1713 //
1714 // State:
1715 //
1716 //---------------------------------------------------------------------------
1717
1718 static tEplKernel EplObdCheckObjectRange (
1719             tEplObdSubEntryPtr pSubindexEntry_p,
1720             void * pData_p)
1721 {
1722
1723 tEplKernel      Ret;
1724 void *   pRangeData;
1725
1726     ASSERTMSG (pSubindexEntry_p != NULL,
1727         "EplObdCheckObjectRange(): no address to subindex struct!\n");
1728
1729     Ret  = kEplSuccessful;
1730
1731     // check if data range has to be checked
1732     if ((pSubindexEntry_p->m_Access & kEplObdAccRange) == 0)
1733     {
1734         goto Exit;
1735     }
1736
1737     // get address of default data
1738     pRangeData = pSubindexEntry_p->m_pDefault;
1739
1740     // jump to called object type
1741     switch ((tEplObdType) pSubindexEntry_p->m_Type)
1742     {
1743         // -----------------------------------------------------------------
1744         // ObdType kEplObdTypBool will not be checked because there are only
1745         // two possible values 0 or 1.
1746
1747         // -----------------------------------------------------------------
1748         // ObdTypes which has to be check up because numerical values
1749         case kEplObdTypInt8:
1750
1751             // switch to lower limit
1752             pRangeData = ((tEplObdInteger8 *) pRangeData) + 1;
1753
1754             // check if value is to low
1755             if (*((tEplObdInteger8 *) pData_p) < *((tEplObdInteger8 *) pRangeData))
1756             {
1757                 Ret = kEplObdValueTooLow;
1758                 break;
1759             }
1760
1761             // switch to higher limit
1762             pRangeData = ((tEplObdInteger8 *) pRangeData) + 1;
1763
1764             // check if value is to high
1765             if (*((tEplObdInteger8 *) pData_p) > *((tEplObdInteger8 *) pRangeData))
1766             {
1767                 Ret = kEplObdValueTooHigh;
1768             }
1769
1770             break;
1771
1772         case kEplObdTypUInt8:
1773
1774             // switch to lower limit
1775             pRangeData = ((tEplObdUnsigned8 *) pRangeData) + 1;
1776
1777             // check if value is to low
1778             if (*((tEplObdUnsigned8 *) pData_p) < *((tEplObdUnsigned8 *) pRangeData))
1779             {
1780                 Ret = kEplObdValueTooLow;
1781                 break;
1782             }
1783
1784             // switch to higher limit
1785             pRangeData = ((tEplObdUnsigned8*) pRangeData) + 1;
1786
1787             // check if value is to high
1788             if (*((tEplObdUnsigned8 *) pData_p) > *((tEplObdUnsigned8 *) pRangeData))
1789             {
1790                 Ret = kEplObdValueTooHigh;
1791             }
1792
1793             break;
1794
1795         case kEplObdTypInt16:
1796
1797             // switch to lower limit
1798             pRangeData = ((tEplObdInteger16 *) pRangeData) + 1;
1799
1800             // check if value is to low
1801             if (*((tEplObdInteger16 *) pData_p) < *((tEplObdInteger16 *) pRangeData))
1802             {
1803                 Ret = kEplObdValueTooLow;
1804                 break;
1805             }
1806
1807             // switch to higher limit
1808             pRangeData = ((tEplObdInteger16 *) pRangeData) + 1;
1809
1810             // check if value is to high
1811             if (*((tEplObdInteger16 *) pData_p) > *((tEplObdInteger16 *) pRangeData))
1812             {
1813                 Ret = kEplObdValueTooHigh;
1814             }
1815
1816             break;
1817
1818         case kEplObdTypUInt16:
1819
1820             // switch to lower limit
1821             pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1;
1822
1823             // check if value is to low
1824             if (*((tEplObdUnsigned16 *) pData_p) < *((tEplObdUnsigned16 *) pRangeData))
1825             {
1826                 Ret = kEplObdValueTooLow;
1827                 break;
1828             }
1829
1830             // switch to higher limit
1831             pRangeData = ((tEplObdUnsigned16 *) pRangeData) + 1;
1832
1833             // check if value is to high
1834             if (*((tEplObdUnsigned16 *) pData_p) > *((tEplObdUnsigned16 *) pRangeData))
1835             {
1836                 Ret = kEplObdValueTooHigh;
1837             }
1838
1839             break;
1840
1841         case kEplObdTypInt32:
1842
1843             // switch to lower limit
1844             pRangeData = ((tEplObdInteger32 *) pRangeData) + 1;
1845
1846             // check if value is to low
1847             if (*((tEplObdInteger32 *) pData_p) < *((tEplObdInteger32 *) pRangeData))
1848             {
1849                 Ret = kEplObdValueTooLow;
1850                 break;
1851             }
1852
1853             // switch to higher limit
1854             pRangeData = ((tEplObdInteger32 *) pRangeData) + 1;
1855
1856             // check if value is to high
1857             if (*((tEplObdInteger32 *) pData_p) > *((tEplObdInteger32 *) pRangeData))
1858             {
1859                 Ret = kEplObdValueTooHigh;
1860             }
1861
1862             break;
1863
1864         case kEplObdTypUInt32:
1865
1866             // switch to lower limit
1867             pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1;
1868
1869             // check if value is to low
1870             if (*((tEplObdUnsigned32 *) pData_p) < *((tEplObdUnsigned32 *) pRangeData))
1871             {
1872                 Ret = kEplObdValueTooLow;
1873                 break;
1874             }
1875
1876             // switch to higher limit
1877             pRangeData = ((tEplObdUnsigned32 *) pRangeData) + 1;
1878
1879             // check if value is to high
1880             if (*((tEplObdUnsigned32 *) pData_p) > *((tEplObdUnsigned32 *) pRangeData))
1881             {
1882                 Ret = kEplObdValueTooHigh;
1883             }
1884
1885             break;
1886
1887         case kEplObdTypReal32:
1888
1889             // switch to lower limit
1890             pRangeData = ((tEplObdReal32 *) pRangeData) + 1;
1891
1892             // check if value is to low
1893             if (*((tEplObdReal32 *) pData_p) < *((tEplObdReal32 *) pRangeData))
1894             {
1895                 Ret = kEplObdValueTooLow;
1896                 break;
1897             }
1898
1899             // switch to higher limit
1900             pRangeData = ((tEplObdReal32 *) pRangeData) + 1;
1901
1902             // check if value is to high
1903             if (*((tEplObdReal32 *) pData_p) > *((tEplObdReal32 *) pRangeData))
1904             {
1905                 Ret = kEplObdValueTooHigh;
1906             }
1907
1908             break;
1909
1910         // -----------------------------------------------------------------
1911         case kEplObdTypInt40:
1912         case kEplObdTypInt48:
1913         case kEplObdTypInt56:
1914         case kEplObdTypInt64:
1915
1916             // switch to lower limit
1917             pRangeData = ((signed QWORD *) pRangeData) + 1;
1918
1919             // check if value is to low
1920             if (*((signed QWORD *) pData_p) < *((signed QWORD *) pRangeData))
1921             {
1922                 Ret = kEplObdValueTooLow;
1923                 break;
1924             }
1925
1926             // switch to higher limit
1927             pRangeData = ((signed QWORD *) pRangeData) + 1;
1928
1929             // check if value is to high
1930             if (*((signed QWORD *) pData_p) > *((signed QWORD *) pRangeData))
1931             {
1932                 Ret = kEplObdValueTooHigh;
1933             }
1934
1935             break;
1936
1937         // -----------------------------------------------------------------
1938         case kEplObdTypUInt40:
1939         case kEplObdTypUInt48:
1940         case kEplObdTypUInt56:
1941         case kEplObdTypUInt64:
1942
1943             // switch to lower limit
1944             pRangeData = ((unsigned QWORD *) pRangeData) + 1;
1945
1946             // check if value is to low
1947             if (*((unsigned QWORD *) pData_p) < *((unsigned QWORD *) pRangeData))
1948             {
1949                 Ret = kEplObdValueTooLow;
1950                 break;
1951             }
1952
1953             // switch to higher limit
1954             pRangeData = ((unsigned QWORD *) pRangeData) + 1;
1955
1956             // check if value is to high
1957             if (*((unsigned QWORD *) pData_p) > *((unsigned QWORD *) pRangeData))
1958             {
1959                 Ret = kEplObdValueTooHigh;
1960             }
1961
1962             break;
1963
1964         // -----------------------------------------------------------------
1965         case kEplObdTypReal64:
1966
1967             // switch to lower limit
1968             pRangeData = ((tEplObdReal64 *) pRangeData) + 1;
1969
1970             // check if value is to low
1971             if (*((tEplObdReal64 *) pData_p) < *((tEplObdReal64 *) pRangeData))
1972             {
1973                 Ret = kEplObdValueTooLow;
1974                 break;
1975             }
1976
1977             // switch to higher limit
1978             pRangeData = ((tEplObdReal64 *) pRangeData) + 1;
1979
1980             // check if value is to high
1981             if (*((tEplObdReal64 *) pData_p) > *((tEplObdReal64 *) pRangeData))
1982             {
1983                 Ret = kEplObdValueTooHigh;
1984             }
1985
1986             break;
1987
1988         // -----------------------------------------------------------------
1989         case kEplObdTypTimeOfDay:
1990         case kEplObdTypTimeDiff:
1991             break;
1992
1993         // -----------------------------------------------------------------
1994         // ObdTypes kEplObdTypXString and kEplObdTypDomain can not be checkt because
1995         // they have no numerical value.
1996         default:
1997
1998             Ret = kEplObdUnknownObjectType;
1999             break;
2000     }
2001
2002 Exit:
2003
2004     return Ret;
2005
2006 }
2007 #endif // (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
2008
2009 //---------------------------------------------------------------------------
2010 //
2011 // Function:    EplObdWriteEntryPre()
2012 //
2013 // Description: Function prepares write of data to an OBD entry. Strings
2014 //              are stored with added '\0' character.
2015 //
2016 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
2017 //              uiIndex_p       =   Index of the OD entry
2018 //              uiSubIndex_p    =   Subindex of the OD Entry
2019 //              pSrcData_p      =   Pointer to the data to write
2020 //              Size_p          =   Size of the data in Byte
2021 //
2022 // Return:      tEplKernel      =   Errorcode
2023 //
2024 //
2025 // State:
2026 //
2027 //---------------------------------------------------------------------------
2028
2029 static tEplKernel PUBLIC EplObdWriteEntryPre (EPL_MCO_DECL_INSTANCE_PTR_
2030     unsigned int  uiIndex_p,
2031     unsigned int  uiSubIndex_p,
2032     void * pSrcData_p,
2033     void** ppDstData_p,
2034     tEplObdSize   Size_p,
2035     tEplObdEntryPtr*        ppObdEntry_p,
2036     tEplObdSubEntryPtr*     ppSubEntry_p,
2037     tEplObdCbParam MEM*     pCbParam_p,
2038     tEplObdSize*  pObdSize_p)
2039 {
2040
2041 tEplKernel              Ret;
2042 tEplObdEntryPtr         pObdEntry;
2043 tEplObdSubEntryPtr      pSubEntry;
2044 tEplObdAccess           Access;
2045 void MEM*               pDstData;
2046 tEplObdSize             ObdSize;
2047 BOOL                    fEntryNumerical;
2048
2049 #if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
2050     tEplObdVStringDomain MEM    MemVStringDomain;
2051     void MEM*                   pCurrData;
2052 #endif
2053
2054     // check for all API function if instance is valid
2055     EPL_MCO_CHECK_INSTANCE_STATE ();
2056
2057     ASSERT (pSrcData_p != NULL);    // should never be NULL
2058
2059     //------------------------------------------------------------------------
2060     // get address of index and subindex entry
2061     Ret = EplObdGetEntry (EPL_MCO_INSTANCE_PTR_
2062         uiIndex_p, uiSubIndex_p, &pObdEntry, &pSubEntry);
2063     if (Ret != kEplSuccessful)
2064     {
2065         goto Exit;
2066     }
2067
2068     // get pointer to object data
2069     pDstData = (void MEM*) EplObdGetObjectDataPtrIntern (pSubEntry);
2070
2071     Access = (tEplObdAccess) pSubEntry->m_Access;
2072
2073     // check access for write
2074     // access violation if adress to current value is NULL
2075     if ( ((Access & kEplObdAccConst) != 0) ||
2076          (pDstData == NULL) )
2077     {
2078         Ret = kEplObdAccessViolation;
2079         goto Exit;
2080     }
2081
2082     //------------------------------------------------------------------------
2083     // get size of object
2084     // -as ObdSize = ObdGetObjectSize (pSubEntry);
2085
2086     //------------------------------------------------------------------------
2087     // To use the same callback function for ObdWriteEntry as well as for
2088     // an SDO download call at first (kEplObdEvPre...) the callback function
2089     // with the argument pointer to object size.
2090     pCbParam_p->m_uiIndex    = uiIndex_p;
2091     pCbParam_p->m_uiSubIndex = uiSubIndex_p;
2092
2093     // Because object size and object pointer are
2094     // adapted by user callback function, re-read
2095     // this values.
2096     ObdSize = EplObdGetObjectSize (pSubEntry);
2097     pDstData = (void MEM*) EplObdGetObjectDataPtrIntern (pSubEntry);
2098
2099     // 09-dec-2004 r.d.:
2100     //      Function EplObdWriteEntry() calls new event kEplObdEvWrStringDomain
2101     //      for String or Domain which lets called module directly change
2102     //      the data pointer or size. This prevents a recursive call to
2103     //      the callback function if it calls EplObdGetEntry().
2104     #if (EPL_OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
2105     if ( (pSubEntry->m_Type == kEplObdTypVString) ||
2106          (pSubEntry->m_Type == kEplObdTypDomain)  ||
2107          (pSubEntry->m_Type == kEplObdTypOString))
2108     {
2109         if (pSubEntry->m_Type == kEplObdTypVString)
2110         {
2111             // reserve one byte for 0-termination
2112             // -as ObdSize -= 1;
2113             Size_p += 1;
2114         }
2115
2116         // fill out new arg-struct
2117         MemVStringDomain.m_DownloadSize = Size_p;
2118         MemVStringDomain.m_ObjSize      = ObdSize;
2119         MemVStringDomain.m_pData        = pDstData;
2120
2121         pCbParam_p->m_ObdEvent = kEplObdEvWrStringDomain;
2122         pCbParam_p->m_pArg     = &MemVStringDomain;
2123         //  call user callback
2124         Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
2125                 pObdEntry->m_fpCallback, pCbParam_p);
2126         if (Ret != kEplSuccessful)
2127         {
2128             goto Exit;
2129         }
2130
2131         // write back new settings
2132         pCurrData = pSubEntry->m_pCurrent;
2133         if ((pSubEntry->m_Type == kEplObdTypVString)
2134             ||(pSubEntry->m_Type ==  kEplObdTypOString))
2135         {
2136             ((tEplObdVString MEM*) pCurrData)->m_Size    = MemVStringDomain.m_ObjSize;
2137             ((tEplObdVString MEM*) pCurrData)->m_pString = MemVStringDomain.m_pData;
2138         }
2139         else // if (pSdosTableEntry_p->m_bObjType == kEplObdTypDomain)
2140         {
2141             ((tEplObdVarEntry MEM*) pCurrData)->m_Size  = MemVStringDomain.m_ObjSize;
2142             ((tEplObdVarEntry MEM*) pCurrData)->m_pData = (void MEM*) MemVStringDomain.m_pData;
2143         }
2144
2145         // Because object size and object pointer are
2146         // adapted by user callback function, re-read
2147         // this values.
2148         ObdSize  = MemVStringDomain.m_ObjSize;
2149         pDstData = (void MEM*) MemVStringDomain.m_pData;
2150     }
2151     #endif //#if (OBD_USE_STRING_DOMAIN_IN_RAM != FALSE)
2152
2153     // 07-dec-2004 r.d.: size from application is needed because callback function can change the object size
2154     // -as 16.11.04 CbParam.m_pArg     = &ObdSize;
2155     // 09-dec-2004 r.d.: CbParam.m_pArg     = &Size_p;
2156     pCbParam_p->m_pArg     = &ObdSize;
2157     pCbParam_p->m_ObdEvent = kEplObdEvInitWrite;
2158     Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
2159         pObdEntry->m_fpCallback, pCbParam_p);
2160     if (Ret != kEplSuccessful)
2161     {
2162         goto Exit;
2163     }
2164
2165     if (Size_p > ObdSize)
2166     {
2167         Ret = kEplObdValueLengthError;
2168         goto Exit;
2169     }
2170
2171     if (pSubEntry->m_Type == kEplObdTypVString)
2172     {
2173         if (((char MEM*) pSrcData_p)[Size_p - 1] == '\0')
2174         {   // last byte of source string contains null character
2175
2176             // reserve one byte in destination for 0-termination
2177             Size_p  -= 1;
2178         }
2179         else if (Size_p >= ObdSize)
2180         {   // source string is not 0-terminated
2181             // and destination buffer is too short
2182             Ret = kEplObdValueLengthError;
2183             goto Exit;
2184         }
2185     }
2186
2187     Ret = EplObdIsNumericalIntern(pSubEntry, &fEntryNumerical);
2188     if (Ret != kEplSuccessful)
2189     {
2190         goto Exit;
2191     }
2192
2193     if ((fEntryNumerical != FALSE)
2194         && (Size_p != ObdSize))
2195     {
2196         // type is numerical, therefor size has to fit, but it does not.
2197         Ret = kEplObdValueLengthError;
2198         goto Exit;
2199     }
2200
2201     // use given size, because non-numerical objects can be written with shorter values
2202     ObdSize = Size_p;
2203
2204     // set output parameters
2205     *pObdSize_p = ObdSize;
2206     *ppObdEntry_p = pObdEntry;
2207     *ppSubEntry_p = pSubEntry;
2208     *ppDstData_p = pDstData;
2209
2210     // all checks are done
2211     // the caller may now convert the numerial source value to platform byte order in a temporary buffer
2212
2213 Exit:
2214
2215     return Ret;
2216
2217 }
2218
2219
2220 //---------------------------------------------------------------------------
2221 //
2222 // Function:    EplObdWriteEntryPost()
2223 //
2224 // Description: Function finishes write of data to an OBD entry. Strings
2225 //              are stored with added '\0' character.
2226 //
2227 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR_
2228 //              uiIndex_p       =   Index of the OD entry
2229 //              uiSubIndex_p    =   Subindex of the OD Entry
2230 //              pSrcData_p      =   Pointer to the data to write
2231 //              Size_p          =   Size of the data in Byte
2232 //
2233 // Return:      tEplKernel      =   Errorcode
2234 //
2235 //
2236 // State:
2237 //
2238 //---------------------------------------------------------------------------
2239
2240 static tEplKernel PUBLIC EplObdWriteEntryPost (EPL_MCO_DECL_INSTANCE_PTR_
2241     tEplObdEntryPtr         pObdEntry_p,
2242     tEplObdSubEntryPtr      pSubEntry_p,
2243     tEplObdCbParam MEM*     pCbParam_p,
2244     void * pSrcData_p,
2245     void * pDstData_p,
2246     tEplObdSize   ObdSize_p)
2247 {
2248
2249 tEplKernel              Ret;
2250
2251
2252     // caller converted the source value to platform byte order
2253     // now the range of the value may be checked
2254
2255     #if (EPL_OBD_CHECK_OBJECT_RANGE != FALSE)
2256     {
2257         // check data range
2258         Ret = EplObdCheckObjectRange (pSubEntry_p, pSrcData_p);
2259         if (Ret != kEplSuccessful)
2260         {
2261             goto Exit;
2262         }
2263     }
2264     #endif
2265
2266     // now call user callback function to check value
2267     // write address of source data to structure of callback parameters
2268     // so callback function can check this data
2269     pCbParam_p->m_pArg     = pSrcData_p;
2270     pCbParam_p->m_ObdEvent = kEplObdEvPreWrite;
2271     Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
2272         pObdEntry_p->m_fpCallback, pCbParam_p);
2273     if (Ret != kEplSuccessful)
2274     {
2275         goto Exit;
2276     }
2277
2278     // copy object data to OBD
2279     EPL_MEMCPY (pDstData_p, pSrcData_p, ObdSize_p);
2280
2281     // terminate string with 0
2282     if (pSubEntry_p->m_Type == kEplObdTypVString)
2283     {
2284         ((char MEM*) pDstData_p)[ObdSize_p] = '\0';
2285     }
2286
2287     // write address of destination to structure of callback parameters
2288     // so callback function can change data subsequently
2289     pCbParam_p->m_pArg     = pDstData_p;
2290     pCbParam_p->m_ObdEvent = kEplObdEvPostWrite;
2291     Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
2292         pObdEntry_p->m_fpCallback, pCbParam_p);
2293
2294 Exit:
2295
2296     return Ret;
2297
2298 }
2299
2300
2301 //---------------------------------------------------------------------------
2302 //
2303 // Function:    EplObdGetObjectSize()
2304 //
2305 // Description: function to get size of object
2306 //              The function determines if an object type an fixed data type (BYTE, WORD, ...)
2307 //              or non fixed object (string, domain). This information is used to decide
2308 //              if download data are stored temporary or not. For objects with fixed data length
2309 //              and types a value range checking can process.
2310 //              For strings the function returns the whole object size not the
2311 //              length of string.
2312 //
2313 // Parameters:  pSubIndexEntry_p
2314 //
2315 // Return:      tEplObdSize
2316 //
2317 // State:
2318 //
2319 //---------------------------------------------------------------------------
2320
2321 static tEplObdSize EplObdGetObjectSize (tEplObdSubEntryPtr pSubIndexEntry_p)
2322 {
2323
2324 tEplObdSize DataSize = 0;
2325 void * pData;
2326
2327     switch (pSubIndexEntry_p->m_Type)
2328     {
2329         // -----------------------------------------------------------------
2330         case kEplObdTypBool:
2331
2332             DataSize = 1;
2333             break;
2334
2335         // -----------------------------------------------------------------
2336         // ObdTypes which has to be check because numerical values
2337         case kEplObdTypInt8:
2338             DataSize = sizeof (tEplObdInteger8);
2339             break;
2340
2341         // -----------------------------------------------------------------
2342         case kEplObdTypUInt8:
2343             DataSize = sizeof (tEplObdUnsigned8);
2344             break;
2345
2346         // -----------------------------------------------------------------
2347         case kEplObdTypInt16:
2348             DataSize = sizeof (tEplObdInteger16);
2349             break;
2350
2351         // -----------------------------------------------------------------
2352         case kEplObdTypUInt16:
2353             DataSize = sizeof (tEplObdUnsigned16);
2354             break;
2355
2356         // -----------------------------------------------------------------
2357         case kEplObdTypInt32:
2358             DataSize = sizeof (tEplObdInteger32);
2359             break;
2360
2361         // -----------------------------------------------------------------
2362         case kEplObdTypUInt32:
2363             DataSize = sizeof (tEplObdUnsigned32);
2364             break;
2365
2366         // -----------------------------------------------------------------
2367         case kEplObdTypReal32:
2368             DataSize = sizeof (tEplObdReal32);
2369             break;
2370
2371         // -----------------------------------------------------------------
2372         // ObdTypes which has to be not checked because not NUM values
2373         case kEplObdTypDomain:
2374
2375             pData = (void *) pSubIndexEntry_p->m_pCurrent;
2376             if ((void MEM*) pData != (void MEM*) NULL)
2377             {
2378                 DataSize = ((tEplObdVarEntry MEM*) pData)->m_Size;
2379             }
2380             break;
2381
2382         // -----------------------------------------------------------------
2383         case kEplObdTypVString:
2384         //case kEplObdTypUString:
2385
2386             // If OD entry is defined by macro EPL_OBD_SUBINDEX_ROM_VSTRING
2387             // then the current pointer is always NULL. The function
2388             // returns the length of default string.
2389             pData = (void *) pSubIndexEntry_p->m_pCurrent;
2390             if ((void MEM*) pData != (void MEM*) NULL)
2391             {
2392                 // The max. size of strings defined by STRING-Macro is stored in
2393                 // tEplObdVString of current value.
2394                 // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
2395                 DataSize = ((tEplObdVString MEM*) pData)->m_Size;
2396             }
2397             else
2398             {
2399                 // The current position is not decleared. The string
2400                 // is located in ROM, therefor use default pointer.
2401                 pData = (void *) pSubIndexEntry_p->m_pDefault;
2402                 if ((CONST void ROM*) pData != (CONST void ROM*) NULL)
2403                 {
2404                    // The max. size of strings defined by STRING-Macro is stored in
2405                    // tEplObdVString of default value.
2406                    DataSize = ((CONST tEplObdVString ROM*) pData)->m_Size;
2407                 }
2408             }
2409
2410             break;
2411
2412         // -----------------------------------------------------------------
2413         case kEplObdTypOString:
2414
2415             pData = (void *) pSubIndexEntry_p->m_pCurrent;
2416             if ((void MEM*) pData != (void MEM*) NULL)
2417             {
2418                 // The max. size of strings defined by STRING-Macro is stored in
2419                 // tEplObdVString of current value.
2420                 // (types tEplObdVString, tEplObdOString and tEplObdUString has the same members)
2421                 DataSize = ((tEplObdOString MEM*) pData)->m_Size;
2422             }
2423             else
2424             {
2425                 // The current position is not decleared. The string
2426                 // is located in ROM, therefor use default pointer.
2427                 pData = (void *) pSubIndexEntry_p->m_pDefault;
2428                 if ((CONST void ROM*) pData != (CONST void ROM*) NULL)
2429                 {
2430                    // The max. size of strings defined by STRING-Macro is stored in
2431                    // tEplObdVString of default value.
2432                    DataSize = ((CONST tEplObdOString ROM*) pData)->m_Size;
2433                 }
2434             }
2435             break;
2436
2437         // -----------------------------------------------------------------
2438         case kEplObdTypInt24:
2439         case kEplObdTypUInt24:
2440
2441             DataSize = 3;
2442             break;
2443
2444
2445         // -----------------------------------------------------------------
2446         case kEplObdTypInt40:
2447         case kEplObdTypUInt40:
2448
2449             DataSize = 5;
2450             break;
2451
2452         // -----------------------------------------------------------------
2453         case kEplObdTypInt48:
2454         case kEplObdTypUInt48:
2455
2456             DataSize = 6;
2457             break;
2458
2459         // -----------------------------------------------------------------
2460         case kEplObdTypInt56:
2461         case kEplObdTypUInt56:
2462
2463             DataSize = 7;
2464             break;
2465
2466         // -----------------------------------------------------------------
2467         case kEplObdTypInt64:
2468         case kEplObdTypUInt64:
2469         case kEplObdTypReal64:
2470
2471             DataSize = 8;
2472             break;
2473
2474         // -----------------------------------------------------------------
2475         case kEplObdTypTimeOfDay:
2476         case kEplObdTypTimeDiff:
2477
2478             DataSize = 6;
2479             break;
2480
2481         // -----------------------------------------------------------------
2482         default:
2483             break;
2484     }
2485
2486     return DataSize;
2487 }
2488
2489 //---------------------------------------------------------------------------
2490 //
2491 // Function:    EplObdGetObjectDefaultPtr()
2492 //
2493 // Description: function to get the default pointer (type specific)
2494 //
2495 // Parameters:  pSubIndexEntry_p    = pointer to subindex structure
2496 //
2497 // Returns:     (void *)   = pointer to default value
2498 //
2499 // State:
2500 //
2501 //---------------------------------------------------------------------------
2502
2503 static void * EplObdGetObjectDefaultPtr (tEplObdSubEntryPtr pSubIndexEntry_p)
2504 {
2505
2506 void *   pDefault;
2507 tEplObdType     Type;
2508
2509     ASSERTMSG (pSubIndexEntry_p != NULL, "EplObdGetObjectDefaultPtr(): pointer to SubEntry not valid!\n");
2510
2511     // get address to default data from default pointer
2512     pDefault = pSubIndexEntry_p->m_pDefault;
2513     if (pDefault != NULL)
2514     {
2515         // there are some special types, whose default pointer always is NULL or has to get from other structure
2516         // get type from subindex structure
2517         Type = pSubIndexEntry_p->m_Type;
2518
2519         // check if object type is a string value
2520         if ((Type == kEplObdTypVString) /* ||
2521             (Type == kEplObdTypUString) */ )
2522         {
2523
2524             // EPL_OBD_SUBINDEX_RAM_VSTRING
2525             //    tEplObdSize         m_Size;       --> size of default string
2526             //    char *    m_pDefString; --> pointer to  default string
2527             //    char *    m_pString;    --> pointer to string in RAM
2528             //
2529             pDefault = (void *) ((tEplObdVString *) pDefault)->m_pString;
2530         }
2531         else if(Type == kEplObdTypOString)
2532         {
2533              pDefault = (void *) ((tEplObdOString *) pDefault)->m_pString;
2534         }
2535     }
2536
2537     return pDefault;
2538
2539 }
2540
2541
2542 //---------------------------------------------------------------------------
2543 //
2544 // Function:    EplObdGetVarEntry()
2545 //
2546 // Description: gets a variable entry of an object
2547 //
2548 // Parameters:  pSubindexEntry_p
2549 //              ppVarEntry_p
2550 //
2551 // Return:      tCopKernel
2552 //
2553 // State:
2554 //
2555 //---------------------------------------------------------------------------
2556
2557 static tEplKernel EplObdGetVarEntry (
2558     tEplObdSubEntryPtr    pSubindexEntry_p,
2559     tEplObdVarEntry MEM** ppVarEntry_p)
2560 {
2561
2562 tEplKernel Ret = kEplObdVarEntryNotExist;
2563
2564     ASSERT (ppVarEntry_p != NULL);   // is not allowed to be NULL
2565     ASSERT (pSubindexEntry_p != NULL);
2566
2567     // check VAR-Flag - only this object points to variables
2568     if ((pSubindexEntry_p->m_Access & kEplObdAccVar) != 0)
2569     {
2570         // check if object is an array
2571         if ((pSubindexEntry_p->m_Access & kEplObdAccArray) != 0)
2572         {
2573             *ppVarEntry_p = &((tEplObdVarEntry MEM*) pSubindexEntry_p->m_pCurrent)[pSubindexEntry_p->m_uiSubIndex - 1];
2574         }
2575         else
2576         {
2577             *ppVarEntry_p = (tEplObdVarEntry MEM*) pSubindexEntry_p->m_pCurrent;
2578         }
2579
2580         Ret = kEplSuccessful;
2581     }
2582
2583     return Ret;
2584
2585 }
2586
2587 //---------------------------------------------------------------------------
2588 //
2589 // Function:    EplObdGetEntry()
2590 //
2591 // Description: gets a index entry from OD
2592 //
2593 // Parameters:  uiIndex_p       =   Index number
2594 //              uiSubindex_p    =   Subindex number
2595 //              ppObdEntry_p    =   pointer to the pointer to the entry
2596 //              ppObdSubEntry_p =   pointer to the pointer to the subentry
2597 //
2598 // Return:      tEplKernel
2599
2600 //
2601 // State:
2602 //
2603 //---------------------------------------------------------------------------
2604
2605 static tEplKernel  EplObdGetEntry (EPL_MCO_DECL_INSTANCE_PTR_
2606     unsigned int             uiIndex_p,
2607     unsigned int             uiSubindex_p,
2608     tEplObdEntryPtr*         ppObdEntry_p,
2609     tEplObdSubEntryPtr*      ppObdSubEntry_p)
2610 {
2611
2612 tEplObdEntryPtr         pObdEntry;
2613 tEplObdCbParam MEM      CbParam;
2614 tEplKernel              Ret;
2615
2616     // check for all API function if instance is valid
2617     EPL_MCO_CHECK_INSTANCE_STATE ();
2618
2619     //------------------------------------------------------------------------
2620     // get address of entry of index
2621     Ret = EplObdGetIndexIntern (&EPL_MCO_GLB_VAR (m_ObdInitParam), uiIndex_p, &pObdEntry);
2622     if (Ret != kEplSuccessful)
2623     {
2624         goto Exit;
2625     }
2626
2627     //------------------------------------------------------------------------
2628     // get address of entry of subindex
2629     Ret = EplObdGetSubindexIntern (pObdEntry, uiSubindex_p, ppObdSubEntry_p);
2630     if (Ret != kEplSuccessful)
2631     {
2632         goto Exit;
2633     }
2634
2635     //------------------------------------------------------------------------
2636     // call callback function to inform user/stack that an object will be searched
2637     // if the called module returnes an error then we abort the searching with kEplObdIndexNotExist
2638     CbParam.m_uiIndex    = uiIndex_p;
2639     CbParam.m_uiSubIndex = uiSubindex_p;
2640     CbParam.m_pArg       = NULL;
2641     CbParam.m_ObdEvent   = kEplObdEvCheckExist;
2642     Ret = EplObdCallObjectCallback (EPL_MCO_INSTANCE_PTR_
2643         pObdEntry->m_fpCallback, &CbParam);
2644     if (Ret != kEplSuccessful)
2645     {
2646         Ret = kEplObdIndexNotExist;
2647         goto Exit;
2648     }
2649
2650     //------------------------------------------------------------------------
2651     // it is allowed to set ppObdEntry_p to NULL
2652     // if so, no address will be written to calling function
2653     if (ppObdEntry_p != NULL)
2654     {
2655         *ppObdEntry_p = pObdEntry;
2656     }
2657
2658 Exit:
2659
2660     return Ret;
2661
2662 }
2663 //---------------------------------------------------------------------------
2664 //
2665 // Function:    EplObdGetObjectCurrentPtr()
2666 //
2667 // Description: function to get Current pointer (type specific)
2668 //
2669 // Parameters:  pSubIndexEntry_p
2670 //
2671 // Return:      void MEM*
2672 //
2673 // State:
2674 //
2675 //---------------------------------------------------------------------------
2676
2677 static void MEM* EplObdGetObjectCurrentPtr (tEplObdSubEntryPtr pSubIndexEntry_p)
2678 {
2679
2680 void MEM*       pData;
2681 unsigned int    uiArrayIndex;
2682 tEplObdSize     Size;
2683
2684     pData = pSubIndexEntry_p->m_pCurrent;
2685
2686     // check if constant object
2687     if (pData != NULL)
2688     {
2689         // check if object is an array
2690         if ((pSubIndexEntry_p->m_Access & kEplObdAccArray) != 0)
2691         {
2692             // calculate correct data pointer
2693             uiArrayIndex = pSubIndexEntry_p->m_uiSubIndex - 1;
2694             if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0)
2695             {
2696                 Size = sizeof (tEplObdVarEntry);
2697             }
2698             else
2699             {
2700                 Size = EplObdGetObjectSize (pSubIndexEntry_p);
2701             }
2702             pData = ((BYTE MEM*) pData) + (Size * uiArrayIndex);
2703         }
2704
2705         // check if VarEntry
2706         if ((pSubIndexEntry_p->m_Access & kEplObdAccVar) != 0)
2707         {
2708             // The data pointer is stored in VarEntry->pData
2709             pData = ((tEplObdVarEntry MEM*) pData)->m_pData;
2710         }
2711
2712         // the default pointer is stored for strings in tEplObdVString
2713         else if ((pSubIndexEntry_p->m_Type == kEplObdTypVString) /* ||
2714             (pSubIndexEntry_p->m_Type == kEplObdTypUString)    */ )
2715         {
2716             pData = (void MEM*) ((tEplObdVString MEM*) pData)->m_pString;
2717         }
2718         else if (pSubIndexEntry_p->m_Type == kEplObdTypOString)
2719         {
2720             pData = (void MEM*) ((tEplObdOString MEM*) pData)->m_pString;
2721         }
2722     }
2723
2724     return pData;
2725
2726 }
2727
2728
2729 //---------------------------------------------------------------------------
2730 //
2731 // Function:    EplObdGetIndexIntern()
2732 //
2733 // Description: gets a index entry from OD
2734 //
2735 // Parameters:  pInitParam_p
2736 //              uiIndex_p
2737 //              ppObdEntry_p
2738 //
2739 // Return:      tEplKernel
2740 //
2741 // State:
2742 //
2743 //---------------------------------------------------------------------------
2744
2745 static tEplKernel EplObdGetIndexIntern (
2746                         tEplObdInitParam MEM*    pInitParam_p,
2747                         unsigned int             uiIndex_p,
2748                         tEplObdEntryPtr*         ppObdEntry_p)
2749 {
2750
2751 tEplObdEntryPtr pObdEntry;
2752 tEplKernel      Ret;
2753 unsigned int    uiIndex;
2754
2755 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
2756
2757 unsigned int  nLoop;
2758
2759     // if user OD is used then objekts also has to be searched in user OD
2760     // there is less code need if we do this in a loop
2761     nLoop = 2;
2762
2763 #endif
2764
2765     ASSERTMSG (ppObdEntry_p != NULL, "EplObdGetIndexIntern(): pointer to index entry is NULL!\n");
2766
2767     Ret = kEplObdIndexNotExist;
2768
2769     // get start address of OD part
2770     // start address depends on object index because
2771     // object dictionary is divided in 3 parts
2772     if ((uiIndex_p >= 0x1000) && (uiIndex_p < 0x2000))
2773     {
2774         pObdEntry = pInitParam_p->m_pPart;
2775     }
2776     else if ((uiIndex_p >= 0x2000) && (uiIndex_p < 0x6000))
2777     {
2778         pObdEntry = pInitParam_p->m_pManufacturerPart;
2779     }
2780
2781     // index range 0xA000 to 0xFFFF is reserved for DSP-405
2782     // DS-301 defines that range 0x6000 to 0x9FFF (!!!) is stored if "store" was written to 0x1010/3.
2783     // Therefore default configuration is OBD_INCLUDE_A000_TO_DEVICE_PART = FALSE.
2784     // But a CANopen Application which does not implement dynamic OD or user-OD but wants to use static objets 0xA000...
2785     // should set OBD_INCLUDE_A000_TO_DEVICE_PART to TRUE.
2786
2787 #if (EPL_OBD_INCLUDE_A000_TO_DEVICE_PART == FALSE)
2788     else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0x9FFF))
2789 #else
2790     else if ((uiIndex_p >= 0x6000) && (uiIndex_p < 0xFFFF))
2791 #endif
2792     {
2793         pObdEntry = pInitParam_p->m_pDevicePart;
2794     }
2795
2796
2797 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
2798
2799     // if index does not match in static OD then index only has to be searched in user OD
2800     else
2801     {
2802         // begin from first entry of user OD part
2803         pObdEntry = pInitParam_p->m_pUserPart;
2804
2805         // no user OD is available
2806         if (pObdEntry == NULL)
2807         {
2808             goto Exit;
2809         }
2810
2811         // loop must only run once
2812         nLoop = 1;
2813     }
2814
2815     do
2816     {
2817
2818 #else
2819
2820         // no user OD is available
2821         // so other object can be found in OD
2822         else
2823         {
2824             Ret = kEplObdIllegalPart;
2825             goto Exit;
2826         }
2827
2828 #endif
2829
2830         // note:
2831         // The end of Index table is marked with m_uiIndex = 0xFFFF.
2832         // If this function will be called with wIndex_p = 0xFFFF, entry
2833         // should not be found. Therefor it is important to use
2834         // while{} instead of do{}while !!!
2835
2836         // get first index of index table
2837         uiIndex = pObdEntry->m_uiIndex;
2838
2839         // search Index in OD part
2840         while (uiIndex != EPL_OBD_TABLE_INDEX_END)
2841         {
2842             // go to the end of this function if index is found
2843             if (uiIndex_p == uiIndex)
2844             {
2845                 // write address of OD entry to calling function
2846                 *ppObdEntry_p = pObdEntry;
2847                 Ret = kEplSuccessful;
2848                 goto Exit;
2849             }
2850
2851             // objects are sorted in OD
2852             // if the current index in OD is greater than the index which is to search then break loop
2853             // in this case user OD has to be search too
2854             if (uiIndex_p < uiIndex)
2855             {
2856                 break;
2857             }
2858
2859             // next entry in index table
2860             pObdEntry++;
2861
2862             // get next index of index table
2863             uiIndex = pObdEntry->m_uiIndex;
2864         }
2865
2866 #if (defined (EPL_OBD_USER_OD) && (EPL_OBD_USER_OD != FALSE))
2867
2868         // begin from first entry of user OD part
2869         pObdEntry = pInitParam_p->m_pUserPart;
2870
2871         // no user OD is available
2872         if (pObdEntry == NULL)
2873         {
2874             goto Exit;
2875         }
2876
2877         // switch next loop for user OD
2878         nLoop--;
2879
2880     } while (nLoop > 0);
2881
2882 #endif
2883
2884     // in this line Index was not found
2885
2886 Exit:
2887
2888     return Ret;
2889
2890 }
2891
2892
2893 //---------------------------------------------------------------------------
2894 //
2895 // Function:    EplObdGetSubindexIntern()
2896 //
2897 // Description: gets a subindex entry from a index entry
2898 //
2899 // Parameters:  pObdEntry_p
2900 //              bSubIndex_p
2901 //              ppObdSubEntry_p
2902 //
2903 // Return:      tEplKernel
2904 //
2905 // State:
2906 //
2907 //---------------------------------------------------------------------------
2908
2909 static tEplKernel EplObdGetSubindexIntern (
2910     tEplObdEntryPtr           pObdEntry_p,
2911     unsigned int              uiSubIndex_p,
2912     tEplObdSubEntryPtr*       ppObdSubEntry_p)
2913 {
2914
2915 tEplObdSubEntryPtr pSubEntry;
2916 unsigned int       nSubIndexCount;
2917 tEplKernel         Ret;
2918
2919     ASSERTMSG (pObdEntry_p != NULL, "EplObdGetSubindexIntern(): pointer to index is NULL!\n");
2920     ASSERTMSG (ppObdSubEntry_p != NULL, "EplObdGetSubindexIntern(): pointer to subindex is NULL!\n");
2921
2922     Ret = kEplObdSubindexNotExist;
2923
2924     // get start address of subindex table and count of subindices
2925     pSubEntry     = pObdEntry_p->m_pSubIndex;
2926     nSubIndexCount =  pObdEntry_p->m_uiCount;
2927     ASSERTMSG ((pSubEntry != NULL) && (nSubIndexCount > 0),
2928         "ObdGetSubindexIntern(): invalid subindex table within index table!\n");   // should never be NULL
2929
2930     // search subindex in subindex table
2931     while (nSubIndexCount > 0)
2932     {
2933         // check if array is found
2934         if ((pSubEntry->m_Access & kEplObdAccArray) != 0)
2935         {
2936             // check if subindex is in range
2937             if (uiSubIndex_p < pObdEntry_p->m_uiCount)
2938             {
2939                 // update subindex number (subindex entry of an array is always in RAM !!!)
2940                 pSubEntry->m_uiSubIndex = uiSubIndex_p;
2941                 *ppObdSubEntry_p = pSubEntry;
2942                 Ret = kEplSuccessful;
2943                 goto Exit;
2944             }
2945         }
2946
2947         // go to the end of this function if subindex is found
2948         else if (uiSubIndex_p == pSubEntry->m_uiSubIndex)
2949         {
2950             *ppObdSubEntry_p = pSubEntry;
2951             Ret = kEplSuccessful;
2952             goto Exit;
2953         }
2954
2955         // objects are sorted in OD
2956         // if the current subindex in OD is greater than the subindex which is to search then break loop
2957         // in this case user OD has to be search too
2958         if (uiSubIndex_p < pSubEntry->m_uiSubIndex)
2959         {
2960             break;
2961         }
2962
2963         pSubEntry++;
2964         nSubIndexCount--;
2965     }
2966
2967     // in this line SubIndex was not fount
2968
2969 Exit:
2970
2971     return Ret;
2972
2973 }
2974
2975
2976 //---------------------------------------------------------------------------
2977 //
2978 // Function:    EplObdSetStoreLoadObjCallback()
2979 //
2980 // Description: function set address to callbackfunction for command Store and Load
2981 //
2982 // Parameters:  fpCallback_p
2983 //
2984 // Return:      tEplKernel
2985 //
2986 // State:
2987 //
2988 //---------------------------------------------------------------------------
2989 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
2990 EPLDLLEXPORT tEplKernel PUBLIC EplObdSetStoreLoadObjCallback (EPL_MCO_DECL_INSTANCE_PTR_
2991     tEplObdStoreLoadObjCallback fpCallback_p)
2992 {
2993
2994     EPL_MCO_CHECK_INSTANCE_STATE ();
2995
2996     // set new address of callback function
2997     EPL_MCO_GLB_VAR (m_fpStoreLoadObjCallback) = fpCallback_p;
2998
2999     return kEplSuccessful;
3000
3001 }
3002 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
3003
3004
3005 //---------------------------------------------------------------------------
3006 //
3007 // Function:    EplObdAccessOdPartIntern()
3008 //
3009 // Description: runs through OD and executes a job
3010 //
3011 // Parameters:  CurrentOdPart_p
3012 //              pObdEnty_p
3013 //              Direction_p     = what is to do (load values from flash or EEPROM, store, ...)
3014 //
3015 // Return:      tEplKernel
3016 //
3017 // State:
3018 //
3019 //---------------------------------------------------------------------------
3020
3021 static tEplKernel EplObdAccessOdPartIntern (EPL_MCO_DECL_INSTANCE_PTR_
3022     tEplObdPart     CurrentOdPart_p,
3023     tEplObdEntryPtr pObdEnty_p,
3024     tEplObdDir      Direction_p)
3025 {
3026
3027 tEplObdSubEntryPtr          pSubIndex;
3028 unsigned int                nSubIndexCount;
3029 tEplObdAccess               Access;
3030 void MEM*                   pDstData;
3031 void *               pDefault;
3032 tEplObdSize                 ObjSize;
3033 tEplKernel                  Ret;
3034 tEplObdCbStoreParam MEM     CbStore;
3035 tEplObdVarEntry MEM*        pVarEntry;
3036
3037     ASSERT (pObdEnty_p != NULL);
3038
3039     Ret = kEplSuccessful;
3040
3041     // prepare structure for STORE RESTORE callback function
3042     CbStore.m_bCurrentOdPart = (BYTE) CurrentOdPart_p;
3043     CbStore.m_pData          = NULL;
3044     CbStore.m_ObjSize        = 0;
3045
3046     // command of first action depends on direction to access
3047     #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
3048     if (Direction_p == kEplObdDirLoad)
3049     {
3050         CbStore.m_bCommand = (BYTE) kEplObdCommOpenRead;
3051
3052         // call callback function for previous command
3053         Ret = EplObdCallStoreCallback (EPL_MCO_INSTANCE_PTR_
3054             &CbStore);
3055         if (Ret != kEplSuccessful)
3056         {
3057             goto Exit;
3058         }
3059
3060         // set command for index and subindex loop
3061         CbStore.m_bCommand = (BYTE) kEplObdCommReadObj;
3062     }
3063     else if (Direction_p == kEplObdDirStore)
3064     {
3065         CbStore.m_bCommand = (BYTE) kEplObdCommOpenWrite;
3066
3067         // call callback function for previous command
3068         Ret = EplObdCallStoreCallback (EPL_MCO_INSTANCE_PTR_
3069             &CbStore);
3070         if (Ret != kEplSuccessful)
3071         {
3072             goto Exit;
3073         }
3074
3075         // set command for index and subindex loop
3076         CbStore.m_bCommand = (BYTE) kEplObdCommWriteObj;
3077     }
3078     #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
3079
3080     // we should not restore the OD values here
3081     // the next NMT command "Reset Node" or "Reset Communication" resets the OD data
3082     if (Direction_p != kEplObdDirRestore)
3083     {
3084         // walk through OD part till end is found
3085         while (pObdEnty_p->m_uiIndex != EPL_OBD_TABLE_INDEX_END)
3086         {
3087             // get address to subindex table and count of subindices
3088             pSubIndex     = pObdEnty_p->m_pSubIndex;
3089             nSubIndexCount = pObdEnty_p->m_uiCount;
3090             ASSERT ((pSubIndex != NULL) && (nSubIndexCount > 0));    // should never be NULL
3091
3092             // walk through subindex table till all subinices were restored
3093             while (nSubIndexCount != 0)
3094             {
3095                 Access = (tEplObdAccess) pSubIndex->m_Access;
3096
3097                 // get pointer to current and default data
3098                 pDefault = EplObdGetObjectDefaultPtr (pSubIndex);
3099                 pDstData = EplObdGetObjectCurrentPtr (pSubIndex);
3100
3101                 // NOTE (for kEplObdTypVString):
3102                 //      The function returnes the max. number of bytes for a
3103                 //      current string.
3104                 //      r.d.: For stings the default-size will be read in other lines following (kEplObdDirInit).
3105                 ObjSize  = EplObdGetObjectSize (pSubIndex);
3106
3107                 // switch direction of OD access
3108                 switch (Direction_p)
3109                 {
3110                     // --------------------------------------------------------------------------
3111                     // VarEntry structures has to be initialized
3112                     case kEplObdDirInit:
3113
3114                         // If VAR-Flag is set, m_pCurrent means not address of data
3115                         // but address of tEplObdVarEntry. Address of data has to be get from
3116                         // this structure.
3117                         if ((Access & kEplObdAccVar) != 0)
3118                         {
3119                             EplObdGetVarEntry (pSubIndex, &pVarEntry);
3120                             EplObdInitVarEntry (pVarEntry, pSubIndex->m_Type, ObjSize);
3121 /*
3122                             if ((Access & kEplObdAccArray) == 0)
3123                             {
3124                                 EplObdInitVarEntry (pSubIndex->m_pCurrent, pSubIndex->m_Type, ObjSize);
3125                             }
3126                             else
3127                             {
3128                                 EplObdInitVarEntry ((tEplObdVarEntry MEM*) (((BYTE MEM*) pSubIndex->m_pCurrent) + (sizeof (tEplObdVarEntry) * pSubIndex->m_uiSubIndex)),
3129                                     pSubIndex->m_Type, ObjSize);
3130                             }
3131 */
3132                             // at this time no application variable is defined !!!
3133                             // therefore data can not be copied.
3134                             break;
3135                         }
3136                         else if (pSubIndex->m_Type == kEplObdTypVString)
3137                         {
3138                             // If pointer m_pCurrent is not equal to NULL then the
3139                             // string was defined with EPL_OBD_SUBINDEX_RAM_VSTRING. The current
3140                             // pointer points to struct tEplObdVString located in MEM.
3141                             // The element size includes the max. number of
3142                             // bytes. The element m_pString includes the pointer
3143                             // to string in MEM. The memory location of default string
3144                             // must be copied to memory location of current string.
3145
3146                             pDstData = pSubIndex->m_pCurrent;
3147                             if (pDstData != NULL)
3148                             {
3149                                 // 08-dec-2004: code optimization !!!
3150                                 //              entries ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_pString
3151                                 //              and ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read
3152                                 //              twice. thats not necessary!
3153
3154                                 // For copying data we have to set the destination pointer to the real RAM string. This
3155                                 // pointer to RAM string is located in default string info structure. (translated r.d.)
3156                                 pDstData = (void MEM*) ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_pString;
3157                                 ObjSize  = ((tEplObdVStringDef ROM*) pSubIndex->m_pDefault)->m_Size;
3158
3159
3160                                 ((tEplObdVString MEM*) pSubIndex->m_pCurrent)->m_pString = pDstData;
3161                                 ((tEplObdVString MEM*) pSubIndex->m_pCurrent)->m_Size    = ObjSize;
3162                             }
3163
3164                         }
3165                         else if(pSubIndex->m_Type == kEplObdTypOString)
3166                         {
3167                             pDstData = pSubIndex->m_pCurrent;
3168                             if (pDstData != NULL)
3169                             {
3170                                 // 08-dec-2004: code optimization !!!
3171                                 //              entries ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_pString
3172                                 //              and ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_Size were read
3173                                 //              twice. thats not necessary!
3174
3175                                 // For copying data we have to set the destination pointer to the real RAM string. This
3176                                 // pointer to RAM string is located in default string info structure. (translated r.d.)
3177                                 pDstData = (void MEM*) ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_pString;
3178                                 ObjSize  = ((tEplObdOStringDef ROM*) pSubIndex->m_pDefault)->m_Size;
3179
3180
3181                                 ((tEplObdOString MEM*) pSubIndex->m_pCurrent)->m_pString = pDstData;
3182                                 ((tEplObdOString MEM*) pSubIndex->m_pCurrent)->m_Size    = ObjSize;
3183                             }
3184
3185                         }
3186
3187
3188                         // no break !! because copy of data has to done too.
3189
3190                     // --------------------------------------------------------------------------
3191                     // all objects has to be restored with default values
3192                     case kEplObdDirRestore:
3193
3194                         // 09-dec-2004 r.d.: optimization! the same code for kEplObdDirRestore and kEplObdDirLoad
3195                         //                   is replaced to function ObdCopyObjectData() with a new parameter.
3196
3197
3198                         // restore object data for init phase
3199                         EplObdCopyObjectData (pDstData, pDefault, ObjSize, pSubIndex->m_Type);
3200                         break;
3201
3202                     // --------------------------------------------------------------------------
3203                     // objects with attribute kEplObdAccStore has to be load from EEPROM or from a file
3204                     case kEplObdDirLoad:
3205
3206                         // restore object data for init phase
3207                         EplObdCopyObjectData (pDstData, pDefault, ObjSize, pSubIndex->m_Type);
3208
3209                         // no break !! because callback function has to be called too.
3210
3211                     // --------------------------------------------------------------------------
3212                     // objects with attribute kEplObdAccStore has to be stored in EEPROM or in a file
3213                     case kEplObdDirStore:
3214
3215                         // when attribute kEplObdAccStore is set, then call callback function
3216                         #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
3217                         if ((Access & kEplObdAccStore) != 0)
3218                         {
3219                             // fill out data pointer and size of data
3220                             CbStore.m_pData    = pDstData;
3221                             CbStore.m_ObjSize  = ObjSize;
3222
3223                             // call callback function for read or write object
3224                             Ret = ObdCallStoreCallback (EPL_MCO_INSTANCE_PTR_
3225                                 &CbStore);
3226                             if (Ret != kEplSuccessful)
3227                             {
3228                                 goto Exit;
3229                             }
3230                         }
3231                         #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
3232                         break;
3233
3234
3235                     // --------------------------------------------------------------------------
3236                     // if OD Builder key has to be checked no access to subindex and data should be made
3237                     case kEplObdDirOBKCheck:
3238
3239                         // no break !! because we want to break the second loop too.
3240
3241
3242                     // --------------------------------------------------------------------------
3243                     // unknown Direction
3244                     default:
3245
3246                         // so we can break the second loop earler
3247                         nSubIndexCount = 1;
3248                         break;
3249                 }
3250
3251                 nSubIndexCount--;
3252
3253                 // next subindex entry
3254                 if ((Access & kEplObdAccArray) == 0)
3255                 {
3256                     pSubIndex++;
3257                     if ((nSubIndexCount > 0)
3258                         && ((pSubIndex->m_Access & kEplObdAccArray) != 0))
3259                     {
3260                         // next subindex points to an array
3261                         // reset subindex number
3262                         pSubIndex->m_uiSubIndex = 1;
3263                     }
3264                 }
3265                 else
3266                 {
3267                     if (nSubIndexCount > 0)
3268                     {
3269                         // next subindex points to an array
3270                         // increment subindex number
3271                         pSubIndex->m_uiSubIndex++;
3272                     }
3273                 }
3274             }
3275
3276             // next index entry
3277             pObdEnty_p++;
3278         }
3279     }
3280
3281     // -----------------------------------------------------------------------------------------
3282     // command of last action depends on direction to access
3283     if (Direction_p == kEplObdDirOBKCheck)
3284     {
3285
3286         goto Exit;
3287     }
3288     #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
3289     else
3290     {
3291         if (Direction_p == kEplObdDirLoad)
3292         {
3293             CbStore.m_bCommand = (BYTE) kEplObdCommCloseRead;
3294         }
3295         else if (Direction_p == kEplObdDirStore)
3296         {
3297             CbStore.m_bCommand = (BYTE) kEplObdCommCloseWrite;
3298         }
3299         else if (Direction_p == kEplObdDirRestore)
3300         {
3301             CbStore.m_bCommand = (BYTE) kEplObdCommClear;
3302         }
3303         else
3304         {
3305             goto Exit;
3306         }
3307
3308         // call callback function for last command
3309         Ret = EplObdCallStoreCallback (EPL_MCO_INSTANCE_PTR_
3310             &CbStore);
3311     }
3312     #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
3313
3314 //    goto Exit;
3315
3316 Exit:
3317
3318     return Ret;
3319
3320 }
3321
3322
3323 // ----------------------------------------------------------------------------
3324 // Function:    EplObdCopyObjectData()
3325 //
3326 // Description: checks pointers to object data and copy them from source to destination
3327 //
3328 // Parameters:  pDstData_p              = destination pointer
3329 //              pSrcData_p              = source pointer
3330 //              ObjSize_p               = size of object
3331 //              ObjType_p               =
3332 //
3333 // Returns:     tEplKernel              = error code
3334 // ----------------------------------------------------------------------------
3335
3336 static void EplObdCopyObjectData (
3337             void MEM*           pDstData_p,
3338             void *              pSrcData_p,
3339             tEplObdSize         ObjSize_p,
3340             tEplObdType         ObjType_p)
3341 {
3342
3343
3344 tEplObdSize StrSize = 0;
3345
3346
3347     // it is allowed to set default and current address to NULL (nothing to copy)
3348     if (pDstData_p != NULL)
3349     {
3350
3351         if (ObjType_p == kEplObdTypVString)
3352         {
3353             // The function calculates the really number of characters of string. The
3354             // object entry size can be bigger as string size of default string.
3355             // The '\0'-termination is included. A string with no characters has a
3356             // size of 1.
3357             StrSize = EplObdGetStrLen ((void *) pSrcData_p, ObjSize_p, kEplObdTypVString);
3358
3359             // If the string length is greater than or equal to the entry size in OD then only copy
3360             // entry size - 1 and always set the '\0'-termination.
3361             if (StrSize >= ObjSize_p)
3362             {
3363                 StrSize = ObjSize_p - 1;
3364             }
3365         }
3366
3367         if (pSrcData_p != NULL)
3368         {
3369             // copy data
3370             EPL_MEMCPY (pDstData_p, pSrcData_p, ObjSize_p);
3371
3372             if (ObjType_p == kEplObdTypVString)
3373             {
3374                 ((char MEM*) pDstData_p)[StrSize] = '\0';
3375             }
3376         }
3377     }
3378
3379 }
3380
3381
3382 //---------------------------------------------------------------------------
3383 //
3384 // Function:    EplObdIsNumericalIntern()
3385 //
3386 // Description: function checks if a entry is numerical or not
3387 //
3388 //
3389 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = Instancepointer
3390 //              uiIndex_p           = Index
3391 //              uiSubIndex_p        = Subindex
3392 //              pfEntryNumerical_p  = pointer to BOOL for returnvalue
3393 //                                  -> TRUE if entry a numerical value
3394 //                                  -> FALSE if entry not a numerical value
3395 //
3396 // Return:      tEplKernel = Errorcode
3397 //
3398 // State:
3399 //
3400 //---------------------------------------------------------------------------
3401 static tEplKernel EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,
3402                                         BOOL*         pfEntryNumerical_p)
3403 {
3404 tEplKernel          Ret = kEplSuccessful;
3405
3406
3407     // get Type
3408     if((pObdSubEntry_p->m_Type == kEplObdTypVString)
3409         || (pObdSubEntry_p->m_Type == kEplObdTypOString)
3410         || (pObdSubEntry_p->m_Type == kEplObdTypDomain))
3411     {   // not numerical types
3412         *pfEntryNumerical_p = FALSE;
3413     }
3414     else
3415     {   // numerical types
3416         *pfEntryNumerical_p = TRUE;
3417     }
3418
3419     return Ret;
3420
3421 }
3422
3423
3424 // -------------------------------------------------------------------------
3425 // function to classify object type (fixed/non fixed)
3426 // -------------------------------------------------------------------------
3427
3428 // ----------------------------------------------------------------------------
3429 // Function:    EplObdCallStoreCallback()
3430 //
3431 // Description: checks address to callback function and calles it when unequal
3432 //              to NULL
3433 //
3434 // Parameters:  EPL_MCO_DECL_INSTANCE_PTR_ = (instance pointer)
3435 //              pCbStoreParam_p        = address to callback parameters
3436 //
3437 // Returns:     tEplKernel             = error code
3438 // ----------------------------------------------------------------------------
3439 #if (EPL_OBD_USE_STORE_RESTORE != FALSE)
3440 static tEplKernel EplObdCallStoreCallback (EPL_MCO_DECL_INSTANCE_PTR_
3441     tEplObdCbStoreParam MEM* pCbStoreParam_p)
3442 {
3443
3444 tEplKernel Ret = kEplSuccessful;
3445
3446     ASSERT (pCbStoreParam_p != NULL);
3447
3448     // check if function pointer is NULL - if so, no callback should be called
3449     if (EPL_MCO_GLB_VAR (m_fpStoreLoadObjCallback) != NULL)
3450     {
3451         Ret = EPL_MCO_GLB_VAR (m_fpStoreLoadObjCallback) (EPL_MCO_INSTANCE_PARAM_IDX_()
3452             pCbStoreParam_p);
3453     }
3454
3455     return Ret;
3456
3457 }
3458 #endif // (EPL_OBD_USE_STORE_RESTORE != FALSE)
3459 //---------------------------------------------------------------------------
3460 //
3461 // Function:    EplObdGetObjectDataPtrIntern()
3462 //
3463 // Description: Function gets the data pointer of an object.
3464 //              It returnes the current data pointer. But if object is an
3465 //              constant object it returnes the default pointer.
3466 //
3467 // Parameters:  pSubindexEntry_p = pointer to subindex entry
3468 //
3469 // Return:      void *    = pointer to object data
3470 //
3471 // State:
3472 //
3473 //---------------------------------------------------------------------------
3474
3475 void * EplObdGetObjectDataPtrIntern (tEplObdSubEntryPtr pSubindexEntry_p)
3476 {
3477
3478 void * pData;
3479 tEplObdAccess Access;
3480
3481     ASSERTMSG (pSubindexEntry_p != NULL, "EplObdGetObjectDataPtrIntern(): pointer to SubEntry not valid!\n");
3482
3483     // there are are some objects whose data pointer has to get from other structure
3484     // get access type for this object
3485     Access = pSubindexEntry_p->m_Access;
3486
3487     // If object has access type = const,
3488     // for data only exists default values.
3489     if ((Access & kEplObdAccConst) != 0)
3490     {
3491         // The pointer to defualt value can be received from ObdGetObjectDefaultPtr()
3492         pData = ((void *) EplObdGetObjectDefaultPtr (pSubindexEntry_p));
3493     }
3494     else
3495     {
3496         // The pointer to current value can be received from ObdGetObjectCurrentPtr()
3497         pData = ((void *) EplObdGetObjectCurrentPtr (pSubindexEntry_p));
3498     }
3499
3500     return pData;
3501
3502 }
3503 #endif // end of #if(((EPL_MODULE_INTEGRATION) & (EPL_MODULE_OBDK)) != 0)
3504 // EOF
3505