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