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