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