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