• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
EplObdInit(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam MEM * pInitParam_p)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 
EplObdAddInstance(EPL_MCO_DECL_PTR_INSTANCE_PTR_ tEplObdInitParam MEM * pInitParam_p)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)
EplObdDeleteInstance(EPL_MCO_DECL_INSTANCE_PTR)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 
EplObdWriteEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,unsigned int uiSubIndex_p,void * pSrcData_p,tEplObdSize Size_p)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 
EplObdReadEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,unsigned int uiSubIndex_p,void * pDstData_p,tEplObdSize * pSize_p)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 
EplObdAccessOdPart(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart ObdPart_p,tEplObdDir Direction_p)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 
EplObdDefineVar(EPL_MCO_DECL_INSTANCE_PTR_ tEplVarParam MEM * pVarParam_p)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 
EplObdGetObjectDataPtr(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,unsigned int uiSubIndex_p)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 //---------------------------------------------------------------------------
EplObdRegisterUserOd(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pUserOd_p)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 
EplObdInitVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdVarEntry MEM * pVarEntry_p,tEplObdType Type_p,tEplObdSize ObdSize_p)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 //---------------------------------------------------------------------------
EplObdGetDataSize(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,unsigned int uiSubIndex_p)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 //---------------------------------------------------------------------------
EplObdGetNodeId(EPL_MCO_DECL_INSTANCE_PTR)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 //---------------------------------------------------------------------------
EplObdSetNodeId(EPL_MCO_DECL_PTR_INSTANCE_PTR_ unsigned int uiNodeId_p,tEplObdNodeIdType NodeIdType_p)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 //---------------------------------------------------------------------------
EplObdIsNumerical(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,unsigned int uiSubIndex_p,BOOL * pfEntryNumerical_p)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 //---------------------------------------------------------------------------
EplObdReadEntryToLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,unsigned int uiSubIndex_p,void * pDstData_p,tEplObdSize * pSize_p)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 //---------------------------------------------------------------------------
EplObdWriteEntryFromLe(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,unsigned int uiSubIndex_p,void * pSrcData_p,tEplObdSize Size_p)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 //---------------------------------------------------------------------------
EplObdGetAccessType(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,unsigned int uiSubIndex_p,tEplObdAccess * pAccessTyp_p)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 
EplObdSearchVarEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,unsigned int uiSubindex_p,tEplObdVarEntry MEM ** ppVarEntry_p)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 
EPL_MCO_DECL_INSTANCE_FCT()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 
EplObdGetDataSizeIntern(tEplObdSubEntryPtr pSubIndexEntry_p)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 
EplObdGetStrLen(void * pObjData_p,tEplObdSize ObjLen_p,tEplObdType ObjType_p)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 
EplObdCheckObjectRange(tEplObdSubEntryPtr pSubindexEntry_p,void * pData_p)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 
EplObdWriteEntryPre(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,unsigned int uiSubIndex_p,void * pSrcData_p,void ** ppDstData_p,tEplObdSize Size_p,tEplObdEntryPtr * ppObdEntry_p,tEplObdSubEntryPtr * ppSubEntry_p,tEplObdCbParam MEM * pCbParam_p,tEplObdSize * pObdSize_p)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 
EplObdWriteEntryPost(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdEntryPtr pObdEntry_p,tEplObdSubEntryPtr pSubEntry_p,tEplObdCbParam MEM * pCbParam_p,void * pSrcData_p,void * pDstData_p,tEplObdSize ObdSize_p)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 
EplObdGetObjectSize(tEplObdSubEntryPtr pSubIndexEntry_p)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 
EplObdGetObjectDefaultPtr(tEplObdSubEntryPtr pSubIndexEntry_p)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 
EplObdGetVarEntry(tEplObdSubEntryPtr pSubindexEntry_p,tEplObdVarEntry MEM ** ppVarEntry_p)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 
EplObdGetEntry(EPL_MCO_DECL_INSTANCE_PTR_ unsigned int uiIndex_p,unsigned int uiSubindex_p,tEplObdEntryPtr * ppObdEntry_p,tEplObdSubEntryPtr * ppObdSubEntry_p)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 
EplObdGetObjectCurrentPtr(tEplObdSubEntryPtr pSubIndexEntry_p)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 
EplObdGetIndexIntern(tEplObdInitParam MEM * pInitParam_p,unsigned int uiIndex_p,tEplObdEntryPtr * ppObdEntry_p)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 
EplObdGetSubindexIntern(tEplObdEntryPtr pObdEntry_p,unsigned int uiSubIndex_p,tEplObdSubEntryPtr * ppObdSubEntry_p)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
EplObdSetStoreLoadObjCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdStoreLoadObjCallback fpCallback_p)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 
EplObdAccessOdPartIntern(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdPart CurrentOdPart_p,tEplObdEntryPtr pObdEnty_p,tEplObdDir Direction_p)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 
EplObdCopyObjectData(void MEM * pDstData_p,void * pSrcData_p,tEplObdSize ObjSize_p,tEplObdType ObjType_p)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 //---------------------------------------------------------------------------
EplObdIsNumericalIntern(tEplObdSubEntryPtr pObdSubEntry_p,BOOL * pfEntryNumerical_p)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)
EplObdCallStoreCallback(EPL_MCO_DECL_INSTANCE_PTR_ tEplObdCbStoreParam MEM * pCbStoreParam_p)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 
EplObdGetObjectDataPtrIntern(tEplObdSubEntryPtr pSubindexEntry_p)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
3263