]> rtime.felk.cvut.cz Git - arc.git/blob - diagnostic/Dem/Dem.c
Dem, event status is set to changed when test passes and test has not previously...
[arc.git] / diagnostic / Dem / Dem.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 // 904 PC-Lint MISRA 14.7: OK. Allow VALIDATE, VALIDATE_RV and VALIDATE_NO_RV to return value.\r
17 //lint -emacro(904,VALIDATE_RV,VALIDATE_NO_RV,VALIDATE)\r
18 \r
19 // 522 PC-Lint exception for empty functions\r
20 //lint -esym(522,storeFreezeFrameDataEvtMem)\r
21 //lint -esym(522,deleteFreezeFrameDataPriMem)\r
22 //lint -esym(522,storeFreezeFrameDataPreInit)\r
23 //lint -esym(522,storeFreezeFrameDataPriMem)\r
24 //lint -esym(522,updateFreezeFrameOccurrencePreInit)\r
25 \r
26 // PC-Lint misunderstanding of MISRA 8.12, 18.1: Empty arrays are OK as long as size 0 is specified.\r
27 //lint -esym(85,preInitFreezeFrameBuffer)\r
28 //lint -esym(85,priMemFreezeFrameBuffer)\r
29 \r
30 \r
31 /*\r
32  *  General requirements\r
33  */\r
34 /** @req DEM126 */\r
35 /** @req DEM151.partially */\r
36 /** @req DEM152 */\r
37 /** @req DEM013.14229-1 */\r
38 /** @req DEM277 */\r
39 /** @req DEM363 */\r
40 /** @req DEM113 */ /** @req DEM174 */\r
41 /** @req DEM286 */\r
42 /** @req DEM267 */\r
43 /** @req DEM364 */\r
44 /** @req DEM114 */\r
45 /** @req DEM124 */\r
46 /** @req DEM370 */\r
47 \r
48 \r
49 \r
50 #include <string.h>\r
51 #include "Dem.h"\r
52 //#include "Fim.h"\r
53 #include "NvM.h"\r
54 //#include "SchM_Dem.h"\r
55 #include "MemMap.h"\r
56 #include "Cpu.h"\r
57 #include "DEM_Types.h"\r
58 #include "DEM_Lcfg.h"\r
59 \r
60 #define USE_DEBUG_PRINTF\r
61 #include "debug.h"\r
62 /*\r
63  * Local defines\r
64  */\r
65 #define DEBOUNCE_FDC_TEST_FAILED  127\r
66 #define DEBOUNCE_FDC_TEST_PASSED -128\r
67 \r
68 #if  ( DEM_DEV_ERROR_DETECT == STD_ON )\r
69 #include "Det.h"\r
70 /** @req DEM117 */\r
71 #define VALIDATE_RV(_exp,_api,_err,_rv ) \\r
72         if( !(_exp) ) { \\r
73           Det_ReportError(MODULE_ID_DEM, 0, _api, _err); \\r
74           return _rv; \\r
75         }\r
76 \r
77 #define VALIDATE_NO_RV(_exp,_api,_err ) \\r
78   if( !(_exp) ) { \\r
79           Det_ReportError(MODULE_ID_DEM, 0, _api, _err); \\r
80           return; \\r
81         }\r
82 #define DET_REPORTERROR(_x,_y,_z,_q) Det_ReportError(_x, _y, _z, _q)\r
83 \r
84 #else\r
85 #define VALIDATE_RV(_exp,_api,_err,_rv )\r
86 #define VALIDATE_NO_RV(_exp,_api,_err )\r
87 #define DET_REPORTERROR(_x,_y,_z,_q)\r
88 #endif\r
89 \r
90 #if (DEM_OBD_SUPPORT == STD_ON)\r
91 #error "DEM_OBD_SUPPORT is set to STD_ON, this is not supported by the code."\r
92 #endif\r
93 \r
94 #if (DEM_PTO_SUPPORT == STD_ON)\r
95 #error "DEM_PTO_SUPPORT is set to STD_ON, this is not supported by the code."\r
96 #endif\r
97 \r
98 #if (DEM_TYPE_OF_DTC_SUPPORTED != 0x01)\r
99 #error "DEM_TYPE_OF_DTC_SUPPORTED is not set to 1 (ISO14229-1), only ISO14229-1 is currently supported by the code."\r
100 #endif\r
101 \r
102 \r
103 /*\r
104  * Local types\r
105  */\r
106 \r
107 // DtcFilterType\r
108 typedef struct {\r
109         Dem_EventStatusExtendedType dtcStatusMask;\r
110         Dem_DTCKindType                         dtcKind;\r
111         Dem_DTCOriginType                       dtcOrigin;\r
112         Dem_FilterWithSeverityType      filterWithSeverity;\r
113         Dem_DTCSeverityType                     dtcSeverityMask;\r
114         Dem_FilterForFDCType            filterForFaultDetectionCounter;\r
115         uint16                                          faultIndex;\r
116 } DtcFilterType;\r
117 \r
118 // DisableDtcStorageType\r
119 typedef struct {\r
120         boolean                                         storageDisabled;\r
121         Dem_DTCGroupType                        dtcGroup;\r
122         Dem_DTCKindType                         dtcKind;\r
123 } DisableDtcStorageType;\r
124 \r
125 // For keeping track of the events status\r
126 typedef struct {\r
127         Dem_EventIdType                         eventId;\r
128         const Dem_EventParameterType *eventParamRef;\r
129         sint8                                           faultDetectionCounter;\r
130         uint16                                          occurrence;                             /** @req DEM011 */\r
131         Dem_EventStatusExtendedType     eventStatusExtended;    /** @req DEM006 */\r
132         boolean                                         errorStatusChanged;\r
133 } EventStatusRecType;\r
134 \r
135 // Types for storing different event data on event memory\r
136 typedef struct {\r
137         Dem_EventIdType                         eventId;\r
138         uint16                                          occurrence;\r
139         Dem_EventStatusExtendedType eventStatusExtended;\r
140         ChecksumType                            checksum;\r
141 } EventRecType;\r
142 \r
143 typedef struct {\r
144         Dem_EventIdType         eventId;\r
145         uint16                          dataSize;\r
146         uint8                           data[DEM_MAX_SIZE_EXT_DATA];\r
147         ChecksumType            checksum;\r
148 } ExtDataRecType;\r
149 \r
150 \r
151 // State variable\r
152 typedef enum\r
153 {\r
154   DEM_UNINITIALIZED = 0,\r
155   DEM_PREINITIALIZED,\r
156   DEM_INITIALIZED\r
157 } Dem_StateType; /** @req DEM169 */\r
158 \r
159 \r
160 static Dem_StateType demState = DEM_UNINITIALIZED;\r
161 \r
162 // Help pointer to configuration set\r
163 static const Dem_ConfigSetType *configSet;\r
164 \r
165 /*\r
166  * Allocation of DTC filter parameters\r
167  */\r
168 static DtcFilterType dtcFilter;\r
169 \r
170 /*\r
171  * Allocation of Disable/Enable DTC storage parameters\r
172  */\r
173 static DisableDtcStorageType disableDtcStorage;\r
174 \r
175 /*\r
176  * Allocation of operation cycle state list\r
177  */\r
178 static Dem_OperationCycleStateType operationCycleStateList[DEM_OPERATION_CYCLE_ID_ENDMARK];\r
179 \r
180 /*\r
181  * Allocation of local event status buffer\r
182  */\r
183 static EventStatusRecType       eventStatusBuffer[DEM_MAX_NUMBER_EVENT];\r
184 \r
185 /*\r
186  * Allocation of pre-init event memory (used between pre-init and init)\r
187  */\r
188 /** @req DEM207 */\r
189 static FreezeFrameRecType       preInitFreezeFrameBuffer[DEM_MAX_NUMBER_FF_DATA_PRE_INIT];\r
190 static ExtDataRecType           preInitExtDataBuffer[DEM_MAX_NUMBER_EXT_DATA_PRE_INIT];\r
191 \r
192 /*\r
193  * Allocation of primary event memory ramlog (after init) in uninitialized memory\r
194  */\r
195 /** @req DEM162 */\r
196 EventRecType                    priMemEventBuffer[DEM_MAX_NUMBER_EVENT_PRI_MEM] __attribute__ ((section (".dem_eventmemory_pri")));\r
197 static FreezeFrameRecType       priMemFreezeFrameBuffer[DEM_MAX_NUMBER_FF_DATA_PRI_MEM] __attribute__ ((section (".dem_eventmemory_pri")));\r
198 //FreezeFrameRecType        FreezeFrameMirrorBuffer[DEM_MAX_NUMBER_FF_DATA_PRI_MEM] __attribute__ ((section (".dem_eventmemory_pri")));\r
199 extern FreezeFrameRecType*  FreezeFrameMirrorBuffer[];\r
200 static ExtDataRecType           priMemExtDataBuffer[DEM_MAX_NUMBER_EXT_DATA_PRI_MEM] __attribute__ ((section (".dem_eventmemory_pri")));\r
201 HealingRecType                  priMemAgingBuffer[DEM_MAX_NUMBER_AGING_PRI_MEM] __attribute__ ((section (".dem_eventmemory_pri")));\r
202 extern HealingRecType                   HealingMirrorBuffer[DEM_MAX_NUMBER_AGING_PRI_MEM];\r
203 \r
204 /* block in NVRam, use for freezeframe */\r
205 extern const NvM_BlockIdType FreezeFrameBlockId[DEM_MAX_NUMBER_FF_DATA_PRI_MEM];\r
206 /* block in NVRam, use for aging */\r
207 extern const NvM_BlockIdType HealingBlockId;\r
208 \r
209 \r
210 /*\r
211 *Allocation of freezeFrame storage timestamp,record the time order\r
212 */\r
213 /**private variable for freezeframe */\r
214 static uint32 FF_TimeStamp = 0;\r
215 \r
216 /*\r
217  * TRUE:        priMemFreezeFrameBuffer changed,\r
218  * FALSE:       priMemFreezeFrameBuffer not changed\r
219  */\r
220 static boolean FFIsModified = FALSE;\r
221 \r
222 /*\r
223  * TRUE:        priMemAgingBuffer changed,\r
224  * FALSE:       priMemAgingBuffer not changed\r
225  */\r
226 static boolean AgingIsModified = FALSE;\r
227 \r
228 /*\r
229  * Procedure:   zeroPriMemBuffers\r
230  * Description: Fill the primary buffers with zeroes\r
231  */\r
232 //lint -save\r
233 //lint -e84 //PC-Lint exception, size 0 is OK.\r
234 //lint -e957    PC-Lint exception - Used only by DemTest\r
235 void demZeroPriMemBuffers(void)\r
236 {\r
237         memset(priMemEventBuffer, 0, sizeof(priMemEventBuffer));\r
238         memset(priMemFreezeFrameBuffer, 0, sizeof(priMemFreezeFrameBuffer));\r
239         memset(priMemExtDataBuffer, 0, sizeof(priMemExtDataBuffer));\r
240 }\r
241 //lint -restore\r
242 \r
243 /*\r
244  * Procedure:   calcChecksum\r
245  * Description: Calculate checksum over *data to *(data+nrOfBytes-1) area\r
246  */\r
247 static ChecksumType calcChecksum(void *data, uint16 nrOfBytes)\r
248 {\r
249         uint16 i;\r
250         uint8 *byte = (uint8*)data;\r
251         ChecksumType sum = 0;\r
252 \r
253         for (i = 0; i < nrOfBytes; i++) {\r
254                 sum += byte[i];\r
255         }\r
256         sum ^= 0xaaaau;\r
257         return sum;\r
258 }\r
259 \r
260 \r
261 /*\r
262  * Procedure:   checkDtcKind\r
263  * Description: Return TRUE if "dtcKind" match the events DTCKind or "dtcKind"\r
264  *                              is "DEM_DTC_KIND_ALL_DTCS" otherwise FALSE.\r
265  */\r
266 static boolean checkDtcKind(Dem_DTCKindType dtcKind, const Dem_EventParameterType *eventParam)\r
267 {\r
268         boolean result = FALSE;\r
269 \r
270         if (dtcKind == DEM_DTC_KIND_ALL_DTCS) {\r
271                 result = TRUE;\r
272         }\r
273         else {\r
274                 if (eventParam->DTCClassRef != NULL) {\r
275                         if (eventParam->DTCClassRef->DTCKind == dtcKind) {\r
276                                 result = TRUE;\r
277                         }\r
278                 }\r
279         }\r
280         return result;\r
281 }\r
282 \r
283 \r
284 /*\r
285  * Procedure:   checkDtcGroup\r
286  * Description: Return TRUE if "dtc" match the events DTC or "dtc" is\r
287  *                              "DEM_DTC_GROUP_ALL_DTCS" otherwise FALSE.\r
288  */\r
289 static boolean checkDtcGroup(uint32 dtc, const Dem_EventParameterType *eventParam)\r
290 {\r
291         boolean result = FALSE;\r
292 \r
293         if (dtc == DEM_DTC_GROUP_ALL_DTCS) {\r
294                 result = TRUE;\r
295         }\r
296         else {\r
297                 if (eventParam->DTCClassRef != NULL) {\r
298                         if (eventParam->DTCClassRef->DTC == dtc) {\r
299                                 result = TRUE;\r
300                         }\r
301                 }\r
302         }\r
303         return result;\r
304 }\r
305 \r
306 \r
307 /*\r
308  * Procedure:   checkDtcOrigin\r
309  * Description: Return TRUE if "dtcOrigin" match any of the events DTCOrigin otherwise FALSE.\r
310  */\r
311 static boolean checkDtcOrigin(Dem_DTCOriginType dtcOrigin, const Dem_EventParameterType *eventParam)\r
312 {\r
313         boolean result = FALSE;\r
314         boolean dtcOriginFound = FALSE;\r
315         uint16 i;\r
316 \r
317         for (i = 0;(i < DEM_MAX_NR_OF_EVENT_DESTINATION) && (!dtcOriginFound); i++){\r
318                 dtcOriginFound = (eventParam->EventClass->EventDestination[i] == dtcOrigin);\r
319         }\r
320 \r
321         if (dtcOriginFound) {\r
322                 result = TRUE;\r
323         }\r
324 \r
325         return result;\r
326 }\r
327 \r
328 /*\r
329  * Procedure:   checkDtcSeverityMask\r
330  * Description: Return TRUE if "dtcSeverityMask" match any of the events DTC severity otherwise FALSE.\r
331  */\r
332 // PC-Lint (715 etc): Remove errors until function is filled.\r
333 //lint -e{715}          Symbol not referenced\r
334 static boolean checkDtcSeverityMask(Dem_DTCSeverityType dtcSeverityMask, const Dem_EventParameterType *eventParam)\r
335 {\r
336         boolean result = TRUE;\r
337 \r
338         // TODO: This function is optional, may be implemented here.\r
339 \r
340         return result;\r
341 }\r
342 \r
343 \r
344 /*\r
345  * Procedure:   checkDtcFaultDetectionCounterMask\r
346  * Description: TBD.\r
347  */\r
348 // PC-Lint (715 etc): Remove errors until function is filled.\r
349 //lint -e{715}          Symbol not referenced\r
350 static boolean checkDtcFaultDetectionCounter(const Dem_EventParameterType *eventParam)\r
351 {\r
352         boolean result = TRUE;\r
353 \r
354         // TODO: Not implemented yet.\r
355 \r
356         return result;\r
357 }\r
358 \r
359 \r
360 /*\r
361  * Procedure:   lookupEventStatusRec\r
362  * Description: Returns the pointer to event id parameters of "eventId" in "*eventStatusBuffer",\r
363  *                              if not found NULL is returned.\r
364  */\r
365 static void lookupEventStatusRec(Dem_EventIdType eventId, EventStatusRecType **const eventStatusRec)\r
366 {\r
367         uint8 i;\r
368         boolean eventIdFound = FALSE;\r
369 \r
370         for (i = 0; (i < DEM_MAX_NUMBER_EVENT) && (!eventIdFound); i++) {\r
371                 eventIdFound = (eventStatusBuffer[i].eventId == eventId);\r
372         }\r
373 \r
374         if (eventIdFound) {\r
375                 *eventStatusRec = &eventStatusBuffer[i-1];\r
376         } else {\r
377                 *eventStatusRec = NULL;\r
378         }\r
379 }\r
380 \r
381 \r
382 /*\r
383  * Procedure:   lookupEventIdParameter\r
384  * Description: Returns the pointer to event id parameters of "eventId" in "*eventIdParam",\r
385  *                              if not found NULL is returned.\r
386  */\r
387 static void lookupEventIdParameter(Dem_EventIdType eventId, const Dem_EventParameterType **const eventIdParam)\r
388 {\r
389         const Dem_EventParameterType *EventIdParamList = configSet->EventParameter;\r
390 \r
391         /* Lookup the correct event id parameters */\r
392         uint16 i=0;\r
393         while ((EventIdParamList[i].EventID != eventId) && (!EventIdParamList[i].Arc_EOL)) {\r
394                 i++;\r
395         }\r
396 \r
397         if (!EventIdParamList[i].Arc_EOL) {\r
398                 *eventIdParam = &EventIdParamList[i];\r
399         } else {\r
400                 *eventIdParam = NULL;\r
401         }\r
402 }\r
403 \r
404 \r
405 /*\r
406  * Procedure:   preDebounceNone\r
407  * Description: Returns the result of the debouncing.\r
408  */\r
409 static Dem_EventStatusType preDebounceNone(const Dem_EventStatusType reportedStatus, const EventStatusRecType* statusRecord) {\r
410         Dem_EventStatusType returnCode;\r
411         (void)statusRecord;             // Just to get rid of PC-Lint warnings\r
412 \r
413         switch (reportedStatus) {\r
414         case DEM_EVENT_STATUS_FAILED: /** @req DEM091.NoneFailed */\r
415         case DEM_EVENT_STATUS_PASSED: /** @req DEM091.NonePassed */\r
416                 // Already debounced, do nothing.\r
417                 break;\r
418 \r
419         default:\r
420                 // TODO: What to do with PREFAIL and PREPASSED on no debouncing?\r
421                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_PREDEBOUNCE_NONE_ID, DEM_E_PARAM_DATA);\r
422                 break;\r
423         }\r
424 \r
425         returnCode = reportedStatus;\r
426         return returnCode;\r
427 }\r
428 \r
429 \r
430 /*\r
431  * Procedure:   preDebounceCounterBased\r
432  * Description: Returns the result of the debouncing.\r
433  */\r
434 static Dem_EventStatusType preDebounceCounterBased(Dem_EventStatusType reportedStatus, EventStatusRecType* statusRecord) {\r
435         Dem_EventStatusType returnCode;\r
436         const Dem_PreDebounceCounterBasedType* pdVars = statusRecord->eventParamRef->EventClass->PreDebounceAlgorithmClass->PreDebounceAlgorithm.PreDebounceCounterBased;\r
437 \r
438         switch (reportedStatus) {\r
439         case DEM_EVENT_STATUS_PREFAILED:\r
440                 if (statusRecord->faultDetectionCounter < DEBOUNCE_FDC_TEST_FAILED) {\r
441                         if ((pdVars->JumpUp) && (statusRecord->faultDetectionCounter < 0)) {\r
442                                 statusRecord->faultDetectionCounter = 0;\r
443                         } else {\r
444                                 if (((sint16)statusRecord->faultDetectionCounter + (sint8)pdVars->CountInStepSize) < DEBOUNCE_FDC_TEST_FAILED) {\r
445                                         statusRecord->faultDetectionCounter += (sint8)pdVars->CountInStepSize;\r
446                                 } else {\r
447                                         statusRecord->faultDetectionCounter = DEBOUNCE_FDC_TEST_FAILED;\r
448                                 }\r
449                         }\r
450                 }\r
451                 break;\r
452 \r
453         case DEM_EVENT_STATUS_PREPASSED:\r
454                 if (statusRecord->faultDetectionCounter > DEBOUNCE_FDC_TEST_PASSED) {\r
455                         if ((pdVars->JumpDown) && (statusRecord->faultDetectionCounter > 0)) {\r
456                                 statusRecord->faultDetectionCounter = 0;\r
457                         } else {\r
458                                 if (((sint16)statusRecord->faultDetectionCounter - (sint8)pdVars->CountOutStepSize) > DEBOUNCE_FDC_TEST_PASSED) {\r
459                                         statusRecord->faultDetectionCounter -= (sint8)pdVars->CountOutStepSize;\r
460                                 } else {\r
461                                         statusRecord->faultDetectionCounter = DEBOUNCE_FDC_TEST_PASSED;\r
462                                 }\r
463                         }\r
464                 }\r
465                 break;\r
466 \r
467         case DEM_EVENT_STATUS_FAILED:\r
468                 statusRecord->faultDetectionCounter = DEBOUNCE_FDC_TEST_FAILED; /** @req DEM091.CounterFailed */\r
469                 break;\r
470 \r
471         case DEM_EVENT_STATUS_PASSED:\r
472                 statusRecord->faultDetectionCounter = DEBOUNCE_FDC_TEST_PASSED; /** @req DEM091.CounterPassed */\r
473                 break;\r
474 \r
475         default:\r
476                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_PREDEBOUNCE_COUNTER_BASED_ID, DEM_E_PARAM_DATA);\r
477                 break;\r
478 \r
479         }\r
480 \r
481         switch (statusRecord->faultDetectionCounter) {\r
482         case DEBOUNCE_FDC_TEST_FAILED:\r
483                 returnCode = DEM_EVENT_STATUS_FAILED;\r
484                 break;\r
485 \r
486         case DEBOUNCE_FDC_TEST_PASSED:\r
487                 returnCode = DEM_EVENT_STATUS_PASSED;\r
488                 break;\r
489 \r
490         default:\r
491                 returnCode = reportedStatus;\r
492                 break;\r
493         }\r
494 \r
495         return returnCode;\r
496 }\r
497 \r
498 \r
499 /*\r
500  * Procedure:   updateEventStatusRec\r
501  * Description: Update the status of "eventId", if not exist and "createIfNotExist" is\r
502  *                              true a new record is created\r
503  */\r
504 static void updateEventStatusRec(const Dem_EventParameterType *eventParam, Dem_EventStatusType eventStatus, boolean createIfNotExist, EventStatusRecType *eventStatusRec)\r
505 {\r
506         EventStatusRecType *eventStatusRecPtr;\r
507         sint8 faultCounterBeforeDebounce = 0;\r
508         sint8 faultCounterAfterDebounce = 0;\r
509         imask_t state;\r
510     Irq_Save(state);\r
511 \r
512         lookupEventStatusRec(eventParam->EventID, &eventStatusRecPtr);\r
513 \r
514         if ((eventStatusRecPtr == NULL) && (createIfNotExist)) {\r
515                 lookupEventStatusRec(DEM_EVENT_ID_NULL, &eventStatusRecPtr);\r
516                 if (eventStatusRecPtr != NULL) {\r
517                         eventStatusRecPtr->eventId = eventParam->EventID;\r
518                         eventStatusRecPtr->eventParamRef = eventParam;\r
519                         eventStatusRecPtr->faultDetectionCounter = 0;\r
520                         eventStatusRecPtr->occurrence = 0;\r
521                         eventStatusRecPtr->eventStatusExtended = DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR | DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE;\r
522                         eventStatusRecPtr->errorStatusChanged = FALSE;\r
523                 }\r
524                 else {\r
525                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_UPDATE_EVENT_STATUS_ID, DEM_E_EVENT_STATUS_BUFF_FULL);\r
526                 }\r
527         }\r
528 \r
529 \r
530         if (eventStatusRecPtr != NULL) {\r
531                 faultCounterBeforeDebounce = eventStatusRecPtr->faultDetectionCounter;\r
532 \r
533                 if (eventParam->EventClass->PreDebounceAlgorithmClass != NULL) {\r
534                         switch (eventParam->EventClass->PreDebounceAlgorithmClass->PreDebounceName) { /** @req DEM004 */ /** @req DEM342 */\r
535                         case DEM_NO_PRE_DEBOUNCE:\r
536                                 eventStatus = preDebounceNone(eventStatus, eventStatusRecPtr);\r
537                                 break;\r
538 \r
539                         case DEM_PRE_DEBOUNCE_COUNTER_BASED:\r
540                                 eventStatus = preDebounceCounterBased(eventStatus, eventStatusRecPtr);\r
541                                 break;\r
542 \r
543                         default:\r
544                                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_UPDATE_EVENT_STATUS_ID, DEM_E_NOT_IMPLEMENTED_YET);\r
545                                 break;\r
546                         }\r
547                 }\r
548                 faultCounterAfterDebounce = eventStatusRecPtr->faultDetectionCounter;\r
549                 \r
550                 eventStatusRecPtr->errorStatusChanged = FALSE;\r
551 \r
552                 if (eventStatus == DEM_EVENT_STATUS_FAILED) {\r
553                         if (!(eventStatusRecPtr->eventStatusExtended & DEM_TEST_FAILED)) {\r
554                                 eventStatusRecPtr->occurrence++;\r
555                                 eventStatusRecPtr->errorStatusChanged = TRUE;\r
556                         }\r
557                         /** @req DEM036 */ /** @req DEM379.PendingSet */\r
558                         eventStatusRecPtr->eventStatusExtended |= (DEM_TEST_FAILED | DEM_TEST_FAILED_THIS_OPERATION_CYCLE | DEM_TEST_FAILED_SINCE_LAST_CLEAR | DEM_PENDING_DTC | DEM_CONFIRMED_DTC);\r
559                         eventStatusRecPtr->eventStatusExtended &= (Dem_EventStatusExtendedType)~(DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR | DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE);\r
560                 }\r
561 \r
562                 if (eventStatus == DEM_EVENT_STATUS_PASSED) {\r
563                         if (eventStatusRecPtr->eventStatusExtended & (DEM_TEST_FAILED | DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE)) {\r
564                                 eventStatusRecPtr->errorStatusChanged = TRUE;\r
565                         }\r
566                         /** @req DEM036 */\r
567                         eventStatusRecPtr->eventStatusExtended &= (Dem_EventStatusExtendedType)~DEM_TEST_FAILED;\r
568                         eventStatusRecPtr->eventStatusExtended &= (Dem_EventStatusExtendedType)~(DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR | DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE);\r
569                 }\r
570 \r
571                 if ((eventStatus == DEM_EVENT_STATUS_PREFAILED)\\r
572                         && (faultCounterBeforeDebounce <= 0) && (faultCounterAfterDebounce > 0)){\r
573                         eventStatusRecPtr->errorStatusChanged = TRUE;\r
574                 }\r
575 \r
576                 memcpy(eventStatusRec, eventStatusRecPtr, sizeof(EventStatusRecType));\r
577         }\r
578         else {\r
579                 eventStatusRec->eventId = DEM_EVENT_ID_NULL;\r
580                 eventStatusRec->faultDetectionCounter = 0;\r
581                 eventStatusRec->occurrence = 0;\r
582                 eventStatusRec->eventStatusExtended = DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR;\r
583                 eventStatusRec->errorStatusChanged = FALSE;\r
584         }\r
585 \r
586     Irq_Restore(state);\r
587 }\r
588 \r
589 \r
590 /*\r
591  * Procedure:   mergeEventStatusRec\r
592  * Description: Update the occurrence counter of status, if not exist a new record is created\r
593  */\r
594 static void mergeEventStatusRec(const EventRecType *eventRec)\r
595 {\r
596         EventStatusRecType *eventStatusRecPtr;\r
597         imask_t state;\r
598     Irq_Save(state);\r
599 \r
600         // Lookup event ID\r
601         lookupEventStatusRec(eventRec->eventId, &eventStatusRecPtr);\r
602 \r
603         if (eventStatusRecPtr != NULL) {\r
604                 // Update occurrence counter.\r
605                 eventStatusRecPtr->occurrence += eventRec->occurrence;\r
606                 // Merge event status extended with stored\r
607                 // TEST_FAILED_SINCE_LAST_CLEAR should be set if set if set in either\r
608                 eventStatusRecPtr->eventStatusExtended |= (Dem_EventStatusExtendedType)(eventRec->eventStatusExtended & DEM_TEST_FAILED_SINCE_LAST_CLEAR);\r
609                 // DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR should cleared if cleared in either\r
610                 eventStatusRecPtr->eventStatusExtended |= (Dem_EventStatusExtendedType)(eventRec->eventStatusExtended & eventStatusRecPtr->eventStatusExtended & DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR);\r
611                 // DEM_PENDING_DTC and DEM_CONFIRMED_DTC should be set if set in either\r
612                 eventStatusRecPtr->eventStatusExtended |= (Dem_EventStatusExtendedType)(eventRec->eventStatusExtended & (DEM_PENDING_DTC | DEM_CONFIRMED_DTC));\r
613 \r
614         }\r
615         else {\r
616                 // Search for free position\r
617                 lookupEventStatusRec(DEM_EVENT_ID_NULL, &eventStatusRecPtr);\r
618 \r
619                 if (eventStatusRecPtr != NULL) {\r
620                         // Create new event, from stored event\r
621                         eventStatusRecPtr->eventId = eventRec->eventId;\r
622                         lookupEventIdParameter(eventRec->eventId, &eventStatusRecPtr->eventParamRef);\r
623                         eventStatusRecPtr->faultDetectionCounter = 0;\r
624                         eventStatusRecPtr->occurrence = eventRec->occurrence;\r
625                         eventStatusRecPtr->eventStatusExtended = DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR;\r
626                         eventStatusRecPtr->errorStatusChanged = FALSE;\r
627                 }\r
628                 else {\r
629                         // Error: Event status buffer full\r
630                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_MERGE_EVENT_STATUS_ID, DEM_E_EVENT_STATUS_BUFF_FULL);\r
631                 }\r
632         }\r
633 \r
634     Irq_Restore(state);\r
635 }\r
636 \r
637 /*\r
638  * Procedure:   resetEventStatusRec\r
639  * Description: Reset the status record of "eventParam->eventId" from "eventStatusBuffer".\r
640  */\r
641 static void resetEventStatusRec(const Dem_EventParameterType *eventParam)\r
642 {\r
643         EventStatusRecType *eventStatusRecPtr;\r
644         imask_t state;\r
645         Irq_Save(state);\r
646 \r
647         // Lookup event ID\r
648         lookupEventStatusRec(eventParam->EventID, &eventStatusRecPtr);\r
649 \r
650         if (eventStatusRecPtr != NULL) {\r
651                 // Reset event record\r
652                 eventStatusRecPtr->faultDetectionCounter = 0;\r
653                 eventStatusRecPtr->eventStatusExtended = (DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR);\r
654                 eventStatusRecPtr->errorStatusChanged = FALSE;\r
655                 eventStatusRecPtr->occurrence = 0;\r
656         }\r
657 \r
658         Irq_Restore(state);\r
659 }\r
660 \r
661 /*\r
662  * Procedure:   getEventStatusRec\r
663  * Description: Returns the status record of "eventId" in "eventStatusRec"\r
664  */\r
665 static void getEventStatusRec(Dem_EventIdType eventId, EventStatusRecType *eventStatusRec)\r
666 {\r
667         EventStatusRecType *eventStatusRecPtr;\r
668 \r
669         // Lookup event ID\r
670         lookupEventStatusRec(eventId, &eventStatusRecPtr);\r
671 \r
672         if (eventStatusRecPtr != NULL) {\r
673                 // Copy the record\r
674                 memcpy(eventStatusRec, eventStatusRecPtr, sizeof(EventStatusRecType));\r
675         }\r
676         else {\r
677                 eventStatusRec->eventId = DEM_EVENT_ID_NULL;\r
678         }\r
679 }\r
680 \r
681 \r
682 /*\r
683  * Procedure:   lookupDtcEvent\r
684  * Description: Returns TRUE if the DTC was found and "eventStatusRec" points\r
685  *                              to the event record found.\r
686  */\r
687 static boolean lookupDtcEvent(uint32 dtc, EventStatusRecType **eventStatusRec)\r
688 {\r
689         boolean dtcFound = FALSE;\r
690         uint16 i;\r
691 \r
692         *eventStatusRec = NULL;\r
693 \r
694         for (i = 0; (i < DEM_MAX_NUMBER_EVENT) && (!dtcFound); i++) {\r
695                 if (eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) {\r
696                         if (eventStatusBuffer[i].eventParamRef->DTCClassRef != NULL) {\r
697 \r
698                                 // Check DTC\r
699                                 if (eventStatusBuffer[i].eventParamRef->DTCClassRef->DTC == dtc) {\r
700                                         *eventStatusRec = &eventStatusBuffer[i];\r
701                                         dtcFound = TRUE;\r
702                                 }\r
703                         }\r
704                 }\r
705         }\r
706 \r
707         return dtcFound;\r
708 }\r
709 \r
710 \r
711 /*\r
712  * Procedure:   matchEventWithDtcFilter\r
713  * Description: Returns TRUE if the event pointed by "event" fulfill\r
714  *                              the "dtcFilter" global filter settings.\r
715  */\r
716 static boolean matchEventWithDtcFilter(const EventStatusRecType *eventRec)\r
717 {\r
718         boolean dtcMatch = FALSE;\r
719 \r
720         // Check status\r
721         if ((dtcFilter.dtcStatusMask == DEM_DTC_STATUS_MASK_ALL) || (eventRec->eventStatusExtended & dtcFilter.dtcStatusMask)) {\r
722                 if (eventRec->eventParamRef != NULL) {\r
723 \r
724                         // Check dtcKind\r
725                         if (checkDtcKind(dtcFilter.dtcKind, eventRec->eventParamRef)) {\r
726 \r
727                                 // Check dtcOrigin\r
728                                 if (checkDtcOrigin(dtcFilter.dtcOrigin, eventRec->eventParamRef)) {\r
729 \r
730                                         // Check severity\r
731                                         if ((dtcFilter.filterWithSeverity == DEM_FILTER_WITH_SEVERITY_NO)\r
732                                                 || ((dtcFilter.filterWithSeverity == DEM_FILTER_WITH_SEVERITY_YES) && (checkDtcSeverityMask(dtcFilter.dtcSeverityMask, eventRec->eventParamRef)))) {\r
733 \r
734                                                 // Check fault detection counter\r
735                                                 if ((dtcFilter.filterForFaultDetectionCounter == DEM_FILTER_FOR_FDC_NO)\r
736                                                         || ((dtcFilter.filterWithSeverity == DEM_FILTER_FOR_FDC_YES) && (checkDtcFaultDetectionCounter(eventRec->eventParamRef)))) {\r
737                                                         dtcMatch = TRUE;\r
738                                                 }\r
739                                         }\r
740                                 }\r
741                         }\r
742                 }\r
743         }\r
744 \r
745         return dtcMatch;\r
746 }\r
747 /*\r
748  * Procedure:   bubbleSort\r
749  * Description: bubble sort\r
750  */\r
751 static void bubbleSort(FreezeFrameRecType *freezeFrameBuf, uint16 length)\r
752 {\r
753         FreezeFrameRecType temp;\r
754         uint16 i = 0;\r
755         uint16 j = 0;\r
756 \r
757         //Bubble sort:rearrange priMemFreezeFrameBuffer from little to big\r
758         for(i=0;i<length;i++){\r
759                 for(j=length-1; j > i; j--){\r
760                         if(freezeFrameBuf[i].timeStamp > freezeFrameBuf[j].timeStamp){\r
761                                 //exchange buffer data\r
762                                 memcpy(&temp,&freezeFrameBuf[i],sizeof(FreezeFrameRecType));\r
763                                 memcpy(&freezeFrameBuf[i],&freezeFrameBuf[j],sizeof(FreezeFrameRecType));\r
764                                 memcpy(&freezeFrameBuf[j],&temp,sizeof(FreezeFrameRecType));            \r
765                         }\r
766                 }\r
767         }\r
768 \r
769 }\r
770 \r
771 /*\r
772  * Procedure:   retrieveEventStatusBit\r
773  * Description: retrieve Event Status Bit\r
774  */\r
775 static boolean retrieveEventStatusBit(FreezeFrameRecType *freezeFrameBuf, \r
776                                                                                         uint16 length , \r
777                                                                                         Dem_EventStatusExtendedType nBit, \r
778                                                                                         FreezeFrameRecType **freezeFrame)\r
779 {\r
780         boolean freezeFrameFound = FALSE;\r
781         uint16 i = 0;\r
782         uint16 j = 0;\r
783 \r
784         for(i=0;i<length;i++){\r
785                 for(j=0; (j < DEM_MAX_NUMBER_EVENT) && (!freezeFrameFound); j++){\r
786                         freezeFrameFound = (eventStatusBuffer[j].eventId == freezeFrameBuf[i].eventId)\\r
787                                                  && (!(eventStatusBuffer[j].eventStatusExtended & nBit));\r
788                         if(freezeFrameFound == TRUE){\r
789                                 *freezeFrame = &freezeFrameBuf[i];\r
790                         }\r
791                 }               \r
792         }\r
793 \r
794         return freezeFrameFound;\r
795 \r
796 }\r
797 \r
798 /*\r
799  * Procedure:   lookupFreezeFrameForDisplacementPreInit\r
800  * Description: implement displacement strategy preinit:1.find out the oldest "not confirmed" DTC\r
801  *                                                                                                 2.find out the oldest inactive DTC,inactive:testFailed is not set\r
802  *                                                                                                3.find ou the oldest active DTC,active:testFailed is set\r
803  */\r
804 static boolean lookupFreezeFrameForDisplacementPreInit(FreezeFrameRecType **freezeFrame)\r
805 {\r
806         boolean freezeFrameFound = FALSE;\r
807                 \r
808         /* Bubble sort:rearrange priMemFreezeFrameBuffer from little to big */\r
809         bubbleSort(preInitFreezeFrameBuffer, DEM_MAX_NUMBER_FF_DATA_PRE_INIT);\r
810 \r
811         /* find out the oldest not confirmed dtc */\r
812         freezeFrameFound = retrieveEventStatusBit(preInitFreezeFrameBuffer, DEM_MAX_NUMBER_FF_DATA_PRE_INIT, DEM_CONFIRMED_DTC, freezeFrame);\r
813 \r
814         /* if all confirmed,lookup the oldest inactive dtc */\r
815         if(freezeFrameFound == FALSE){\r
816                 freezeFrameFound = retrieveEventStatusBit(preInitFreezeFrameBuffer, DEM_MAX_NUMBER_FF_DATA_PRE_INIT, DEM_TEST_FAILED, freezeFrame);\r
817         }\r
818         \r
819         /* if all confirmed,lookup the oldest active dtc */\r
820         if(freezeFrameFound == FALSE){\r
821                 *freezeFrame = &preInitFreezeFrameBuffer[0];\r
822                 freezeFrameFound = TRUE;\r
823         }                       \r
824 \r
825         return freezeFrameFound;\r
826 }\r
827 \r
828 /*\r
829  * Procedure:   lookupFreezeFrameForDisplacement\r
830  * Description: implement displacement strategy:1.find out the oldest "not confirmed" DTC\r
831  *                                                                                      2.find out the oldest inactive DTC,inactive:testFailed is not set\r
832  *                                                                                      3.find ou the oldest active DTC,active:testFailed is set\r
833  */\r
834 static boolean lookupFreezeFrameForDisplacement(FreezeFrameRecType **freezeFrame)\r
835 {\r
836         boolean freezeFrameFound = FALSE;\r
837         \r
838         bubbleSort(priMemFreezeFrameBuffer, DEM_MAX_NUMBER_FF_DATA_PRI_MEM);\r
839 \r
840         /* Find out the oldest not confirmed dtc */\r
841         freezeFrameFound = retrieveEventStatusBit(priMemFreezeFrameBuffer, DEM_MAX_NUMBER_FF_DATA_PRI_MEM, DEM_CONFIRMED_DTC, freezeFrame);\r
842 \r
843         /* If all confirmed, lookup the oldest inactive dtc */\r
844         if(freezeFrameFound == FALSE){\r
845                 freezeFrameFound = retrieveEventStatusBit(priMemFreezeFrameBuffer, DEM_MAX_NUMBER_FF_DATA_PRI_MEM, DEM_TEST_FAILED, freezeFrame);\r
846         }\r
847 \r
848         /* If all confirmed,lookup the oldest active dtc */\r
849         if(freezeFrameFound == FALSE){  \r
850                 *freezeFrame = &priMemFreezeFrameBuffer[0];\r
851                 freezeFrameFound = TRUE;        \r
852         }\r
853 \r
854         return freezeFrameFound;\r
855 }\r
856 /*\r
857  * Procedure:   rearrangeFreezeFrameTimeStamp\r
858  * Description: rearrange FF timestamp when timestamp is beyond DEM_MAX_TIMESTAMP_FOR_REARRANGEMENT                     \r
859  */\r
860 static void rearrangeFreezeFrameTimeStamp(uint32 *timeStamp)\r
861 {\r
862         FreezeFrameRecType temp;\r
863         uint32 i = 0;\r
864         uint32 j = 0;\r
865         uint32 k = 0;\r
866         \r
867         /* Bubble sort:rearrange priMemFreezeFrameBuffer from little to big */\r
868         for(i=0;i<DEM_MAX_NUMBER_FF_DATA_PRI_MEM;i++){\r
869                 if(priMemFreezeFrameBuffer[i].eventId != DEM_EVENT_ID_NULL){\r
870                         for(j=DEM_MAX_NUMBER_FF_DATA_PRI_MEM-1; j > i; j--){\r
871                                 if(priMemFreezeFrameBuffer[j].eventId != DEM_EVENT_ID_NULL){\r
872                                         if(priMemFreezeFrameBuffer[i].timeStamp > priMemFreezeFrameBuffer[j].timeStamp){\r
873                                                 //exchange buffer data\r
874                                                 memcpy(&temp,&priMemFreezeFrameBuffer[i],sizeof(FreezeFrameRecType));\r
875                                                 memcpy(&priMemFreezeFrameBuffer[i],&priMemFreezeFrameBuffer[j],sizeof(FreezeFrameRecType));\r
876                                                 memcpy(&priMemFreezeFrameBuffer[j],&temp,sizeof(FreezeFrameRecType));           \r
877                                         }\r
878 \r
879                                 }\r
880                                 \r
881                         }\r
882                         priMemFreezeFrameBuffer[i].timeStamp = k++;\r
883                 }\r
884                 \r
885         }\r
886         /* update the current timeStamp */\r
887         *timeStamp = k;\r
888 \r
889 }\r
890 /*\r
891  * Procedure:   getFreezeFrameData\r
892  * Description: get FF data according configuration                     \r
893  */\r
894 static void getFreezeFrameData(const Dem_EventParameterType *eventParam, \r
895                                FreezeFrameRecType *freezeFrame,\r
896                                Dem_EventStatusType eventStatus,\r
897                                EventStatusRecType *eventStatusRec)\r
898 {\r
899         Dem_FreezeFrameStorageConditonType prefailedOrFailed;\r
900         Std_ReturnType callbackReturnCode;\r
901         uint16 i = 0;\r
902         uint16 storeIndex = 0;\r
903         uint16 recordSize = 0;\r
904         imask_t state;\r
905         const Dem_FreezeFrameClassType *FreezeFrameLocal = NULL;\r
906         Dcm_NegativeResponseCodeType errorCode;//should include Dcm_Lcfg.h\r
907 \r
908         /* clear FF data record */\r
909         memset(freezeFrame, 0, sizeof(FreezeFrameRecType ));\r
910 \r
911         /* check if prefailed or failed */\r
912         if(eventStatusRec->eventStatusExtended & DEM_TEST_FAILED){\r
913                 prefailedOrFailed = FAILED;//confirm the FF is stored for failed\r
914 \r
915         }\r
916         else{\r
917                  if(eventStatus == DEM_EVENT_STATUS_PREFAILED){\r
918                         prefailedOrFailed = PREFAILED;//confirm the FF is stored for prefailed\r
919                  }\r
920                  else{\r
921                         prefailedOrFailed = FF_STORAGE_CONDITION_WRONG;\r
922                         freezeFrame->eventId = DEM_EVENT_ID_NULL;\r
923                         return;\r
924                  }\r
925         }\r
926 \r
927         /* Find out the corresponding FF class */\r
928         for(i = 0;(i<DEM_MAX_NR_OF_CLASSES_IN_FREEZEFRAME_DATA) && (eventParam->FreezeFrameClassRef[i] != NULL);i++){\r
929                 if(eventParam->FreezeFrameClassRef[i]->FFStorageCondition == prefailedOrFailed){\r
930                         FreezeFrameLocal = eventParam->FreezeFrameClassRef[i];\r
931                         break;\r
932                 }\r
933         }\r
934         /* get the dids */\r
935         if(FreezeFrameLocal != NULL){\r
936                 if(FreezeFrameLocal->FFIdClassRef != NULL){\r
937                         for (i = 0; (i < DEM_MAX_NR_OF_RECORDS_IN_FREEZEFRAME_DATA) && (!(FreezeFrameLocal->FFIdClassRef[i].Arc_EOL)); i++) {\r
938                                 if(FreezeFrameLocal->FFIdClassRef[i].PidOrDidUsePort == FALSE){\r
939                                         if(FreezeFrameLocal->FFIdClassRef[i].DidReadDataLengthFnc != NULL){\r
940                                                 callbackReturnCode = FreezeFrameLocal->FFIdClassRef[i].DidReadDataLengthFnc(&recordSize);\r
941                                                 if(callbackReturnCode != E_OK){\r
942                                                         //if fail to read data length,discard the storage of FF\r
943                                                         freezeFrame->eventId = DEM_EVENT_ID_NULL;\r
944                                                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GET_FREEZEFRAME_ID, DEM_READ_DATA_LENGTH_FAILED);\r
945                                                         return;\r
946                                                 }\r
947                                         }\r
948                                         /* if no readDidDataLengthFunction, then try the PidOrDidSize. */\r
949                                         else{\r
950                                                 recordSize = FreezeFrameLocal->FFIdClassRef[i].PidOrDidSize;\r
951                                         }\r
952                                         /* read out the did data */\r
953                                         if ((storeIndex + recordSize + DEM_DID_IDENTIFIER_SIZE_OF_BYTES) <= DEM_MAX_SIZE_FF_DATA) {\r
954                                                 /* store DID */\r
955                                                 freezeFrame->data[storeIndex] = (FreezeFrameLocal->FFIdClassRef[i].DidIdentifier>> 8) & 0xFFu;\r
956                                                 storeIndex++;\r
957                                                 freezeFrame->data[storeIndex] = FreezeFrameLocal->FFIdClassRef[i].DidIdentifier & 0xFFu;\r
958                                                 storeIndex++;\r
959                                                 /* store data */\r
960                                                 if(FreezeFrameLocal->FFIdClassRef[i].DidConditionCheckReadFnc != NULL){\r
961                                                         callbackReturnCode = FreezeFrameLocal->FFIdClassRef[i].DidConditionCheckReadFnc(&errorCode);\r
962                                                         if ((callbackReturnCode == E_OK) && (errorCode == DCM_E_POSITIVERESPONSE)) {\r
963                                                                 if(FreezeFrameLocal->FFIdClassRef[i].DidReadFnc!= NULL){\r
964                                                                         callbackReturnCode = FreezeFrameLocal->FFIdClassRef[i].DidReadFnc(&freezeFrame->data[storeIndex]);\r
965                                                                         if (callbackReturnCode != E_OK) {\r
966                                                                                 memset(&freezeFrame->data[storeIndex], DEM_FREEZEFRAME_DEFAULT_VALUE, recordSize);\r
967                                                                         }\r
968                                                                         storeIndex += recordSize;\r
969 \r
970                                                                 }\r
971                                                                 else{\r
972                                                                         memset(&freezeFrame->data[storeIndex], DEM_FREEZEFRAME_DEFAULT_VALUE, recordSize);\r
973                                                                         storeIndex += recordSize;\r
974                                                                 }\r
975 \r
976                                                         }\r
977                                                         else{\r
978                                                                 memset(&freezeFrame->data[storeIndex], DEM_FREEZEFRAME_DEFAULT_VALUE, recordSize);\r
979                                                                 storeIndex += recordSize;\r
980                                                         }\r
981                                                 }\r
982                                                 else{\r
983                                                         memset(&freezeFrame->data[storeIndex], DEM_FREEZEFRAME_DEFAULT_VALUE, recordSize);\r
984                                                         storeIndex += recordSize;\r
985                                                 }\r
986 \r
987                                         }\r
988                                         else{\r
989                                                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GET_FREEZEFRAME_ID, DEM_E_FF_TOO_BIG);\r
990                                                 break;\r
991                                         }       \r
992                                 }\r
993                                 else{\r
994                                         //TODO:RTE should provide the port\r
995                                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GET_FREEZEFRAME_ID, DEM_DSP_DID_USE_PORT_IS_TRUE);\r
996                                 }\r
997                         }       \r
998                 }\r
999 \r
1000         }\r
1001         else{\r
1002                 /* create an empty FF */\r
1003                 freezeFrame->eventId = DEM_EVENT_ID_NULL;\r
1004         }\r
1005 \r
1006         /* Check if any data has been stored */\r
1007         if (storeIndex != 0) {\r
1008                 freezeFrame->eventId = eventParam->EventID;\r
1009                 freezeFrame->occurrence = eventStatusRec->occurrence;\r
1010                 freezeFrame->dataSize = storeIndex;\r
1011                 freezeFrame->recordNumber = FreezeFrameLocal->FFRecordNumber;\r
1012                 Irq_Save(state);\r
1013 \r
1014                 if(FF_TimeStamp > DEM_MAX_TIMESTAMP_FOR_REARRANGEMENT){\r
1015                         rearrangeFreezeFrameTimeStamp(&FF_TimeStamp);\r
1016                 }\r
1017                 \r
1018                 freezeFrame->timeStamp = FF_TimeStamp;\r
1019 \r
1020                 FF_TimeStamp++;\r
1021 \r
1022                 Irq_Restore(state);\r
1023 \r
1024                 freezeFrame->checksum = calcChecksum(freezeFrame, sizeof(FreezeFrameRecType)-sizeof(ChecksumType));\r
1025         }\r
1026         else{\r
1027                 freezeFrame->eventId = DEM_EVENT_ID_NULL;\r
1028                 freezeFrame->dataSize = storeIndex;\r
1029                 freezeFrame->checksum = 0;\r
1030         }       \r
1031 }\r
1032 \r
1033 \r
1034 /*\r
1035  * Procedure:   storeFreezeFrameDataPreInit\r
1036  * Description: store FF in before  preInitFreezeFrameBuffer DEM's full initialization                          \r
1037  */\r
1038 static void storeFreezeFrameDataPreInit(const Dem_EventParameterType *eventParam, const FreezeFrameRecType *freezeFrame)\r
1039 {\r
1040         boolean eventIdFound = FALSE;\r
1041         boolean eventIdFreePositionFound=FALSE;\r
1042         FreezeFrameRecType *freezeFrameLocal = NULL;\r
1043         uint16 i;\r
1044         imask_t state;\r
1045 \r
1046         Irq_Save(state);\r
1047 \r
1048         /* Check if already stored */\r
1049         for (i = 0; (i<DEM_MAX_NUMBER_FF_DATA_PRE_INIT) && (!eventIdFound); i++){\r
1050                 eventIdFound = ((preInitFreezeFrameBuffer[i].eventId == eventParam->EventID) && (preInitFreezeFrameBuffer[i].recordNumber== freezeFrame->recordNumber));\r
1051         }\r
1052 \r
1053         if(eventIdFound){\r
1054                 /* overwrite existing */\r
1055                 memcpy(&preInitFreezeFrameBuffer[i-1], freezeFrame, sizeof(FreezeFrameRecType));\r
1056         }\r
1057         else{\r
1058                 /* lookup first free position */\r
1059                 for (i = 0; (i<DEM_MAX_NUMBER_FF_DATA_PRE_INIT) && (!eventIdFreePositionFound); i++){\r
1060                         if(preInitFreezeFrameBuffer[i].eventId == DEM_EVENT_ID_NULL){\r
1061                                 eventIdFreePositionFound=TRUE;\r
1062                         }\r
1063                 }\r
1064 \r
1065                 if (eventIdFreePositionFound) {\r
1066                         memcpy(&preInitFreezeFrameBuffer[i-1], freezeFrame, sizeof(FreezeFrameRecType));\r
1067                 }\r
1068                 else {                  \r
1069                         /* do displacement */\r
1070                         if(lookupFreezeFrameForDisplacementPreInit(&freezeFrameLocal)){\r
1071                                 memcpy(freezeFrameLocal, freezeFrame, sizeof(FreezeFrameRecType));\r
1072                         }\r
1073                         else{\r
1074                                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_STORE_FF_DATA_PRE_INIT_ID, DEM_E_PRE_INIT_FF_DATA_BUFF_FULL);\r
1075                         }\r
1076                 }\r
1077         }\r
1078 \r
1079         Irq_Restore(state);\r
1080 }\r
1081 \r
1082 \r
1083 /*\r
1084  * Procedure:   updateFreezeFrameOccurrencePreInit\r
1085  * Description: update the occurrence in preInitFreezeFrameBuffer according to the occurrence stored in priMemEventBuffer                               \r
1086  */\r
1087 static void updateFreezeFrameOccurrencePreInit(const EventRecType *EventBuffer)\r
1088 {\r
1089         uint16 i;\r
1090 \r
1091         for (i = 0; i<DEM_MAX_NUMBER_FF_DATA_PRE_INIT; i++){\r
1092                 if(preInitFreezeFrameBuffer[i].eventId == EventBuffer->eventId){\r
1093                         preInitFreezeFrameBuffer[i].occurrence += EventBuffer->occurrence;\r
1094                 }\r
1095         }\r
1096         \r
1097 }\r
1098 /*\r
1099  * Procedure:   initCurrentFreezeFrameTimeStamp\r
1100  * Description: initialize current timestamp and update the corresponding timestamp in preInitFreezeFrameBuffer         \r
1101  */\r
1102 static void initCurrentFreezeFrameTimeStamp(uint32 *timeStampPtr)\r
1103 {\r
1104         uint16 i = 0;\r
1105         uint32 temp = 0;\r
1106         imask_t state;\r
1107 \r
1108         Irq_Save(state);\r
1109 \r
1110         /* Find out the biggest timestamp in the last power on */\r
1111         for (i = 0; i<DEM_MAX_NUMBER_FF_DATA_PRI_MEM; i++){\r
1112                 if((priMemFreezeFrameBuffer[i].eventId != DEM_EVENT_ID_NULL) && \r
1113                   (priMemFreezeFrameBuffer[i].timeStamp > temp)){\r
1114                         temp = priMemFreezeFrameBuffer[i].timeStamp;\r
1115                 }\r
1116         }\r
1117         temp++;\r
1118         for (i = 0; i<DEM_MAX_NUMBER_FF_DATA_PRE_INIT; i++){\r
1119                 if(preInitFreezeFrameBuffer[i].eventId != DEM_EVENT_ID_NULL){\r
1120                         preInitFreezeFrameBuffer[i].timeStamp += temp;\r
1121                 }\r
1122         }\r
1123         *timeStampPtr += temp;  \r
1124         Irq_Restore(state);\r
1125 }\r
1126 \r
1127 /*\r
1128  * Procedure:   getExtendedData\r
1129  * Description: Collects the extended data according to "eventParam" and return it in "extData",\r
1130  *                              if not found eventId is set to DEM_EVENT_ID_NULL.\r
1131  */\r
1132 static void getExtendedData(const Dem_EventParameterType *eventParam, ExtDataRecType *extData)\r
1133 {\r
1134         Std_ReturnType callbackReturnCode;\r
1135         uint16 i;\r
1136         uint16 storeIndex = 0;\r
1137         uint16 recordSize;\r
1138 \r
1139         // Clear ext data record\r
1140         memset(extData, 0, sizeof(ExtDataRecType));\r
1141 \r
1142         // Check if any pointer to extended data class\r
1143         if (eventParam->ExtendedDataClassRef != NULL) {\r
1144                 // Request extended data and copy it to the buffer\r
1145                 for (i = 0; (i < DEM_MAX_NR_OF_RECORDS_IN_EXTENDED_DATA) && (eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef[i] != NULL); i++) {\r
1146                         recordSize = eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef[i]->DataSize;\r
1147                         if ((storeIndex + recordSize) <= DEM_MAX_SIZE_EXT_DATA) {\r
1148                                 callbackReturnCode = eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef[i]->CallbackGetExtDataRecord(&extData->data[storeIndex]); /** @req DEM282 */\r
1149                                 if (callbackReturnCode != E_OK) {\r
1150                                         // Callback data currently not available, clear space.\r
1151                                         memset(&extData->data[storeIndex], 0xFF, recordSize);\r
1152                                 }\r
1153                                 storeIndex += recordSize;\r
1154                         }\r
1155                         else {\r
1156                                 // Error: Size of extended data record is bigger than reserved space.\r
1157                                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GET_EXTENDED_DATA_ID, DEM_E_EXT_DATA_TOO_BIG);\r
1158                                 break;  // Break the loop\r
1159                         }\r
1160                 }\r
1161         }\r
1162 \r
1163         // Check if any data has been stored\r
1164         if (storeIndex != 0) {\r
1165                 extData->eventId = eventParam->EventID;\r
1166                 extData->dataSize = storeIndex;\r
1167                 extData->checksum = calcChecksum(extData, sizeof(ExtDataRecType)-sizeof(ChecksumType));\r
1168         }\r
1169         else {\r
1170                 extData->eventId = DEM_EVENT_ID_NULL;\r
1171                 extData->dataSize = storeIndex;\r
1172                 extData->checksum = 0;\r
1173         }\r
1174 }\r
1175 \r
1176 \r
1177 /*\r
1178  * Procedure:   storeExtendedDataPreInit\r
1179  * Description: Store the extended data pointed by "extendedData" to the "preInitExtDataBuffer",\r
1180  *                              if non existent a new entry is created.\r
1181  */\r
1182 static void storeExtendedDataPreInit(const Dem_EventParameterType *eventParam, const ExtDataRecType *extendedData)\r
1183 {\r
1184         boolean eventIdFound = FALSE;\r
1185         boolean eventIdFreePositionFound=FALSE;\r
1186         uint16 i;\r
1187         imask_t state;\r
1188     Irq_Save(state);\r
1189 \r
1190         // Check if already stored\r
1191         for (i = 0; (i<DEM_MAX_NUMBER_EXT_DATA_PRE_INIT) && (!eventIdFound); i++){\r
1192                 eventIdFound = (preInitExtDataBuffer[i].eventId == eventParam->EventID);\r
1193         }\r
1194 \r
1195         if(eventIdFound){\r
1196                 // Yes, overwrite existing\r
1197                 memcpy(&preInitExtDataBuffer[i-1], extendedData, sizeof(ExtDataRecType));\r
1198         }\r
1199         else{\r
1200                 // No, lookup first free position\r
1201                 for (i = 0; (i<DEM_MAX_NUMBER_EXT_DATA_PRE_INIT) && (!eventIdFreePositionFound); i++){\r
1202                         if(preInitExtDataBuffer[i].eventId ==0){\r
1203                                 eventIdFreePositionFound=TRUE;\r
1204                         }\r
1205                 }\r
1206 \r
1207                 if (eventIdFreePositionFound) {\r
1208                         memcpy(&preInitExtDataBuffer[i-1], extendedData, sizeof(ExtDataRecType));\r
1209                 }\r
1210                 else {\r
1211                         // Error: Pre init extended data buffer full\r
1212                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_STORE_EXT_DATA_PRE_INIT_ID, DEM_E_PRE_INIT_EXT_DATA_BUFF_FULL);\r
1213                 }\r
1214         }\r
1215 \r
1216     Irq_Restore(state);\r
1217 }\r
1218 \r
1219 /*\r
1220  * Procedure:   storeEventPriMem\r
1221  * Description: Store the event data of "eventStatus->eventId" in "priMemEventBuffer",\r
1222  *                              if non existent a new entry is created.\r
1223  */\r
1224 static void storeEventPriMem(const Dem_EventParameterType *eventParam, const EventStatusRecType *eventStatus)\r
1225 {\r
1226         boolean eventIdFound = FALSE;\r
1227         boolean eventIdFreePositionFound=FALSE;\r
1228         uint16 i;\r
1229         imask_t state;\r
1230     Irq_Save(state);\r
1231 \r
1232         (void)*eventParam;      // Currently not used, do this to avoid warning\r
1233 \r
1234         // Lookup event ID\r
1235         for (i = 0; (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI) && (!eventIdFound); i++){\r
1236                 eventIdFound = (priMemEventBuffer[i].eventId == eventStatus->eventId);\r
1237         }\r
1238 \r
1239         if (eventIdFound) {\r
1240                 // Update event found\r
1241                 priMemEventBuffer[i-1].occurrence = eventStatus->occurrence;\r
1242                 priMemEventBuffer[i-1].eventStatusExtended = eventStatus->eventStatusExtended;\r
1243                 priMemEventBuffer[i-1].checksum = calcChecksum(&priMemEventBuffer[i-1], sizeof(EventRecType)-sizeof(ChecksumType));\r
1244         }\r
1245         else {\r
1246                 // Search for free position\r
1247                 for (i=0; (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI) && (!eventIdFreePositionFound); i++){\r
1248                         eventIdFreePositionFound = (priMemEventBuffer[i].eventId == DEM_EVENT_ID_NULL);\r
1249                 }\r
1250 \r
1251 \r
1252                 if (eventIdFreePositionFound) {\r
1253                         priMemEventBuffer[i-1].eventId = eventStatus->eventId;\r
1254                         priMemEventBuffer[i-1].occurrence = eventStatus->occurrence;\r
1255                         priMemEventBuffer[i-1].eventStatusExtended = eventStatus->eventStatusExtended;\r
1256                         priMemEventBuffer[i-1].checksum = calcChecksum(&priMemEventBuffer[i-1], sizeof(EventRecType)-sizeof(ChecksumType));\r
1257                 }\r
1258                 else {\r
1259                         // Error: Pri mem event buffer full\r
1260                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_STORE_EVENT_PRI_MEM_ID, DEM_E_PRI_MEM_EVENT_BUFF_FULL);\r
1261                 }\r
1262         }\r
1263 \r
1264     Irq_Restore(state);\r
1265 }\r
1266 \r
1267 /*\r
1268  * Procedure:   deleteEventPriMem\r
1269  * Description: Delete the event data of "eventParam->eventId" from "priMemEventBuffer".\r
1270  */\r
1271 static void deleteEventPriMem(const Dem_EventParameterType *eventParam)\r
1272 {\r
1273         boolean eventIdFound = FALSE;\r
1274         uint16 i;\r
1275         imask_t state;\r
1276     Irq_Save(state);\r
1277 \r
1278         for (i = 0; (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI) && (!eventIdFound); i++){\r
1279                 eventIdFound = (priMemEventBuffer[i].eventId == eventParam->EventID);\r
1280         }\r
1281 \r
1282         if (eventIdFound) {\r
1283                 memset(&priMemEventBuffer[i-1], 0, sizeof(EventRecType));\r
1284         }\r
1285 \r
1286     Irq_Restore(state);\r
1287 }\r
1288 \r
1289 /*\r
1290  * Procedure:   storeEventEvtMem\r
1291  * Description: Store the event data of "eventStatus->eventId" in event memory according to\r
1292  *                              "eventParam" destination option.\r
1293  */\r
1294 static void storeEventEvtMem(const Dem_EventParameterType *eventParam, const EventStatusRecType *eventStatus)\r
1295 {\r
1296         uint16 i;\r
1297 \r
1298         for (i = 0; (i < DEM_MAX_NR_OF_EVENT_DESTINATION)\r
1299                                  && (eventParam->EventClass->EventDestination[i] != DEM_EVENT_DESTINATION_END_OF_LIST); i++) {\r
1300                 switch (eventParam->EventClass->EventDestination[i])\r
1301                 {\r
1302                 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:\r
1303                         storeEventPriMem(eventParam, eventStatus);      /** @req DEM010 */\r
1304                         break;\r
1305 \r
1306                 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:\r
1307                 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:\r
1308                 case DEM_DTC_ORIGIN_MIRROR_MEMORY:\r
1309                         // Not yet supported\r
1310                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GLOBAL_ID, DEM_E_NOT_IMPLEMENTED_YET);\r
1311                         break;\r
1312                 default:\r
1313                         break;\r
1314                 }\r
1315         }\r
1316 }\r
1317 \r
1318 \r
1319 /*\r
1320  * Procedure:   storeExtendedDataPriMem\r
1321  * Description: Store the extended data pointed by "extendedData" to the "priMemExtDataBuffer",\r
1322  *                              if non existent a new entry is created.\r
1323  */\r
1324 static void storeExtendedDataPriMem(const Dem_EventParameterType *eventParam, const ExtDataRecType *extendedData) /** @req DEM041 */\r
1325 {\r
1326         boolean eventIdFound = FALSE;\r
1327         boolean eventIdFreePositionFound=FALSE;\r
1328         uint16 i;\r
1329         imask_t state;\r
1330     Irq_Save(state);\r
1331 \r
1332         // Check if already stored\r
1333         for (i = 0; (i<DEM_MAX_NUMBER_EXT_DATA_PRI_MEM) && (!eventIdFound); i++){\r
1334                 eventIdFound = (priMemExtDataBuffer[i].eventId == eventParam->EventID);\r
1335         }\r
1336 \r
1337         if (eventIdFound) {\r
1338                 // Yes, overwrite existing\r
1339                 memcpy(&priMemExtDataBuffer[i-1], extendedData, sizeof(ExtDataRecType));\r
1340         }\r
1341         else {\r
1342                 // No, lookup first free position\r
1343                 for (i = 0; (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM) && (!eventIdFreePositionFound); i++){\r
1344                         eventIdFreePositionFound =  (priMemExtDataBuffer[i].eventId == DEM_EVENT_ID_NULL);\r
1345                 }\r
1346                 if (eventIdFreePositionFound) {\r
1347                         memcpy(&priMemExtDataBuffer[i-1], extendedData, sizeof(ExtDataRecType));\r
1348                 }\r
1349                 else {\r
1350                         // Error: Pri mem extended data buffer full\r
1351                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_STORE_EXT_DATA_PRI_MEM_ID, DEM_E_PRI_MEM_EXT_DATA_BUFF_FULL);\r
1352                 }\r
1353         }\r
1354 \r
1355     Irq_Restore(state);\r
1356 }\r
1357 \r
1358 /*\r
1359  * Procedure:   deleteExtendedDataPriMem\r
1360  * Description: Delete the extended data of "eventParam->eventId" from "priMemExtDataBuffer".\r
1361  */\r
1362 static void deleteExtendedDataPriMem(const Dem_EventParameterType *eventParam)\r
1363 {\r
1364         boolean eventIdFound = FALSE;\r
1365         uint16 i;\r
1366         imask_t state;\r
1367     Irq_Save(state);\r
1368 \r
1369         // Check if already stored\r
1370         for (i = 0;(i<DEM_MAX_NUMBER_EXT_DATA_PRI_MEM) && (!eventIdFound); i++){\r
1371                 eventIdFound = (priMemExtDataBuffer[i].eventId == eventParam->EventID);\r
1372         }\r
1373 \r
1374         if (eventIdFound) {\r
1375                 // Yes, clear record\r
1376                 memset(&priMemExtDataBuffer[i-1], 0, sizeof(ExtDataRecType));\r
1377         }\r
1378 \r
1379     Irq_Restore(state);\r
1380 }\r
1381 \r
1382 /*\r
1383  * Procedure:   storeExtendedDataEvtMem\r
1384  * Description: Store the extended data in event memory according to\r
1385  *                              "eventParam" destination option\r
1386  */\r
1387 static void storeExtendedDataEvtMem(const Dem_EventParameterType *eventParam, const ExtDataRecType *extendedData)\r
1388 {\r
1389         uint16 i;\r
1390 \r
1391         for (i = 0; (i < DEM_MAX_NR_OF_EVENT_DESTINATION) && (eventParam->EventClass->EventDestination[i] != DEM_EVENT_DESTINATION_END_OF_LIST); i++) {\r
1392                 switch (eventParam->EventClass->EventDestination[i])\r
1393                 {\r
1394                 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:\r
1395                         storeExtendedDataPriMem(eventParam, extendedData);\r
1396                         break;\r
1397 \r
1398                 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:\r
1399                 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:\r
1400                 case DEM_DTC_ORIGIN_MIRROR_MEMORY:\r
1401                         // Not yet supported\r
1402                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GLOBAL_ID, DEM_E_NOT_IMPLEMENTED_YET);\r
1403                         break;\r
1404 \r
1405                 default:\r
1406                         break;\r
1407                 }\r
1408         }\r
1409 }\r
1410 \r
1411 \r
1412 /*\r
1413  * Procedure:   lookupExtendedDataRecNumParam\r
1414  * Description: Returns TRUE if the requested extended data number was found among the configured records for the event.\r
1415  *                              "extDataRecClassPtr" returns a pointer to the record class, "posInExtData" returns the position in stored extended data.\r
1416  */\r
1417 static boolean lookupExtendedDataRecNumParam(uint8 extendedDataNumber, const Dem_EventParameterType *eventParam, Dem_ExtendedDataRecordClassType const **extDataRecClassPtr, uint16 *posInExtData)\r
1418 {\r
1419         boolean recNumFound = FALSE;\r
1420 \r
1421         if (eventParam->ExtendedDataClassRef != NULL) {\r
1422                 uint16  byteCnt = 0;\r
1423                 uint16 i;\r
1424 \r
1425                 // Request extended data and copy it to the buffer\r
1426                 for (i = 0; (i < DEM_MAX_NR_OF_RECORDS_IN_EXTENDED_DATA) && (eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef[i] != NULL) && (!recNumFound); i++) {\r
1427                         if (eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef[i]->RecordNumber == extendedDataNumber) {\r
1428                                 *extDataRecClassPtr =  eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef[i];\r
1429                                 *posInExtData = byteCnt;\r
1430                                 recNumFound = TRUE;\r
1431                         }\r
1432                         byteCnt += eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef[i]->DataSize;\r
1433                 }\r
1434         }\r
1435 \r
1436         return recNumFound;\r
1437 }\r
1438 \r
1439 \r
1440 /*\r
1441  * Procedure:   lookupExtendedDataPriMem\r
1442  * Description: Returns TRUE if the requested event id is found, "extData" points to the found data.\r
1443  */\r
1444 static boolean lookupExtendedDataPriMem(Dem_EventIdType eventId, ExtDataRecType **extData)\r
1445 {\r
1446         boolean eventIdFound = FALSE;\r
1447         sint16 i;\r
1448 \r
1449         // Lookup corresponding extended data\r
1450         for (i = 0; (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM) && (!eventIdFound); i++) {\r
1451                 eventIdFound = (priMemExtDataBuffer[i].eventId == eventId);\r
1452         }\r
1453 \r
1454         if (eventIdFound) {\r
1455                 // Yes, return pointer\r
1456                 *extData = &priMemExtDataBuffer[i-1];\r
1457         }\r
1458 \r
1459         return eventIdFound;\r
1460 }\r
1461 /*\r
1462  * Procedure:   copyNvmMirror\r
1463  * Description: Copies Nvram to buffer\r
1464  */\r
1465 \r
1466 Std_ReturnType copyNvmMirror(const NvM_BlockIdType BlockId, uint8 *dstPtr, const uint8 *srcPtr, uint8 len)\r
1467 {\r
1468 \r
1469 #if (DEM_USE_NVM == STD_ON)\r
1470         Std_ReturnType blockReadStatus = E_NOT_OK;\r
1471         NvM_RequestResultType requestResult;\r
1472 \r
1473     if( BlockId != 0 ) {\r
1474                 NvM_GetErrorStatus(BlockId, &requestResult);\r
1475                 if(requestResult != NVM_REQ_PENDING ) {\r
1476                         memcpy(dstPtr, srcPtr, len);\r
1477                         blockReadStatus = E_OK;\r
1478                 }\r
1479     }\r
1480 \r
1481     return blockReadStatus;\r
1482 #else\r
1483     return E_OK;\r
1484 #endif\r
1485 }\r
1486 /*\r
1487  * Procedure:   writeNvmMirror\r
1488  * Description: store data in NVRam\r
1489  */\r
1490 Std_ReturnType writeNvmMirror(const NvM_BlockIdType BlockId, uint8 *dstPtr, const uint8 *srcPtr, uint8 len)\r
1491 {\r
1492 #if (DEM_USE_NVM == STD_ON)\r
1493         Std_ReturnType blockWriteStatus = E_NOT_OK;\r
1494         NvM_RequestResultType requestResult;\r
1495 \r
1496     if( BlockId != 0 ) {\r
1497         NvM_GetErrorStatus(BlockId, &requestResult);\r
1498                 if(requestResult != NVM_REQ_PENDING ) {\r
1499                         memcpy(dstPtr, srcPtr, len);\r
1500                         (void)NvM_WriteBlock(BlockId, (const uint8*)dstPtr);\r
1501                         blockWriteStatus = E_OK;\r
1502                 }\r
1503     }\r
1504 \r
1505     return blockWriteStatus;\r
1506 #else\r
1507     return E_OK;\r
1508 #endif\r
1509 }\r
1510 \r
1511 /*\r
1512  * Procedure:   storeAgingRecPerMem\r
1513  * Description: store aging records in NVRam\r
1514  */\r
1515 static void storeAgingRecPerMem(const NvM_BlockIdType AgingBlockId)\r
1516 {\r
1517         imask_t state;\r
1518 \r
1519         Irq_Save(state);\r
1520 \r
1521         if( E_NOT_OK == writeNvmMirror(AgingBlockId, (uint8 *)HealingMirrorBuffer, (const uint8 *)priMemAgingBuffer, sizeof(priMemAgingBuffer)) ){\r
1522                 AgingIsModified = TRUE;\r
1523         }\r
1524 \r
1525         Irq_Restore(state);\r
1526 }\r
1527 /*\r
1528  * Procedure:   deleteAgingRecPriMem\r
1529  * Description: delete aging record in primary memory\r
1530  */\r
1531 static void deleteAgingRecPriMem(const Dem_EventParameterType *eventParam)\r
1532 {\r
1533         uint16 i;\r
1534         imask_t state;\r
1535 \r
1536         Irq_Save(state);\r
1537 \r
1538         for (i = 0; i<DEM_MAX_NUMBER_FF_DATA_PRI_MEM; i++){\r
1539                 if (priMemAgingBuffer[i].eventId == eventParam->EventID){\r
1540                         memset(&priMemAgingBuffer[i], 0, sizeof(HealingRecType));\r
1541                 }\r
1542         }\r
1543 \r
1544         Irq_Restore(state);\r
1545 }\r
1546 \r
1547 /*\r
1548  * Procedure:   storeFreezeFrameDataPriMem\r
1549  * Description: store FreezeFrame data record in primary memory\r
1550  */\r
1551 static void storeFreezeFrameDataPriMem(const Dem_EventParameterType *eventParam, const FreezeFrameRecType *freezeFrame)\r
1552 {\r
1553         boolean eventIdFound = FALSE;\r
1554         boolean eventIdFreePositionFound=FALSE;\r
1555         boolean displacementPositionFound=FALSE;\r
1556         FreezeFrameRecType *freezeFrameLocal;\r
1557         uint16 i;\r
1558         imask_t state;\r
1559 \r
1560         Irq_Save(state);\r
1561 \r
1562         /* Check if already stored */\r
1563         for (i = 0; (i<DEM_MAX_NUMBER_FF_DATA_PRI_MEM) && (!eventIdFound); i++){\r
1564                 eventIdFound = ((priMemFreezeFrameBuffer[i].eventId == eventParam->EventID) && (priMemFreezeFrameBuffer[i].recordNumber == freezeFrame->recordNumber));\r
1565         }\r
1566 \r
1567         if (eventIdFound) {\r
1568                 memcpy(&priMemFreezeFrameBuffer[i-1], freezeFrame, sizeof(FreezeFrameRecType));\r
1569         }\r
1570         else {\r
1571                 for (i = 0; (i < DEM_MAX_NUMBER_FF_DATA_PRI_MEM) && (!eventIdFreePositionFound); i++){\r
1572                         eventIdFreePositionFound =  (priMemFreezeFrameBuffer[i].eventId == DEM_EVENT_ID_NULL);\r
1573                 }\r
1574                 if (eventIdFreePositionFound) {\r
1575                         memcpy(&priMemFreezeFrameBuffer[i-1], freezeFrame, sizeof(FreezeFrameRecType));\r
1576                 }\r
1577                 else {\r
1578                         displacementPositionFound = lookupFreezeFrameForDisplacement(&freezeFrameLocal);\r
1579                         if(displacementPositionFound){\r
1580                                 memcpy(freezeFrameLocal, freezeFrame, sizeof(FreezeFrameRecType));\r
1581                         }\r
1582                         else{\r
1583                                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_STORE_FF_DATA_PRI_MEM_ID, DEM_E_PRI_MEM_FF_DATA_BUFF_FULL);\r
1584                         }                       \r
1585                 }\r
1586         }\r
1587 \r
1588         Irq_Restore(state);\r
1589 }\r
1590 /*\r
1591  * Procedure:   storeFreezeFrameDataPerMem\r
1592  * Description: Store the freeze frame data in NVRam\r
1593  * \r
1594  */\r
1595 static void storeFreezeFrameDataPerMem()\r
1596 {\r
1597         imask_t state;\r
1598 \r
1599         Irq_Save(state);\r
1600 \r
1601         for(uint16 i = 0; i < DEM_MAX_NUMBER_FF_DATA_PRI_MEM; i++){\r
1602                 if(memcmp(&priMemFreezeFrameBuffer[i], FreezeFrameMirrorBuffer[i], sizeof(FreezeFrameRecType))){\r
1603                         if( E_NOT_OK == writeNvmMirror(FreezeFrameBlockId[i], (uint8 *)FreezeFrameMirrorBuffer[i], (const uint8 *)&priMemFreezeFrameBuffer[i], sizeof(FreezeFrameRecType)) ) {\r
1604                                 FFIsModified = TRUE;\r
1605                         }\r
1606                 }\r
1607         }\r
1608 \r
1609         Irq_Restore(state);\r
1610 }\r
1611 \r
1612 // PC-Lint (715 etc): Remove errors until function is filled.\r
1613 //lint -e{715}          Symbol not referenced\r
1614 static void deleteFreezeFrameDataPriMem(const Dem_EventParameterType *eventParam)\r
1615 {\r
1616         uint16 i;\r
1617         imask_t state;\r
1618 \r
1619         Irq_Save(state);\r
1620 \r
1621         for (i = 0; i<DEM_MAX_NUMBER_FF_DATA_PRI_MEM; i++){\r
1622                 if (priMemFreezeFrameBuffer[i].eventId == eventParam->EventID){\r
1623                         memset(&priMemFreezeFrameBuffer[i], 0, sizeof(FreezeFrameRecType));\r
1624 \r
1625                 }\r
1626         }\r
1627 \r
1628         Irq_Restore(state);\r
1629 }\r
1630 \r
1631 /*\r
1632  * Procedure:   storeFreezeFrameDataEvtMem\r
1633  * Description: Store the freeze frame data in event memory according to\r
1634  *                              "eventParam" destination option\r
1635  */\r
1636 static void storeFreezeFrameDataEvtMem(const Dem_EventParameterType *eventParam, const FreezeFrameRecType *freezeFrame)\r
1637 {\r
1638         uint16 i;\r
1639 \r
1640         for (i = 0; (i < DEM_MAX_NR_OF_EVENT_DESTINATION) && (eventParam->EventClass->EventDestination[i] != DEM_EVENT_DESTINATION_END_OF_LIST); i++) {\r
1641                 switch (eventParam->EventClass->EventDestination[i])\r
1642                 {\r
1643                 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:\r
1644                         storeFreezeFrameDataPriMem(eventParam, freezeFrame);\r
1645                         storeFreezeFrameDataPerMem();\r
1646                         break;\r
1647 \r
1648                 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:\r
1649                 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:\r
1650                 case DEM_DTC_ORIGIN_MIRROR_MEMORY:\r
1651                         // Not yet supported\r
1652                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GLOBAL_ID, DEM_E_NOT_IMPLEMENTED_YET);\r
1653                         break;\r
1654 \r
1655                 default:\r
1656                         break;\r
1657                 }\r
1658         }\r
1659 }\r
1660 \r
1661 /*\r
1662  * Procedure:   lookupFreezeFrameDataRecNumParam\r
1663  * Description: Returns TRUE if the requested freezeFrame data number was found among the configured records for the event.\r
1664  *                              "freezeFrameClassPtr" returns a pointer to the record class.\r
1665  */\r
1666 static boolean lookupFreezeFrameDataRecNumParam(uint8 recordNumber, const Dem_EventParameterType *eventParam, Dem_FreezeFrameClassType const **freezeFrameClassPtr)\r
1667 {\r
1668         boolean recNumFound = FALSE;\r
1669         uint16 i;\r
1670 \r
1671         if (eventParam->FreezeFrameClassRef != NULL) {\r
1672                 for (i = 0; (i < DEM_MAX_NR_OF_CLASSES_IN_FREEZEFRAME_DATA) && (eventParam->FreezeFrameClassRef[i] != NULL) && (!recNumFound); i++) {\r
1673                         if (eventParam->FreezeFrameClassRef[i]->FFRecordNumber == recordNumber) {\r
1674                                 *freezeFrameClassPtr =  eventParam->FreezeFrameClassRef[i];\r
1675                                 recNumFound = TRUE;\r
1676                         }\r
1677                 }\r
1678         }\r
1679 \r
1680         return recNumFound;\r
1681 }\r
1682 \r
1683 /*\r
1684  * Procedure:   lookupFreezeFrameDataSize\r
1685  * Description: Returns TRUE if the requested freezeFrame data size was obtained successfully from the configuration.\r
1686  *                              "dataSize" returns a pointer to the data size.\r
1687  */\r
1688 static boolean lookupFreezeFrameDataSize(uint8 recordNumber, Dem_FreezeFrameClassType const  **freezeFrameClassPtr, uint16 *dataSize)\r
1689 {\r
1690         Std_ReturnType callbackReturnCode;\r
1691         boolean dataSizeFound = TRUE;\r
1692         uint16 dataSizeLocal = 0;\r
1693         uint16 i;\r
1694 \r
1695         if (*freezeFrameClassPtr != NULL) {\r
1696                 for (i = 0; (i < DEM_MAX_NR_OF_RECORDS_IN_FREEZEFRAME_DATA) && ((*freezeFrameClassPtr)->FFIdClassRef[i].Arc_EOL != TRUE); i++) { \r
1697                         if((*freezeFrameClassPtr)->FFIdClassRef[i].DidReadDataLengthFnc != NULL){\r
1698                                 callbackReturnCode = (*freezeFrameClassPtr)->FFIdClassRef[i].DidReadDataLengthFnc(&dataSizeLocal);\r
1699                                 if(callbackReturnCode != E_OK){\r
1700                                         return (dataSizeFound = FALSE); \r
1701                                 }\r
1702                         }\r
1703                         else{\r
1704                                 dataSizeLocal = (*freezeFrameClassPtr)->FFIdClassRef[i].PidOrDidSize;\r
1705                         }\r
1706                         \r
1707                         *dataSize += dataSizeLocal + DEM_DID_IDENTIFIER_SIZE_OF_BYTES;\r
1708                 }\r
1709 \r
1710         }\r
1711 \r
1712         return dataSizeFound;\r
1713 }\r
1714 \r
1715 /*\r
1716  * Procedure:   lookupFreezeFrameDataPriMem\r
1717  * Description: Returns TRUE if the requested event id is found, "freezeFrame" points to the found data.\r
1718  */\r
1719 static boolean lookupFreezeFrameDataPriMem(Dem_EventIdType eventId,uint8 recordNumber, FreezeFrameRecType **freezeFrame)\r
1720 {\r
1721         boolean eventIdFound = FALSE;\r
1722         uint16 i;\r
1723 \r
1724         for (i = 0; (i < DEM_MAX_NUMBER_FF_DATA_PRI_MEM) && (!eventIdFound); i++) {\r
1725                 eventIdFound = ((priMemFreezeFrameBuffer[i].eventId == eventId) && (priMemFreezeFrameBuffer[i].recordNumber == recordNumber));\r
1726         }\r
1727 \r
1728         if (eventIdFound) {\r
1729                 *freezeFrame = &priMemFreezeFrameBuffer[i-1];\r
1730         }\r
1731 \r
1732         return eventIdFound;\r
1733 }\r
1734 \r
1735 /*\r
1736  * Procedure:   handlePreInitEvent\r
1737  * Description: Handle the updating of event status and storing of\r
1738  *                              event related data in preInit buffers.\r
1739  */\r
1740 static void handlePreInitEvent(Dem_EventIdType eventId, Dem_EventStatusType eventStatus)\r
1741 {\r
1742         const Dem_EventParameterType *eventParam;\r
1743         EventStatusRecType eventStatusLocal;\r
1744         FreezeFrameRecType freezeFrameLocal;\r
1745         ExtDataRecType extendedDataLocal;\r
1746 \r
1747         lookupEventIdParameter(eventId, &eventParam);\r
1748         if (eventParam != NULL) {\r
1749                 if (eventParam->EventClass->OperationCycleRef < DEM_OPERATION_CYCLE_ID_ENDMARK) {\r
1750                         if (operationCycleStateList[eventParam->EventClass->OperationCycleRef] == DEM_CYCLE_STATE_START) {\r
1751                                 if (eventStatus == DEM_EVENT_STATUS_FAILED) {\r
1752                                         updateEventStatusRec(eventParam, eventStatus, TRUE, &eventStatusLocal);\r
1753                                 }\r
1754                                 else {\r
1755                                         updateEventStatusRec(eventParam, eventStatus, FALSE, &eventStatusLocal);\r
1756                                 }\r
1757 \r
1758                                 if (eventStatusLocal.errorStatusChanged) {\r
1759                                         if (eventStatusLocal.eventStatusExtended & DEM_TEST_FAILED) {\r
1760                                                 getExtendedData(eventParam, &extendedDataLocal);\r
1761                                                 if (extendedDataLocal.eventId != DEM_EVENT_ID_NULL) {\r
1762                                                         storeExtendedDataPreInit(eventParam, &extendedDataLocal);\r
1763                                                 }\r
1764                                                 getFreezeFrameData(eventParam, &freezeFrameLocal,eventStatus,&eventStatusLocal);\r
1765                                                 if (freezeFrameLocal.eventId != DEM_EVENT_ID_NULL) {\r
1766                                                         storeFreezeFrameDataPreInit(eventParam, &freezeFrameLocal);\r
1767                                                 }\r
1768                                         }\r
1769                                 }\r
1770 \r
1771                                 \r
1772                         }\r
1773                         else {\r
1774                                 // Operation cycle not started\r
1775                                 // TODO: Report error?\r
1776                         }\r
1777                 }\r
1778                 else {\r
1779                         // Operation cycle not set\r
1780                         // TODO: Report error?\r
1781                 }\r
1782         }\r
1783         else {\r
1784                 // Event ID not configured\r
1785                 // TODO: Report error?\r
1786         }\r
1787 }\r
1788 \r
1789 \r
1790 /*\r
1791  * Procedure:   handleEvent\r
1792  * Description: Handle the updating of event status and storing of\r
1793  *                              event related data in event memory.\r
1794  */\r
1795 static Std_ReturnType handleEvent(Dem_EventIdType eventId, Dem_EventStatusType eventStatus)\r
1796 {\r
1797         Std_ReturnType returnCode = E_OK;\r
1798         const Dem_EventParameterType *eventParam;\r
1799         EventStatusRecType eventStatusLocal;\r
1800         FreezeFrameRecType freezeFrameLocal;\r
1801         ExtDataRecType extendedDataLocal;\r
1802         Dem_EventStatusType eventStatusTemp = eventStatus;\r
1803 \r
1804         lookupEventIdParameter(eventId, &eventParam);\r
1805         if (eventParam != NULL) {\r
1806                 if (eventParam->EventClass->OperationCycleRef < DEM_OPERATION_CYCLE_ID_ENDMARK) {\r
1807                         if (operationCycleStateList[eventParam->EventClass->OperationCycleRef] == DEM_CYCLE_STATE_START) {\r
1808                                 if ((!((disableDtcStorage.storageDisabled) && (checkDtcGroup(disableDtcStorage.dtcGroup, eventParam)) && (checkDtcKind(disableDtcStorage.dtcKind, eventParam)))))  {\r
1809                                         updateEventStatusRec(eventParam, eventStatus, TRUE, &eventStatusLocal);\r
1810                                         if (eventStatusLocal.errorStatusChanged) {\r
1811                                                 if (eventStatusLocal.eventStatusExtended & DEM_TEST_FAILED) {\r
1812                                                         storeEventEvtMem(eventParam, &eventStatusLocal); /** @req DEM184 */\r
1813                                                         getExtendedData(eventParam, &extendedDataLocal);\r
1814                                                         if (extendedDataLocal.eventId != DEM_EVENT_ID_NULL)\r
1815                                                         {\r
1816                                                                 storeExtendedDataEvtMem(eventParam, &extendedDataLocal);\r
1817                                                         }\r
1818                                                 }\r
1819 \r
1820                                                 if ((eventStatusTemp == DEM_EVENT_STATUS_PREFAILED)\r
1821                                                                 || (eventStatusLocal.eventStatusExtended & DEM_TEST_FAILED)){\r
1822                                                         getFreezeFrameData(eventParam, &freezeFrameLocal,eventStatus,&eventStatusLocal);\r
1823                                                         if (freezeFrameLocal.eventId != DEM_EVENT_ID_NULL) {\r
1824                                                                 storeFreezeFrameDataEvtMem(eventParam, &freezeFrameLocal); /** @req DEM190 */\r
1825                                                         }\r
1826                                                 }\r
1827                                                 else{\r
1828                                                         // do nothing\r
1829                                                 }\r
1830                                         }                                       \r
1831                                 }\r
1832                         }\r
1833                         else {\r
1834                                 // Operation cycle not started\r
1835                                 returnCode = E_NOT_OK;\r
1836                         }\r
1837                 }\r
1838                 else {\r
1839                         // Operation cycle not set\r
1840                         returnCode = E_NOT_OK;\r
1841                 }\r
1842         }\r
1843         else {\r
1844                 // Event ID not configured\r
1845                 returnCode = E_NOT_OK;\r
1846         }\r
1847 \r
1848         return returnCode;\r
1849 }\r
1850 \r
1851 \r
1852 /*\r
1853  * Procedure:   resetEventStatus\r
1854  * Description: Resets the events status of eventId.\r
1855  */\r
1856 static void resetEventStatus(Dem_EventIdType eventId)\r
1857 {\r
1858         EventStatusRecType *eventStatusRecPtr;\r
1859         imask_t state;\r
1860     Irq_Save(state);\r
1861 \r
1862         lookupEventStatusRec(eventId, &eventStatusRecPtr);\r
1863         if (eventStatusRecPtr != NULL) {\r
1864                 eventStatusRecPtr->eventStatusExtended &= (Dem_EventStatusExtendedType)~DEM_TEST_FAILED; /** @req DEM187 */\r
1865         }\r
1866 \r
1867     Irq_Restore(state);\r
1868 }\r
1869 \r
1870 \r
1871 /*\r
1872  * Procedure:   getEventStatus\r
1873  * Description: Returns the extended event status bitmask of eventId in "eventStatusExtended".\r
1874  */\r
1875 static void getEventStatus(Dem_EventIdType eventId, Dem_EventStatusExtendedType *eventStatusExtended)\r
1876 {\r
1877         EventStatusRecType eventStatusLocal;\r
1878 \r
1879         // Get recorded status\r
1880         getEventStatusRec(eventId, &eventStatusLocal);\r
1881         if (eventStatusLocal.eventId == eventId) {\r
1882                 *eventStatusExtended = eventStatusLocal.eventStatusExtended; /** @req DEM051 */\r
1883         }\r
1884         else {\r
1885                 // Event Id not found, no report received.\r
1886                 *eventStatusExtended = DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR;\r
1887         }\r
1888 }\r
1889 \r
1890 \r
1891 /*\r
1892  * Procedure:   getEventFailed\r
1893  * Description: Returns the TRUE or FALSE of "eventId" in "eventFailed" depending on current status.\r
1894  */\r
1895 static void getEventFailed(Dem_EventIdType eventId, boolean *eventFailed)\r
1896 {\r
1897         EventStatusRecType eventStatusLocal;\r
1898 \r
1899         // Get recorded status\r
1900         getEventStatusRec(eventId, &eventStatusLocal);\r
1901         if (eventStatusLocal.eventId == eventId) {\r
1902                 if (eventStatusLocal.eventStatusExtended & DEM_TEST_FAILED) { /** @req DEM052 */\r
1903                         *eventFailed = TRUE;\r
1904                 }\r
1905                 else {\r
1906                         *eventFailed = FALSE;\r
1907                 }\r
1908         }\r
1909         else {\r
1910                 // Event Id not found, assume ok.\r
1911                 *eventFailed = FALSE;\r
1912         }\r
1913 }\r
1914 \r
1915 \r
1916 /*\r
1917  * Procedure:   getEventTested\r
1918  * Description: Returns the TRUE or FALSE of "eventId" in "eventTested" depending on\r
1919  *                              current status the "test not completed this operation cycle" bit.\r
1920  */\r
1921 static void getEventTested(Dem_EventIdType eventId, boolean *eventTested)\r
1922 {\r
1923         EventStatusRecType eventStatusLocal;\r
1924 \r
1925         // Get recorded status\r
1926         getEventStatusRec(eventId, &eventStatusLocal);\r
1927         if (eventStatusLocal.eventId == eventId) {\r
1928                 if ( !(eventStatusLocal.eventStatusExtended & DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE)) { /** @req DEM053 */\r
1929                         *eventTested = TRUE;\r
1930                 }\r
1931                 else {\r
1932                         *eventTested = FALSE;\r
1933                 }\r
1934         }\r
1935         else {\r
1936                 // Event Id not found, not tested.\r
1937                 *eventTested = FALSE;\r
1938         }\r
1939 }\r
1940 \r
1941 \r
1942 /*\r
1943  * Procedure:   getFaultDetectionCounter\r
1944  * Description: Returns pre debounce counter of "eventId" in "counter" and return value E_OK if\r
1945  *                              the counter was available else E_NOT_OK.\r
1946  */\r
1947 static Std_ReturnType getFaultDetectionCounter(Dem_EventIdType eventId, sint8 *counter)\r
1948 {\r
1949         Std_ReturnType returnCode = E_NOT_OK;\r
1950         const Dem_EventParameterType *eventParam;\r
1951 \r
1952         lookupEventIdParameter(eventId, &eventParam);\r
1953         if (eventParam != NULL) {\r
1954                 if (eventParam->EventClass->PreDebounceAlgorithmClass != NULL) {\r
1955                         switch (eventParam->EventClass->PreDebounceAlgorithmClass->PreDebounceName)\r
1956                         {\r
1957                         case DEM_NO_PRE_DEBOUNCE:\r
1958                                 if (eventParam->EventClass->PreDebounceAlgorithmClass->PreDebounceAlgorithm.PreDebounceMonitorInternal != NULL) {\r
1959                                         if (eventParam->EventClass->PreDebounceAlgorithmClass->PreDebounceAlgorithm.PreDebounceMonitorInternal->CallbackGetFDCntFnc != NULL) {\r
1960                                                 returnCode = eventParam->EventClass->PreDebounceAlgorithmClass->PreDebounceAlgorithm.PreDebounceMonitorInternal->CallbackGetFDCntFnc(counter); /** @req DEM204.None */ /** @req DEM264 */ /** @req DEM265 */\r
1961                                         }\r
1962                                 }\r
1963                                 break;\r
1964 \r
1965                         case DEM_PRE_DEBOUNCE_COUNTER_BASED:\r
1966                                 {\r
1967                                         EventStatusRecType *eventStatusRec;\r
1968 \r
1969                                         lookupEventStatusRec(eventId, &eventStatusRec);\r
1970                                         if (eventStatusRec != NULL) {\r
1971                                                 *counter = eventStatusRec->faultDetectionCounter; /** @req DEM204.Counter */\r
1972                                         } else {\r
1973                                                 *counter = 0;\r
1974                                         }\r
1975                                         returnCode = E_OK;\r
1976                                 }\r
1977                                 break;\r
1978 \r
1979                         case DEM_PRE_DEBOUNCE_FREQUENCY_BASED:\r
1980                         case DEM_PRE_DEBOUNCE_TIME_BASED:\r
1981                                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETFAULTDETECTIONCOUNTER_ID, DEM_E_NOT_IMPLEMENTED_YET);\r
1982                                 break;\r
1983 \r
1984                         default:\r
1985                                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETFAULTDETECTIONCOUNTER_ID, DEM_E_PARAM_DATA);\r
1986                                 break;\r
1987                         }\r
1988                 }\r
1989         }\r
1990 \r
1991         return returnCode;\r
1992 }\r
1993 /*\r
1994  * Procedure:   deleteEventMemory\r
1995  * Description: If aging of an event occurs, the Dem module shall delete the event from \r
1996  *                              the event memory including its event related data\r
1997  */\r
1998 static void deleteEventMemory(const Dem_EventParameterType *eventParam)\r
1999 {\r
2000         uint16 i;\r
2001 \r
2002         for (i = 0; (i < DEM_MAX_NR_OF_EVENT_DESTINATION) && (eventParam->EventClass->EventDestination[i] != DEM_EVENT_DESTINATION_END_OF_LIST); i++) {\r
2003                 switch (eventParam->EventClass->EventDestination[i])\r
2004                 {\r
2005                 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:\r
2006                         deleteEventPriMem(eventParam);\r
2007                         deleteFreezeFrameDataPriMem(eventParam);\r
2008                         deleteExtendedDataPriMem(eventParam);\r
2009                         storeFreezeFrameDataPerMem();\r
2010                         break;\r
2011 \r
2012                 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:\r
2013                         //TODO:need to add corresponding event and extended deleting functions\r
2014 \r
2015                         break;\r
2016 \r
2017                 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:\r
2018                 case DEM_DTC_ORIGIN_MIRROR_MEMORY:\r
2019                         // Not yet supported\r
2020                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GLOBAL_ID, DEM_E_NOT_IMPLEMENTED_YET);\r
2021                         break;\r
2022 \r
2023                 default:\r
2024                         break;\r
2025                 }\r
2026 \r
2027         }\r
2028 \r
2029 }\r
2030 /*\r
2031  * Procedure:   lookupAgingRecPriMem\r
2032  * Description: Returns the pointer to event id parameters of "eventId" in "*priMemAgingBuffer",\r
2033  *                              if not found NULL is returned.\r
2034  */\r
2035 static boolean lookupAgingRecPriMem(Dem_EventIdType eventId, const HealingRecType **agingRec)\r
2036 {\r
2037         uint16 i;\r
2038         boolean agingRecFound = FALSE;\r
2039         \r
2040         for (i = 0; i < DEM_MAX_NUMBER_AGING_PRI_MEM && (!agingRecFound); i++) {\r
2041                 if(priMemAgingBuffer[i].eventId == eventId){\r
2042                         agingRecFound = TRUE;\r
2043                 }\r
2044 \r
2045         }\r
2046 \r
2047         if(agingRecFound){\r
2048                 *agingRec = &priMemAgingBuffer[i-1];\r
2049         }\r
2050         else{\r
2051                 *agingRec = NULL;\r
2052         }\r
2053 \r
2054         return agingRecFound;\r
2055 \r
2056 }\r
2057 \r
2058 \r
2059 /*\r
2060  * Procedure:   handleAging\r
2061  * Description: according to the operation state of "operationCycleId" to "cycleState" , handle the aging relatived data\r
2062  *                              Returns E_OK if operation was successful else E_NOT_OK.\r
2063  */\r
2064 static Std_ReturnType handleAging(Dem_OperationCycleIdType operationCycleId, Dem_OperationCycleStateType cycleState)\r
2065 {\r
2066         uint16 i;\r
2067         Std_ReturnType returnCode = E_OK;\r
2068         HealingRecType *agingRecLocal = NULL;\r
2069         boolean agingRecFound = FALSE;\r
2070 \r
2071         if (operationCycleId < DEM_OPERATION_CYCLE_ID_ENDMARK) {\r
2072                 switch (cycleState)\r
2073                 {\r
2074                 case DEM_CYCLE_STATE_START:\r
2075                         break;\r
2076 \r
2077                 case DEM_CYCLE_STATE_END:/** @req Dem490 */\r
2078                         for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {\r
2079                                 if(eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL){\r
2080                                         if(eventStatusBuffer[i].eventParamRef != NULL){\r
2081                                                 if(eventStatusBuffer[i].eventParamRef->EventClass != NULL){\r
2082                                                         if((eventStatusBuffer[i].eventParamRef->EventClass->HealingAllowed == TRUE)\\r
2083                                                                 && (eventStatusBuffer[i].eventParamRef->EventClass->HealingCycleRef == operationCycleId)){\r
2084                                                                 if((eventStatusBuffer[i].eventStatusExtended & DEM_CONFIRMED_DTC)\\r
2085                                                                         && (!(eventStatusBuffer[i].eventStatusExtended & DEM_TEST_FAILED))\\r
2086                                                                         && (!(eventStatusBuffer[i].eventStatusExtended & DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE))){\r
2087                                                                         agingRecFound = lookupAgingRecPriMem(eventStatusBuffer[i].eventId, (const HealingRecType **)(&agingRecLocal));\r
2088                                                                         if(agingRecFound){\r
2089                                                                                 agingRecLocal->agingCounter++;/** @req Dem489 */\r
2090                                                                                 agingRecLocal->checksum = calcChecksum(agingRecLocal,sizeof(HealingRecType) - sizeof(ChecksumType));\r
2091                                                                                 if(agingRecLocal->agingCounter > eventStatusBuffer[i].eventParamRef->EventClass->HealingCycleCounter){\r
2092                                                                                         //deleteEventMemory(eventStatusBuffer[i].eventParamRef); /** @req Dem497 */\r
2093 \r
2094                                                                                         deleteAgingRecPriMem(eventStatusBuffer[i].eventParamRef);\r
2095 \r
2096                                                                                         eventStatusBuffer[i].eventStatusExtended &= (Dem_EventStatusExtendedType)(~DEM_CONFIRMED_DTC);\r
2097                                                                                         eventStatusBuffer[i].eventStatusExtended &= (Dem_EventStatusExtendedType)(~DEM_PENDING_DTC);\r
2098                                                                                         eventStatusBuffer[i].eventStatusExtended &= (Dem_EventStatusExtendedType)(~DEM_WARNING_INDICATOR_REQUESTED);\r
2099                                                                                 }\r
2100                                                                                 /* Set the flag,start up the storage of NVRam in main function. */\r
2101                                                                                 AgingIsModified = TRUE;\r
2102                                                                         }\r
2103                                                                         else{\r
2104                                                                                 /* If it does exist,establish a new record for the corresponding event */\r
2105                                                                                 agingRecFound = lookupAgingRecPriMem(DEM_EVENT_ID_NULL, (const HealingRecType **)(&agingRecLocal));\r
2106                                                                                 if(agingRecFound){\r
2107                                                                                         agingRecLocal->eventId = eventStatusBuffer[i].eventId;\r
2108                                                                                         agingRecLocal->agingCounter++;\r
2109                                                                                         agingRecLocal->checksum = calcChecksum(agingRecLocal,sizeof(HealingRecType) - sizeof(ChecksumType));\r
2110                                                                                         AgingIsModified = TRUE;\r
2111                                                                                 }\r
2112                                                                                 else{\r
2113                                                                                         /* primary memory of aging records is full. */\r
2114                                                                                 }\r
2115                                                                         }\r
2116                                                                 }\r
2117                                                                 else{\r
2118                                                                         /* If the status bit testFailed (bit 0) is set during the operation cycle, the counter shall be reset. */\r
2119                                                                         if(eventStatusBuffer[i].eventStatusExtended & DEM_TEST_FAILED){\r
2120                                                                                 agingRecFound = lookupAgingRecPriMem(eventStatusBuffer[i].eventId, (const HealingRecType **)(&agingRecLocal));\r
2121                                                                                 if(agingRecFound){\r
2122                                                                                         if(agingRecLocal->agingCounter){\r
2123                                                                                                 agingRecLocal->agingCounter = 0;\r
2124                                                                                                 agingRecLocal->checksum = calcChecksum(agingRecLocal,sizeof(HealingRecType) - sizeof(ChecksumType));\r
2125                                                                                                 AgingIsModified = TRUE;\r
2126                                                                                         }\r
2127                                                                                 }\r
2128                                                                         }\r
2129                                                                 }\r
2130                                                         }\r
2131                                                 }\r
2132                                         }\r
2133                                 }\r
2134                         }\r
2135                         break;\r
2136                 default:\r
2137                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_SETOPERATIONCYCLESTATE_ID, DEM_E_PARAM_DATA);\r
2138                         returnCode = E_NOT_OK;\r
2139                         break;\r
2140                 }\r
2141         }\r
2142         else {\r
2143                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_SETOPERATIONCYCLESTATE_ID, DEM_E_PARAM_DATA);\r
2144                 returnCode = E_NOT_OK;\r
2145                 }\r
2146 \r
2147         return returnCode;\r
2148 \r
2149 }\r
2150 \r
2151 /*\r
2152  * Procedure:   setOperationCycleState\r
2153  * Description: Change the operation state of "operationCycleId" to "cycleState" and updates stored\r
2154  *                              event connected to this cycle id.\r
2155  *                              Returns E_OK if operation was successful else E_NOT_OK.\r
2156  */\r
2157 static Std_ReturnType setOperationCycleState(Dem_OperationCycleIdType operationCycleId, Dem_OperationCycleStateType cycleState) /** @req DEM338 */\r
2158 {\r
2159         uint16 i;\r
2160         Std_ReturnType returnCode = E_OK;\r
2161 \r
2162         if (operationCycleId < DEM_OPERATION_CYCLE_ID_ENDMARK) {\r
2163                 switch (cycleState)\r
2164                 {\r
2165                 case DEM_CYCLE_STATE_START:\r
2166                         operationCycleStateList[operationCycleId] = cycleState;\r
2167                         // Lookup event ID\r
2168                         for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {\r
2169                                 if ((eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) && (eventStatusBuffer[i].eventParamRef->EventClass->OperationCycleRef == operationCycleId)) {\r
2170                                         eventStatusBuffer[i].eventStatusExtended &= (Dem_EventStatusExtendedType)~DEM_TEST_FAILED_THIS_OPERATION_CYCLE;\r
2171                                         eventStatusBuffer[i].eventStatusExtended |= DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE;\r
2172                                 }\r
2173                         }\r
2174                         break;\r
2175 \r
2176                 case DEM_CYCLE_STATE_END:\r
2177                         operationCycleStateList[operationCycleId] = cycleState;\r
2178                         // Lookup event ID\r
2179                         for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {\r
2180                                 if ((eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) && (eventStatusBuffer[i].eventParamRef->EventClass->OperationCycleRef == operationCycleId)) {\r
2181                                         if ((!(eventStatusBuffer[i].eventStatusExtended & DEM_TEST_FAILED_THIS_OPERATION_CYCLE)) && (!(eventStatusBuffer[i].eventStatusExtended & DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE))) {\r
2182                                                 eventStatusBuffer[i].eventStatusExtended &= (Dem_EventStatusExtendedType)~DEM_PENDING_DTC;              // Clear pendingDTC bit /** @req DEM379.PendingClear\r
2183                                                 storeEventEvtMem(eventStatusBuffer[i].eventParamRef, &eventStatusBuffer[i]);\r
2184                                         }\r
2185                                 }\r
2186                         }\r
2187                         break;\r
2188                 default:\r
2189                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_SETOPERATIONCYCLESTATE_ID, DEM_E_PARAM_DATA);\r
2190                         returnCode = E_NOT_OK;\r
2191                         break;\r
2192                 }\r
2193         }\r
2194         else {\r
2195                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_SETOPERATIONCYCLESTATE_ID, DEM_E_PARAM_DATA);\r
2196                 returnCode = E_NOT_OK;\r
2197                 }\r
2198 \r
2199         return returnCode;\r
2200 }\r
2201 \r
2202 \r
2203 //==============================================================================//\r
2204 //                                                                                                                                                              //\r
2205 //                                        E X T E R N A L   F U N C T I O N S                                           //\r
2206 //                                                                                                                                                              //\r
2207 //==============================================================================//\r
2208 \r
2209 /*********************************************\r
2210  * Interface for upper layer modules (8.3.1) *\r
2211  *********************************************/\r
2212 \r
2213 /*\r
2214  * Procedure:   Dem_GetVersionInfo\r
2215  * Reentrant:   Yes\r
2216  */\r
2217 // Defined in Dem.h\r
2218 \r
2219 \r
2220 /***********************************************\r
2221  * Interface ECU State Manager <-> DEM (8.3.2) *\r
2222  ***********************************************/\r
2223 \r
2224 /*\r
2225  * Procedure:   Dem_PreInit\r
2226  * Reentrant:   No\r
2227  */\r
2228 void Dem_PreInit(void)\r
2229 {\r
2230         /** @req DEM180 */\r
2231         uint16 i, j;\r
2232 \r
2233         EventStatusRecType *eventStatusRecPtr;\r
2234         const Dem_EventParameterType *eventIdParamList;\r
2235 \r
2236         VALIDATE_NO_RV(DEM_Config.ConfigSet != NULL, DEM_PREINIT_ID, DEM_E_CONFIG_PTR_INVALID);\r
2237 \r
2238         configSet = DEM_Config.ConfigSet;\r
2239 \r
2240         // Initializion of operation cycle states.\r
2241         for (i = 0; i < DEM_OPERATION_CYCLE_ID_ENDMARK; i++) {\r
2242                 operationCycleStateList[i] = DEM_CYCLE_STATE_END;\r
2243         }\r
2244 \r
2245         // Initialize the event status buffer\r
2246         for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {\r
2247                 eventStatusBuffer[i].eventId = DEM_EVENT_ID_NULL;\r
2248                 eventStatusBuffer[i].eventParamRef = NULL;\r
2249                 eventStatusBuffer[i].faultDetectionCounter = 0;\r
2250                 eventStatusBuffer[i].occurrence = 0;\r
2251                 eventStatusBuffer[i].eventStatusExtended = DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR;\r
2252                 eventStatusBuffer[i].errorStatusChanged = FALSE;\r
2253         }\r
2254 \r
2255         // Insert all supported events into event status buffer\r
2256         uint16 index = 0;\r
2257         eventIdParamList = configSet->EventParameter;\r
2258         while( !eventIdParamList[index].Arc_EOL ) {\r
2259                 // Find next free position in event status buffer\r
2260                 lookupEventStatusRec(DEM_EVENT_ID_NULL, &eventStatusRecPtr);\r
2261                 if(NULL != eventStatusRecPtr) {\r
2262                         eventStatusRecPtr->eventId = eventIdParamList[index].EventID;\r
2263                         eventStatusRecPtr->eventParamRef = &eventIdParamList[index];\r
2264                 } else {\r
2265                         // event status buffer is full\r
2266                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_PREINIT_ID, DEM_E_EVENT_STATUS_BUFF_FULL);\r
2267                 }\r
2268                 index++;\r
2269         }\r
2270 \r
2271         //lint -save\r
2272         //lint -e568 -e685 //PC-Lint exception.\r
2273         //lint -e681 //PC-Lint exception to MISRA 14.1: Loop is not entered. This only happens when config variable is zero. Keep as it is for less complex code.\r
2274         // Initialize the pre init buffers\r
2275         for (i = 0; i < DEM_MAX_NUMBER_FF_DATA_PRE_INIT; i++) {\r
2276                 preInitFreezeFrameBuffer[i].checksum = 0;\r
2277                 preInitFreezeFrameBuffer[i].eventId = DEM_EVENT_ID_NULL;\r
2278                 preInitFreezeFrameBuffer[i].occurrence = 0;\r
2279                 preInitFreezeFrameBuffer[i].dataSize = 0;\r
2280                 for (j = 0; j < DEM_MAX_SIZE_FF_DATA;j++){\r
2281                         preInitFreezeFrameBuffer[i].data[j] = 0;\r
2282                 }\r
2283         }\r
2284         //lint -restore\r
2285 \r
2286         for (i = 0; i < DEM_MAX_NUMBER_EXT_DATA_PRE_INIT; i++) {\r
2287                 preInitExtDataBuffer[i].checksum = 0;\r
2288                 preInitExtDataBuffer[i].eventId = DEM_EVENT_ID_NULL;\r
2289                 preInitExtDataBuffer[i].dataSize = 0;\r
2290                 for (j = 0; j < DEM_MAX_SIZE_EXT_DATA;j++){\r
2291                         preInitExtDataBuffer[i].data[j] = 0;\r
2292                 }\r
2293         }\r
2294 \r
2295         disableDtcStorage.storageDisabled = FALSE;\r
2296 \r
2297         (void)setOperationCycleState(DEM_ACTIVE, DEM_CYCLE_STATE_START); /** @req DEM047 */\r
2298 \r
2299         demState = DEM_PREINITIALIZED;\r
2300 }\r
2301 \r
2302 \r
2303 /*\r
2304  * Procedure:   Dem_Init\r
2305  * Reentrant:   No\r
2306  */\r
2307 void Dem_Init(void)\r
2308 {\r
2309         uint16 i;\r
2310         ChecksumType cSum;\r
2311         const Dem_EventParameterType *eventParam;\r
2312 \r
2313         if(DEM_PREINITIALIZED != demState){\r
2314                 /*\r
2315                  * Dem_PreInit was has not been called since last time Dem_Shutdown was called.\r
2316                  * This suggests that we are resuming from sleep. According to section 5.7 in\r
2317                  * EcuM specification, RAM content is assumed to be still valid from the previous cycle.\r
2318                  * Do not read from saved error log since buffers already contains this data.\r
2319                  */\r
2320                 (void)setOperationCycleState(DEM_ACTIVE, DEM_CYCLE_STATE_START);\r
2321 \r
2322         } else {\r
2323 \r
2324                 for(i = 0; i < DEM_MAX_NUMBER_FF_DATA_PRI_MEM; i++){\r
2325                         if( E_NOT_OK == copyNvmMirror(FreezeFrameBlockId[i], (uint8 *)&priMemFreezeFrameBuffer[i], (const uint8 *)&FreezeFrameMirrorBuffer[i], sizeof(FreezeFrameRecType)) ){\r
2326                                 //TODO:NVM is busy or block id is 0,report error or what?\r
2327                         }\r
2328                 }\r
2329                 //recover Aging from NVRam to RAM\r
2330                 if(E_OK == copyNvmMirror(HealingBlockId, (uint8*)priMemAgingBuffer, (const uint8*)HealingMirrorBuffer, sizeof(priMemAgingBuffer)) ){\r
2331 \r
2332                 }\r
2333 \r
2334                 // Validate aging records stored in primary memory\r
2335                 for (i = 0; i < DEM_MAX_NUMBER_AGING_PRI_MEM; i++){\r
2336                         cSum = calcChecksum(&priMemAgingBuffer[i], sizeof(HealingRecType) - sizeof(ChecksumType));\r
2337                         if ((cSum != priMemAgingBuffer[i].checksum) || (priMemAgingBuffer[i].eventId == DEM_EVENT_ID_NULL)) {\r
2338                                 // Unlegal record, clear the record\r
2339                                 memset(&priMemAgingBuffer[i], 0, sizeof(HealingRecType));\r
2340                                 AgingIsModified = TRUE;\r
2341                         }\r
2342                 }\r
2343 \r
2344                 // Validate event records stored in primary memory\r
2345                 for (i = 0; i < DEM_MAX_NUMBER_EVENT_PRI_MEM; i++) {\r
2346                         cSum = calcChecksum(&priMemEventBuffer[i], sizeof(EventRecType)-sizeof(ChecksumType));\r
2347                         if ((cSum != priMemEventBuffer[i].checksum) || (priMemEventBuffer[i].eventId == DEM_EVENT_ID_NULL)) {\r
2348                                 // Unlegal record, clear the record\r
2349                                 memset(&priMemEventBuffer[i], 0, sizeof(EventRecType));\r
2350                         }\r
2351                         else {\r
2352                                 // Valid, update current status\r
2353                                 mergeEventStatusRec(&priMemEventBuffer[i]);\r
2354 \r
2355                                 // Update occurrence counter on pre init stored freeze frames\r
2356                                 updateFreezeFrameOccurrencePreInit(&priMemEventBuffer[i]);\r
2357                         }\r
2358                 }\r
2359 \r
2360                 //initialize the current timestamp and update the timestamp in pre init\r
2361                 initCurrentFreezeFrameTimeStamp(&FF_TimeStamp);//add by i-soft\r
2362 \r
2363                 // Validate extended data records stored in primary memory\r
2364                 for (i = 0; i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM; i++) {\r
2365                         cSum = calcChecksum(&priMemExtDataBuffer[i], sizeof(ExtDataRecType)-sizeof(ChecksumType));\r
2366                         if ((cSum != priMemExtDataBuffer[i].checksum) || (priMemExtDataBuffer[i].eventId == DEM_EVENT_ID_NULL)) {\r
2367                                 // Unlegal record, clear the record\r
2368                                 memset(&priMemExtDataBuffer[i], 0, sizeof(ExtDataRecType));\r
2369                         }\r
2370                 }\r
2371 \r
2372                 //initialize the current timestamp and update the timestamp in pre init\r
2373                 initCurrentFreezeFrameTimeStamp(&FF_TimeStamp);\r
2374 \r
2375                 //lint -save\r
2376                 //lint -e568 //PC-Lint exception.\r
2377                 //lint -e685 //PC-Lint exception.\r
2378                 //lint -e681 //PC-Lint exception to MISRA 14.1: Loop is not entered. This only happens when DEM_MAX_NUMBER_FF_DATA_PRE_INIT is zero. Keep as it is for less complex code.\r
2379                 // Validate freeze frame records stored in primary memory\r
2380                 for (i = 0; i < DEM_MAX_NUMBER_FF_DATA_PRI_MEM; i++) {\r
2381                         cSum = calcChecksum(&priMemFreezeFrameBuffer[i], sizeof(FreezeFrameRecType)-sizeof(ChecksumType));\r
2382                         if ((cSum != priMemFreezeFrameBuffer[i].checksum) || (priMemFreezeFrameBuffer[i].eventId == DEM_EVENT_ID_NULL)) {\r
2383                                 // Unlegal record, clear the record\r
2384                                 memset(&priMemFreezeFrameBuffer[i], 0, sizeof(FreezeFrameRecType));\r
2385                         }\r
2386                 }\r
2387                 //lint -restore\r
2388 \r
2389                 /* Transfer updated event data to event memory */\r
2390                 for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {\r
2391                         if (eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) {\r
2392                                 lookupEventIdParameter(eventStatusBuffer[i].eventId, &eventParam);\r
2393                                 storeEventEvtMem(eventParam, &eventStatusBuffer[i]);\r
2394                         }\r
2395                 }\r
2396 \r
2397                 /* Transfer extended data to event memory if necessary */\r
2398                 for (i = 0; i < DEM_MAX_NUMBER_EXT_DATA_PRE_INIT; i++) {\r
2399                         if (preInitExtDataBuffer[i].eventId !=  DEM_EVENT_ID_NULL) {\r
2400                                 lookupEventIdParameter(preInitExtDataBuffer[i].eventId, &eventParam);\r
2401                                 storeExtendedDataEvtMem(eventParam, &preInitExtDataBuffer[i]);\r
2402                         }\r
2403                 }\r
2404 \r
2405                 //lint -save\r
2406                 //lint -e568 //PC-Lint exception.\r
2407                 //lint -e685 //PC-Lint exception.\r
2408                 //lint -e681 //PC-Lint exception to MISRA 14.1: Loop is not entered. This only happens when DEM_MAX_NUMBER_FF_DATA_PRE_INIT is zero. Keep as it is for less complex code.\r
2409                 /* Transfer freeze frames to event memory */\r
2410                 for (i = 0; i < DEM_MAX_NUMBER_FF_DATA_PRE_INIT; i++) {\r
2411                         if (preInitFreezeFrameBuffer[i].eventId != DEM_EVENT_ID_NULL) {\r
2412                                 lookupEventIdParameter(preInitFreezeFrameBuffer[i].eventId, &eventParam);\r
2413                                 storeFreezeFrameDataEvtMem(eventParam, &preInitFreezeFrameBuffer[i]);\r
2414                         }\r
2415                 }\r
2416                 //lint -restore\r
2417         }\r
2418 \r
2419         // Init the dtc filter\r
2420         dtcFilter.dtcStatusMask = DEM_DTC_STATUS_MASK_ALL;                                      // All allowed\r
2421         dtcFilter.dtcKind = DEM_DTC_KIND_ALL_DTCS;                                                      // All kinds of DTCs\r
2422         dtcFilter.dtcOrigin = DEM_DTC_ORIGIN_PRIMARY_MEMORY;                            // Primary memory\r
2423         dtcFilter.filterWithSeverity = DEM_FILTER_WITH_SEVERITY_NO;                     // No Severity filtering\r
2424         dtcFilter.dtcSeverityMask = DEM_SEVERITY_NO_SEVERITY;                           // Not used when filterWithSeverity is FALSE\r
2425         dtcFilter.filterForFaultDetectionCounter = DEM_FILTER_FOR_FDC_NO;       // No fault detection counter filtering\r
2426 \r
2427         dtcFilter.faultIndex = DEM_MAX_NUMBER_EVENT;\r
2428 \r
2429         disableDtcStorage.storageDisabled = FALSE;\r
2430 \r
2431         demState = DEM_INITIALIZED;\r
2432 }\r
2433 \r
2434 \r
2435 /*\r
2436  * Procedure:   Dem_shutdown\r
2437  * Reentrant:   No\r
2438  */\r
2439 void Dem_Shutdown(void)\r
2440 {\r
2441         (void)setOperationCycleState(DEM_ACTIVE, DEM_CYCLE_STATE_END); /** @req DEM047 */\r
2442 \r
2443         /* handleAging() should be called behind setOperationCycleState() */\r
2444         (void)handleAging(DEM_ACTIVE, DEM_CYCLE_STATE_END);\r
2445 \r
2446         demState = DEM_UNINITIALIZED; /** @req DEM368 */\r
2447 }\r
2448 \r
2449 \r
2450 /*\r
2451  * Interface for basic software scheduler\r
2452  */\r
2453 void Dem_MainFunction(void)/** @req DEM125 */\r
2454 {       \r
2455         if (FFIsModified) {\r
2456                 storeFreezeFrameDataPerMem(FreezeFrameBlockId);\r
2457         }\r
2458 \r
2459         if (AgingIsModified) {\r
2460                 storeAgingRecPerMem(HealingBlockId);\r
2461         }\r
2462 }\r
2463 \r
2464 \r
2465 /***************************************************\r
2466  * Interface SW-Components via RTE <-> DEM (8.3.3) *\r
2467  ***************************************************/\r
2468 \r
2469 /*\r
2470  * Procedure:   Dem_SetEventStatus\r
2471  * Reentrant:   Yes\r
2472  */\r
2473 Std_ReturnType Dem_SetEventStatus(Dem_EventIdType eventId, Dem_EventStatusType eventStatus) /** @req DEM330 */\r
2474 {\r
2475         Std_ReturnType returnCode = E_OK;\r
2476 \r
2477         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started\r
2478         {\r
2479                 returnCode = handleEvent(eventId, eventStatus);\r
2480         }\r
2481         else\r
2482         {\r
2483                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_SETEVENTSTATUS_ID, DEM_E_UNINIT);\r
2484                 returnCode = E_NOT_OK;\r
2485         }\r
2486 \r
2487         return returnCode;\r
2488 }\r
2489 \r
2490 \r
2491 /*\r
2492  * Procedure:   Dem_ResetEventStatus\r
2493  * Reentrant:   Yes\r
2494  */\r
2495 Std_ReturnType Dem_ResetEventStatus(Dem_EventIdType eventId) /** @req DEM331 */\r
2496 {\r
2497         Std_ReturnType returnCode = E_OK;\r
2498 \r
2499         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started\r
2500         {\r
2501                 resetEventStatus(eventId); /** @req DEM186 */\r
2502         }\r
2503         else\r
2504         {\r
2505                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_RESETEVENTSTATUS_ID, DEM_E_UNINIT);\r
2506                 returnCode = E_NOT_OK;\r
2507         }\r
2508 \r
2509         return returnCode;\r
2510 }\r
2511 \r
2512 \r
2513 /*\r
2514  * Procedure:   Dem_GetEventStatus\r
2515  * Reentrant:   Yes\r
2516  */\r
2517 Std_ReturnType Dem_GetEventStatus(Dem_EventIdType eventId, Dem_EventStatusExtendedType *eventStatusExtended) /** @req DEM332 */\r
2518 {\r
2519         Std_ReturnType returnCode = E_OK;\r
2520 \r
2521         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started\r
2522         {\r
2523                 getEventStatus(eventId, eventStatusExtended);\r
2524         }\r
2525         else\r
2526         {\r
2527                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETEVENTSTATUS_ID, DEM_E_UNINIT);\r
2528                 returnCode = E_NOT_OK;\r
2529         }\r
2530 \r
2531         return returnCode;\r
2532 }\r
2533 \r
2534 \r
2535 /*\r
2536  * Procedure:   Dem_GetEventFailed\r
2537  * Reentrant:   Yes\r
2538  */\r
2539 Std_ReturnType Dem_GetEventFailed(Dem_EventIdType eventId, boolean *eventFailed) /** @req DEM333 */\r
2540 {\r
2541         Std_ReturnType returnCode = E_OK;\r
2542 \r
2543         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started\r
2544         {\r
2545                 getEventFailed(eventId, eventFailed);\r
2546         }\r
2547         else\r
2548         {\r
2549                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETEVENTFAILED_ID, DEM_E_UNINIT);\r
2550                 returnCode = E_NOT_OK;\r
2551         }\r
2552 \r
2553         return returnCode;\r
2554 }\r
2555 \r
2556 \r
2557 /*\r
2558  * Procedure:   Dem_GetEventTested\r
2559  * Reentrant:   Yes\r
2560  */\r
2561 Std_ReturnType Dem_GetEventTested(Dem_EventIdType eventId, boolean *eventTested)\r
2562 {\r
2563         Std_ReturnType returnCode = E_OK;\r
2564 \r
2565         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started\r
2566         {\r
2567                 getEventTested(eventId, eventTested);\r
2568         }\r
2569         else\r
2570         {\r
2571                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETEVENTTESTED_ID, DEM_E_UNINIT);\r
2572                 returnCode = E_NOT_OK;\r
2573         }\r
2574 \r
2575         return returnCode;\r
2576 }\r
2577 \r
2578 \r
2579 /*\r
2580  * Procedure:   Dem_GetFaultDetectionCounter\r
2581  * Reentrant:   No\r
2582  */\r
2583 Std_ReturnType Dem_GetFaultDetectionCounter(Dem_EventIdType eventId, sint8 *counter)\r
2584 {\r
2585         Std_ReturnType returnCode = E_OK;\r
2586 \r
2587         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started\r
2588         {\r
2589                 returnCode = getFaultDetectionCounter(eventId, counter);\r
2590         }\r
2591         else\r
2592         {\r
2593                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETFAULTDETECTIONCOUNTER_ID, DEM_E_UNINIT);\r
2594                 returnCode = E_NOT_OK;\r
2595         }\r
2596 \r
2597         return returnCode;\r
2598 }\r
2599 \r
2600 \r
2601 /*\r
2602  * Procedure:   Dem_SetOperationCycleState\r
2603  * Reentrant:   No\r
2604  */\r
2605 Std_ReturnType Dem_SetOperationCycleState(Dem_OperationCycleIdType operationCycleId, Dem_OperationCycleStateType cycleState)\r
2606 {\r
2607         Std_ReturnType returnCode = E_OK;\r
2608 \r
2609         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started\r
2610         {\r
2611                 returnCode = setOperationCycleState(operationCycleId, cycleState);\r
2612                 (void)handleAging(operationCycleId, cycleState);\r
2613 \r
2614         }\r
2615         else\r
2616         {\r
2617                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_SETOPERATIONCYCLESTATE_ID, DEM_E_UNINIT);\r
2618                 returnCode = E_NOT_OK;\r
2619         }\r
2620 \r
2621         return returnCode;\r
2622 }\r
2623 \r
2624 \r
2625 /*\r
2626  * Procedure:   Dem_GetDTCOfEvent\r
2627  * Reentrant:   Yes\r
2628  */\r
2629 Std_ReturnType Dem_GetDTCOfEvent(Dem_EventIdType eventId, Dem_DTCKindType dtcKind, uint32* dtcOfEvent)\r
2630 {\r
2631         Std_ReturnType returnCode = E_NO_DTC_AVAILABLE;\r
2632         const Dem_EventParameterType *eventParam;\r
2633 \r
2634         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started\r
2635         {\r
2636                 lookupEventIdParameter(eventId, &eventParam);\r
2637 \r
2638                 if (eventParam != NULL) {\r
2639                         if (checkDtcKind(dtcKind, eventParam)) {\r
2640                                 if (eventParam->DTCClassRef != NULL) {\r
2641                                         *dtcOfEvent = eventParam->DTCClassRef->DTC; /** @req DEM269 */\r
2642                                         returnCode = E_OK;\r
2643                                 }\r
2644                         }\r
2645                 }\r
2646                 else {\r
2647                         // Event Id not found\r
2648                         returnCode = E_NOT_OK;\r
2649                 }\r
2650         }\r
2651         else\r
2652         {\r
2653                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETDTCOFEVENT_ID, DEM_UNINITIALIZED);\r
2654                 returnCode = E_NOT_OK;\r
2655         }\r
2656 \r
2657         return returnCode;\r
2658 }\r
2659 \r
2660 \r
2661 /********************************************\r
2662  * Interface BSW-Components <-> DEM (8.3.4) *\r
2663  ********************************************/\r
2664 \r
2665 /*\r
2666  * Procedure:   Dem_ReportErrorStatus\r
2667  * Reentrant:   Yes\r
2668  */\r
2669 void Dem_ReportErrorStatus( Dem_EventIdType eventId, Dem_EventStatusType eventStatus ) /** @req DEM107 *//** @req DEM206 */\r
2670 {\r
2671 \r
2672         switch (demState) {\r
2673                 case DEM_PREINITIALIZED:\r
2674                         // Update status and check if is to be stored\r
2675                         if ((eventStatus == DEM_EVENT_STATUS_PASSED) || (eventStatus == DEM_EVENT_STATUS_FAILED)) {\r
2676                                 handlePreInitEvent(eventId, eventStatus); /** @req DEM168 */\r
2677                         }\r
2678                         break;\r
2679 \r
2680                 case DEM_INITIALIZED:\r
2681                         (void)handleEvent(eventId, eventStatus);        /** @req DEM167 */\r
2682                         break;\r
2683 \r
2684                 case DEM_UNINITIALIZED:\r
2685                 default:\r
2686                         // Uninitialized can not do anything\r
2687                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_REPORTERRORSTATUS_ID, DEM_E_UNINIT);\r
2688 \r
2689                         break;\r
2690 \r
2691         } // switch (demState)\r
2692 }\r
2693 \r
2694 /*********************************\r
2695  * Interface DCM <-> DEM (8.3.5) *\r
2696  *********************************/\r
2697 /*\r
2698  * Procedure:   Dem_GetDTCStatusAvailabilityMask\r
2699  * Reentrant:   No\r
2700  */\r
2701 Std_ReturnType Dem_GetDTCStatusAvailabilityMask(uint8 *dtcStatusMask) /** @req DEM014 */\r
2702 {\r
2703         *dtcStatusMask =        DEM_DTC_STATUS_AVAILABILITY_MASK;               // User configuration mask\r
2704         *dtcStatusMask &=       DEM_TEST_FAILED                                                 // Mask with supported bits /** @req DEM060 */\r
2705                                                 | DEM_TEST_FAILED_THIS_OPERATION_CYCLE\r
2706                                                 | DEM_PENDING_DTC\r
2707                                                 | DEM_CONFIRMED_DTC\r
2708                                                 | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR\r
2709                                                 | DEM_TEST_FAILED_SINCE_LAST_CLEAR\r
2710                                                 | DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE\r
2711 //                                              | DEM_WARNING_INDICATOR_REQUESTED       TODO: Add support for this bit\r
2712                                                 ;\r
2713 \r
2714         return E_OK;\r
2715 }\r
2716 \r
2717 \r
2718 /*\r
2719  * Procedure:   Dem_SetDTCFilter\r
2720  * Reentrant:   No\r
2721  */\r
2722 Dem_ReturnSetDTCFilterType Dem_SetDTCFilter(uint8 dtcStatusMask,\r
2723                 Dem_DTCKindType dtcKind,\r
2724                 Dem_DTCOriginType dtcOrigin,\r
2725                 Dem_FilterWithSeverityType filterWithSeverity,\r
2726                 Dem_DTCSeverityType dtcSeverityMask,\r
2727                 Dem_FilterForFDCType filterForFaultDetectionCounter)\r
2728 {\r
2729         Dem_ReturnSetDTCFilterType returnCode = DEM_FILTER_ACCEPTED;\r
2730 \r
2731         if (demState == DEM_INITIALIZED) {\r
2732                 // Check dtcKind parameter\r
2733                 VALIDATE_RV((dtcKind == DEM_DTC_KIND_ALL_DTCS) || (dtcKind == DEM_DTC_KIND_EMISSION_REL_DTCS), DEM_SETDTCFILTER_ID, DEM_E_PARAM_DATA, DEM_WRONG_FILTER);\r
2734 \r
2735                 // Check dtcOrigin parameter\r
2736                 VALIDATE_RV((dtcOrigin == DEM_DTC_ORIGIN_SECONDARY_MEMORY) || (dtcOrigin == DEM_DTC_ORIGIN_PRIMARY_MEMORY)\r
2737                                         || (dtcOrigin == DEM_DTC_ORIGIN_PERMANENT_MEMORY) || (dtcOrigin == DEM_DTC_ORIGIN_MIRROR_MEMORY), DEM_SETDTCFILTER_ID, DEM_E_PARAM_DATA, DEM_WRONG_FILTER);\r
2738 \r
2739                 // Check filterWithSeverity and dtcSeverityMask parameter\r
2740                 VALIDATE_RV(((filterWithSeverity == DEM_FILTER_WITH_SEVERITY_NO)\r
2741                                         || ((filterWithSeverity == DEM_FILTER_WITH_SEVERITY_YES)\r
2742                                                 && (!(dtcSeverityMask & (Dem_DTCSeverityType)~(DEM_SEVERITY_MAINTENANCE_ONLY | DEM_SEVERITY_CHECK_AT_NEXT_FALT | DEM_SEVERITY_CHECK_IMMEDIATELY))))), DEM_SETDTCFILTER_ID, DEM_E_PARAM_DATA, DEM_WRONG_FILTER);\r
2743 \r
2744                 // Check filterForFaultDetectionCounter parameter\r
2745                 VALIDATE_RV((filterForFaultDetectionCounter == DEM_FILTER_FOR_FDC_YES) || (filterForFaultDetectionCounter ==  DEM_FILTER_FOR_FDC_NO), DEM_SETDTCFILTER_ID, DEM_E_PARAM_DATA, DEM_WRONG_FILTER);\r
2746 \r
2747                 // Yes all parameters correct, set the new filters.  /** @req DEM057 */\r
2748                 dtcFilter.dtcStatusMask = dtcStatusMask;\r
2749                 dtcFilter.dtcKind = dtcKind;\r
2750                 dtcFilter.dtcOrigin = dtcOrigin;\r
2751                 dtcFilter.filterWithSeverity = filterWithSeverity;\r
2752                 dtcFilter.dtcSeverityMask = dtcSeverityMask;\r
2753                 dtcFilter.filterForFaultDetectionCounter = filterForFaultDetectionCounter;\r
2754                 dtcFilter.faultIndex = DEM_MAX_NUMBER_EVENT;\r
2755         } else {\r
2756                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_SETDTCFILTER_ID, DEM_E_UNINIT);\r
2757                 returnCode = DEM_WRONG_FILTER;\r
2758         }\r
2759 \r
2760         return returnCode;\r
2761 }\r
2762 \r
2763 \r
2764 /*\r
2765  * Procedure:   Dem_GetStatusOfDTC\r
2766  * Reentrant:   No\r
2767  */\r
2768 Dem_ReturnGetStatusOfDTCType Dem_GetStatusOfDTC(uint32 dtc, Dem_DTCKindType dtcKind, Dem_DTCOriginType dtcOrigin, Dem_EventStatusExtendedType* status) {\r
2769         Dem_ReturnGetStatusOfDTCType returnCode = DEM_STATUS_FAILED;\r
2770         EventStatusRecType *eventRec;\r
2771 \r
2772         if (demState == DEM_INITIALIZED) {\r
2773                 if (lookupDtcEvent(dtc, &eventRec)) {\r
2774                         if (checkDtcKind(dtcKind, eventRec->eventParamRef)) {\r
2775                                 if (checkDtcOrigin(dtcOrigin,eventRec->eventParamRef)) {\r
2776                                         *status = eventRec->eventStatusExtended; /** @req DEM059 */\r
2777                                         returnCode = DEM_STATUS_OK;\r
2778                                 }\r
2779                                 else {\r
2780                                         returnCode = DEM_STATUS_WRONG_DTCORIGIN; /** @req DEM171 */\r
2781                                 }\r
2782                         }\r
2783                         else {\r
2784                                 returnCode = DEM_STATUS_WRONG_DTCKIND;\r
2785                         }\r
2786                 }\r
2787                 else {\r
2788                         returnCode = DEM_STATUS_WRONG_DTC; /** @req DEM172 */\r
2789                 }\r
2790         } else {\r
2791                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETSTATUSOFDTC_ID, DEM_E_UNINIT);\r
2792                 returnCode = DEM_STATUS_FAILED;\r
2793         }\r
2794 \r
2795         return returnCode;\r
2796 }\r
2797 \r
2798 \r
2799 /*\r
2800  * Procedure:   Dem_GetNumberOfFilteredDtc\r
2801  * Reentrant:   No\r
2802  */\r
2803 Dem_ReturnGetNumberOfFilteredDTCType Dem_GetNumberOfFilteredDtc(uint16 *numberOfFilteredDTC) {\r
2804         uint16 i;\r
2805         uint16 numberOfFaults = 0;\r
2806         Dem_ReturnGetNumberOfFilteredDTCType returnCode = DEM_NUMBER_OK;\r
2807 \r
2808         if (demState == DEM_INITIALIZED) {\r
2809                 //Dem_DisableEventStatusUpdate();\r
2810 \r
2811                 for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {\r
2812                         if (eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) {\r
2813                                 if (matchEventWithDtcFilter(&eventStatusBuffer[i])) {\r
2814                                         if (eventStatusBuffer[i].eventParamRef->DTCClassRef != NULL) {\r
2815                                                 numberOfFaults++;\r
2816                                         }\r
2817                                 }\r
2818                         }\r
2819                 }\r
2820 \r
2821                 //Dem_EnableEventStatusUpdate();\r
2822 \r
2823                 *numberOfFilteredDTC = numberOfFaults; /** @req DEM061 */\r
2824         } else {\r
2825                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETNUMBEROFFILTEREDDTC_ID, DEM_E_UNINIT);\r
2826                 returnCode = DEM_NUMBER_FAILED;\r
2827         }\r
2828 \r
2829         return returnCode;\r
2830 }\r
2831 \r
2832 \r
2833 /*\r
2834  * Procedure:   Dem_GetNextFilteredDTC\r
2835  * Reentrant:   No\r
2836  */\r
2837 Dem_ReturnGetNextFilteredDTCType Dem_GetNextFilteredDTC(uint32 *dtc, Dem_EventStatusExtendedType *dtcStatus)\r
2838 {\r
2839         Dem_ReturnGetNextFilteredDTCType returnCode = DEM_FILTERED_OK;\r
2840         boolean dtcFound = FALSE;\r
2841 \r
2842         if (demState == DEM_INITIALIZED) {\r
2843                 // TODO: This job should be done in an more advanced way according to Dem217\r
2844                 while ((!dtcFound) && (dtcFilter.faultIndex != 0)) {\r
2845                         dtcFilter.faultIndex--;\r
2846                         if (eventStatusBuffer[dtcFilter.faultIndex].eventId != DEM_EVENT_ID_NULL) {\r
2847                                 if (matchEventWithDtcFilter(&eventStatusBuffer[dtcFilter.faultIndex])) {\r
2848                                         if (eventStatusBuffer[dtcFilter.faultIndex].eventParamRef->DTCClassRef != NULL) {\r
2849                                                 *dtc = eventStatusBuffer[dtcFilter.faultIndex].eventParamRef->DTCClassRef->DTC; /** @req DEM216 */\r
2850                                                 *dtcStatus = eventStatusBuffer[dtcFilter.faultIndex].eventStatusExtended;\r
2851                                                 dtcFound = TRUE;\r
2852                                         }\r
2853                                 }\r
2854                         }\r
2855                 }\r
2856 \r
2857                 if (!dtcFound) {\r
2858                         dtcFilter.faultIndex = DEM_MAX_NUMBER_EVENT;\r
2859                         returnCode = DEM_FILTERED_NO_MATCHING_DTC;\r
2860                 }\r
2861         } else {\r
2862                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETNEXTFILTEREDDTC_ID, DEM_E_UNINIT);\r
2863                 returnCode = DEM_FILTERED_NO_MATCHING_DTC;\r
2864         }\r
2865 \r
2866         return returnCode;\r
2867 }\r
2868 \r
2869 \r
2870 /*\r
2871  * Procedure:   Dem_GetTranslationType\r
2872  * Reentrant:   No\r
2873  */\r
2874 Dem_ReturnTypeOfDtcSupportedType Dem_GetTranslationType(void)\r
2875 {\r
2876         return DEM_TYPE_OF_DTC_SUPPORTED; /** @req DEM231 */\r
2877 }\r
2878 \r
2879 \r
2880 /*\r
2881  * Procedure:   Dem_ClearDTC\r
2882  * Reentrant:   No\r
2883  */\r
2884 Dem_ReturnClearDTCType Dem_ClearDTC(uint32 dtc, Dem_DTCKindType dtcKind, Dem_DTCOriginType dtcOrigin) /** @req DEM009 *//** @req DEM241 */\r
2885 {\r
2886         Dem_ReturnClearDTCType returnCode = DEM_CLEAR_OK;\r
2887         Dem_EventIdType eventId;\r
2888         const Dem_EventParameterType *eventParam;\r
2889         uint16 i, j;\r
2890 \r
2891         if (demState == DEM_INITIALIZED) {\r
2892                 for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {\r
2893                         eventId = eventStatusBuffer[i].eventId;\r
2894                         if (eventId != DEM_EVENT_ID_NULL) {\r
2895                                 eventParam = eventStatusBuffer[i].eventParamRef;\r
2896                                 if (eventParam != NULL) {\r
2897                                         //lint --e(506) PC-Lint exception Misra 13.7, 14.1 Allow configuration variables in boolean expression\r
2898                                         //lint --e(774) PC-Lint exception       Related to MISRA 13.7\r
2899                                         if ((DEM_CLEAR_ALL_EVENTS == STD_ON) || (eventParam->DTCClassRef != NULL)) {\r
2900                                                 if (checkDtcKind(dtcKind, eventParam)) {\r
2901                                                         if (checkDtcGroup(dtc, eventParam)) {\r
2902                                                                 boolean dtcOriginFound = FALSE;\r
2903                                                                 for (j = 0; (j < DEM_MAX_NR_OF_EVENT_DESTINATION) && (!dtcOriginFound) ; j++){\r
2904                                                                         dtcOriginFound =(eventParam->EventClass->EventDestination[j] == dtcOrigin);\r
2905                                                                 }\r
2906                                                                 if (dtcOriginFound) {\r
2907                                                                         switch (dtcOrigin)\r
2908                                                                         {\r
2909                                                                         case DEM_DTC_ORIGIN_PRIMARY_MEMORY:\r
2910                                                                                 /** @req DEM077 */\r
2911                                                                                 deleteEventPriMem(eventParam);\r
2912                                                                                 deleteFreezeFrameDataPriMem(eventParam);\r
2913                                                                                 deleteExtendedDataPriMem(eventParam);\r
2914                                                                                 resetEventStatusRec(eventParam);\r
2915                                                                                 storeFreezeFrameDataPerMem();\r
2916                                                                                 break;\r
2917                                                                                 \r
2918                                                                         case DEM_DTC_ORIGIN_PERMANENT_MEMORY:\r
2919                                                                                 \r
2920                                                                                 break;\r
2921                                                                                 \r
2922                                                                         case DEM_DTC_ORIGIN_SECONDARY_MEMORY:                                                                   \r
2923                                                                         case DEM_DTC_ORIGIN_MIRROR_MEMORY:\r
2924                                                                                 // Not yet supported\r
2925                                                                                 returnCode = DEM_CLEAR_WRONG_DTCORIGIN;\r
2926                                                                                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_CLEARDTC_ID, DEM_E_NOT_IMPLEMENTED_YET);\r
2927                                                                                 break;\r
2928                                                                         default:\r
2929                                                                                 returnCode = DEM_CLEAR_WRONG_DTCORIGIN;\r
2930                                                                                 break;\r
2931                                                                         }\r
2932                                                                 }\r
2933                                                         }\r
2934                                                 }\r
2935                                         }\r
2936                                 }\r
2937                                 else {\r
2938                                         // Fatal error, no event parameters found for the stored event!\r
2939                                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_CLEARDTC_ID, DEM_E_UNEXPECTED_EXECUTION);\r
2940                                 }\r
2941                         }\r
2942                 }\r
2943         } else {\r
2944                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_CLEARDTC_ID, DEM_E_UNINIT);\r
2945                 returnCode = DEM_CLEAR_FAILED;\r
2946         }\r
2947 \r
2948         return returnCode;\r
2949 }\r
2950 \r
2951 \r
2952 /*\r
2953  * Procedure:   Dem_DisableDTCStorage\r
2954  * Reentrant:   No\r
2955  */\r
2956 Dem_ReturnControlDTCStorageType Dem_DisableDTCStorage(Dem_DTCGroupType dtcGroup, Dem_DTCKindType dtcKind) /** @req DEM035 */\r
2957 {\r
2958         Dem_ReturnControlDTCStorageType returnCode = DEM_CONTROL_DTC_STORAGE_OK;\r
2959 \r
2960         if (demState == DEM_INITIALIZED) {\r
2961                 // Check dtcGroup parameter\r
2962                 if (dtcGroup == DEM_DTC_GROUP_ALL_DTCS) {\r
2963                         // Check dtcKind parameter\r
2964                         if ((dtcKind == DEM_DTC_KIND_ALL_DTCS) || (dtcKind ==  DEM_DTC_KIND_EMISSION_REL_DTCS)) {\r
2965                                 /** @req DEM079 */\r
2966                                 disableDtcStorage.dtcGroup = dtcGroup;\r
2967                                 disableDtcStorage.dtcKind = dtcKind;\r
2968                                 disableDtcStorage.storageDisabled = TRUE;\r
2969                         } else {\r
2970                                 returnCode = DEM_CONTROL_DTC_STORAGE_N_OK;\r
2971                         }\r
2972                 } else {\r
2973                         returnCode = DEM_CONTROL_DTC_WRONG_DTCGROUP;\r
2974                 }\r
2975         } else {\r
2976                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_DISABLEDTCSTORAGE_ID, DEM_E_UNINIT);\r
2977                 returnCode = DEM_CONTROL_DTC_STORAGE_N_OK;\r
2978         }\r
2979 \r
2980         return returnCode;\r
2981 }\r
2982 \r
2983 \r
2984 /*\r
2985  * Procedure:   Dem_EnableDTCStorage\r
2986  * Reentrant:   No\r
2987  */\r
2988 Dem_ReturnControlDTCStorageType Dem_EnableDTCStorage(Dem_DTCGroupType dtcGroup, Dem_DTCKindType dtcKind)\r
2989 {\r
2990         Dem_ReturnControlDTCStorageType returnCode = DEM_CONTROL_DTC_STORAGE_OK;\r
2991 \r
2992         if (demState == DEM_INITIALIZED) {\r
2993                 // TODO: Behavior is not defined if group or kind do not match active settings, therefore the filter is just switched off.\r
2994                 (void)dtcGroup; (void)dtcKind;  // Just to make get rid of PC-Lint warnings\r
2995                 disableDtcStorage.storageDisabled = FALSE; /** @req DEM080 */\r
2996         } else {\r
2997                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_ENABLEDTCSTORAGE_ID, DEM_E_UNINIT);\r
2998                 returnCode = DEM_CONTROL_DTC_STORAGE_N_OK;\r
2999         }\r
3000 \r
3001         return returnCode;\r
3002 }\r
3003 \r
3004 /*\r
3005  * Procedure:   Dem_GetExtendedDataRecordByDTC\r
3006  * Reentrant:   No\r
3007  */\r
3008 Dem_ReturnGetExtendedDataRecordByDTCType Dem_GetExtendedDataRecordByDTC(uint32 dtc, Dem_DTCKindType dtcKind, Dem_DTCOriginType dtcOrigin, uint8 extendedDataNumber, uint8 *destBuffer, uint16 *bufSize)\r
3009 {\r
3010         Dem_ReturnGetExtendedDataRecordByDTCType returnCode = DEM_RECORD_WRONG_DTC;\r
3011         EventStatusRecType *eventRec;\r
3012         Dem_ExtendedDataRecordClassType const *extendedDataRecordClass = NULL;\r
3013         ExtDataRecType *extData;\r
3014         uint16 posInExtData = 0;\r
3015 \r
3016         if (demState == DEM_INITIALIZED) {\r
3017                 if (lookupDtcEvent(dtc, &eventRec)) {\r
3018                         if (checkDtcKind(dtcKind, eventRec->eventParamRef)) {\r
3019                                 if (checkDtcOrigin(dtcOrigin, eventRec->eventParamRef)) {\r
3020                                         if (lookupExtendedDataRecNumParam(extendedDataNumber, eventRec->eventParamRef, &extendedDataRecordClass, &posInExtData)) {\r
3021                                                 if (*bufSize >= extendedDataRecordClass->DataSize) {\r
3022                                                         switch (dtcOrigin)\r
3023                                                         {\r
3024                                                         case DEM_DTC_ORIGIN_PRIMARY_MEMORY:\r
3025                                                                 if (lookupExtendedDataPriMem(eventRec->eventId, &extData)) {\r
3026                                                                         // Yes all conditions met, copy the extended data record to destination buffer.\r
3027                                                                         memcpy(destBuffer, &extData->data[posInExtData], extendedDataRecordClass->DataSize); /** @req DEM075 */\r
3028                                                                         *bufSize = extendedDataRecordClass->DataSize;\r
3029                                                                         returnCode = DEM_RECORD_OK;\r
3030                                                                 }\r
3031                                                                 else {\r
3032                                                                         // The record number is legal but no record was found for the DTC\r
3033                                                                         *bufSize = 0;\r
3034                                                                         returnCode = DEM_RECORD_OK;\r
3035                                                                 }\r
3036                                                                 break;\r
3037 \r
3038                                                         case DEM_DTC_ORIGIN_SECONDARY_MEMORY:\r
3039                                                         case DEM_DTC_ORIGIN_PERMANENT_MEMORY:\r
3040                                                         case DEM_DTC_ORIGIN_MIRROR_MEMORY:\r
3041                                                                 // Not yet supported\r
3042                                                                 returnCode = DEM_RECORD_WRONG_DTCORIGIN;\r
3043                                                                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETEXTENDEDDATARECORDBYDTC_ID, DEM_E_NOT_IMPLEMENTED_YET);\r
3044                                                                 break;\r
3045                                                         default:\r
3046                                                                 returnCode = DEM_RECORD_WRONG_DTCORIGIN;\r
3047                                                                 break;\r
3048                                                         }\r
3049                                                 }\r
3050                                                 else {\r
3051                                                         returnCode = DEM_RECORD_BUFFERSIZE;\r
3052                                                 }\r
3053                                         }\r
3054                                         else {\r
3055                                                 returnCode = DEM_RECORD_NUMBER;\r
3056                                         }\r
3057                                 }\r
3058                                 else {\r
3059                                         returnCode = DEM_RECORD_WRONG_DTCORIGIN;\r
3060                                 }\r
3061                         }\r
3062                         else {\r
3063                                 returnCode = DEM_RECORD_DTCKIND;\r
3064                         }\r
3065                 }\r
3066         } else {\r
3067                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETEXTENDEDDATARECORDBYDTC_ID, DEM_E_UNINIT);\r
3068                 returnCode = DEM_RECORD_WRONG_DTC;\r
3069         }\r
3070 \r
3071         return returnCode;\r
3072 }\r
3073 \r
3074 \r
3075 /*\r
3076  * Procedure:   Dem_GetSizeOfExtendedDataRecordByDTC\r
3077  * Reentrant:   No\r
3078  */\r
3079 Dem_ReturnGetSizeOfExtendedDataRecordByDTCType Dem_GetSizeOfExtendedDataRecordByDTC(uint32 dtc, Dem_DTCKindType dtcKind, Dem_DTCOriginType dtcOrigin, uint8 extendedDataNumber, uint16 *sizeOfExtendedDataRecord)\r
3080 {\r
3081         Dem_ReturnGetExtendedDataRecordByDTCType returnCode = DEM_GET_SIZEOFEDRBYDTC_W_DTC;\r
3082         EventStatusRecType *eventRec;\r
3083         Dem_ExtendedDataRecordClassType const *extendedDataRecordClass = NULL;\r
3084         uint16 posInExtData;\r
3085 \r
3086         if (demState == DEM_INITIALIZED) {\r
3087                 if (lookupDtcEvent(dtc, &eventRec)) {\r
3088                         if (checkDtcKind(dtcKind, eventRec->eventParamRef)) {\r
3089                                 if (checkDtcOrigin(dtcOrigin, eventRec->eventParamRef)) {\r
3090                                         if (lookupExtendedDataRecNumParam(extendedDataNumber, eventRec->eventParamRef, &extendedDataRecordClass, &posInExtData)) {\r
3091                                                 *sizeOfExtendedDataRecord = extendedDataRecordClass->DataSize; /** @req DEM076 */\r
3092                                                 returnCode = DEM_GET_SIZEOFEDRBYDTC_OK;\r
3093                                         }\r
3094                                         else {\r
3095                                                 returnCode = DEM_GET_SIZEOFEDRBYDTC_W_RNUM;\r
3096                                         }\r
3097                                 }\r
3098                                 else {\r
3099                                         returnCode = DEM_GET_SIZEOFEDRBYDTC_W_DTCOR;\r
3100                                 }\r
3101                         }\r
3102                         else {\r
3103                                 returnCode = DEM_GET_SIZEOFEDRBYDTC_W_DTCKI;\r
3104                         }\r
3105                 }\r
3106         } else {\r
3107                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETSIZEOFEXTENDEDDATARECORDBYDTC_ID, DEM_E_UNINIT);\r
3108                 returnCode = DEM_GET_SIZEOFEDRBYDTC_W_DTC;\r
3109         }\r
3110 \r
3111         return returnCode;\r
3112 }\r
3113 \r
3114 /*\r
3115  * Procedure:   Dem_GetFreezeFrameDataByDTC\r
3116  * Reentrant:   No\r
3117  */\r
3118 /** @req DEM236 */ \r
3119 Dem_ReturnGetFreezeFrameDataByDTCType Dem_GetFreezeFrameDataByDTC(uint32  dtc,Dem_DTCKindType  dtcKind,Dem_DTCOriginType  dtcOrigin,uint8  recordNumber,uint8*  destBuffer,uint8*  bufSize)\r
3120 {\r
3121         Dem_ReturnGetFreezeFrameDataByDTCType returnCode = DEM_GET_FFDATABYDTC_WRONG_DTC;\r
3122         EventStatusRecType *eventRec;\r
3123         Dem_FreezeFrameClassType const *FFDataRecordClass = NULL;\r
3124         FreezeFrameRecType *freezeframe;\r
3125         uint16 FFDataSize = 0;\r
3126 \r
3127         if (demState == DEM_INITIALIZED) {\r
3128                 if (lookupDtcEvent(dtc, &eventRec)) {\r
3129                         if (checkDtcKind(dtcKind, eventRec->eventParamRef)) {\r
3130                                 if (checkDtcOrigin(dtcOrigin, eventRec->eventParamRef)) {\r
3131                                         if (lookupFreezeFrameDataRecNumParam(recordNumber, eventRec->eventParamRef, &FFDataRecordClass)) {\r
3132                                                 if(lookupFreezeFrameDataSize(recordNumber, &FFDataRecordClass, &FFDataSize)){\r
3133                                                         if (*bufSize >= FFDataSize) {\r
3134                                                                 switch (dtcOrigin)\r
3135                                                                 {\r
3136                                                                 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:\r
3137                                                                         if (lookupFreezeFrameDataPriMem(eventRec->eventId,recordNumber, &freezeframe)) {\r
3138                                                                                 memcpy(destBuffer, freezeframe->data, FFDataSize); /** @req DEM071 */\r
3139                                                                                 *bufSize = FFDataSize;\r
3140                                                                                 returnCode = DEM_GET_FFDATABYDTC_OK;\r
3141                                                                         }\r
3142                                                                         else {\r
3143                                                                                 *bufSize = 0;\r
3144                                                                                 returnCode = DEM_GET_FFDATABYDTC_OK;\r
3145                                                                         }\r
3146                                                                         break;\r
3147 \r
3148                                                                 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:\r
3149                                                                 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:\r
3150                                                                 case DEM_DTC_ORIGIN_MIRROR_MEMORY:\r
3151                                                                         // Not yet supported\r
3152                                                                         returnCode = DEM_GET_FFDATABYDTC_WRONG_DTCORIGIN;\r
3153                                                                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETFREEZEFRAMEDATARECORDBYDTC_ID, DEM_E_NOT_IMPLEMENTED_YET);\r
3154                                                                         break;\r
3155                                                                 default:\r
3156                                                                         returnCode = DEM_GET_FFDATABYDTC_WRONG_DTCORIGIN;\r
3157                                                                         break;\r
3158                                                                 }\r
3159                                                         }\r
3160                                                         else{\r
3161                                                                 returnCode = DEM_GET_FFDATABYDTC_BUFFERSIZE;\r
3162                                                         }\r
3163                                                 }\r
3164                                                 else {\r
3165                                                         returnCode = DEM_GET_FFDATABYDTC_BUFFERSIZE;\r
3166                                                 }\r
3167                                         }\r
3168                                         else {\r
3169                                                 returnCode = DEM_GET_FFDATABYDTC_RECORDNUMBER;\r
3170                                         }\r
3171                                 }\r
3172                                 else {\r
3173                                         returnCode = DEM_GET_FFDATABYDTC_WRONG_DTCORIGIN;\r
3174                                 }\r
3175                         }\r
3176                         else {\r
3177                                 returnCode = DEM_GET_FFDATABYDTC_WRONG_DTCKIND;\r
3178                         }\r
3179                 }\r
3180                 else{\r
3181                         returnCode = DEM_GET_FFDATABYDTC_WRONG_DTC;\r
3182 \r
3183                 }\r
3184         } else {\r
3185                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETFREEZEFRAMEDATARECORDBYDTC_ID, DEM_E_UNINIT);\r
3186                 returnCode = DEM_GET_ID_PENDING;\r
3187         }\r
3188 \r
3189         return returnCode;\r
3190 \r
3191 \r
3192 }\r
3193 \r
3194 /*\r
3195  * Procedure:   Dem_GetFreezeFrameDataIdentifierByDTC\r
3196  * Reentrant:   No\r
3197  */\r
3198 Dem_GetFreezeFameDataIdentifierByDTCType Dem_GetFreezeFrameDataIdentifierByDTC(uint32  dtc,\r
3199                                                                                                                                                                                 Dem_DTCKindType  dtcKind,\r
3200                                                                                                                                                                                 Dem_DTCOriginType  dtcOrigin,\r
3201                                                                                                                                                                                 uint8  recordNumber,\r
3202                                                                                                                                                                                 uint8*  arraySize,\r
3203                                                                                                                                                                                 const  uint16** dataId )/** @req DEM237 */\r
3204 {\r
3205         Dem_GetFreezeFameDataIdentifierByDTCType returnCode = DEM_GET_ID_WRONG_FF_TYPE;\r
3206         Dem_FreezeFrameClassType const *FFDataRecordClass = NULL;\r
3207         EventStatusRecType *eventRec;\r
3208         uint8 didNum = 0;\r
3209         uint16 i = 0;\r
3210         if (demState == DEM_INITIALIZED) {\r
3211                 if (lookupDtcEvent(dtc, &eventRec)) {\r
3212                         if (checkDtcKind(dtcKind, eventRec->eventParamRef)) {\r
3213                                 if (checkDtcOrigin(dtcOrigin, eventRec->eventParamRef)) {\r
3214                                         if (lookupFreezeFrameDataRecNumParam(recordNumber, eventRec->eventParamRef, &FFDataRecordClass)) {\r
3215                                                 if(FFDataRecordClass->FFIdClassRef != NULL){\r
3216                                                         for(i=0; (i < DEM_MAX_NR_OF_RECORDS_IN_FREEZEFRAME_DATA) && (!(FFDataRecordClass->FFIdClassRef[i].Arc_EOL)); i++){\r
3217                                                                 if(didNum < *arraySize){\r
3218                                                                         dataId[didNum] = &FFDataRecordClass->FFIdClassRef[i].DidIdentifier;/** @req DEM073 */\r
3219                                                                         didNum++;\r
3220                                                                         returnCode = DEM_GET_ID_OK;\r
3221                                                                 }else{\r
3222                                                                         returnCode = DEM_GET_ID_WRONG_FF_TYPE;\r
3223                                                                 }\r
3224                                                         }\r
3225                                                         *arraySize = didNum;\r
3226                                                 }\r
3227                                                 \r
3228                                         }\r
3229                                         else{\r
3230                                                 returnCode = DEM_GET_ID_WRONG_FF_TYPE;\r
3231                                         }\r
3232                                 }\r
3233                                 else{\r
3234                                         returnCode = DEM_GET_ID_WRONG_DTCORIGIN;\r
3235                                 }\r
3236                         }\r
3237                         else{\r
3238                                 returnCode = DEM_GET_ID_WRONG_DTCKIND;\r
3239                         }\r
3240                 }\r
3241                 else{\r
3242                         returnCode = DEM_GET_ID_WRONG_DTC;\r
3243                 }\r
3244                 \r
3245         } \r
3246         else{\r
3247                 DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETFREEZEFRAMEDATAIDENTIFIERBYDTC_ID, DEM_E_UNINIT);\r
3248         }\r
3249 \r
3250         return returnCode;\r
3251 \r
3252 }\r
3253 \r
3254 /*\r
3255  * Procedure:   Dem_GetSizeOfFreezeFrame\r
3256  * Reentrant:   No\r
3257  */\r
3258  /** @req DEM238 */\r
3259 Dem_ReturnGetSizeOfFreezeFrameType Dem_GetSizeOfFreezeFrame(uint32  dtc,Dem_DTCKindType  dtcKind,Dem_DTCOriginType  dtcOrigin,uint8  recordNumber,uint16*  sizeOfFreezeFrame)  \r
3260 {\r
3261         Dem_ReturnGetSizeOfFreezeFrameType returnCode = DEM_GET_SIZEOFFF_PENDING;\r
3262         Dem_FreezeFrameClassType const *FFDataRecordClass = NULL;\r
3263         Std_ReturnType callbackReturnCode;\r
3264         EventStatusRecType *eventRec;\r
3265         uint16 dataSize = 0;\r
3266         uint16 i = 0;\r
3267         \r
3268         if (demState == DEM_INITIALIZED) {\r
3269                 if (lookupDtcEvent(dtc, &eventRec)) {\r
3270                         if (checkDtcKind(dtcKind, eventRec->eventParamRef)) {\r
3271                                 if (checkDtcOrigin(dtcOrigin, eventRec->eventParamRef)) {\r
3272                                         if (lookupFreezeFrameDataRecNumParam(recordNumber, eventRec->eventParamRef, &FFDataRecordClass)) {\r
3273                                                 if(FFDataRecordClass->FFIdClassRef != NULL){\r
3274                                                         for(i = 0; (i < DEM_MAX_NR_OF_RECORDS_IN_FREEZEFRAME_DATA) && (!(FFDataRecordClass->FFIdClassRef[i].Arc_EOL)); i++){\r
3275                                                                 /* read out the did size */\r
3276                                                                 if(FFDataRecordClass->FFIdClassRef[i].DidReadDataLengthFnc != NULL){\r
3277                                                                         callbackReturnCode = FFDataRecordClass->FFIdClassRef[i].DidReadDataLengthFnc(&dataSize);\r
3278                                                                         if(callbackReturnCode != E_OK){\r
3279                                                                                 return (returnCode = DEM_GET_SIZEOFFF_PENDING);\r
3280                                                                         }\r
3281                                                                 }\r
3282                                                                 else{\r
3283                                                                         dataSize = FFDataRecordClass->FFIdClassRef[i].PidOrDidSize;\r
3284                                                                 }\r
3285                                                                 *sizeOfFreezeFrame += dataSize+DEM_DID_IDENTIFIER_SIZE_OF_BYTES;/** @req DEM074 */\r
3286                                                                 returnCode = DEM_GET_SIZEOFFF_OK;               \r
3287                                                         }                               \r
3288                                                 }\r
3289                                         }\r
3290                                         else{\r
3291                                                 returnCode = DEM_GET_SIZEOFFF_WRONG_RNUM;\r
3292                                         }\r
3293                                 }\r
3294                                 else{\r
3295                                         returnCode = DEM_GET_SIZEOFFF_WRONG_DTCOR;\r
3296                                 }\r
3297                         }\r
3298                         else{\r
3299                                 returnCode = DEM_GET_SIZEOFFF_WRONG_DTCKIND;\r
3300                         }\r
3301                 }\r
3302                 else{\r
3303                         returnCode = DEM_GET_SIZEOFFF_WRONG_DTC;\r
3304                 }\r
3305                 \r
3306         } \r
3307         else{\r
3308                         DET_REPORTERROR(MODULE_ID_DEM, 0, DEM_GETFREEZEFRAMEDATAIDENTIFIERBYDTC_ID, DEM_E_UNINIT);\r
3309                         returnCode = DEM_GET_SIZEOFFF_PENDING;\r
3310                 }\r
3311 \r
3312         return returnCode;\r
3313 \r
3314 \r
3315 }\r
3316 \r
3317 \r
3318 #ifdef DEM_UNIT_TEST\r
3319 void getFFDataPreInit(FreezeFrameRecType **buf)\r
3320 {\r
3321         *buf = &preInitFreezeFrameBuffer[0];\r
3322         return;\r
3323 }\r
3324 void getPriMemFFBufPtr(FreezeFrameRecType **buf)\r
3325 {\r
3326         *buf = &priMemFreezeFrameBuffer[0];\r
3327         return;\r
3328 }\r
3329 \r
3330 uint32 getCurTimeStamp()\r
3331 {\r
3332         return FF_TimeStamp;\r
3333 }\r
3334 \r
3335 void getPriMemEventRecBufPtr(EventStatusRecType **buf)\r
3336 {\r
3337         *buf = &eventStatusBuffer[0];\r
3338         return;\r
3339 }\r
3340 \r
3341 void getPriMemAgingBufPtr(HealingRecType **buf)\r
3342 {\r
3343         *buf = &priMemAgingBuffer[0];\r
3344         return;\r
3345 }\r
3346 #endif\r
3347 \r
3348 \r
3349 \r
3350 \r
3351 \r
3352 /***********************************\r
3353  * OBD-specific Interfaces (8.3.6) *\r
3354  ***********************************/\r
3355 \r
3356 \r
3357 \r