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