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