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