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