]> rtime.felk.cvut.cz Git - arc.git/blob - diagnostic/Dem/Dem.c
Merged in from default
[arc.git] / diagnostic / Dem / Dem.c
1 /* -------------------------------- Arctic Core ------------------------------
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com
3  *
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>
5  *
6  * This source code is free software; you can redistribute it and/or modify it
7  * under the terms of the GNU General Public License version 2 as published by the
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13  * for more details.
14  * -------------------------------- Arctic Core ------------------------------*/
15
16
17
18
19
20 #include <string.h>
21 #include "Dem.h"
22 #include "Det.h"
23 //#include "Fim.h"
24 //#include "Nvm.h"
25 //#include "SchM_Dem.h"
26 #include "MemMap.h"
27 #include "Mcu.h"
28
29 /*
30  * Local types
31  */
32
33 typedef uint16 ChecksumType;
34
35 // DtcFilterType
36 typedef struct {
37         Dem_EventStatusExtendedType dtcStatusMask;
38         Dem_DTCKindType                         dtcKind;
39         Dem_DTCOriginType                       dtcOrigin;
40         Dem_FilterWithSeverityType      filterWithSeverity;
41         Dem_DTCSeverityType                     dtcSeverityMask;
42         Dem_FilterForFDCType            filterForFaultDetectionCounter;
43         uint16                                          faultIndex;
44 } DtcFilterType;
45
46 // DisableDtcStorageType
47 typedef struct {
48         boolean                                         storageDisabled;
49         Dem_DTCGroupType                        dtcGroup;
50         Dem_DTCKindType                         dtcKind;
51 } DisableDtcStorageType;
52
53 // For keeping track of the events status
54 typedef struct {
55         Dem_EventIdType                         eventId;
56         const Dem_EventParameterType *eventParamRef;
57         uint16                                          occurrence;
58         Dem_EventStatusType                     eventStatus;
59         boolean                                         eventStatusChanged;
60         Dem_EventStatusExtendedType     eventStatusExtended;
61 } EventStatusRecType;
62
63
64 // Types for storing different event data on event memory
65 typedef struct {
66         Dem_EventIdType         eventId;
67         uint16                          occurrence;
68         ChecksumType            checksum;
69 } EventRecType;
70
71 typedef struct {
72         Dem_EventIdType         eventId;
73         uint16                          occurrence;
74         uint16                          dataSize;
75         sint8                           data[DEM_MAX_SIZE_FF_DATA];
76         ChecksumType            checksum;
77 } FreezeFrameRecType;
78
79 typedef struct {
80         Dem_EventIdType         eventId;
81         uint16                          dataSize;
82         uint8                           data[DEM_MAX_SIZE_EXT_DATA];
83         ChecksumType            checksum;
84 } ExtDataRecType;
85
86
87 // State variable
88 typedef enum
89 {
90   DEM_UNINITIALIZED = 0,
91   DEM_PREINITIALIZED,
92   DEM_INITIALIZED
93 } Dem_StateType;
94
95 static Dem_StateType demState = DEM_UNINITIALIZED;
96
97 // Help pointer to configuration set
98 static const Dem_ConfigSetType *configSet;
99
100 #if (DEM_VERSION_INFO_API == STD_ON)
101 static Std_VersionInfoType _Dem_VersionInfo =
102 {
103   .vendorID   = (uint16)1,
104   .moduleID   = (uint16)1,
105   .instanceID = (uint8)1,
106   .sw_major_version = (uint8)DEM_SW_MAJOR_VERSION,
107   .sw_minor_version = (uint8)DEM_SW_MINOR_VERSION,
108   .sw_patch_version = (uint8)DEM_SW_PATCH_VERSION,
109   .ar_major_version = (uint8)DEM_AR_MAJOR_VERSION,
110   .ar_minor_version = (uint8)DEM_AR_MINOR_VERSION,
111   .ar_patch_version = (uint8)DEM_AR_PATCH_VERSION,
112 };
113 #endif /* DEM_VERSION_INFO_API */
114
115 /*
116  * Allocation of DTC filter parameters
117  */
118 static DtcFilterType dtcFilter;
119
120 /*
121  * Allocation of Disable/Enable DTC storage parameters
122  */
123 static DisableDtcStorageType disableDtcStorage;
124
125 /*
126  * Allocation of operation cycle state list
127  */
128 static Dem_OperationCycleStateType operationCycleStateList[DEM_OPERATION_CYCLE_ID_ENDMARK];
129
130 /*
131  * Allocation of local event status buffer
132  */
133 static EventStatusRecType       eventStatusBuffer[DEM_MAX_NUMBER_EVENT];
134
135 /*
136  * Allocation of pre-init event memory (used between pre-init and init)
137  */
138 static FreezeFrameRecType       preInitFreezeFrameBuffer[DEM_MAX_NUMBER_FF_DATA_PRE_INIT];
139 static ExtDataRecType           preInitExtDataBuffer[DEM_MAX_NUMBER_EXT_DATA_PRE_INIT];
140
141 /*
142  * Allocation of primary event memory ramlog (after init) in uninitialized memory
143  */
144 static EventRecType             priMemEventBuffer[DEM_MAX_NUMBER_EVENT_PRI_MEM] __attribute__ ((section (".dem_eventmemory_pri")));
145 static FreezeFrameRecType       priMemFreezeFrameBuffer[DEM_MAX_NUMBER_FF_DATA_PRI_MEM] __attribute__ ((section (".dem_eventmemory_pri")));
146 static ExtDataRecType           priMemExtDataBuffer[DEM_MAX_NUMBER_EXT_DATA_PRI_MEM] __attribute__ ((section (".dem_eventmemory_pri")));
147
148
149 /*
150  * Procedure:   setZero
151  * Description: Fill the *ptr to *(ptr+nrOfBytes-1) area with zeroes
152  */
153 void setZero(void *ptr, uint16 nrOfBytes)
154 {
155         uint8 *clrPtr = (uint8*)ptr;
156
157         if (nrOfBytes > 0)
158         {
159                 *clrPtr = 0x00;
160                 memcpy(clrPtr+1, clrPtr, nrOfBytes-1);
161         }
162 }
163
164
165 /*
166  * Procedure:   setFF
167  * Description: Fill the *ptr to *(ptr+nrOfBytes-1) area with 0xFF
168  */
169 void setFF(void *ptr, uint16 nrOfBytes)
170 {
171         uint8 *clrPtr = (uint8*)ptr;
172
173         if (nrOfBytes > 0)
174         {
175                 *clrPtr = 0xFF;
176                 memcpy(clrPtr+1, clrPtr, nrOfBytes-1);
177         }
178 }
179
180
181 /*
182  * Procedure:   zeroPriMemBuffers
183  * Description: Fill the primary buffers with zeroes
184  */
185 void zeroPriMemBuffers(void)
186 {
187         setZero(priMemEventBuffer, sizeof(priMemEventBuffer));
188         setZero(priMemFreezeFrameBuffer, sizeof(priMemFreezeFrameBuffer));
189         setZero(priMemExtDataBuffer, sizeof(priMemExtDataBuffer));
190 }
191
192
193 /*
194  * Procedure:   calcChecksum
195  * Description: Calculate checksum over *data to *(data+nrOfBytes-1) area
196  */
197 ChecksumType calcChecksum(void *data, uint16 nrOfBytes)
198 {
199         uint16 i;
200         uint8 *ptr = (uint8*)data;
201         ChecksumType sum = 0;
202
203         for (i = 0; i < nrOfBytes; i++)
204                 sum += *ptr++;
205         sum ^= 0xaaaa;
206         return sum;
207 }
208
209
210 /*
211  * Procedure:   checkDtcKind
212  * Description: Return TRUE if "dtcKind" match the events DTCKind or "dtcKind"
213  *                              is "DEM_DTC_KIND_ALL_DTCS" otherwise FALSE.
214  */
215 boolean checkDtcKind(Dem_DTCKindType dtcKind, const Dem_EventParameterType *eventParam)
216 {
217         boolean result = FALSE;
218
219         if (dtcKind == DEM_DTC_KIND_ALL_DTCS) {
220                 result = TRUE;
221         }
222         else {
223                 if (eventParam->DTCClassRef != NULL) {
224                         if (eventParam->DTCClassRef->DTCKind == dtcKind) {
225                                 result = TRUE;
226                         }
227                 }
228         }
229         return result;
230 }
231
232
233 /*
234  * Procedure:   checkDtcGroup
235  * Description: Return TRUE if "dtc" match the events DTC or "dtc" is
236  *                              "DEM_DTC_GROUP_ALL_DTCS" otherwise FALSE.
237  */
238 boolean checkDtcGroup(uint32 dtc, const Dem_EventParameterType *eventParam)
239 {
240         boolean result = FALSE;
241
242         if (dtc == DEM_DTC_GROUP_ALL_DTCS) {
243                 result = TRUE;
244         }
245         else {
246                 if (eventParam->DTCClassRef != NULL) {
247                         if (eventParam->DTCClassRef->DTC == dtc) {
248                                 result = TRUE;
249                         }
250                 }
251         }
252         return result;
253 }
254
255
256 /*
257  * Procedure:   checkDtcOrigin
258  * Description: Return TRUE if "dtcOrigin" match any of the events DTCOrigin otherwise FALSE.
259  */
260 boolean checkDtcOrigin(Dem_DTCOriginType dtcOrigin, const Dem_EventParameterType *eventParam)
261 {
262         boolean result = FALSE;
263         uint16 i;
264
265         for (i = 0; (i < DEM_MAX_NR_OF_EVENT_DESTINATION) && (eventParam->EventClass->EventDestination[i] != dtcOrigin); i++);
266
267         if (i < DEM_MAX_NR_OF_EVENT_DESTINATION) {
268                 result = TRUE;
269         }
270
271         return result;
272 }
273
274
275 /*
276  * Procedure:   checkDtcSeverityMask
277  * Description: Return TRUE if "dtcSeverityMask" match any of the events DTC severity otherwise FALSE.
278  */
279 boolean checkDtcSeverityMask(Dem_DTCSeverityType dtcSeverityMask, const Dem_EventParameterType *eventParam)
280 {
281         boolean result = TRUE;
282
283         // TODO: This function is optional, may be implemented here.
284
285         return result;
286 }
287
288
289 /*
290  * Procedure:   checkDtcFaultDetectionCounterMask
291  * Description: TBD.
292  */
293 boolean checkDtcFaultDetectionCounter(const Dem_EventParameterType *eventParam)
294 {
295         boolean result = TRUE;
296
297         // TODO: Not implemented yet.
298
299         return result;
300 }
301
302
303 /*
304  * Procedure:   lookupEventIdParameter
305  * Description: Returns the pointer to event id parameters of "eventId" in "*eventIdParam",
306  *                              if not found NULL is returned.
307  */
308 void lookupEventIdParameter(Dem_EventIdType eventId, const Dem_EventParameterType **const eventIdParam)
309 {
310         uint16 i;
311         *eventIdParam = NULL;
312
313         // Lookup the correct event id parameters
314         for (i = 0; !configSet->EventParameter[i].Arc_EOL; i++) {
315                 if (configSet->EventParameter[i].EventID == eventId) {
316                         *eventIdParam = &configSet->EventParameter[i];
317                         return;
318                 }
319         }
320         // Id not found return with NULL pointer
321 }
322
323
324 /*
325  * Procedure:   updateEventStatusRec
326  * Description: Update the status of "eventId", if not exist and "createIfNotExist" is
327  *                              true a new record is created
328  */
329 void updateEventStatusRec(const Dem_EventParameterType *eventParam, Dem_EventStatusType eventStatus, boolean createIfNotExist, EventStatusRecType *eventStatusRec)
330 {
331         uint16 i;
332         imask_t state = McuE_EnterCriticalSection();
333
334         // Lookup event ID
335         for (i = 0; (eventStatusBuffer[i].eventId != eventParam->EventID) && (i < DEM_MAX_NUMBER_EVENT); i++);
336
337         if ((i == DEM_MAX_NUMBER_EVENT) && (createIfNotExist)) {
338                 // Search for free position
339                 for (i = 0; (eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) && (i < DEM_MAX_NUMBER_EVENT); i++);
340
341                 if (i < DEM_MAX_NUMBER_EVENT) {
342                         // Create new event record
343                         eventStatusBuffer[i].eventId = eventParam->EventID;
344                         eventStatusBuffer[i].eventParamRef = eventParam;
345                         eventStatusBuffer[i].occurrence = 0;
346                         eventStatusBuffer[i].eventStatus = DEM_EVENT_STATUS_PASSED;
347                         eventStatusBuffer[i].eventStatusChanged = FALSE;
348                         eventStatusBuffer[i].eventStatusExtended = DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR | DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE;
349                 }
350                 else {
351                         // Error: Event status buffer full
352 #if (DEM_DEV_ERROR_DETECT == STD_ON)
353                         Det_ReportError(MODULE_ID_DEM, 0, DEM_UPDATE_EVENT_STATUS_ID, DEM_E_EVENT_STATUS_BUFF_FULL);
354 #endif
355                 }
356         }
357
358         if (i < DEM_MAX_NUMBER_EVENT) {
359                 // Update event record
360                 eventStatusBuffer[i].eventStatusExtended &= ~(DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR | DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE);
361
362                 if (eventStatus == DEM_EVENT_STATUS_FAILED) {
363                         eventStatusBuffer[i].eventStatusExtended |= (DEM_TEST_FAILED | DEM_TEST_FAILED_THIS_OPERATION_CYCLE | DEM_TEST_FAILED_SINCE_LAST_CLEAR | DEM_PENDING_DTC);
364                         if       (eventStatusBuffer[i].eventStatus != eventStatus) {
365                                 eventStatusBuffer[i].occurrence++;
366                         }
367                 }
368
369                 if (eventStatus == DEM_EVENT_STATUS_PASSED) {
370                         eventStatusBuffer[i].eventStatusExtended &= ~DEM_TEST_FAILED;
371                 }
372
373                 if (eventStatusBuffer[i].eventStatus != eventStatus) {
374                         eventStatusBuffer[i].eventStatus = eventStatus;
375                         eventStatusBuffer[i].eventStatusChanged = TRUE;
376                 }
377                 else {
378                         eventStatusBuffer[i].eventStatusChanged = FALSE;
379                 }
380
381                 // Copy the record
382                 memcpy(eventStatusRec, &eventStatusBuffer[i], sizeof(EventStatusRecType));
383         }
384         else {
385                 // Copy an empty record to return data
386                 eventStatusRec->eventId = DEM_EVENT_ID_NULL;
387                 eventStatusRec->eventStatus = DEM_EVENT_STATUS_PASSED;
388                 eventStatusRec->occurrence = 0;
389                 eventStatusRec->eventStatusChanged = FALSE;
390                 eventStatusRec->eventStatusExtended = DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR;
391         }
392
393         McuE_ExitCriticalSection(state);
394 }
395
396
397 /*
398  * Procedure:   mergeEventStatusRec
399  * Description: Update the occurrence counter of status, if not exist a new record is created
400  */
401 void mergeEventStatusRec(EventRecType *eventRec)
402 {
403         uint16 i;
404         imask_t state = McuE_EnterCriticalSection();
405
406         // Lookup event ID
407         for (i = 0; (eventStatusBuffer[i].eventId != eventRec->eventId) && (i < DEM_MAX_NUMBER_EVENT); i++);
408
409         if (i < DEM_MAX_NUMBER_EVENT) {
410                 // Update occurrence counter, rest of pre init state is kept.
411                 eventStatusBuffer[i].occurrence += eventRec->occurrence;
412
413         }
414         else {
415                 // Search for free position
416                 for (i = 0; (eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) && (i < DEM_MAX_NUMBER_EVENT); i++);
417
418                 if (i < DEM_MAX_NUMBER_EVENT) {
419                         // Create new event, from stored event
420                         eventStatusBuffer[i].eventId = eventRec->eventId;
421                         lookupEventIdParameter(eventRec->eventId, &eventStatusBuffer[i].eventParamRef);
422                         eventStatusBuffer[i].occurrence = eventRec->occurrence;
423                         eventStatusBuffer[i].eventStatus = DEM_EVENT_STATUS_PASSED;
424                         eventStatusBuffer[i].eventStatusChanged = FALSE;
425                         eventStatusBuffer[i].eventStatusExtended = DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR;
426                 }
427                 else {
428                         // Error: Event status buffer full
429 #if (DEM_DEV_ERROR_DETECT == STD_ON)
430                         Det_ReportError(MODULE_ID_DEM, 0, DEM_MERGE_EVENT_STATUS_ID, DEM_E_EVENT_STATUS_BUFF_FULL);
431 #endif
432                 }
433         }
434
435         McuE_ExitCriticalSection(state);
436 }
437
438
439 /*
440  * Procedure:   deleteEventStatusRec
441  * Description: Delete the status record of "eventParam->eventId" from "eventStatusBuffer".
442  */
443 void deleteEventStatusRec(const Dem_EventParameterType *eventParam)
444 {
445         uint16 i;
446         imask_t state = McuE_EnterCriticalSection();
447
448         // Lookup event ID
449         for (i = 0; (eventStatusBuffer[i].eventId != eventParam->EventID) && (i < DEM_MAX_NUMBER_EVENT); i++);
450
451         if (i < DEM_MAX_NUMBER_EVENT) {
452                 // Delete event record
453                 setZero(&eventStatusBuffer[i], sizeof(EventStatusRecType));
454         }
455
456         McuE_ExitCriticalSection(state);
457 }
458
459
460 /*
461  * Procedure:   getEventStatusRec
462  * Description: Returns the status record of "eventId" in "eventStatusRec"
463  */
464 void getEventStatusRec(Dem_EventIdType eventId, EventStatusRecType *eventStatusRec)
465 {
466         uint16 i;
467         // Lookup event ID
468         for (i = 0; (eventStatusBuffer[i].eventId != eventId) && (i < DEM_MAX_NUMBER_EVENT); i++);
469
470         if (i < DEM_MAX_NUMBER_EVENT) {
471                 // Copy the record
472                 memcpy(eventStatusRec, &eventStatusBuffer[i], sizeof(EventStatusRecType));
473         }
474         else {
475                 eventStatusRec->eventId = DEM_EVENT_ID_NULL;
476                 eventStatusRec->eventStatus = DEM_EVENT_STATUS_PASSED;
477                 eventStatusRec->occurrence = 0;
478         }
479 }
480
481
482 /*
483  * Procedure:   lookupDtcEvent
484  * Description: Returns TRUE if the DTC was found and "eventStatusRec" points
485  *                              to the event record found.
486  */
487 boolean lookupDtcEvent(uint32 dtc, EventStatusRecType **eventStatusRec)
488 {
489         boolean dtcFound = FALSE;
490         uint16 i;
491
492         *eventStatusRec = NULL;
493
494         for (i = 0; (i < DEM_MAX_NUMBER_EVENT) && !dtcFound; i++) {
495                 if (eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) {
496                         if (eventStatusBuffer[i].eventParamRef->DTCClassRef != NULL) {
497
498                                 // Check DTC
499                                 if (eventStatusBuffer[i].eventParamRef->DTCClassRef->DTC == dtc) {
500                                         *eventStatusRec = &eventStatusBuffer[i];
501                                         dtcFound = TRUE;
502                                 }
503                         }
504                 }
505         }
506
507         return dtcFound;
508 }
509
510
511 /*
512  * Procedure:   matchEventWithDtcFilter
513  * Description: Returns TRUE if the event pointed by "event" fulfill
514  *                              the "dtcFilter" global filter settings.
515  */
516 boolean matchEventWithDtcFilter(const EventStatusRecType *eventRec)
517 {
518         boolean dtcMatch = FALSE;
519
520         // Check status
521         if ((dtcFilter.dtcStatusMask == DEM_DTC_STATUS_MASK_ALL) || (eventRec->eventStatusExtended & dtcFilter.dtcStatusMask)) {
522                 if (eventRec->eventParamRef != NULL) {
523
524                         // Check dtcKind
525                         if (checkDtcKind(dtcFilter.dtcKind, eventRec->eventParamRef)) {
526
527                                 // Check dtcOrigin
528                                 if (checkDtcOrigin(dtcFilter.dtcOrigin, eventRec->eventParamRef)) {
529
530                                         // Check severity
531                                         if ((dtcFilter.filterWithSeverity == DEM_FILTER_WITH_SEVERITY_NO)
532                                                 || ((dtcFilter.filterWithSeverity == DEM_FILTER_WITH_SEVERITY_YES) && checkDtcSeverityMask(dtcFilter.dtcSeverityMask, eventRec->eventParamRef))) {
533
534                                                 // Check fault detection counter
535                                                 if ((dtcFilter.filterForFaultDetectionCounter == DEM_FILTER_FOR_FDC_NO)
536                                                         || ((dtcFilter.filterWithSeverity == DEM_FILTER_FOR_FDC_YES) && checkDtcFaultDetectionCounter(eventRec->eventParamRef))) {
537                                                         dtcMatch = TRUE;
538                                                 }
539                                         }
540                                 }
541                         }
542                 }
543         }
544
545         return dtcMatch;
546 }
547
548
549 void getFreezeFrameData(const Dem_EventParameterType *eventParam, FreezeFrameRecType *freezeFrame)
550 {
551         // TODO: Fill out
552         freezeFrame->eventId = DEM_EVENT_ID_NULL;       // Not supported yet
553 }
554
555
556 void storeFreezeFrameDataPreInit(const Dem_EventParameterType *eventParam, FreezeFrameRecType *freezeFrame)
557 {
558         // TODO: Fill out
559 }
560
561
562 void updateFreezeFrameOccurrencePreInit(EventRecType *EventBuffer)
563 {
564         // TODO: Fill out
565 }
566
567
568 /*
569  * Procedure:   getExtendedData
570  * Description: Collects the extended data according to "eventParam" and return it in "extData",
571  *                              if not found eventId is set to DEM_EVENT_ID_NULL.
572  */
573 void getExtendedData(const Dem_EventParameterType *eventParam, ExtDataRecType *extData)
574 {
575         Std_ReturnType callbackReturnCode;
576         uint16 i;
577         uint16 storeIndex = 0;
578         uint16 recordSize;
579
580         // Clear ext data record
581         setZero(extData, sizeof(ExtDataRecType));
582
583         // Check if any pointer to extended data class
584         if (eventParam->ExtendedDataClassRef != NULL) {
585                 // Request extended data and copy it to the buffer
586                 for (i = 0; (i < DEM_MAX_NR_OF_RECORDS_IN_EXTENDED_DATA) && (eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef[i] != NULL); i++) {
587                         recordSize = eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef[i]->DataSize;
588                         if ((storeIndex + recordSize) <= DEM_MAX_SIZE_EXT_DATA) {
589                                 callbackReturnCode = eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef[i]->CallbackGetExtDataRecord(&extData->data[storeIndex]);
590                                 if (callbackReturnCode != E_OK) {
591                                         // Callback data currently not available, clear space.
592                                         setFF(&extData->data[storeIndex], recordSize);
593                                 }
594                                 storeIndex += recordSize;
595                         }
596                         else {
597                                 // Error: Size of extended data record is bigger than reserved space.
598 #if (DEM_DEV_ERROR_DETECT == STD_ON)
599                                 Det_ReportError(MODULE_ID_DEM, 0, DEM_GET_EXTENDED_DATA_ID, DEM_E_EXT_DATA_TO_BIG);
600 #endif
601                                 break;  // Break the loop
602                         }
603                 }
604         }
605
606         // Check if any data has been stored
607         if (storeIndex != 0) {
608                 extData->eventId = eventParam->EventID;
609                 extData->dataSize = storeIndex;
610                 extData->checksum = calcChecksum(extData, sizeof(ExtDataRecType)-sizeof(ChecksumType));
611         }
612         else {
613                 extData->eventId = DEM_EVENT_ID_NULL;
614                 extData->dataSize = storeIndex;
615                 extData->checksum = 0;
616         }
617 }
618
619
620 /*
621  * Procedure:   storeExtendedDataPreInit
622  * Description: Store the extended data pointed by "extendedData" to the "preInitExtDataBuffer",
623  *                              if non existent a new entry is created.
624  */
625 void storeExtendedDataPreInit(const Dem_EventParameterType *eventParam, ExtDataRecType *extendedData)
626 {
627         uint16 i;
628         imask_t state = McuE_EnterCriticalSection();
629
630         // Check if already stored
631         for (i = 0; (preInitExtDataBuffer[i].eventId != eventParam->EventID) && (i<DEM_MAX_NUMBER_EXT_DATA_PRE_INIT); i++);
632
633         if (i < DEM_MAX_NUMBER_EXT_DATA_PRE_INIT) {
634                 // Yes, overwrite existing
635                 memcpy(&preInitExtDataBuffer[i], extendedData, sizeof(ExtDataRecType));
636         }
637         else {
638                 // No, lookup first free position
639                 for (i = 0; (preInitExtDataBuffer[i].eventId !=0) && (i<DEM_MAX_NUMBER_EXT_DATA_PRE_INIT); i++);
640
641                 if (i < DEM_MAX_NUMBER_EXT_DATA_PRE_INIT) {
642                         memcpy(&preInitExtDataBuffer[i], extendedData, sizeof(ExtDataRecType));
643                 }
644                 else {
645                         // Error: Pre init extended data buffer full
646 #if (DEM_DEV_ERROR_DETECT == STD_ON)
647                         Det_ReportError(MODULE_ID_DEM, 0, DEM_STORE_EXT_DATA_PRE_INIT_ID, DEM_E_PRE_INIT_EXT_DATA_BUFF_FULL);
648 #endif
649                 }
650         }
651
652         McuE_ExitCriticalSection(state);
653 }
654
655
656 /*
657  * Procedure:   storeEventPriMem
658  * Description: Store the event data of "eventStatus->eventId" in "priMemEventBuffer",
659  *                              if non existent a new entry is created.
660  */
661 void storeEventPriMem(const Dem_EventParameterType *eventParam, EventStatusRecType *eventStatus)
662 {
663         uint16 i;
664         imask_t state = McuE_EnterCriticalSection();
665
666
667         // Lookup event ID
668         for (i = 0; (priMemEventBuffer[i].eventId != eventStatus->eventId) && (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI); i++);
669
670         if (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI) {
671                 // Update event found
672                 priMemEventBuffer[i].occurrence = eventStatus->occurrence;
673                 priMemEventBuffer[i].checksum = calcChecksum(&priMemEventBuffer[i], sizeof(EventRecType)-sizeof(ChecksumType));
674         }
675         else {
676                 // Search for free position
677                 for (i=0; (priMemEventBuffer[i].eventId != DEM_EVENT_ID_NULL) && (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI); i++);
678
679                 if (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI) {
680                         priMemEventBuffer[i].eventId = eventStatus->eventId;
681                         priMemEventBuffer[i].occurrence = eventStatus->occurrence;
682                         priMemEventBuffer[i].checksum = calcChecksum(&priMemEventBuffer[i], sizeof(EventRecType)-sizeof(ChecksumType));
683                 }
684                 else {
685                         // Error: Pri mem event buffer full
686 #if (DEM_DEV_ERROR_DETECT == STD_ON)
687                         Det_ReportError(MODULE_ID_DEM, 0, DEM_STORE_EVENT_PRI_MEM_ID, DEM_E_PRI_MEM_EVENT_BUFF_FULL);
688 #endif
689                 }
690         }
691
692         McuE_ExitCriticalSection(state);
693 }
694
695
696 /*
697  * Procedure:   deleteEventPriMem
698  * Description: Delete the event data of "eventParam->eventId" from "priMemEventBuffer".
699  */
700 void deleteEventPriMem(const Dem_EventParameterType *eventParam)
701 {
702         uint16 i;
703         imask_t state = McuE_EnterCriticalSection();
704
705
706         // Lookup event ID
707         for (i = 0; (priMemEventBuffer[i].eventId != eventParam->EventID) && (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI); i++);
708
709         if (i < DEM_MAX_NUMBER_EVENT_ENTRY_PRI) {
710                 // Delete event found
711                 setZero(&priMemEventBuffer[i], sizeof(EventRecType));
712         }
713
714         McuE_ExitCriticalSection(state);
715 }
716
717
718 /*
719  * Procedure:   storeEventEvtMem
720  * Description: Store the event data of "eventStatus->eventId" in event memory according to
721  *                              "eventParam" destination option.
722  */
723 void storeEventEvtMem(const Dem_EventParameterType *eventParam, EventStatusRecType *eventStatus)
724 {
725         uint16 i;
726
727         for (i = 0; (i < DEM_MAX_NR_OF_EVENT_DESTINATION) && (eventParam->EventClass->EventDestination[i] != NULL); i++) {
728                 switch (eventParam->EventClass->EventDestination[i])
729                 {
730                 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:
731                         storeEventPriMem(eventParam, eventStatus);
732                         break;
733
734                 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:
735                 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:
736                 case DEM_DTC_ORIGIN_MIRROR_MEMORY:
737                         // Not yet supported
738 #if (DEM_DEV_ERROR_DETECT == STD_ON)
739                         Det_ReportError(MODULE_ID_DEM, 0, DEM_GLOBAL_ID, DEM_E_NOT_IMPLEMENTED_YET);
740 #endif
741                         break;
742                 default:
743                         break;
744                 }
745         }
746 }
747
748
749 /*
750  * Procedure:   storeExtendedDataPriMem
751  * Description: Store the extended data pointed by "extendedData" to the "priMemExtDataBuffer",
752  *                              if non existent a new entry is created.
753  */
754 void storeExtendedDataPriMem(const Dem_EventParameterType *eventParam, ExtDataRecType *extendedData)
755 {
756         uint16 i;
757         imask_t state = McuE_EnterCriticalSection();
758
759         // Check if already stored
760         for (i = 0; (priMemExtDataBuffer[i].eventId != eventParam->EventID) && (i<DEM_MAX_NUMBER_EXT_DATA_PRI_MEM); i++);
761
762         if (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM) {
763                 // Yes, overwrite existing
764                 memcpy(&priMemExtDataBuffer[i], extendedData, sizeof(ExtDataRecType));
765         }
766         else {
767                 // No, lookup first free position
768                 for (i = 0; (priMemExtDataBuffer[i].eventId != DEM_EVENT_ID_NULL) && (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM); i++);
769                 if (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM) {
770                         memcpy(&priMemExtDataBuffer[i], extendedData, sizeof(ExtDataRecType));
771                 }
772                 else {
773                         // Error: Pri mem extended data buffer full
774 #if (DEM_DEV_ERROR_DETECT == STD_ON)
775                         Det_ReportError(MODULE_ID_DEM, 0, DEM_STORE_EXT_DATA_PRI_MEM_ID, DEM_E_PRI_MEM_EXT_DATA_BUFF_FULL);
776 #endif
777                 }
778         }
779
780         McuE_ExitCriticalSection(state);
781 }
782
783
784 /*
785  * Procedure:   deleteExtendedDataPriMem
786  * Description: Delete the extended data of "eventParam->eventId" from "priMemExtDataBuffer".
787  */
788 void deleteExtendedDataPriMem(const Dem_EventParameterType *eventParam)
789 {
790         uint16 i;
791         imask_t state = McuE_EnterCriticalSection();
792
793         // Check if already stored
794         for (i = 0; (priMemExtDataBuffer[i].eventId != eventParam->EventID) && (i<DEM_MAX_NUMBER_EXT_DATA_PRI_MEM); i++);
795
796         if (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM) {
797                 // Yes, clear record
798                 setZero(&priMemExtDataBuffer[i], sizeof(ExtDataRecType));
799         }
800
801         McuE_ExitCriticalSection(state);
802 }
803
804
805 /*
806  * Procedure:   storeExtendedDataEvtMem
807  * Description: Store the extended data in event memory according to
808  *                              "eventParam" destination option
809  */
810 void storeExtendedDataEvtMem(const Dem_EventParameterType *eventParam, ExtDataRecType *extendedData)
811 {
812         uint16 i;
813
814         for (i = 0; (i < DEM_MAX_NR_OF_EVENT_DESTINATION) && (eventParam->EventClass->EventDestination[i] != NULL); i++) {
815                 switch (eventParam->EventClass->EventDestination[i])
816                 {
817                 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:
818                         storeExtendedDataPriMem(eventParam, extendedData);
819                         break;
820
821                 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:
822                 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:
823                 case DEM_DTC_ORIGIN_MIRROR_MEMORY:
824                         // Not yet supported
825 #if (DEM_DEV_ERROR_DETECT == STD_ON)
826                         Det_ReportError(MODULE_ID_DEM, 0, DEM_GLOBAL_ID, DEM_E_NOT_IMPLEMENTED_YET);
827 #endif
828                         break;
829
830                 default:
831                         break;
832                 }
833         }
834 }
835
836
837 /*
838  * Procedure:   lookupExtendedDataRecNumParam
839  * Description: Returns TRUE if the requested extended data number was found among the configured records for the event.
840  *                              "extDataRecClassPtr" returns a pointer to the record class, "posInExtData" returns the position in stored extended data.
841  */
842 boolean lookupExtendedDataRecNumParam(uint8 extendedDataNumber, const Dem_EventParameterType *eventParam, Dem_ExtendedDataRecordClassType const **extDataRecClassPtr, uint8 *posInExtData)
843 {
844         boolean recNumFound = FALSE;
845
846         if (eventParam->ExtendedDataClassRef != NULL) {
847                 Dem_ExtendedDataRecordClassType const* const* extDataRecClassRefList = eventParam->ExtendedDataClassRef->ExtendedDataRecordClassRef;
848                 uint16  byteCnt = 0;
849                 uint16 i;
850
851                 // Request extended data and copy it to the buffer
852                 for (i = 0; (i < DEM_MAX_NR_OF_RECORDS_IN_EXTENDED_DATA) && (extDataRecClassRefList[i] != NULL) && !recNumFound; i++) {
853                         if (extDataRecClassRefList[i]->RecordNumber == extendedDataNumber) {
854                                 *extDataRecClassPtr =  extDataRecClassRefList[i];
855                                 *posInExtData = byteCnt;
856                                 recNumFound = TRUE;
857                         }
858                         byteCnt += extDataRecClassRefList[i]->DataSize;
859                 }
860         }
861
862         return recNumFound;
863 }
864
865
866 /*
867  * Procedure:   lookupExtendedDataPriMem
868  * Description: Returns TRUE if the requested event id is found, "extData" points to the found data.
869  */
870 boolean lookupExtendedDataPriMem(Dem_EventIdType eventId, ExtDataRecType **extData)
871 {
872         boolean eventIdFound = FALSE;
873         uint16 i;
874
875         // Lookup corresponding extended data
876         for (i = 0; (priMemExtDataBuffer[i].eventId != eventId) && (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM); i++);
877
878         if (i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM) {
879                 // Yes, return pointer
880                 *extData = &priMemExtDataBuffer[i];
881                 eventIdFound = TRUE;
882         }
883
884         return eventIdFound;
885 }
886
887
888 void storeFreezeFrameDataPriMem(const Dem_EventParameterType *eventParam, FreezeFrameRecType *freezeFrame)
889 {
890         // TODO: Fill out
891 }
892
893
894 void deleteFreezeFrameDataPriMem(const Dem_EventParameterType *eventParam)
895 {
896         // TODO: Fill out
897 }
898
899
900 /*
901  * Procedure:   storeFreezeFrameDataEvtMem
902  * Description: Store the freeze frame data in event memory according to
903  *                              "eventParam" destination option
904  */
905 void storeFreezeFrameDataEvtMem(const Dem_EventParameterType *eventParam, FreezeFrameRecType *freezeFrame)
906 {
907         uint16 i;
908
909         for (i = 0; (i < DEM_MAX_NR_OF_EVENT_DESTINATION) && (eventParam->EventClass->EventDestination[i] != NULL); i++) {
910                 switch (eventParam->EventClass->EventDestination[i])
911                 {
912                 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:
913                         storeFreezeFrameDataPriMem(eventParam, freezeFrame);
914                         break;
915
916                 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:
917                 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:
918                 case DEM_DTC_ORIGIN_MIRROR_MEMORY:
919                         // Not yet supported
920 #if (DEM_DEV_ERROR_DETECT == STD_ON)
921                         Det_ReportError(MODULE_ID_DEM, 0, DEM_GLOBAL_ID, DEM_E_NOT_IMPLEMENTED_YET);
922 #endif
923                         break;
924                 default:
925                         break;
926                 }
927         }
928 }
929
930
931 /*
932  * Procedure:   handlePreInitEvent
933  * Description: Handle the updating of event status and storing of
934  *                              event related data in preInit buffers.
935  */
936 void handlePreInitEvent(Dem_EventIdType eventId, Dem_EventStatusType eventStatus)
937 {
938         const Dem_EventParameterType *eventParam;
939         EventStatusRecType eventStatusLocal;
940         FreezeFrameRecType freezeFrameLocal;
941         ExtDataRecType extendedDataLocal;
942
943         // Find configuration for this event
944         lookupEventIdParameter(eventId, &eventParam);
945         if (eventParam != NULL) {
946                 if (eventParam->EventClass->OperationCycleRef < DEM_OPERATION_CYCLE_ID_ENDMARK) {
947                         if (operationCycleStateList[eventParam->EventClass->OperationCycleRef] == DEM_CYCLE_STATE_START) {
948                                 if (eventStatus == DEM_EVENT_STATUS_PASSED) {
949                                         updateEventStatusRec(eventParam, eventStatus, FALSE, &eventStatusLocal);
950                                 }
951                                 else {
952                                         updateEventStatusRec(eventParam, eventStatus, TRUE, &eventStatusLocal);
953                                 }
954
955                                 if (eventStatusLocal.eventStatusChanged) {
956
957                                         if (eventStatusLocal.eventStatus == DEM_EVENT_STATUS_FAILED) {
958                                                 // Collect freeze frame data
959                                                 getFreezeFrameData(eventParam, &freezeFrameLocal);
960                                                 if (freezeFrameLocal.eventId != DEM_EVENT_ID_NULL) {
961                                                         storeFreezeFrameDataPreInit(eventParam, &freezeFrameLocal);
962                                                 }
963
964                                                 // Collect extended data
965                                                 getExtendedData(eventParam, &extendedDataLocal);
966                                                 if (extendedDataLocal.eventId != DEM_EVENT_ID_NULL) {
967                                                         storeExtendedDataPreInit(eventParam, &extendedDataLocal);
968                                                 }
969                                         }
970                                 }
971                         }
972                         else {
973                                 // Operation cycle not started
974                                 // TODO: Report error?
975                         }
976                 }
977                 else {
978                         // Operation cycle not set
979                         // TODO: Report error?
980                 }
981         }
982         else {
983                 // Event ID not configured
984                 // TODO: Report error?
985         }
986 }
987
988
989 /*
990  * Procedure:   handleEvent
991  * Description: Handle the updating of event status and storing of
992  *                              event related data in event memory.
993  */
994 Std_ReturnType handleEvent(Dem_EventIdType eventId, Dem_EventStatusType eventStatus)
995 {
996         Std_ReturnType returnCode = E_OK;
997         const Dem_EventParameterType *eventParam;
998         EventStatusRecType eventStatusLocal;
999         FreezeFrameRecType freezeFrameLocal;
1000         ExtDataRecType extendedDataLocal;
1001
1002         // Find configuration for this event
1003         lookupEventIdParameter(eventId, &eventParam);
1004         if (eventParam != NULL) {
1005                 if (eventParam->EventClass->OperationCycleRef < DEM_OPERATION_CYCLE_ID_ENDMARK) {
1006                         if (operationCycleStateList[eventParam->EventClass->OperationCycleRef] == DEM_CYCLE_STATE_START) {
1007                                 if (!(disableDtcStorage.storageDisabled && checkDtcGroup(disableDtcStorage.dtcGroup, eventParam) && checkDtcKind(disableDtcStorage.dtcKind, eventParam)))  {
1008                                         updateEventStatusRec(eventParam, eventStatus, TRUE, &eventStatusLocal);
1009                                         if (eventStatusLocal.eventStatusChanged) {
1010                                                 if (eventStatusLocal.eventStatus == DEM_EVENT_STATUS_FAILED) {
1011                                                         storeEventEvtMem(eventParam, &eventStatusLocal);
1012                                                         // Collect freeze frame data
1013                                                         getFreezeFrameData(eventParam, &freezeFrameLocal);
1014                                                         if (freezeFrameLocal.eventId != DEM_EVENT_ID_NULL) {
1015                                                                 storeFreezeFrameDataEvtMem(eventParam, &freezeFrameLocal);
1016                                                         }
1017
1018                                                         // Collect extended data
1019                                                         getExtendedData(eventParam, &extendedDataLocal);
1020                                                         if (extendedDataLocal.eventId != DEM_EVENT_ID_NULL)
1021                                                         {
1022                                                                 storeExtendedDataEvtMem(eventParam, &extendedDataLocal);
1023                                                         }
1024                                                 }
1025                                         }
1026                                 }
1027                         }
1028                         else {
1029                                 // Operation cycle not started
1030                                 returnCode = E_NOT_OK;
1031                         }
1032                 }
1033                 else {
1034                         // Operation cycle not set
1035                         returnCode = E_NOT_OK;
1036                 }
1037         }
1038         else {
1039                 // Event ID not configured
1040                 returnCode = E_NOT_OK;
1041         }
1042
1043         return returnCode;
1044 }
1045
1046
1047 /*
1048  * Procedure:   getEventStatus
1049  * Description: Returns the extended event status bitmask of eventId in "eventStatusExtended".
1050  */
1051 void getEventStatus(Dem_EventIdType eventId, Dem_EventStatusExtendedType *eventStatusExtended)
1052 {
1053         EventStatusRecType eventStatusLocal;
1054
1055         // Get recorded status
1056         getEventStatusRec(eventId, &eventStatusLocal);
1057         if (eventStatusLocal.eventId == eventId) {
1058                 *eventStatusExtended = eventStatusLocal.eventStatusExtended;
1059         }
1060         else {
1061                 // Event Id not found, no report received.
1062                 *eventStatusExtended = DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR;
1063         }
1064 }
1065
1066
1067 /*
1068  * Procedure:   getEventFailed
1069  * Description: Returns the TRUE or FALSE of "eventId" in "eventFailed" depending on current status.
1070  */
1071 void getEventFailed(Dem_EventIdType eventId, boolean *eventFailed)
1072 {
1073         EventStatusRecType eventStatusLocal;
1074
1075         // Get recorded status
1076         getEventStatusRec(eventId, &eventStatusLocal);
1077         if (eventStatusLocal.eventId == eventId) {
1078                 if (eventStatusLocal.eventStatusExtended & DEM_TEST_FAILED) {
1079                         *eventFailed = TRUE;
1080                 }
1081                 else {
1082                         *eventFailed = FALSE;
1083                 }
1084         }
1085         else {
1086                 // Event Id not found, assume ok.
1087                 *eventFailed = FALSE;
1088         }
1089 }
1090
1091
1092 /*
1093  * Procedure:   getEventTested
1094  * Description: Returns the TRUE or FALSE of "eventId" in "eventTested" depending on
1095  *                              current status the "test not completed this operation cycle" bit.
1096  */
1097 void getEventTested(Dem_EventIdType eventId, boolean *eventTested)
1098 {
1099         EventStatusRecType eventStatusLocal;
1100
1101         // Get recorded status
1102         getEventStatusRec(eventId, &eventStatusLocal);
1103         if (eventStatusLocal.eventId == eventId) {
1104                 if ( !(eventStatusLocal.eventStatusExtended & DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE)) {
1105                         *eventTested = TRUE;
1106                 }
1107                 else {
1108                         *eventTested = FALSE;
1109                 }
1110         }
1111         else {
1112                 // Event Id not found, not tested.
1113                 *eventTested = FALSE;
1114         }
1115 }
1116
1117
1118 /*
1119  * Procedure:   getFaultDetectionCounter
1120  * Description: Returns pre debounce counter of "eventId" in "counter" and return value E_OK if
1121  *                              the counter was available else E_NOT_OK.
1122  */
1123 Std_ReturnType getFaultDetectionCounter(Dem_EventIdType eventId, sint8 *counter)
1124 {
1125         Std_ReturnType returnCode = E_NOT_OK;
1126         const Dem_EventParameterType *eventParam;
1127
1128         lookupEventIdParameter(eventId, &eventParam);
1129         if (eventParam != NULL) {
1130                 if (eventParam->EventClass->PreDebounceAlgorithmClass != NULL) {
1131                         switch (eventParam->EventClass->PreDebounceAlgorithmClass->PreDebounceName)
1132                         {
1133                         case DEM_NO_PRE_DEBOUNCE:
1134                                 if (eventParam->EventClass->PreDebounceAlgorithmClass->PreDebounceAlgorithm.PreDebounceMonitorInternal != NULL) {
1135                                         returnCode = eventParam->EventClass->PreDebounceAlgorithmClass->PreDebounceAlgorithm.PreDebounceMonitorInternal->CallbackGetFDCntFnc(counter);
1136                                 }
1137                                 break;
1138
1139                         case DEM_PRE_DEBOUNCE_COUNTER_BASED:
1140                         case DEM_PRE_DEBOUNCE_FREQUENCY_BASED:
1141                         case DEM_PRE_DEBOUNCE_TIME_BASED:
1142 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1143                                 Det_ReportError(MODULE_ID_DEM, 0, DEM_GETFAULTDETECTIONCOUNTER_ID, DEM_E_NOT_IMPLEMENTED_YET);
1144 #endif
1145                                 break;
1146
1147                         default:
1148 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1149                                 Det_ReportError(MODULE_ID_DEM, 0, DEM_GETFAULTDETECTIONCOUNTER_ID, DEM_E_PARAM_DATA);
1150 #endif
1151                                 break;
1152                         }
1153                 }
1154         }
1155
1156         return returnCode;
1157 }
1158
1159
1160 /*
1161  * Procedure:   setOperationCycleState
1162  * Description: Change the operation state of "operationCycleId" to "cycleState" and updates stored
1163  *                              event connected to this cycle id.
1164  *                              Returns E_OK if operation was successful else E_NOT_OK.
1165  */
1166 Std_ReturnType setOperationCycleState(Dem_OperationCycleIdType operationCycleId, Dem_OperationCycleStateType cycleState)
1167 {
1168         uint16 i;
1169         Std_ReturnType returnCode = E_OK;
1170
1171         if (operationCycleId < DEM_OPERATION_CYCLE_ID_ENDMARK) {
1172                 switch (cycleState)
1173                 {
1174                 case DEM_CYCLE_STATE_START:
1175                         operationCycleStateList[operationCycleId] = cycleState;
1176                         // Lookup event ID
1177                         for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {
1178                                 if ((eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) && (eventStatusBuffer[i].eventParamRef->EventClass->OperationCycleRef == operationCycleId)) {
1179                                         eventStatusBuffer[i].eventStatusExtended &= ~DEM_TEST_FAILED_THIS_OPERATION_CYCLE;
1180                                         eventStatusBuffer[i].eventStatusExtended |= DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE;
1181                                 }
1182                         }
1183                         break;
1184
1185                 case DEM_CYCLE_STATE_END:
1186                         operationCycleStateList[operationCycleId] = cycleState;
1187                         // Lookup event ID
1188                         for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {
1189                                 if ((eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) && (eventStatusBuffer[i].eventParamRef->EventClass->OperationCycleRef == operationCycleId)) {
1190                                         if (!(eventStatusBuffer[i].eventStatusExtended & DEM_TEST_FAILED_THIS_OPERATION_CYCLE) && !(eventStatusBuffer[i].eventStatusExtended & DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE)) {
1191                                                 eventStatusBuffer[i].eventStatusExtended &= ~DEM_PENDING_DTC;           // Clear pendingDTC bit
1192                                         }
1193                                 }
1194                         }
1195                         break;
1196                 default:
1197 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1198                         Det_ReportError(MODULE_ID_DEM, 0, DEM_SETOPERATIONCYCLESTATE_ID, DEM_E_PARAM_DATA);
1199 #endif
1200                         returnCode = E_NOT_OK;
1201                         break;
1202                 }
1203         }
1204         else {
1205 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1206                 Det_ReportError(MODULE_ID_DEM, 0, DEM_SETOPERATIONCYCLESTATE_ID, DEM_E_PARAM_DATA);
1207 #endif
1208                 returnCode = E_NOT_OK;
1209                 }
1210
1211         return returnCode;
1212 }
1213
1214
1215 //==============================================================================//
1216 //                                                                                                                                                              //
1217 //                                        E X T E R N A L   F U N C T I O N S                                           //
1218 //                                                                                                                                                              //
1219 //==============================================================================//
1220
1221 /*********************************************
1222  * Interface for upper layer modules (8.3.1) *
1223  *********************************************/
1224
1225 /*
1226  * Procedure:   Dem_GetVersionInfo
1227  * Reentrant:   Yes
1228  */
1229 #if (DEM_VERSION_INFO_API == STD_ON)
1230 void Dem_GetVersionInfo(Std_VersionInfoType *versionInfo) {
1231         memcpy(versionInfo, &_Dem_VersionInfo, sizeof(Std_VersionInfoType));
1232 }
1233 #endif /* DEM_VERSION_INFO_API */
1234
1235
1236 /***********************************************
1237  * Interface ECU State Manager <-> DEM (8.3.2) *
1238  ***********************************************/
1239
1240 /*
1241  * Procedure:   Dem_PreInit
1242  * Reentrant:   No
1243  */
1244 void Dem_PreInit(void)
1245 {
1246         int i, j;
1247
1248         if (DEM_Config.ConfigSet == NULL) {
1249 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1250                 Det_ReportError(MODULE_ID_DEM, 0, DEM_PREINIT_ID, DEM_E_CONFIG_PTR_INVALID);
1251 #endif
1252                 return;
1253         } else {
1254                 configSet = DEM_Config.ConfigSet;
1255         }
1256
1257         // Initializion of operation cycle states.
1258         for (i = 0; i < DEM_OPERATION_CYCLE_ID_ENDMARK; i++) {
1259                 operationCycleStateList[i] = DEM_CYCLE_STATE_END;
1260         }
1261
1262         // Initialize the event status buffer
1263         for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {
1264                 eventStatusBuffer[i].eventId = DEM_EVENT_ID_NULL;
1265                 eventStatusBuffer[i].occurrence = 0;
1266                 eventStatusBuffer[i].eventStatusExtended = DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR;
1267                 eventStatusBuffer[i].eventStatus = DEM_EVENT_STATUS_PASSED;
1268                 eventStatusBuffer[i].eventStatusChanged = FALSE;
1269         }
1270
1271         // Initialize the pre init buffers
1272         for (i = 0; i < DEM_MAX_NUMBER_FF_DATA_PRE_INIT; i++) {
1273                 preInitFreezeFrameBuffer[i].checksum = 0;
1274                 preInitFreezeFrameBuffer[i].eventId = DEM_EVENT_ID_NULL;
1275                 preInitFreezeFrameBuffer[i].occurrence = 0;
1276                 preInitFreezeFrameBuffer[i].dataSize = 0;
1277                 for (j = 0; j < DEM_MAX_SIZE_FF_DATA;j++)
1278                         preInitFreezeFrameBuffer[i].data[j] = 0;
1279         }
1280
1281         for (i = 0; i < DEM_MAX_NUMBER_EXT_DATA_PRE_INIT; i++) {
1282                 preInitExtDataBuffer[i].checksum = 0;
1283                 preInitExtDataBuffer[i].eventId = DEM_EVENT_ID_NULL;
1284                 preInitExtDataBuffer[i].dataSize = 0;
1285                 for (j = 0; j < DEM_MAX_SIZE_EXT_DATA;j++)
1286                         preInitExtDataBuffer[i].data[j] = 0;
1287         }
1288
1289         disableDtcStorage.storageDisabled = FALSE;
1290
1291         setOperationCycleState(DEM_ACTIVE, DEM_CYCLE_STATE_START);
1292
1293         demState = DEM_PREINITIALIZED;
1294 }
1295
1296
1297 /*
1298  * Procedure:   Dem_Init
1299  * Reentrant:   No
1300  */
1301 void Dem_Init(void)
1302 {
1303         uint16 i;
1304         ChecksumType cSum;
1305         const Dem_EventParameterType *eventParam;
1306
1307         /*
1308          *  Validate and read out saved error log from non volatile memory
1309          */
1310
1311         // Validate event records stored in primary memory
1312         for (i = 0; i < DEM_MAX_NUMBER_EVENT_PRI_MEM; i++) {
1313                 cSum = calcChecksum(&priMemEventBuffer[i], sizeof(EventRecType)-sizeof(ChecksumType));
1314                 if ((cSum != priMemEventBuffer[i].checksum) || priMemEventBuffer[i].eventId == DEM_EVENT_ID_NULL) {
1315                         // Unlegal record, clear the record
1316                         setZero(&priMemEventBuffer[i], sizeof(EventRecType));
1317                 }
1318                 else {
1319                         // Valid, update current status
1320                         mergeEventStatusRec(&priMemEventBuffer[i]);
1321
1322                         // Update occurrence counter on pre init stored freeze frames
1323                         updateFreezeFrameOccurrencePreInit(&priMemEventBuffer[i]);
1324                 }
1325         }
1326
1327         // Validate extended data records stored in primary memory
1328         for (i = 0; i < DEM_MAX_NUMBER_EXT_DATA_PRI_MEM; i++) {
1329                 cSum = calcChecksum(&priMemExtDataBuffer[i], sizeof(ExtDataRecType)-sizeof(ChecksumType));
1330                 if ((cSum != priMemExtDataBuffer[i].checksum) || priMemExtDataBuffer[i].eventId == DEM_EVENT_ID_NULL) {
1331                         // Unlegal record, clear the record
1332                         setZero(&priMemExtDataBuffer[i], sizeof(ExtDataRecType));
1333                 }
1334         }
1335
1336         // Validate freeze frame records stored in primary memory
1337         for (i = 0; i < DEM_MAX_NUMBER_FF_DATA_PRI_MEM; i++) {
1338                 cSum = calcChecksum(&priMemFreezeFrameBuffer[i], sizeof(FreezeFrameRecType)-sizeof(ChecksumType));
1339                 if ((cSum != priMemFreezeFrameBuffer[i].checksum) || (priMemFreezeFrameBuffer[i].eventId == DEM_EVENT_ID_NULL)) {
1340                         // Unlegal record, clear the record
1341                         setZero(&priMemFreezeFrameBuffer[i], sizeof(FreezeFrameRecType));
1342                 }
1343         }
1344
1345         /*
1346          *  Handle errors stored in temporary buffer (if any)
1347          */
1348
1349         // Transfer updated event data to event memory
1350         for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {
1351                 if (eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) {
1352                         // Update the event memory
1353                         lookupEventIdParameter(eventStatusBuffer[i].eventId, &eventParam);
1354                         storeEventEvtMem(eventParam, &eventStatusBuffer[i]);
1355                 }
1356         }
1357
1358         // Transfer extended data to event memory if necessary
1359         for (i = 0; i < DEM_MAX_NUMBER_EXT_DATA_PRE_INIT; i++) {
1360                 if (preInitExtDataBuffer[i].eventId !=  DEM_EVENT_ID_NULL) {
1361                         lookupEventIdParameter(preInitExtDataBuffer[i].eventId, &eventParam);
1362                         storeExtendedDataEvtMem(eventParam, &preInitExtDataBuffer[i]);
1363                 }
1364         }
1365
1366         // Transfer freeze frames to event memory
1367         for (i = 0; i < DEM_MAX_NUMBER_FF_DATA_PRE_INIT; i++) {
1368                 if (preInitFreezeFrameBuffer[i].eventId != DEM_EVENT_ID_NULL) {
1369                         lookupEventIdParameter(preInitFreezeFrameBuffer[i].eventId, &eventParam);
1370                         storeFreezeFrameDataEvtMem(eventParam, &preInitFreezeFrameBuffer[i]);
1371                 }
1372         }
1373
1374         // Init the dtc filter
1375         dtcFilter.dtcStatusMask = DEM_DTC_STATUS_MASK_ALL;                                      // All allowed
1376         dtcFilter.dtcKind = DEM_DTC_KIND_ALL_DTCS;                                                      // All kinds of DTCs
1377         dtcFilter.dtcOrigin = DEM_DTC_ORIGIN_PRIMARY_MEMORY;                            // Primary memory
1378         dtcFilter.filterWithSeverity = DEM_FILTER_WITH_SEVERITY_NO;                     // No Severity filtering
1379         dtcFilter.dtcSeverityMask = DEM_SEVERITY_NO_SEVERITY;                           // Not used when filterWithSeverity is FALSE
1380         dtcFilter.filterForFaultDetectionCounter = DEM_FILTER_FOR_FDC_NO;       // No fault detection counter filtering
1381
1382         dtcFilter.faultIndex = DEM_MAX_NUMBER_EVENT;
1383
1384         disableDtcStorage.storageDisabled = FALSE;
1385
1386         demState = DEM_INITIALIZED;
1387 }
1388
1389
1390 /*
1391  * Procedure:   Dem_shutdown
1392  * Reentrant:   No
1393  */
1394 void Dem_Shutdown(void)
1395 {
1396         setOperationCycleState(DEM_ACTIVE, DEM_CYCLE_STATE_END);
1397
1398         demState = DEM_UNINITIALIZED;
1399 }
1400
1401
1402 /*
1403  * Interface for basic software scheduler
1404  */
1405 void Dem_MainFunction(void)
1406 {
1407
1408 }
1409
1410
1411 /***************************************************
1412  * Interface SW-Components via RTE <-> DEM (8.3.3) *
1413  ***************************************************/
1414
1415 /*
1416  * Procedure:   Dem_SetEventStatus
1417  * Reentrant:   Yes
1418  */
1419 Std_ReturnType Dem_SetEventStatus(Dem_EventIdType eventId, Dem_EventStatusType eventStatus)
1420 {
1421         Std_ReturnType returnCode = E_OK;
1422
1423         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1424         {
1425                 returnCode = handleEvent(eventId, eventStatus);
1426         }
1427         else
1428         {
1429 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1430                 Det_ReportError(MODULE_ID_DEM, 0, DEM_SETEVENTSTATUS_ID, DEM_E_UNINIT);
1431                 returnCode = E_NOT_OK;
1432 #endif
1433         }
1434
1435         return returnCode;
1436 }
1437
1438
1439 /*
1440  * Procedure:   Dem_ResetEventStatus
1441  * Reentrant:   Yes
1442  */
1443 Std_ReturnType Dem_ResetEventStatus(Dem_EventIdType eventId)
1444 {
1445         const Dem_EventParameterType *eventParam;
1446         EventStatusRecType eventStatusLocal;
1447         Std_ReturnType returnCode = E_OK;
1448
1449         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1450         {
1451                 lookupEventIdParameter(eventId, &eventParam);
1452                 if (eventParam != NULL) {
1453                         updateEventStatusRec(eventParam, DEM_EVENT_STATUS_PASSED, FALSE, &eventStatusLocal);
1454                 }
1455         }
1456         else
1457         {
1458 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1459                 Det_ReportError(MODULE_ID_DEM, 0, DEM_RESETEVENTSTATUS_ID, DEM_E_UNINIT);
1460 #endif
1461                 returnCode = E_NOT_OK;
1462         }
1463
1464         return returnCode;
1465 }
1466
1467
1468 /*
1469  * Procedure:   Dem_GetEventStatus
1470  * Reentrant:   Yes
1471  */
1472 Std_ReturnType Dem_GetEventStatus(Dem_EventIdType eventId, Dem_EventStatusExtendedType *eventStatusExtended)
1473 {
1474         Std_ReturnType returnCode = E_OK;
1475
1476         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1477         {
1478                 getEventStatus(eventId, eventStatusExtended);
1479         }
1480         else
1481         {
1482 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1483                 Det_ReportError(MODULE_ID_DEM, 0, DEM_GETEVENTSTATUS_ID, DEM_E_UNINIT);
1484 #endif
1485                 returnCode = E_NOT_OK;
1486         }
1487
1488         return returnCode;
1489 }
1490
1491
1492 /*
1493  * Procedure:   Dem_GetEventFailed
1494  * Reentrant:   Yes
1495  */
1496 Std_ReturnType Dem_GetEventFailed(Dem_EventIdType eventId, boolean *eventFailed)
1497 {
1498         Std_ReturnType returnCode = E_OK;
1499
1500         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1501         {
1502                 getEventFailed(eventId, eventFailed);
1503         }
1504         else
1505         {
1506 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1507                 Det_ReportError(MODULE_ID_DEM, 0, DEM_GETEVENTFAILED_ID, DEM_E_UNINIT);
1508 #endif
1509                 returnCode = E_NOT_OK;
1510         }
1511
1512         return returnCode;
1513 }
1514
1515
1516 /*
1517  * Procedure:   Dem_GetEventTested
1518  * Reentrant:   Yes
1519  */
1520 Std_ReturnType Dem_GetEventTested(Dem_EventIdType eventId, boolean *eventTested)
1521 {
1522         Std_ReturnType returnCode = E_OK;
1523
1524         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1525         {
1526                 getEventTested(eventId, eventTested);
1527         }
1528         else
1529         {
1530 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1531                 Det_ReportError(MODULE_ID_DEM, 0, DEM_GETEVENTTESTED_ID, DEM_E_UNINIT);
1532 #endif
1533                 returnCode = E_NOT_OK;
1534         }
1535
1536         return returnCode;
1537 }
1538
1539
1540 /*
1541  * Procedure:   Dem_GetFaultDetectionCounter
1542  * Reentrant:   No
1543  */
1544 Std_ReturnType Dem_GetFaultDetectionCounter(Dem_EventIdType eventId, sint8 *counter)
1545 {
1546         Std_ReturnType returnCode = E_OK;
1547
1548         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1549         {
1550                 returnCode = getFaultDetectionCounter(eventId, counter);
1551         }
1552         else
1553         {
1554 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1555                 Det_ReportError(MODULE_ID_DEM, 0, DEM_GETFAULTDETECTIONCOUNTER_ID, DEM_E_UNINIT);
1556 #endif
1557                 returnCode = E_NOT_OK;
1558         }
1559
1560         return returnCode;
1561 }
1562
1563
1564 /*
1565  * Procedure:   Dem_SetOperationCycleState
1566  * Reentrant:   No
1567  */
1568 Std_ReturnType Dem_SetOperationCycleState(Dem_OperationCycleIdType operationCycleId, Dem_OperationCycleStateType cycleState)
1569 {
1570         Std_ReturnType returnCode = E_OK;
1571
1572         if (demState == DEM_INITIALIZED) // No action is taken if the module is not started
1573         {
1574                 returnCode = setOperationCycleState(operationCycleId, cycleState);
1575
1576         }
1577         else
1578         {
1579 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1580                 Det_ReportError(MODULE_ID_DEM, 0, DEM_SETOPERATIONCYCLESTATE_ID, DEM_E_UNINIT);
1581 #endif
1582                 returnCode = E_NOT_OK;
1583         }
1584
1585         return returnCode;
1586 }
1587
1588
1589 /*
1590  * Procedure:   Dem_GetDTCOfEvent
1591  * Reentrant:   Yes
1592  */
1593 Std_ReturnType Dem_GetDTCOfEvent(Dem_EventIdType eventId, Dem_DTCKindType dtcKind, uint32* dtcOfEvent)
1594 {
1595         Std_ReturnType returnCode = E_NO_DTC_AVAILABLE;
1596         const Dem_EventParameterType *eventParam;
1597
1598         lookupEventIdParameter(eventId, &eventParam);
1599
1600         if (eventParam != NULL) {
1601                 if (checkDtcKind(dtcKind, eventParam)) {
1602                         if (eventParam->DTCClassRef != NULL) {
1603                                 *dtcOfEvent = eventParam->DTCClassRef->DTC;
1604                                 returnCode = E_OK;
1605                         }
1606                 }
1607         }
1608         else {
1609                 // Event Id not found
1610                 returnCode = E_NOT_OK;
1611         }
1612
1613         return returnCode;
1614 }
1615
1616
1617 /********************************************
1618  * Interface BSW-Components <-> DEM (8.3.4) *
1619  ********************************************/
1620
1621 /*
1622  * Procedure:   Dem_ReportErrorStatus
1623  * Reentrant:   Yes
1624  */
1625 void Dem_ReportErrorStatus( Dem_EventIdType eventId, Dem_EventStatusType eventStatus )
1626 {
1627
1628         switch (demState) {
1629                 case DEM_PREINITIALIZED:
1630                         // Update status and check if is to be stored
1631                         if ((eventStatus == DEM_EVENT_STATUS_PASSED) || (eventStatus == DEM_EVENT_STATUS_FAILED)) {
1632                                 handlePreInitEvent(eventId, eventStatus);
1633                         }
1634                         break;
1635
1636                 case DEM_INITIALIZED:
1637                         // Handle report
1638                         if ((eventStatus == DEM_EVENT_STATUS_PASSED) || (eventStatus == DEM_EVENT_STATUS_FAILED)) {
1639                                 (void)handleEvent(eventId, eventStatus);
1640                         }
1641                         break;
1642
1643                 case DEM_UNINITIALIZED:
1644                 default:
1645                         // Uninitialized can not do anything
1646 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1647                         Det_ReportError(MODULE_ID_DEM, 0, DEM_REPORTERRORSTATUS_ID, DEM_E_UNINIT);
1648 #endif
1649                         break;
1650
1651         } // switch (demState)
1652 }
1653
1654 /*********************************
1655  * Interface DCM <-> DEM (8.3.5) *
1656  *********************************/
1657 /*
1658  * Procedure:   Dem_GetDTCStatusAvailabilityMask
1659  * Reentrant:   No
1660  */
1661 Std_ReturnType Dem_GetDTCStatusAvailabilityMask(uint8 *dtcStatusMask)
1662 {
1663         *dtcStatusMask =        DEM_DTC_STATUS_AVAILABILITY_MASK;               // User configuration mask
1664         *dtcStatusMask &=       DEM_TEST_FAILED                                                 // Mask with supported bits
1665                                                 | DEM_TEST_FAILED_THIS_OPERATION_CYCLE
1666                                                 | DEM_PENDING_DTC
1667 //                                              | DEM_CONFIRMED_DTC                                     TODO: Add support for this bit
1668                                                 | DEM_TEST_NOT_COMPLETED_SINCE_LAST_CLEAR
1669                                                 | DEM_TEST_FAILED_SINCE_LAST_CLEAR
1670                                                 | DEM_TEST_NOT_COMPLETED_THIS_OPERATION_CYCLE
1671 //                                              | DEM_WARNING_INDICATOR_REQUESTED       TODO: Add support for this bit
1672                                                 ;
1673
1674         return E_OK;
1675 }
1676
1677
1678 /*
1679  * Procedure:   Dem_SetDTCFilter
1680  * Reentrant:   No
1681  */
1682 Dem_ReturnSetDTCFilterType Dem_SetDTCFilter(uint8 dtcStatusMask,
1683                 Dem_DTCKindType dtcKind,
1684                 Dem_DTCOriginType dtcOrigin,
1685                 Dem_FilterWithSeverityType filterWithSeverity,
1686                 Dem_DTCSeverityType dtcSeverityMask,
1687                 Dem_FilterForFDCType filterForFaultDetectionCounter) {
1688
1689         Dem_ReturnSetDTCFilterType returnCode = DEM_WRONG_FILTER;
1690
1691         // Check dtcKind parameter
1692         if ((dtcKind == DEM_DTC_KIND_ALL_DTCS) || (dtcKind ==  DEM_DTC_KIND_EMISSON_REL_DTCS)) {
1693
1694                 // Check dtcOrigin parameter
1695                 if ((dtcOrigin == DEM_DTC_ORIGIN_SECONDARY_MEMORY) || (dtcOrigin == DEM_DTC_ORIGIN_PRIMARY_MEMORY)
1696                         || (dtcOrigin == DEM_DTC_ORIGIN_PERMANENT_MEMORY) || (dtcOrigin == DEM_DTC_ORIGIN_MIRROR_MEMORY)) {
1697
1698                         // Check filterWithSeverity and dtcSeverityMask parameter
1699                         if ((filterWithSeverity == DEM_FILTER_WITH_SEVERITY_NO)
1700                                 || ((filterWithSeverity == DEM_FILTER_WITH_SEVERITY_YES) && !(dtcSeverityMask & ~(DEM_SEVERITY_MAINTENANCE_ONLY | DEM_SEVERITY_CHECK_AT_NEXT_FALT | DEM_SEVERITY_CHECK_IMMEDIATELY)))){
1701
1702                                 // Check filterForFaultDetectionCounter parameter
1703                                 if ((filterForFaultDetectionCounter == DEM_FILTER_FOR_FDC_YES) || (filterForFaultDetectionCounter ==  DEM_FILTER_FOR_FDC_NO)) {
1704                                         // Yes all parameters correct, set the new filters.
1705                                         dtcFilter.dtcStatusMask = dtcStatusMask;
1706                                         dtcFilter.dtcKind = dtcKind;
1707                                         dtcFilter.dtcOrigin = dtcOrigin;
1708                                         dtcFilter.filterWithSeverity = filterWithSeverity;
1709                                         dtcFilter.dtcSeverityMask = dtcSeverityMask;
1710                                         dtcFilter.filterForFaultDetectionCounter = filterForFaultDetectionCounter;
1711                                         dtcFilter.faultIndex = DEM_MAX_NUMBER_EVENT;
1712                                         returnCode = DEM_FILTER_ACCEPTED;
1713                                 }
1714                         }
1715                 }
1716         }
1717
1718         return returnCode;
1719 }
1720
1721
1722 /*
1723  * Procedure:   Dem_GetStatusOfDTC
1724  * Reentrant:   No
1725  */
1726 Dem_ReturnGetStatusOfDTCType Dem_GetStatusOfDTC(uint32 dtc, Dem_DTCKindType dtcKind, Dem_DTCOriginType dtcOrigin, Dem_EventStatusExtendedType* status) {
1727         Dem_ReturnGetStatusOfDTCType returnCode = DEM_STATUS_FAILED;
1728         EventStatusRecType *eventRec;
1729
1730         if (lookupDtcEvent(dtc, &eventRec)) {
1731                 if (checkDtcKind(dtcKind, eventRec->eventParamRef)) {
1732                         if (checkDtcOrigin(dtcOrigin,eventRec->eventParamRef)) {
1733                                 *status = eventRec->eventStatusExtended;
1734                                 returnCode = DEM_STATUS_OK;
1735                         }
1736                         else {
1737                                 returnCode = DEM_STATUS_WRONG_DTCORIGIN;
1738                         }
1739                 }
1740                 else {
1741                         returnCode = DEM_STATUS_WRONG_DTCKIND;
1742                 }
1743         }
1744         else {
1745                 returnCode = DEM_STATUS_WRONG_DTC;
1746         }
1747
1748         return returnCode;
1749 }
1750
1751
1752 /*
1753  * Procedure:   Dem_GetNumberOfFilteredDtc
1754  * Reentrant:   No
1755  */
1756 Dem_ReturnGetNumberOfFilteredDTCType Dem_GetNumberOfFilteredDtc(uint16 *numberOfFilteredDTC) {
1757         uint16 i;
1758         uint16 numberOfFaults = 0;
1759
1760         //Dem_DisableEventStatusUpdate();
1761
1762         for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {
1763                 if (eventStatusBuffer[i].eventId != DEM_EVENT_ID_NULL) {
1764                         if (matchEventWithDtcFilter(&eventStatusBuffer[i])) {
1765                                 if (eventStatusBuffer[i].eventParamRef->DTCClassRef != NULL) {
1766                                         numberOfFaults++;
1767                                 }
1768                         }
1769                 }
1770         }
1771
1772         //Dem_EnableEventStatusUpdate();
1773
1774         *numberOfFilteredDTC = numberOfFaults;
1775
1776         return DEM_NUMBER_OK;
1777 }
1778
1779
1780 /*
1781  * Procedure:   Dem_GetNextFilteredDTC
1782  * Reentrant:   No
1783  */
1784 Dem_ReturnGetNextFilteredDTCType Dem_GetNextFilteredDTC(uint32 *dtc, Dem_EventStatusExtendedType *dtcStatus)
1785 {
1786         Dem_ReturnGetNextFilteredDTCType returnCode = DEM_FILTERED_OK;
1787         boolean dtcFound = FALSE;
1788
1789         // TODO: This job should be done in an more advanced way according to Dem288
1790         while (!dtcFound && (dtcFilter.faultIndex != 0)) {
1791                 dtcFilter.faultIndex--;
1792                 if (eventStatusBuffer[dtcFilter.faultIndex].eventId != DEM_EVENT_ID_NULL) {
1793                         if (matchEventWithDtcFilter(&eventStatusBuffer[dtcFilter.faultIndex])) {
1794                                 if (eventStatusBuffer[dtcFilter.faultIndex].eventParamRef->DTCClassRef != NULL) {
1795                                         *dtc = eventStatusBuffer[dtcFilter.faultIndex].eventParamRef->DTCClassRef->DTC;
1796                                         *dtcStatus = eventStatusBuffer[dtcFilter.faultIndex].eventStatusExtended;
1797                                         dtcFound = TRUE;
1798                                 }
1799                         }
1800                 }
1801         }
1802
1803         if (!dtcFound) {
1804                 dtcFilter.faultIndex = DEM_MAX_NUMBER_EVENT;
1805                 returnCode = DEM_FILTERED_NO_MATCHING_DTC;
1806         }
1807
1808         return returnCode;
1809 }
1810
1811
1812 /*
1813  * Procedure:   Dem_GetTranslationType
1814  * Reentrant:   No
1815  */
1816 Dem_ReturnTypeOfDtcSupportedType Dem_GetTranslationType(void)
1817 {
1818         return DEM_TYPE_OF_DTC_SUPPORTED;
1819 }
1820
1821
1822 /*
1823  * Procedure:   Dem_ClearDTC
1824  * Reentrant:   No
1825  */
1826 Dem_ReturnClearDTCType Dem_ClearDTC(uint32 dtc, Dem_DTCKindType dtcKind, Dem_DTCOriginType dtcOrigin)
1827 {
1828         Dem_ReturnClearDTCType returnCode = DEM_CLEAR_OK;
1829         Dem_EventIdType eventId;
1830         const Dem_EventParameterType *eventParam;
1831         uint16 i, j;
1832
1833         // Loop through the event buffer
1834         for (i = 0; i < DEM_MAX_NUMBER_EVENT; i++) {
1835                 eventId = eventStatusBuffer[i].eventId;
1836                 if (eventId != DEM_EVENT_ID_NULL) {
1837                         eventParam = eventStatusBuffer[i].eventParamRef;
1838                         if (eventParam != NULL) {
1839                                 if (DEM_CLEAR_ALL_EVENTS | (eventParam->DTCClassRef != NULL)) {
1840                                         if (checkDtcKind(dtcKind, eventParam)) {
1841                                                 if (checkDtcGroup(dtc, eventParam)) {
1842                                                         for (j = 0; (j < DEM_MAX_NR_OF_EVENT_DESTINATION) && (eventParam->EventClass->EventDestination[j] != dtcOrigin); j++);
1843                                                         if (j < DEM_MAX_NR_OF_EVENT_DESTINATION) {
1844                                                                 // Yes! All conditions met.
1845                                                                 switch (dtcOrigin)
1846                                                                 {
1847                                                                 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:
1848                                                                         deleteEventPriMem(eventParam);
1849                                                                         deleteFreezeFrameDataPriMem(eventParam);
1850                                                                         deleteExtendedDataPriMem(eventParam);
1851                                                                         deleteEventStatusRec(eventParam);               // TODO: Shall this be done or just resetting the status?
1852                                                                         break;
1853
1854                                                                 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:
1855                                                                 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:
1856                                                                 case DEM_DTC_ORIGIN_MIRROR_MEMORY:
1857                                                                         // Not yet supported
1858                                                                         returnCode = DEM_CLEAR_WRONG_DTCORIGIN;
1859 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1860                                                                         Det_ReportError(MODULE_ID_DEM, 0, DEM_CLEARDTC_ID, DEM_E_NOT_IMPLEMENTED_YET);
1861 #endif
1862                                                                         break;
1863                                                                 default:
1864                                                                         returnCode = DEM_CLEAR_WRONG_DTCORIGIN;
1865                                                                         break;
1866                                                                 }
1867                                                         }
1868                                                 }
1869                                         }
1870                                 }
1871                         }
1872                         else {
1873                                 // Fatal error, no event parameters found for the stored event!
1874 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1875                         Det_ReportError(MODULE_ID_DEM, 0, DEM_CLEARDTC_ID, DEM_E_UNEXPECTED_EXECUTION);
1876 #endif
1877                         }
1878                 }
1879         }
1880
1881         return returnCode;
1882 }
1883
1884
1885 /*
1886  * Procedure:   Dem_DisableDTCStorage
1887  * Reentrant:   No
1888  */
1889 Dem_ReturnControlDTCStorageType Dem_DisableDTCStorage(Dem_DTCGroupType dtcGroup, Dem_DTCKindType dtcKind)
1890 {
1891         Dem_ReturnControlDTCStorageType returnCode = DEM_CONTROL_DTC_STORAGE_N_OK;
1892
1893         // Check dtcGroup parameter
1894         if (dtcGroup == DEM_DTC_GROUP_ALL_DTCS) {
1895                 // Check dtcKind parameter
1896                 if ((dtcKind == DEM_DTC_KIND_ALL_DTCS) || (dtcKind ==  DEM_DTC_KIND_EMISSON_REL_DTCS)) {
1897                         disableDtcStorage.dtcGroup = dtcGroup;
1898                         disableDtcStorage.dtcKind = dtcKind;
1899                         disableDtcStorage.storageDisabled = TRUE;
1900
1901                         returnCode = DEM_CONTROL_DTC_STORAGE_OK;
1902                 }
1903         }
1904         else {
1905                 returnCode = DEM_CONTROL_DTC_WRONG_DTCGROUP;
1906         }
1907
1908         return returnCode;
1909 }
1910
1911
1912 /*
1913  * Procedure:   Dem_EnableDTCStorage
1914  * Reentrant:   No
1915  */
1916 Dem_ReturnControlDTCStorageType Dem_EnableDTCStorage(Dem_DTCGroupType dtcGroup, Dem_DTCKindType dtcKind)
1917 {
1918         // TODO: Behavior is not defined if group or kind do not match active settings, therefore the filter is just switched off.
1919         disableDtcStorage.storageDisabled = FALSE;
1920
1921         return DEM_CONTROL_DTC_STORAGE_OK;
1922 }
1923
1924 /*
1925  * Procedure:   Dem_GetExtendedDataRecordByDTC
1926  * Reentrant:   No
1927  */
1928 Dem_ReturnGetExtendedDataRecordByDTCType Dem_GetExtendedDataRecordByDTC(uint32 dtc, Dem_DTCKindType dtcKind, Dem_DTCOriginType dtcOrigin, uint8 extendedDataNumber, uint8 *destBuffer, uint8 *bufSize)
1929 {
1930         Dem_ReturnGetExtendedDataRecordByDTCType returnCode = DEM_RECORD_WRONG_DTC;
1931         EventStatusRecType *eventRec;
1932         Dem_ExtendedDataRecordClassType const *extendedDataRecordClass = NULL;
1933         ExtDataRecType *extData;
1934         uint8 posInExtData = 0;
1935
1936         if (lookupDtcEvent(dtc, &eventRec)) {
1937                 if (checkDtcKind(dtcKind, eventRec->eventParamRef)) {
1938                         if (checkDtcOrigin(dtcOrigin, eventRec->eventParamRef)) {
1939                                 if (lookupExtendedDataRecNumParam(extendedDataNumber, eventRec->eventParamRef, &extendedDataRecordClass, &posInExtData)) {
1940                                         if (*bufSize >= extendedDataRecordClass->DataSize) {
1941                                                 switch (dtcOrigin)
1942                                                 {
1943                                                 case DEM_DTC_ORIGIN_PRIMARY_MEMORY:
1944                                                         if (lookupExtendedDataPriMem(eventRec->eventId, &extData)) {
1945                                                                 // Yes all conditions met, copy the extended data record to destination buffer.
1946                                                                 memcpy(destBuffer, &extData->data[posInExtData], extendedDataRecordClass->DataSize);
1947                                                                 *bufSize = extendedDataRecordClass->DataSize;
1948                                                                 returnCode = DEM_RECORD_OK;
1949                                                         }
1950                                                         else {
1951                                                                 // The record number is legal but no record was found for the DTC
1952                                                                 *bufSize = 0;
1953                                                                 returnCode = DEM_RECORD_OK;
1954                                                         }
1955                                                         break;
1956
1957                                                 case DEM_DTC_ORIGIN_SECONDARY_MEMORY:
1958                                                 case DEM_DTC_ORIGIN_PERMANENT_MEMORY:
1959                                                 case DEM_DTC_ORIGIN_MIRROR_MEMORY:
1960                                                         // Not yet supported
1961                                                         returnCode = DEM_RECORD_WRONG_DTCORIGIN;
1962 #if (DEM_DEV_ERROR_DETECT == STD_ON)
1963                                                         Det_ReportError(MODULE_ID_DEM, 0, DEM_GETEXTENDEDDATARECORDBYDTC_ID, DEM_E_NOT_IMPLEMENTED_YET);
1964 #endif
1965                                                         break;
1966                                                 default:
1967                                                         returnCode = DEM_RECORD_WRONG_DTCORIGIN;
1968                                                         break;
1969                                                 }
1970                                         }
1971                                         else {
1972                                                 returnCode = DEM_RECORD_BUFFERSIZE;
1973                                         }
1974                                 }
1975                                 else {
1976                                         returnCode = DEM_RECORD_NUMBER;
1977                                 }
1978                         }
1979                         else {
1980                                 returnCode = DEM_RECORD_WRONG_DTCORIGIN;
1981                         }
1982                 }
1983                 else {
1984                         returnCode = DEM_RECORD_DTCKIND;
1985                 }
1986         }
1987
1988         return returnCode;
1989 }
1990
1991
1992 /*
1993  * Procedure:   Dem_GetSizeOfExtendedDataRecordByDTC
1994  * Reentrant:   No
1995  */
1996 Dem_ReturnGetSizeOfExtendedDataRecordByDTCType Dem_GetSizeOfExtendedDataRecordByDTC(uint32 dtc, Dem_DTCKindType dtcKind, Dem_DTCOriginType dtcOrigin, uint8 extendedDataNumber, uint16 *sizeOfExtendedDataRecord)
1997 {
1998         Dem_ReturnGetExtendedDataRecordByDTCType returnCode = DEM_GET_SIZEOFEDRBYDTC_W_DTC;
1999         EventStatusRecType *eventRec;
2000         Dem_ExtendedDataRecordClassType const *extendedDataRecordClass = NULL;
2001         uint8 posInExtData;
2002
2003         if (lookupDtcEvent(dtc, &eventRec)) {
2004                 if (checkDtcKind(dtcKind, eventRec->eventParamRef)) {
2005                         if (checkDtcOrigin(dtcOrigin, eventRec->eventParamRef)) {
2006                                 if (lookupExtendedDataRecNumParam(extendedDataNumber, eventRec->eventParamRef, &extendedDataRecordClass, &posInExtData)) {
2007                                         *sizeOfExtendedDataRecord = extendedDataRecordClass->DataSize;
2008                                         returnCode = DEM_GET_SIZEOFEDRBYDTC_OK;
2009                                 }
2010                                 else {
2011                                         returnCode = DEM_GET_SIZEOFEDRBYDTC_W_RNUM;
2012                                 }
2013                         }
2014                         else {
2015                                 returnCode = DEM_GET_SIZEOFEDRBYDTC_W_DTCOR;
2016                         }
2017                 }
2018                 else {
2019                         returnCode = DEM_GET_SIZEOFEDRBYDTC_W_DTCKI;
2020                 }
2021         }
2022
2023         return returnCode;
2024 }
2025
2026 /***********************************
2027  * OBD-specific Interfaces (8.3.6) *
2028  ***********************************/
2029
2030
2031