]> rtime.felk.cvut.cz Git - arc.git/blob - diagnostic/Dcm/Dcm_Dsp.c
Merged in from ticket-115
[arc.git] / diagnostic / Dcm / Dcm_Dsp.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 \r
17 \r
18 /*\r
19  *  General requirements\r
20  */\r
21 /** @req DCM273 */ /** @req DCM272 */\r
22 /** @req DCM039 */ /** @req DCM038 */ /** @req DCM269 */\r
23 /** @req DCM271 */ /** @req DCM274 */ /** @req DCM275 */ /** @req DCM424 */\r
24 /** @req DCM007 */\r
25 \r
26 #include <string.h>\r
27 #include "Dcm.h"\r
28 #include "Dcm_Internal.h"\r
29 #include "Dem.h"\r
30 #include "MemMap.h"\r
31 #include "Mcu.h"\r
32 \r
33 #define ZERO_SUB_FUNCTION                       0x00\r
34 \r
35 /*\r
36  * Macros\r
37  */\r
38 #define BYTES_TO_DTC(hb, mb, lb)        (((uint32)(hb) << 16) | ((uint32)(mb) << 8) | (uint32)(lb))\r
39 #define DTC_HIGH_BYTE(dtc)                      (((uint32)(dtc) >> 16) & 0xFF)\r
40 #define DTC_MID_BYTE(dtc)                       (((uint32)(dtc) >> 8) & 0xFF)\r
41 #define DTC_LOW_BYTE(dtc)                       ((uint32)(dtc) & 0xFF)\r
42 \r
43 \r
44 typedef struct {\r
45         boolean resetPending;\r
46         PduIdType resetPduId;\r
47 } DspUdsEcuResetDataType;\r
48 \r
49 static DspUdsEcuResetDataType dspUdsEcuResetData;\r
50 \r
51 \r
52 typedef struct {\r
53         boolean                                                 reqInProgress;\r
54         Dcm_SecLevelType                                reqSecLevel;\r
55         const Dcm_DspSecurityRowType    *reqSecLevelRef;\r
56 } DspUdsSecurityAccessDataType;\r
57 \r
58 static DspUdsSecurityAccessDataType dspUdsSecurityAccesData;\r
59 \r
60 \r
61 void DspInit(void)\r
62 {\r
63         dspUdsSecurityAccesData.reqInProgress = FALSE;\r
64         dspUdsEcuResetData.resetPending = FALSE;\r
65 }\r
66 \r
67 \r
68 void DspMain(void)\r
69 {\r
70 \r
71 }\r
72 \r
73 \r
74 boolean DspCheckSessionLevel(const Dcm_DspSessionRowType **sessionLevelRefTable)\r
75 {\r
76         boolean returnStatus = TRUE;\r
77         Dcm_SesCtrlType currentSession;\r
78 \r
79         DslGetSesCtrlType(&currentSession);\r
80         while (((*sessionLevelRefTable)->DspSessionLevel != currentSession) && !(*sessionLevelRefTable)->Arc_EOL) {\r
81                 sessionLevelRefTable++;\r
82         }\r
83 \r
84         if ((*sessionLevelRefTable)->Arc_EOL) {\r
85                 returnStatus = FALSE;\r
86         }\r
87 \r
88         return returnStatus;\r
89 }\r
90 \r
91 \r
92 boolean DspCheckSecurityLevel(const Dcm_DspSecurityRowType      **securityLevelRefTable)\r
93 {\r
94         boolean returnStatus = TRUE;\r
95         Dcm_SecLevelType currentSecurityLevel;\r
96 \r
97         DslGetSecurityLevel(&currentSecurityLevel);\r
98         while (((*securityLevelRefTable)->DspSecurityLevel != currentSecurityLevel) && !(*securityLevelRefTable)->Arc_EOL) {\r
99                 securityLevelRefTable++;\r
100         }\r
101         if ((*securityLevelRefTable)->Arc_EOL) {\r
102                 returnStatus = FALSE;\r
103         }\r
104 \r
105         return returnStatus;\r
106 }\r
107 \r
108 \r
109 static Std_ReturnType askApplicationForSessionPermission(Dcm_SesCtrlType newSessionLevel)\r
110 {\r
111         Std_ReturnType returnCode = E_OK;\r
112         const Dcm_DslSessionControlType *sesControl = DCM_Config.Dsl->DslSessionControl;\r
113         Dcm_SesCtrlType currentSessionLevel;\r
114         Std_ReturnType result;\r
115 \r
116         while (!sesControl->Arc_EOL && (returnCode != E_SESSION_NOT_ALLOWED)) {\r
117                 if (sesControl->GetSesChgPermission != NULL) {\r
118                         Dcm_GetSesCtrlType(&currentSessionLevel);\r
119                         result = sesControl->GetSesChgPermission(currentSessionLevel ,newSessionLevel);\r
120                         if (result != E_OK) {\r
121                                 returnCode = result;\r
122                         }\r
123                 }\r
124                 sesControl++;\r
125         }\r
126 \r
127         return returnCode;\r
128 }\r
129 \r
130 \r
131 void DspUdsDiagnosticSessionControl(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
132 {\r
133         /** @req DCM250 */\r
134         const Dcm_DspSessionRowType *sessionRow = DCM_Config.Dsp->DspSession->DspSessionRow;\r
135         Dcm_SesCtrlType reqSessionType;\r
136         Std_ReturnType result;\r
137 \r
138         if (pduRxData->SduLength == 2) {\r
139                 reqSessionType = pduRxData->SduDataPtr[1];\r
140                 // Check if type exist in session table\r
141                 while ((sessionRow->DspSessionLevel != reqSessionType) && !sessionRow->Arc_EOL) {\r
142                         sessionRow++;\r
143                 }\r
144 \r
145                 if (!sessionRow->Arc_EOL) {\r
146                         result = askApplicationForSessionPermission(reqSessionType);\r
147                         if (result == E_OK) {\r
148                                 DslSetSesCtrlType(reqSessionType);              /** @req DCM311 */\r
149                                 // Create positive response\r
150                                 pduTxData->SduDataPtr[1] = reqSessionType;\r
151                                 pduTxData->SduLength = 2;\r
152                                 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
153                         }\r
154                         else {\r
155                                 // TODO: Add handling of special case of E_FORCE_RCRRP (Dcm138)\r
156                                 DsdDspProcessingDone(DCM_E_CONDITIONSNOTCORRECT);       /** @req DCM308 */\r
157                         }\r
158                 }\r
159                 else {\r
160                         DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);    /** @req DCM307 */\r
161                 }\r
162         }\r
163         else {\r
164                 // Wrong length\r
165                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);\r
166         }\r
167 }\r
168 \r
169 \r
170 void DspUdsEcuReset(const PduInfoType *pduRxData, PduIdType txPduId, PduInfoType *pduTxData)\r
171 {\r
172         /** @req DCM260 */\r
173         uint8 reqResetType;\r
174 \r
175         if (pduRxData->SduLength == 2) {\r
176                 reqResetType = pduRxData->SduDataPtr[1];\r
177 \r
178                 switch (reqResetType)\r
179                 {\r
180                 case 0x01:      // Hard reset\r
181                         // TODO: Ask application for permission (Dcm373) (Dcm375) (Dcm377)\r
182 \r
183                         // Schedule the reset\r
184                         dspUdsEcuResetData.resetPending = TRUE;\r
185                         dspUdsEcuResetData.resetPduId = txPduId;\r
186 \r
187                         // Create positive response\r
188                         pduTxData->SduDataPtr[1] = reqResetType;\r
189                         pduTxData->SduLength = 2;\r
190                         DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
191                         break;\r
192 \r
193                 default:\r
194                         DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);\r
195                         break;\r
196                 }\r
197         }\r
198         else {\r
199                 // Wrong length\r
200                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);\r
201         }\r
202 }\r
203 \r
204 \r
205 void DspUdsClearDiagnosticInformation(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
206 {\r
207         /** @req DCM247 */\r
208         uint32 dtc;\r
209         Dem_ReturnClearDTCType result;\r
210 \r
211         if (pduRxData->SduLength == 4) {\r
212                 dtc = BYTES_TO_DTC(pduRxData->SduDataPtr[1], pduRxData->SduDataPtr[2], pduRxData->SduDataPtr[3]);\r
213 \r
214                 result = Dem_ClearDTC(dtc, DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY); /** @req DCM005 */\r
215 \r
216                 switch (result)\r
217                 {\r
218                 case DEM_CLEAR_OK:\r
219                         // Create positive response\r
220                         pduTxData->SduLength = 1;\r
221                         DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
222                         break;\r
223 \r
224                 default:\r
225                         DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);\r
226                         break;\r
227                 }\r
228         }\r
229         else {\r
230                 // Wrong length\r
231                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);\r
232         }\r
233 }\r
234 \r
235 \r
236 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x01_0x07_0x11_0x12(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
237 {\r
238         typedef struct {\r
239                 uint8           SID;\r
240                 uint8           reportType;\r
241                 uint8           dtcStatusAvailabilityMask;\r
242                 uint8           dtcFormatIdentifier;\r
243                 uint8           dtcCountHighByte;\r
244                 uint8           dtcCountLowByte;\r
245         } TxDataType;\r
246 \r
247         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
248         Dem_ReturnSetDTCFilterType setDtcFilterResult;\r
249 \r
250         // Setup the DTC filter\r
251         switch (pduRxData->SduDataPtr[1])       /** @req DCM293 */\r
252         {\r
253         case 0x01:      // reportNumberOfDTCByStatusMask\r
254                 setDtcFilterResult = Dem_SetDTCFilter(pduRxData->SduDataPtr[2], DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);\r
255                 break;\r
256 \r
257         case 0x07:      // reportNumberOfDTCBySeverityMaskRecord\r
258                 setDtcFilterResult = Dem_SetDTCFilter(pduRxData->SduDataPtr[3], DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_YES, pduRxData->SduDataPtr[2], DEM_FILTER_FOR_FDC_NO);\r
259                 break;\r
260 \r
261         case 0x11:      // reportNumberOfMirrorMemoryDTCByStatusMask\r
262                 setDtcFilterResult = Dem_SetDTCFilter(pduRxData->SduDataPtr[2], DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_MIRROR_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);\r
263                 break;\r
264 \r
265         case 0x12:      // reportNumberOfEmissionRelatedOBDDTCByStatusMask\r
266                 setDtcFilterResult = Dem_SetDTCFilter(pduRxData->SduDataPtr[2], DEM_DTC_KIND_EMISSION_REL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);\r
267                 break;\r
268 \r
269         default:\r
270                 setDtcFilterResult = DEM_WRONG_FILTER;\r
271                 break;\r
272         }\r
273 \r
274         if (setDtcFilterResult == DEM_FILTER_ACCEPTED) {\r
275                 uint16 numberOfFilteredDtc;\r
276                 uint8 dtcStatusMask;\r
277                 TxDataType *txData = (TxDataType*)pduTxData->SduDataPtr;\r
278 \r
279                 /** @req DCM376 */\r
280                 Dem_GetNumberOfFilteredDtc(&numberOfFilteredDtc);\r
281                 Dem_GetDTCStatusAvailabilityMask(&dtcStatusMask);\r
282 \r
283                 // Create positive response (ISO 14229-1 table 251)\r
284                 txData->reportType = pduRxData->SduDataPtr[1];                                          // reportType\r
285                 txData->dtcStatusAvailabilityMask = dtcStatusMask;                                      // DTCStatusAvailabilityMask\r
286                 txData->dtcFormatIdentifier = Dem_GetTranslationType();                         // DTCFormatIdentifier\r
287                 txData->dtcCountHighByte = (numberOfFilteredDtc >> 8);                          // DTCCount high byte\r
288                 txData->dtcCountLowByte = (numberOfFilteredDtc & 0xFF);                         // DTCCount low byte\r
289                 pduTxData->SduLength = 6;\r
290         }\r
291         else {\r
292                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
293         }\r
294 \r
295         return responseCode;\r
296 }\r
297 \r
298 \r
299 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x02_0x0A_0x0F_0x13_0x15(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
300 {\r
301         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
302         Dem_ReturnSetDTCFilterType setDtcFilterResult;\r
303 \r
304         typedef struct {\r
305                 uint8           dtcHighByte;\r
306                 uint8           dtcMiddleByte;\r
307                 uint8           dtcLowByte;\r
308                 uint8           statusOfDtc;\r
309         } dtcAndStatusRecordType;\r
310 \r
311         typedef struct {\r
312                 uint8                                   SID;\r
313                 uint8                                   reportType;\r
314                 uint8                                   dtcStatusAvailabilityMask;\r
315                 dtcAndStatusRecordType  dtcAndStatusRecord[];\r
316         } TxDataType;\r
317 \r
318         // Setup the DTC filter\r
319         switch (pduRxData->SduDataPtr[1])       /** @req DCM378 */\r
320         {\r
321         case 0x02:      // reportDTCByStatusMask\r
322                 setDtcFilterResult = Dem_SetDTCFilter(pduRxData->SduDataPtr[2], DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);\r
323                 break;\r
324 \r
325         case 0x0A:      // reportSupportedDTC\r
326                 setDtcFilterResult = Dem_SetDTCFilter(DEM_DTC_STATUS_MASK_ALL, DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);\r
327                 break;\r
328 \r
329         case 0x0F:      // reportMirrorMemoryDTCByStatusMask\r
330                 setDtcFilterResult = Dem_SetDTCFilter(pduRxData->SduDataPtr[2], DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_MIRROR_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);\r
331                 break;\r
332 \r
333         case 0x13:      // reportEmissionRelatedOBDDTCByStatusMask\r
334                 setDtcFilterResult = Dem_SetDTCFilter(pduRxData->SduDataPtr[2], DEM_DTC_KIND_EMISSION_REL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);\r
335                 break;\r
336 \r
337         case 0x15:      // reportDTCWithPermanentStatus\r
338                 setDtcFilterResult = Dem_SetDTCFilter(DEM_DTC_STATUS_MASK_ALL, DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PERMANENT_MEMORY, DEM_FILTER_WITH_SEVERITY_NO, VALUE_IS_NOT_USED, DEM_FILTER_FOR_FDC_NO);\r
339                 break;\r
340 \r
341         default:\r
342                 setDtcFilterResult = DEM_WRONG_FILTER;\r
343                 break;\r
344         }\r
345 \r
346         if (setDtcFilterResult == DEM_FILTER_ACCEPTED) {\r
347                 uint8 dtcStatusMask;\r
348                 TxDataType *txData = (TxDataType*)pduTxData->SduDataPtr;\r
349                 Dem_ReturnGetNextFilteredDTCType getNextFilteredDtcResult;\r
350                 uint32 dtc;\r
351                 Dem_EventStatusExtendedType dtcStatus;\r
352                 uint16 nrOfDtcs = 0;\r
353 \r
354                 /** @req DCM377 */\r
355                 Dem_GetDTCStatusAvailabilityMask(&dtcStatusMask);\r
356 \r
357                 // Create positive response (ISO 14229-1 table 252)\r
358                 txData->reportType = pduRxData->SduDataPtr[1];\r
359                 txData->dtcStatusAvailabilityMask = dtcStatusMask;\r
360 \r
361                 if (dtcStatusMask != 0x00) {    /** @req DCM008 */\r
362                         getNextFilteredDtcResult = Dem_GetNextFilteredDTC(&dtc, &dtcStatus);\r
363                         while (getNextFilteredDtcResult == DEM_FILTERED_OK) {\r
364                                 txData->dtcAndStatusRecord[nrOfDtcs].dtcHighByte = DTC_HIGH_BYTE(dtc);\r
365                                 txData->dtcAndStatusRecord[nrOfDtcs].dtcMiddleByte = DTC_MID_BYTE(dtc);\r
366                                 txData->dtcAndStatusRecord[nrOfDtcs].dtcLowByte = DTC_LOW_BYTE(dtc);\r
367                                 txData->dtcAndStatusRecord[nrOfDtcs].statusOfDtc = dtcStatus;\r
368                                 nrOfDtcs++;\r
369                                 getNextFilteredDtcResult = Dem_GetNextFilteredDTC(&dtc, &dtcStatus);\r
370                         }\r
371 \r
372                         if (getNextFilteredDtcResult != DEM_FILTERED_NO_MATCHING_DTC) {\r
373                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
374                         }\r
375                 }\r
376                 pduTxData->SduLength = 3 + nrOfDtcs * sizeof(dtcAndStatusRecordType);\r
377         }\r
378         else {\r
379                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
380         }\r
381 \r
382         return responseCode;\r
383 }\r
384 \r
385 \r
386 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x08(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
387 {\r
388         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
389 \r
390         // TODO: Not supported yet, (DEM module does not currently support severity).\r
391         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
392 \r
393         return responseCode;\r
394 }\r
395 \r
396 \r
397 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x09(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
398 {\r
399         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
400 \r
401         // TODO: Not supported yet, (DEM module does not currently support severity).\r
402         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
403 \r
404         return responseCode;\r
405 }\r
406 \r
407 \r
408 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x06_0x10(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
409 {\r
410         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
411         Dem_DTCOriginType dtcOrigin = NULL;\r
412         uint8 startRecNum;\r
413         uint8 endRecNum;\r
414 \r
415         // Switch on sub function\r
416         switch (pduRxData->SduDataPtr[1])       /** @req DCM378 */\r
417         {\r
418         case 0x06:      // reportDTCExtendedDataRecordByDTCNumber\r
419                 dtcOrigin = DEM_DTC_ORIGIN_PRIMARY_MEMORY;\r
420                 break;\r
421 \r
422         case 0x10:      // reportMirrorMemoryDTCExtendedDataRecordByDTCNumber\r
423                 dtcOrigin = DEM_DTC_ORIGIN_MIRROR_MEMORY;\r
424                 break;\r
425 \r
426         default:\r
427                 responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;\r
428                 break;\r
429         }\r
430 \r
431         // Switch on record number\r
432         switch (pduRxData->SduDataPtr[5])\r
433         {\r
434         case 0xFF:      // Report all Extended Data Records for a particular DTC\r
435                 startRecNum = 0x00;\r
436                 endRecNum = 0xEF;\r
437                 break;\r
438 \r
439         case 0xFE:      // Report all OBD Extended Data Records for a particular DTC\r
440                 startRecNum = 0x90;\r
441                 endRecNum = 0xEF;\r
442                 break;\r
443 \r
444         default:        // Report one specific Extended Data Records for a particular DTC\r
445                 startRecNum = pduRxData->SduDataPtr[5];\r
446                 endRecNum = startRecNum;\r
447                 break;\r
448         }\r
449 \r
450         if (responseCode == DCM_E_POSITIVERESPONSE) {\r
451                 Dem_ReturnGetStatusOfDTCType getStatusOfDtcResult;\r
452                 uint32 dtc;\r
453                 Dem_EventStatusExtendedType statusOfDtc;\r
454 \r
455                 dtc = BYTES_TO_DTC(pduRxData->SduDataPtr[2], pduRxData->SduDataPtr[3], pduRxData->SduDataPtr[4]);\r
456                 getStatusOfDtcResult = Dem_GetStatusOfDTC(dtc, DEM_DTC_KIND_ALL_DTCS, dtcOrigin, &statusOfDtc); /** @req DCM295 */ /** @req DCM475 */\r
457                 if (getStatusOfDtcResult == DEM_STATUS_OK) {\r
458                         Dem_ReturnGetExtendedDataRecordByDTCType getExtendedDataRecordByDtcResult;\r
459                         uint16 recNum;\r
460                         uint8 recLength;\r
461                         uint16 txIndex = 6;\r
462 \r
463                         /** @req DCM297 */ /** @req DCM474 */ /** @req DCM386 */\r
464                         pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1];                    // Sub function\r
465                         pduTxData->SduDataPtr[2] = DTC_HIGH_BYTE(dtc);                                  // DTC high byte\r
466                         pduTxData->SduDataPtr[3] = DTC_MID_BYTE(dtc);                                   // DTC mid byte\r
467                         pduTxData->SduDataPtr[4] = DTC_LOW_BYTE(dtc);                                   // DTC low byte\r
468                         pduTxData->SduDataPtr[5] = statusOfDtc;                                                 // DTC status\r
469                         for (recNum = startRecNum; recNum <= endRecNum; recNum++) {\r
470                                 recLength = pduTxData->SduLength - txIndex -1;  // Calculate what's left in buffer\r
471                                 /** @req DCM296 */ /** @req DCM476 */ /** @req DCM382 */\r
472                                 getExtendedDataRecordByDtcResult = Dem_GetExtendedDataRecordByDTC(dtc, DEM_DTC_KIND_ALL_DTCS, dtcOrigin, recNum, &pduTxData->SduDataPtr[txIndex+1], &recLength);\r
473                                 if (getExtendedDataRecordByDtcResult == DEM_RECORD_OK) {\r
474                                         pduTxData->SduDataPtr[txIndex++] = recNum;\r
475                                         /* Instead of calling Dem_GetSizeOfExtendedDataRecordByDTC() the result from Dem_GetExtendedDataRecordByDTC() is used */\r
476                                         /** @req DCM478 */ /** @req DCM479 */ /** @req DCM480 */\r
477                                         txIndex += recLength;\r
478                                 }\r
479                                 else {\r
480                                         // TODO: What to do here?\r
481                                 }\r
482                         }\r
483                         pduTxData->SduLength = txIndex;\r
484                 }\r
485                 else {\r
486                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
487                 }\r
488         }\r
489 \r
490         return responseCode;\r
491 }\r
492 \r
493 \r
494 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x03(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
495 {\r
496         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
497 \r
498         // TODO: Not supported yet\r
499         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
500 \r
501         return responseCode;\r
502 }\r
503 \r
504 \r
505 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x04(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
506 {\r
507         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
508 \r
509         // TODO: Not supported yet\r
510         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
511 \r
512         return responseCode;\r
513 }\r
514 \r
515 \r
516 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x05(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
517 {\r
518         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
519 \r
520         // TODO: Not supported yet\r
521         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
522 \r
523         return responseCode;\r
524 }\r
525 \r
526 \r
527 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x0B_0x0C_0x0D_0x0E(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
528 {\r
529         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
530 \r
531         // TODO: Not supported yet\r
532         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
533 \r
534         return responseCode;\r
535 }\r
536 \r
537 \r
538 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x14(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
539 {\r
540         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
541 \r
542         // TODO: Not supported yet\r
543         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
544 \r
545         return responseCode;\r
546 }\r
547 \r
548 \r
549 void DspUdsReadDtcInformation(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
550 {\r
551         /** @req DCM248 */\r
552         // Sub function number         0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F 10 11 12 13 14 15\r
553         const uint8 sduLength[0x16] = {0, 3, 3, 6, 6, 3, 6, 4, 4, 5, 2, 2, 2, 2, 2, 3, 6, 3, 3, 3, 2, 2};\r
554 \r
555         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
556 \r
557         uint8 subFunctionNumber = pduRxData->SduDataPtr[1];\r
558 \r
559         // Check length\r
560         if (subFunctionNumber <= 0x15) {\r
561                 if (pduRxData->SduLength == sduLength[subFunctionNumber]) {\r
562                         switch (subFunctionNumber)\r
563                         {\r
564                         case 0x01:      // reportNumberOfDTCByStatusMask\r
565                         case 0x07:      // reportNumberOfDTCBySeverityMaskRecord\r
566                         case 0x11:      // reportNumberOfMirrorMemoryDTCByStatusMask\r
567                         case 0x12:      // reportNumberOfEmissionRelatedOBDDTCByStatusMask\r
568                                 responseCode = udsReadDtcInfoSub_0x01_0x07_0x11_0x12(pduRxData, pduTxData);\r
569                                 break;\r
570 \r
571                         case 0x02:      // reportDTCByStatusMask\r
572                         case 0x0A:      // reportSupportedDTC\r
573                         case 0x0F:      // reportMirrorMemoryDTCByStatusMask\r
574                         case 0x13:      // reportEmissionRelatedOBDDTCByStatusMask\r
575                         case 0x15:      // reportDTCWithPermanentStatus\r
576                                 responseCode = udsReadDtcInfoSub_0x02_0x0A_0x0F_0x13_0x15(pduRxData, pduTxData);\r
577                                 break;\r
578 \r
579                         case 0x08:      // reportDTCBySeverityMaskRecord\r
580                                 responseCode = udsReadDtcInfoSub_0x08(pduRxData, pduTxData);\r
581                                 break;\r
582 \r
583                         case 0x09:      // reportSeverityInformationOfDTC\r
584                                 responseCode = udsReadDtcInfoSub_0x09(pduRxData, pduTxData);\r
585                                 break;\r
586 \r
587                         case 0x06:      // reportDTCExtendedDataRecordByDTCNumber\r
588                         case 0x10:      // reportMirrorMemoryDTCExtendedDataRecordByDTCNumber\r
589                                 responseCode = udsReadDtcInfoSub_0x06_0x10(pduRxData, pduTxData);\r
590                                 break;\r
591 \r
592                         case 0x03:      // reportDTCSnapshotIdentidication\r
593                                 responseCode = udsReadDtcInfoSub_0x03(pduRxData, pduTxData);\r
594                                 break;\r
595 \r
596                         case 0x04:      // reportDTCSnapshotByDtcNumber\r
597                                 responseCode = udsReadDtcInfoSub_0x04(pduRxData, pduTxData);\r
598                                 break;\r
599 \r
600                         case 0x05:      // reportDTCSnapshotRecordNumber\r
601                                 responseCode = udsReadDtcInfoSub_0x05(pduRxData, pduTxData);\r
602                                 break;\r
603 \r
604                         case 0x0B:      // reportFirstTestFailedDTC\r
605                         case 0x0C:      // reportFirstConfirmedDTC\r
606                         case 0x0D:      // reportMostRecentTestFailedDTC\r
607                         case 0x0E:      // reportMostRecentConfirmedDTC\r
608                                 responseCode = udsReadDtcInfoSub_0x0B_0x0C_0x0D_0x0E(pduRxData, pduTxData);\r
609                                 break;\r
610 \r
611                         case 0x14:      // reportDTCFaultDetectionCounter\r
612                                 responseCode = udsReadDtcInfoSub_0x14(pduRxData, pduTxData);\r
613                                 break;\r
614 \r
615                         default:\r
616                                 // Unknown sub function\r
617                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
618                                 break;\r
619                         }\r
620                 }\r
621                 else {\r
622                         // Wrong length\r
623                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
624                 }\r
625         }\r
626         else {\r
627                 // Sub function out of range\r
628                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
629         }\r
630 \r
631         DsdDspProcessingDone(responseCode);\r
632 }\r
633 \r
634 \r
635 static boolean lookupDid(uint16 didNr, const Dcm_DspDidType **didPtr)\r
636 {\r
637         const Dcm_DspDidType *dspDid = DCM_Config.Dsp->DspDid;\r
638         boolean didFound = FALSE;\r
639 \r
640         while ((dspDid->DspDidIdentifier != didNr) &&  !dspDid->Arc_EOL) {\r
641                 dspDid++;\r
642         }\r
643 \r
644         if (!dspDid->Arc_EOL) {\r
645                 didFound = TRUE;\r
646                 *didPtr = dspDid;\r
647         }\r
648 \r
649         return didFound;\r
650 }\r
651 \r
652 \r
653 static Dcm_NegativeResponseCodeType readDidData(const Dcm_DspDidType *didPtr, PduInfoType *pduTxData, uint16 *txPos)\r
654 {\r
655         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
656 \r
657         if ((didPtr->DspDidInfoRef->DspDidAccess.DspDidRead != NULL) && (didPtr->DspDidConditionCheckReadFnc != NULL) && (didPtr->DspDidReadDataFnc != NULL)) { /** @req DCM433 */\r
658                 if (DspCheckSessionLevel(didPtr->DspDidInfoRef->DspDidAccess.DspDidRead->DspDidReadSessionRef)) { /** @req DCM434 */\r
659                         if (DspCheckSecurityLevel(didPtr->DspDidInfoRef->DspDidAccess.DspDidRead->DspDidReadSecurityLevelRef)) { /** @req DCM435 */\r
660                                 Std_ReturnType result;\r
661                                 Dcm_NegativeResponseCodeType errorCode;\r
662                                 result = didPtr->DspDidConditionCheckReadFnc(&errorCode);\r
663                                 if ((result == E_OK) && (errorCode == DCM_E_POSITIVERESPONSE)) {        /** @req DCM439 */\r
664                                         uint16 didLen;\r
665                                         result = E_NOT_OK;\r
666                                         if (didPtr->DspDidInfoRef->DspDidFixedLength) { /** @req DCM436 */\r
667                                                 didLen = didPtr->DspDidSize;\r
668                                                 result = E_OK;\r
669                                         }\r
670                                         else {\r
671                                                 if (didPtr->DspDidReadDataLengthFnc != NULL) {\r
672                                                         result = didPtr->DspDidReadDataLengthFnc(&didLen);\r
673                                                 }\r
674                                         }\r
675 \r
676                                         if (result == E_OK) {\r
677                                                 // Now ready for reading the data!\r
678                                                 if ((*txPos + didLen + 2) <= pduTxData->SduLength) {\r
679                                                         pduTxData->SduDataPtr[*txPos] = (didPtr->DspDidIdentifier >> 8) & 0xFF;\r
680                                                         (*txPos)++;\r
681                                                         pduTxData->SduDataPtr[*txPos] = (didPtr->DspDidIdentifier >> 0) & 0xFF;\r
682                                                         (*txPos)++;\r
683                                                         result = didPtr->DspDidReadDataFnc(&pduTxData->SduDataPtr[*txPos]);     /** @req DCM437 */\r
684                                                         *txPos += didLen;\r
685 \r
686                                                         if (result != E_OK) {\r
687                                                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
688                                                         }\r
689                                                 }\r
690                                                 else { // tx buffer full\r
691                                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
692                                                 }\r
693                                         }\r
694                                         else {  // Not possible to obtain did length\r
695                                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
696                                         }\r
697                                 }\r
698                                 else {  // CheckRead failed\r
699                                         responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
700                                 }\r
701                         }\r
702                         else {  // Not allowed in current security level\r
703                                 responseCode = DCM_E_SECUTITYACCESSDENIED;\r
704                         }\r
705                 }\r
706                 else {  // Not allowed in current session\r
707                         responseCode = DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION;\r
708                 }\r
709         }\r
710         else {  // Read access not configured\r
711                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
712         }\r
713 \r
714         if (responseCode == DCM_E_POSITIVERESPONSE) {\r
715                 // Recurse trough the rest of the dids.         /** @req DCM440 */\r
716                 uint16 i;\r
717                 for (i=0; (!didPtr->DspDidRef[i]->Arc_EOL) && (responseCode == DCM_E_POSITIVERESPONSE); i++) {\r
718                         responseCode = readDidData(didPtr->DspDidRef[i], pduTxData, txPos);\r
719                 }\r
720         }\r
721 \r
722         return responseCode;\r
723 }\r
724 \r
725 void DspUdsReadDataByIdentifier(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
726 {\r
727         /** @req DCM253 */\r
728         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
729         uint8 nrOfDids;\r
730         uint16 didNr;\r
731         const Dcm_DspDidType *didPtr = NULL;\r
732 \r
733         uint16 txPos = 1;\r
734         uint16 i;\r
735 \r
736         if ((pduRxData->SduLength - 1) % 2 == 0 ) {\r
737                 nrOfDids = (pduRxData->SduLength - 1) / 2;\r
738 \r
739                 for (i = 0; (i < nrOfDids) && (responseCode == DCM_E_POSITIVERESPONSE); i++) {\r
740                         didNr = (pduRxData->SduDataPtr[1+i*2] << 8) + pduRxData->SduDataPtr[2+i*2];\r
741                         if (lookupDid(didNr, &didPtr)) {        /** @req DCM438 */\r
742                                 responseCode = readDidData(didPtr, pduTxData, &txPos);\r
743                         }\r
744                         else { // DID not found\r
745                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
746                         }\r
747                 }\r
748         }\r
749         else {\r
750                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
751         }\r
752 \r
753         if (responseCode == DCM_E_POSITIVERESPONSE) {\r
754                 pduTxData->SduLength = txPos;\r
755         }\r
756 \r
757         DsdDspProcessingDone(responseCode);\r
758 }\r
759 \r
760 \r
761 static Dcm_NegativeResponseCodeType readDidScalingData(const Dcm_DspDidType *didPtr, PduInfoType *pduTxData, uint16 *txPos)\r
762 {\r
763         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
764 \r
765         if (didPtr->DspDidGetScalingInfoFnc != NULL) {\r
766                 uint16 scalingInfoLen;\r
767 \r
768                 scalingInfoLen = didPtr->DspDidInfoRef->DspDidScalingInfoSize;\r
769                 if ((*txPos + scalingInfoLen + 2) <= pduTxData->SduLength) {\r
770                         Std_ReturnType result;\r
771                         Dcm_NegativeResponseCodeType errorCode;\r
772 \r
773                         pduTxData->SduDataPtr[*txPos] = (didPtr->DspDidIdentifier >> 8) & 0xFF;\r
774                         (*txPos)++;\r
775                         pduTxData->SduDataPtr[*txPos] = (didPtr->DspDidIdentifier >> 0) & 0xFF;\r
776                         (*txPos)++;\r
777                         result = didPtr->DspDidGetScalingInfoFnc(&pduTxData->SduDataPtr[*txPos], &errorCode);   /** @req DCM394 */\r
778                         *txPos += scalingInfoLen;\r
779 \r
780                         if ((result != E_OK) || (errorCode != DCM_E_POSITIVERESPONSE)) {\r
781                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
782                         }\r
783                 }\r
784                 else { // tx buffer full\r
785                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
786                 }\r
787         }\r
788         else {  // DspDidGetScalingInfoFnc null pointer\r
789                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
790         }\r
791 \r
792         return responseCode;\r
793 }\r
794 \r
795 void DspUdsReadScalingDataByIdentifier(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
796 {\r
797         /** @req DCM258 */\r
798         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
799         uint16 didNr;\r
800         const Dcm_DspDidType *didPtr = NULL;\r
801 \r
802         uint16 txPos = 1;\r
803 \r
804         if (pduRxData->SduLength == 3) {\r
805                 didNr = (pduRxData->SduDataPtr[1] << 8) + pduRxData->SduDataPtr[2];\r
806                 if (lookupDid(didNr, &didPtr)) {\r
807                         responseCode = readDidScalingData(didPtr, pduTxData, &txPos);\r
808                 }\r
809                 else { // DID not found\r
810                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
811                 }\r
812 \r
813                 if (responseCode == DCM_E_POSITIVERESPONSE) {\r
814                         pduTxData->SduLength = txPos;\r
815                 }\r
816         }\r
817         else {\r
818                 // Length not ok\r
819                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
820         }\r
821 \r
822         DsdDspProcessingDone(responseCode);\r
823 }\r
824 \r
825 \r
826 static Dcm_NegativeResponseCodeType writeDidData(const Dcm_DspDidType *didPtr, const PduInfoType *pduRxData, uint16 writeDidLen)\r
827 {\r
828         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
829 \r
830         if ((didPtr->DspDidInfoRef->DspDidAccess.DspDidWrite != NULL) && (didPtr->DspDidConditionCheckWriteFnc != NULL) && (didPtr->DspDidWriteDataFnc != NULL)) {      /** @req DCM468 */\r
831                 if (DspCheckSessionLevel(didPtr->DspDidInfoRef->DspDidAccess.DspDidWrite->DspDidWriteSessionRef)) { /** @req DCM469 */\r
832                         if (DspCheckSecurityLevel(didPtr->DspDidInfoRef->DspDidAccess.DspDidWrite->DspDidWriteSecurityLevelRef)) { /** @req DCM470 */\r
833                                 Std_ReturnType result;\r
834                                 Dcm_NegativeResponseCodeType errorCode;\r
835                                 result = didPtr->DspDidConditionCheckWriteFnc(&errorCode);      /** @req DCM471 */\r
836                                 if ((result == E_OK) && (errorCode == DCM_E_POSITIVERESPONSE)) {\r
837                                         uint16 didLen;\r
838                                         result = E_NOT_OK;\r
839                                         if (didPtr->DspDidInfoRef->DspDidFixedLength) { /** @req DCM472 */\r
840                                                 didLen = didPtr->DspDidSize;\r
841                                                 result = E_OK;\r
842                                         }\r
843                                         else {\r
844                                                 if (didPtr->DspDidReadDataLengthFnc != NULL) {\r
845                                                         result = didPtr->DspDidReadDataLengthFnc(&didLen);\r
846                                                 }\r
847                                         }\r
848 \r
849                                         if (result == E_OK) {\r
850                                                 if (didLen == writeDidLen) {    /** @req DCM473 */\r
851                                                         result = didPtr->DspDidWriteDataFnc(&pduRxData->SduDataPtr[3], didLen, &errorCode);     /** @req DCM395 */\r
852                                                         if ((result != E_OK) || (errorCode != DCM_E_POSITIVERESPONSE)) {\r
853                                                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
854                                                         }\r
855                                                 }\r
856                                                 else {\r
857                                                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
858                                                 }\r
859                                         }\r
860                                         else {  // Not possible to obtain did length\r
861                                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
862                                         }\r
863                                 }\r
864                                 else {  // CheckRead failed\r
865                                         responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
866                                 }\r
867                         }\r
868                         else {  // Not allowed in current security level\r
869                                 responseCode = DCM_E_SECUTITYACCESSDENIED;\r
870                         }\r
871                 }\r
872                 else {  // Not allowed in current session\r
873                         responseCode = DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION;\r
874                 }\r
875         }\r
876         else {  // Read access not configured\r
877                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
878         }\r
879 \r
880         return responseCode;\r
881 }\r
882 \r
883 void DspUdsWriteDataByIdentifier(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
884 {\r
885         /** @req DCM255 */\r
886         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
887         uint16 didNr;\r
888         const Dcm_DspDidType *didPtr = NULL;\r
889 \r
890         uint16 didDataLength;\r
891 \r
892         didDataLength = pduRxData->SduLength - 3;\r
893         didNr = (pduRxData->SduDataPtr[1] << 8) + pduRxData->SduDataPtr[2];\r
894         if (lookupDid(didNr, &didPtr)) {        /** @req DCM467 */\r
895                 responseCode = writeDidData(didPtr, pduRxData, didDataLength);\r
896         }\r
897         else { // DID not found\r
898                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
899         }\r
900 \r
901         if (responseCode == DCM_E_POSITIVERESPONSE) {\r
902                 pduTxData->SduLength = 3;\r
903                 pduTxData->SduDataPtr[1] = (didNr >> 8) & 0xFF;\r
904                 pduTxData->SduDataPtr[2] = (didNr >> 0) & 0xFF;\r
905         }\r
906 \r
907         DsdDspProcessingDone(responseCode);\r
908 }\r
909 \r
910 \r
911 void DspUdsSecurityAccess(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
912 {\r
913         /** @req DCM252 */\r
914         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
915 \r
916         // Check sub function range (0x01 to 0x42)\r
917         if ((pduRxData->SduDataPtr[1] >= 0x01) && (pduRxData->SduDataPtr[1] <= 0x42)) {\r
918                 boolean isRequestSeed = pduRxData->SduDataPtr[1] & 0x01;\r
919                 Dcm_SecLevelType requestedSecurityLevel = (pduRxData->SduDataPtr[1]-1)/2;\r
920                 Dcm_NegativeResponseCodeType getSeedErrorCode;\r
921 \r
922                 if (isRequestSeed) {\r
923                         // requestSeed message\r
924                         // Check if type exist in security table\r
925                         const Dcm_DspSecurityRowType *securityRow = &DCM_Config.Dsp->DspSecurity->DspSecurityRow[0];\r
926                         while ((securityRow->DspSecurityLevel != requestedSecurityLevel) && !securityRow->Arc_EOL) {\r
927                                 securityRow++;\r
928                         }\r
929                         if (!securityRow->Arc_EOL) {\r
930                                 // Check length\r
931                                 if (pduRxData->SduLength == (2 + securityRow->DspSecurityADRSize)) {    /** @req DCM321.RequestSeed */\r
932                                         Dcm_SecLevelType activeSecLevel;\r
933                                         Dcm_GetSecurityLevel(&activeSecLevel);\r
934                                         if (requestedSecurityLevel == activeSecLevel) {         /** @req DCM323 */\r
935                                                 pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1];\r
936                                                 // If same level set the seed to zeroes\r
937                                                 memset(&pduTxData->SduDataPtr[2], 0, securityRow->DspSecuritySeedSize);\r
938                                                 pduTxData->SduLength = 2 + securityRow->DspSecuritySeedSize;\r
939                                         }\r
940                                         else {\r
941                                                 // New security level ask for seed\r
942                                                 if (securityRow->GetSeed != NULL) {\r
943                                                         Std_ReturnType getSeedResult;\r
944                                                         getSeedResult = securityRow->GetSeed(&pduRxData->SduDataPtr[2], &pduTxData->SduDataPtr[2], &getSeedErrorCode); /** @req DCM324.RequestSeed */\r
945                                                         if ((getSeedResult == E_OK) && (getSeedErrorCode == E_OK)) {\r
946                                                                 // Everything ok add sub function to tx message and send it.\r
947                                                                 pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1];\r
948                                                                 pduTxData->SduLength = 2 + securityRow->DspSecuritySeedSize;\r
949 \r
950                                                                 dspUdsSecurityAccesData.reqSecLevel = requestedSecurityLevel;\r
951                                                                 dspUdsSecurityAccesData.reqSecLevelRef = securityRow;\r
952                                                                 dspUdsSecurityAccesData.reqInProgress = TRUE;\r
953                                                         }\r
954                                                         else {\r
955                                                                 // GetSeed returned not ok\r
956                                                                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
957                                                         }\r
958                                                 } else {\r
959                                                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
960                                                 }\r
961                                         }\r
962                                 }\r
963                                 else {\r
964                                         // Length not ok\r
965                                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
966                                 }\r
967                         }\r
968                         else {\r
969                                 // Requested security level not configured\r
970                                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
971                         }\r
972                 }\r
973                 else {\r
974                         // sendKey message\r
975                         if (dspUdsSecurityAccesData.reqInProgress) {\r
976                                 if (pduRxData->SduLength == (2 + dspUdsSecurityAccesData.reqSecLevelRef->DspSecurityKeySize)) { /** @req DCM321.SendKey */\r
977                                         if (requestedSecurityLevel == dspUdsSecurityAccesData.reqSecLevel) {\r
978                                                 if (dspUdsSecurityAccesData.reqSecLevelRef->CompareKey != NULL) {\r
979                                                         Std_ReturnType compareKeyResult;\r
980                                                         compareKeyResult = dspUdsSecurityAccesData.reqSecLevelRef->CompareKey(&pduRxData->SduDataPtr[2]); /** @req DCM324.SendKey */\r
981                                                         if (compareKeyResult == E_OK) {\r
982                                                                 // Request accepted\r
983                                                                 // Kill timer\r
984                                                                 DslSetSecurityLevel(dspUdsSecurityAccesData.reqSecLevelRef->DspSecurityLevel); /** @req DCM325 */\r
985                                                                 dspUdsSecurityAccesData.reqInProgress = FALSE;\r
986                                                                 pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1];\r
987                                                                 pduTxData->SduLength = 2;\r
988                                                         }\r
989                                                         else {\r
990                                                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
991                                                         }\r
992                                                 } else {\r
993                                                         responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
994                                                 }\r
995                                         }\r
996                                         else {\r
997                                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
998                                         }\r
999                                 }\r
1000                                 else {\r
1001                                         // Length not ok\r
1002                                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
1003                                 }\r
1004                         }\r
1005                         else {\r
1006                                 // sendKey request without a preceding requestSeed\r
1007                                 responseCode = DCM_E_REQUESTSEQUENCEERROR;\r
1008                         }\r
1009                 }\r
1010         }\r
1011         else {\r
1012                 responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;\r
1013         }\r
1014 \r
1015         DsdDspProcessingDone(responseCode);\r
1016 }\r
1017 \r
1018 \r
1019 void DspUdsTesterPresent(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
1020 {\r
1021         /** @req DCM251 */\r
1022         if (pduRxData->SduLength == 2) {\r
1023                 switch (pduRxData->SduDataPtr[1])\r
1024                 {\r
1025                 case ZERO_SUB_FUNCTION:\r
1026                         DslResetSessionTimeoutTimer();\r
1027                         // Create positive response\r
1028                         pduTxData->SduDataPtr[1] = ZERO_SUB_FUNCTION;\r
1029                         pduTxData->SduLength = 2;\r
1030                         DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
1031                         break;\r
1032 \r
1033                 default:\r
1034                         DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);\r
1035                         break;\r
1036                 }\r
1037         }\r
1038         else {\r
1039                 // Wrong length\r
1040                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);\r
1041         }\r
1042 }\r
1043 \r
1044 \r
1045 void DspUdsControlDtcSetting(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
1046 {\r
1047         /** @req DCM249 */\r
1048         Dem_ReturnControlDTCStorageType resultCode;\r
1049 \r
1050         if (pduRxData->SduLength == 2) {\r
1051                 switch (pduRxData->SduDataPtr[1])\r
1052                 {\r
1053                 case 0x01:      // ON\r
1054                         resultCode = Dem_EnableDTCStorage(DEM_DTC_GROUP_ALL_DTCS, DEM_DTC_KIND_ALL_DTCS);               /** @req DCM304 */\r
1055                         if (resultCode == DEM_CONTROL_DTC_STORAGE_OK) {\r
1056                                 pduTxData->SduDataPtr[1] = 0x01;\r
1057                                 pduTxData->SduLength = 2;\r
1058                                 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
1059                         }\r
1060                         else {\r
1061                                 DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);\r
1062                         }\r
1063                         break;\r
1064 \r
1065                 case 0x02:      // OFF\r
1066                         resultCode = Dem_DisableDTCStorage(DEM_DTC_GROUP_ALL_DTCS, DEM_DTC_KIND_ALL_DTCS);              /** @req DCM406 */\r
1067                         if (resultCode == DEM_CONTROL_DTC_STORAGE_OK) {\r
1068                                 pduTxData->SduDataPtr[1] = 0x02;\r
1069                                 pduTxData->SduLength = 2;\r
1070                                 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
1071                         }\r
1072                         else {\r
1073                                 DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);\r
1074                         }\r
1075                         break;\r
1076 \r
1077                 default:\r
1078                         DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);\r
1079                         break;\r
1080                 }\r
1081         }\r
1082         else {\r
1083                 // Wrong length\r
1084                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);\r
1085         }\r
1086 }\r
1087 \r
1088 \r
1089 void DspDcmConfirmation(PduIdType confirmPduId)\r
1090 {\r
1091         if (dspUdsEcuResetData.resetPending) {\r
1092                 if (confirmPduId == dspUdsEcuResetData.resetPduId) {\r
1093                         dspUdsEcuResetData.resetPending = FALSE;\r
1094 #if ( MCU_PERFORM_RESET_API == STD_ON )\r
1095                         Mcu_PerformReset();\r
1096 #else\r
1097                         DET_REPORTERROR(MODULE_ID_DCM, 0, DCM_UDS_RESET_ID, DCM_E_NOT_SUPPORTED);\r
1098 #endif\r
1099                 }\r
1100         }\r
1101 }\r
1102 \r
1103 \r
1104 \r