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