]> rtime.felk.cvut.cz Git - arc.git/blob - diagnostic/Dcm/Dcm_Dsp.c
Divided Dcm file into Dcm, Dcm_Dsp, Dcm_Dsd and Dcm_Dsl.
[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 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 Std_ReturnType AskApplicationForSessionPermission(Dcm_SesCtrlType newSessionLevel)\r
68 {\r
69         Std_ReturnType returnCode = E_OK;\r
70         Dcm_SesCtrlType currentSessionLevel;\r
71         Std_ReturnType result;\r
72         uint16 i;\r
73 \r
74         for (i = 0; !DCM_Config.Dsl->DslSessionControl[i].Arc_EOL && (returnCode != E_SESSION_NOT_ALLOWED); i++) {\r
75                 if (DCM_Config.Dsl->DslSessionControl[i].GetSesChgPermission != NULL) {\r
76                         Dcm_GetSesCtrlType(&currentSessionLevel);\r
77                         result = DCM_Config.Dsl->DslSessionControl[i].GetSesChgPermission(currentSessionLevel ,newSessionLevel);\r
78                         if (result != E_OK) {\r
79                                 returnCode = result;\r
80                         }\r
81                 }\r
82         }\r
83 \r
84         return returnCode;\r
85 }\r
86 \r
87 \r
88 void DspUdsDiagnosticSessionControl(void)\r
89 {\r
90         // @req DCM250 **/\r
91         Dcm_SesCtrlType reqSessionType;\r
92         Std_ReturnType result;\r
93         uint16  i;\r
94 \r
95         if (dslMsgData.pduRxData->SduLength == 2) {\r
96                 reqSessionType = dslMsgData.pduRxData->SduDataPtr[1];\r
97                 // Check if type exist in session table\r
98                 for (i = 0; (DCM_Config.Dsp->DspSession->DspSessionRow[i].DspSessionLevel != reqSessionType) && !DCM_Config.Dsp->DspSession->DspSessionRow[i].Arc_EOL;i++);\r
99 \r
100                 if (!DCM_Config.Dsp->DspSession->DspSessionRow[i].Arc_EOL) {\r
101                         result = AskApplicationForSessionPermission(reqSessionType);\r
102                         if (result == E_OK) {\r
103                                 DslSetSesCtrlType(reqSessionType);              /** @req DCM311 **/\r
104                                 // Create positive response\r
105                                 /** @req DCM039.2 **/\r
106                                 dslMsgData.pduTxData->SduDataPtr[1] = reqSessionType;\r
107                                 dslMsgData.pduTxData->SduLength = 2;\r
108                                 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE); /** @req DCM269.2 **/\r
109                         }\r
110                         else {\r
111                                 // TODO: Add handling of special case of E_FORCE_RCRRP (Dcm138)\r
112                                 DsdDspProcessingDone(DCM_E_CONDITIONSNOTCORRECT);       /** @req DCM308 **/\r
113                         }\r
114                 }\r
115                 else {\r
116                         DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);    /** @req DCM307 **/\r
117                 }\r
118         }\r
119         else {\r
120                 // Wrong length\r
121                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);      /** @req DCM272.1 **/\r
122         }\r
123 }\r
124 \r
125 \r
126 void DspUdsEcuReset(void)\r
127 {\r
128         // @req DCM260 **/\r
129         uint8 reqResetType;\r
130 \r
131         if (dslMsgData.pduRxData->SduLength == 2) {\r
132                 reqResetType = dslMsgData.pduRxData->SduDataPtr[1];\r
133 \r
134                 switch (reqResetType)\r
135                 {\r
136                 case 0x01:      // Hard reset\r
137                         // TODO: Ask application for permission (Dcm373) (Dcm375) (Dcm377)\r
138 \r
139                         // Schedule the reset\r
140                         dspUdsEcuResetData.resetPending = TRUE;\r
141                         dspUdsEcuResetData.resetPduId = DCM_PDU_ID_UDS_TX;\r
142 \r
143                         // Create positive response\r
144                         /** @req DCM039.1 **/\r
145                         dslMsgData.pduTxData->SduDataPtr[1] = reqResetType;\r
146                         dslMsgData.pduTxData->SduLength = 2;\r
147                         DsdDspProcessingDone(DCM_E_POSITIVERESPONSE); /** @req DCM269.3 **/\r
148                         break;\r
149 \r
150                 default:\r
151                         DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);    /** @req DCM273.3 **/\r
152                         break;\r
153                 }\r
154         }\r
155         else {\r
156                 // Wrong length\r
157                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);      /** @req DCM272.3 **/\r
158         }\r
159 }\r
160 \r
161 \r
162 void DspUdsClearDiagnosticInformation(void)\r
163 {\r
164         uint32 dtc;\r
165         Dem_ReturnClearDTCType result;\r
166 \r
167         if (dslMsgData.pduRxData->SduLength == 4) {\r
168                 dtc = BYTES_TO_DTC(dslMsgData.pduRxData->SduDataPtr[1], dslMsgData.pduRxData->SduDataPtr[2], dslMsgData.pduRxData->SduDataPtr[3]);\r
169 \r
170                 result = Dem_ClearDTC(dtc, DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY);\r
171 \r
172                 switch (result)\r
173                 {\r
174                 case DEM_CLEAR_OK:\r
175                         // Create positive response\r
176                         /** @req DCM039.1 **/\r
177                         dslMsgData.pduTxData->SduLength = 1;\r
178                         DsdDspProcessingDone(DCM_E_POSITIVERESPONSE); /** @req DCM269.4 **/\r
179                         break;\r
180 \r
181                 default:\r
182                         DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);\r
183                         break;\r
184                 }\r
185         }\r
186         else {\r
187                 // Wrong length\r
188                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);      /** @req DCM272.1 **/\r
189         }\r
190 }\r
191 \r
192 \r
193 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x01_0x07_0x11_0x12(void)\r
194 {\r
195         typedef struct {\r
196                 uint8           SID;\r
197                 uint8           reportType;\r
198                 uint8           dtcStatusAvailabilityMask;\r
199                 uint8           dtcFormatIdentifier;\r
200                 uint8           dtcCountHighByte;\r
201                 uint8           dtcCountLowByte;\r
202         } TxDataType;\r
203 \r
204         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
205         Dem_ReturnSetDTCFilterType setDtcFilterResult;\r
206 \r
207         // Setup the DTC filter\r
208         switch (dslMsgData.pduRxData->SduDataPtr[1])    /** @reg DCM293 **/\r
209         {\r
210         case 0x01:      // reportNumberOfDTCByStatusMask\r
211                 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.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
212                 break;\r
213 \r
214         case 0x07:      // reportNumberOfDTCBySeverityMaskRecord\r
215                 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.pduRxData->SduDataPtr[3], DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY, DEM_FILTER_WITH_SEVERITY_YES, dslMsgData.pduRxData->SduDataPtr[2], DEM_FILTER_FOR_FDC_NO);\r
216                 break;\r
217 \r
218         case 0x11:      // reportNumberOfMirrorMemoryDTCByStatusMask\r
219                 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.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
220                 break;\r
221 \r
222         case 0x12:      // reportNumberOfEmissionRelatedOBDDTCByStatusMask\r
223                 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.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
224                 break;\r
225 \r
226         default:\r
227                 setDtcFilterResult = DEM_WRONG_FILTER;\r
228 #if (DCM_DEV_ERROR_DETECT == STD_ON)\r
229                 Det_ReportError(MODULE_ID_DCM, 0, DCM_UDS_READ_DTC_INFO, DCM_E_UNEXPECTED_PARAM);\r
230 #endif\r
231                 break;\r
232         }\r
233 \r
234         if (setDtcFilterResult == DEM_FILTER_ACCEPTED) {\r
235                 uint16 numberOfFilteredDtc;\r
236                 uint8 dtcStatusMask;\r
237                 TxDataType *txData = (TxDataType*)dslMsgData.pduTxData->SduDataPtr;\r
238 \r
239                 /** @reg DCM376 **/\r
240                 Dem_GetNumberOfFilteredDtc(&numberOfFilteredDtc);\r
241                 Dem_GetDTCStatusAvailabilityMask(&dtcStatusMask);\r
242 \r
243                 // Create positive response (ISO 14229-1 table 251)\r
244                 /** @req DCM039.0x19 **/\r
245                 txData->reportType = dslMsgData.pduRxData->SduDataPtr[1];                       // reportType\r
246                 txData->dtcStatusAvailabilityMask = dtcStatusMask;                                      // DTCStatusAvailabilityMask\r
247                 txData->dtcFormatIdentifier = Dem_GetTranslationType();                         // DTCFormatIdentifier\r
248                 txData->dtcCountHighByte = (numberOfFilteredDtc >> 8);                          // DTCCount high byte\r
249                 txData->dtcCountLowByte = (numberOfFilteredDtc & 0xFF);                         // DTCCount low byte\r
250                 dslMsgData.pduTxData->SduLength = 6;\r
251         }\r
252         else {\r
253                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
254         }\r
255 \r
256         return responseCode;\r
257 }\r
258 \r
259 \r
260 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x02_0x0A_0x0F_0x13_0x15(void)\r
261 {\r
262         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
263         Dem_ReturnSetDTCFilterType setDtcFilterResult;\r
264 \r
265         typedef struct {\r
266                 uint8           dtcHighByte;\r
267                 uint8           dtcMiddleByte;\r
268                 uint8           dtcLowByte;\r
269                 uint8           statusOfDtc;\r
270         } dtcAndStatusRecordType;\r
271 \r
272         typedef struct {\r
273                 uint8                                   SID;\r
274                 uint8                                   reportType;\r
275                 uint8                                   dtcStatusAvailabilityMask;\r
276                 dtcAndStatusRecordType  dtcAndStatusRecord[];\r
277         } TxDataType;\r
278 \r
279         // Setup the DTC filter\r
280         switch (dslMsgData.pduRxData->SduDataPtr[1])    /** @reg DCM378 **/\r
281         {\r
282         case 0x02:      // reportDTCByStatusMask\r
283                 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.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
284                 break;\r
285 \r
286         case 0x0A:      // reportSupportedDTC\r
287                 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
288                 break;\r
289 \r
290         case 0x0F:      // reportMirrorMemoryDTCByStatusMask\r
291                 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.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
292                 break;\r
293 \r
294         case 0x13:      // reportEmissionRelatedOBDDTCByStatusMask\r
295                 setDtcFilterResult = Dem_SetDTCFilter(dslMsgData.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
296                 break;\r
297 \r
298         case 0x15:      // reportDTCWithPermanentStatus\r
299                 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
300                 break;\r
301 \r
302         default:\r
303                 setDtcFilterResult = DEM_WRONG_FILTER;\r
304 #if (DCM_DEV_ERROR_DETECT == STD_ON)\r
305                 Det_ReportError(MODULE_ID_DCM, 0, DCM_UDS_READ_DTC_INFO, DCM_E_UNEXPECTED_PARAM);\r
306 #endif\r
307                 break;\r
308         }\r
309 \r
310         if (setDtcFilterResult == DEM_FILTER_ACCEPTED) {\r
311                 uint8 dtcStatusMask;\r
312                 TxDataType *txData = (TxDataType*)dslMsgData.pduTxData->SduDataPtr;\r
313                 Dem_ReturnGetNextFilteredDTCType getNextFilteredDtcResult;\r
314                 uint32 dtc;\r
315                 Dem_EventStatusExtendedType dtcStatus;\r
316                 uint16 nrOfDtcs = 0;\r
317 \r
318                 /** @reg DCM377 **/\r
319                 Dem_GetDTCStatusAvailabilityMask(&dtcStatusMask);\r
320 \r
321                 // Create positive response (ISO 14229-1 table 252)\r
322                 /** @req DCM039.0x19 **/\r
323                 txData->reportType = dslMsgData.pduRxData->SduDataPtr[1];\r
324                 txData->dtcStatusAvailabilityMask = dtcStatusMask;\r
325 \r
326                 if (dtcStatusMask != 0x00) {    /** @req DCM008 **/\r
327                         getNextFilteredDtcResult = Dem_GetNextFilteredDTC(&dtc, &dtcStatus);\r
328                         while (getNextFilteredDtcResult == DEM_FILTERED_OK) {\r
329                                 txData->dtcAndStatusRecord[nrOfDtcs].dtcHighByte = DTC_HIGH_BYTE(dtc);\r
330                                 txData->dtcAndStatusRecord[nrOfDtcs].dtcMiddleByte = DTC_MID_BYTE(dtc);\r
331                                 txData->dtcAndStatusRecord[nrOfDtcs].dtcLowByte = DTC_LOW_BYTE(dtc);\r
332                                 txData->dtcAndStatusRecord[nrOfDtcs].statusOfDtc = dtcStatus;\r
333                                 nrOfDtcs++;\r
334                                 getNextFilteredDtcResult = Dem_GetNextFilteredDTC(&dtc, &dtcStatus);\r
335                         }\r
336 \r
337                         if (getNextFilteredDtcResult != DEM_FILTERED_NO_MATCHING_DTC) {\r
338                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
339                         }\r
340                 }\r
341                 dslMsgData.pduTxData->SduLength = 3 + nrOfDtcs * sizeof(dtcAndStatusRecordType);\r
342         }\r
343         else {\r
344                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
345         }\r
346 \r
347         return responseCode;\r
348 }\r
349 \r
350 \r
351 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x08(void)\r
352 {\r
353         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
354 \r
355         // TODO: Not supported yet, (DEM module does not currently support severity).\r
356         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
357 \r
358         return responseCode;\r
359 }\r
360 \r
361 \r
362 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x09(void)\r
363 {\r
364         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
365 \r
366         // TODO: Not supported yet, (DEM module does not currently support severity).\r
367         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
368 \r
369         return responseCode;\r
370 }\r
371 \r
372 \r
373 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x06_0x10(void)\r
374 {\r
375         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
376         Dem_DTCOriginType dtcOrigin;\r
377         uint8 startRecNum;\r
378         uint8 endRecNum;\r
379 \r
380         // Switch on sub function\r
381         switch (dslMsgData.pduRxData->SduDataPtr[1])    /** @reg DCM378 **/\r
382         {\r
383         case 0x06:      // reportDTCExtendedDataRecordByDTCNumber\r
384                 dtcOrigin = DEM_DTC_ORIGIN_PRIMARY_MEMORY;\r
385                 break;\r
386 \r
387         case 0x10:      // reportMirrorMemoryDTCExtendedDataRecordByDTCNumber\r
388                 dtcOrigin = DEM_DTC_ORIGIN_MIRROR_MEMORY;\r
389                 break;\r
390 \r
391         default:\r
392                 responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;\r
393 #if (DCM_DEV_ERROR_DETECT == STD_ON)\r
394                 Det_ReportError(MODULE_ID_DCM, 0, DCM_UDS_READ_DTC_INFO, DCM_E_UNEXPECTED_PARAM);\r
395 #endif\r
396                 break;\r
397         }\r
398 \r
399         // Switch on record number\r
400         switch (dslMsgData.pduRxData->SduDataPtr[5])\r
401         {\r
402         case 0xFF:      // Report all Extended Data Records for a particular DTC\r
403                 startRecNum = 0x00;\r
404                 endRecNum = 0xEF;\r
405                 break;\r
406 \r
407         case 0xFE:      // Report all OBD Extended Data Records for a particular DTC\r
408                 startRecNum = 0x90;\r
409                 endRecNum = 0xEF;\r
410                 break;\r
411 \r
412         default:        // Report one specific Extended Data Records for a particular DTC\r
413                 startRecNum = dslMsgData.pduRxData->SduDataPtr[5];\r
414                 endRecNum = startRecNum;\r
415                 break;\r
416         }\r
417 \r
418         if (responseCode == DCM_E_POSITIVERESPONSE) {\r
419                 Dem_ReturnGetStatusOfDTCType getStatusOfDtcResult;\r
420                 uint32 dtc;\r
421                 Dem_EventStatusExtendedType statusOfDtc;\r
422 \r
423                 dtc = BYTES_TO_DTC(dslMsgData.pduRxData->SduDataPtr[2], dslMsgData.pduRxData->SduDataPtr[3], dslMsgData.pduRxData->SduDataPtr[4]);\r
424                 getStatusOfDtcResult = Dem_GetStatusOfDTC(dtc, DEM_DTC_KIND_ALL_DTCS, dtcOrigin, &statusOfDtc); /** @req DCM295 **/ /** @req DCM475 **/\r
425                 if (getStatusOfDtcResult == DEM_STATUS_OK) {\r
426                         Dem_ReturnGetExtendedDataRecordByDTCType getExtendedDataRecordByDtcResult;\r
427                         uint16 recNum;\r
428                         uint8 recLength;\r
429                         uint16 txIndex = 6;\r
430 \r
431                         /** @req DCM297 **/ /** @req DCM474 **/ /** @req DCM386 **/\r
432                         dslMsgData.pduTxData->SduDataPtr[1] = dslMsgData.pduRxData->SduDataPtr[1];      // Sub function\r
433                         dslMsgData.pduTxData->SduDataPtr[2] = DTC_HIGH_BYTE(dtc);                                       // DTC high byte\r
434                         dslMsgData.pduTxData->SduDataPtr[3] = DTC_MID_BYTE(dtc);                                        // DTC mid byte\r
435                         dslMsgData.pduTxData->SduDataPtr[4] = DTC_LOW_BYTE(dtc);                                        // DTC low byte\r
436                         dslMsgData.pduTxData->SduDataPtr[5] = statusOfDtc;                                                      // DTC status\r
437                         for (recNum = startRecNum; recNum <= endRecNum; recNum++) {\r
438                                 recLength = DCM_PHYS_BUFFER_SIZE - txIndex -1;  // Calculate what's left in buffer\r
439                                 /** @req DCM296 **/ /** @req DCM476 **/ /** @req DCM382 **/\r
440                                 getExtendedDataRecordByDtcResult = Dem_GetExtendedDataRecordByDTC(dtc, DEM_DTC_KIND_ALL_DTCS, dtcOrigin, recNum, &dslMsgData.pduTxData->SduDataPtr[txIndex+1], &recLength);\r
441                                 if (getExtendedDataRecordByDtcResult == DEM_RECORD_OK) {\r
442                                         dslMsgData.pduTxData->SduDataPtr[txIndex++] = recNum;\r
443                                         /* Instead of calling Dem_GetSizeOfExtendedDataRecordByDTC() the result from Dem_GetExtendedDataRecordByDTC() is used */\r
444                                         /** @req DCM478 **/ /** @req DCM479 **/ /** @req DCM480 **/\r
445                                         txIndex += recLength;\r
446                                 }\r
447                                 else {\r
448                                         // TODO: What to do here?\r
449                                 }\r
450                         }\r
451                         dslMsgData.pduTxData->SduLength = txIndex;\r
452                 }\r
453                 else {\r
454                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
455                 }\r
456         }\r
457 \r
458         return responseCode;\r
459 }\r
460 \r
461 \r
462 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x03(void)\r
463 {\r
464         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
465 \r
466         // TODO: Not supported yet\r
467         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
468 \r
469         return responseCode;\r
470 }\r
471 \r
472 \r
473 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x04(void)\r
474 {\r
475         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
476 \r
477         // TODO: Not supported yet\r
478         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
479 \r
480         return responseCode;\r
481 }\r
482 \r
483 \r
484 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x05(void)\r
485 {\r
486         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
487 \r
488         // TODO: Not supported yet\r
489         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
490 \r
491         return responseCode;\r
492 }\r
493 \r
494 \r
495 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x0B_0x0C_0x0D_0x0E(void)\r
496 {\r
497         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
498 \r
499         // TODO: Not supported yet\r
500         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
501 \r
502         return responseCode;\r
503 }\r
504 \r
505 \r
506 Dcm_NegativeResponseCodeType DspUdsReadDtcInfoSub_0x14(void)\r
507 {\r
508         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
509 \r
510         // TODO: Not supported yet\r
511         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
512 \r
513         return responseCode;\r
514 }\r
515 \r
516 \r
517 void DspUdsReadDtcInformation(void)\r
518 {\r
519         /** @reg DCM248 **/\r
520         // 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
521         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
522 \r
523         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
524 \r
525         uint8 subFunctionNumber = dslMsgData.pduRxData->SduDataPtr[1];\r
526 \r
527         // Check length\r
528         if (subFunctionNumber <= 0x15) {\r
529                 if (dslMsgData.pduRxData->SduLength == sduLength[subFunctionNumber]) {\r
530                         switch (subFunctionNumber)\r
531                         {\r
532                         case 0x01:      // reportNumberOfDTCByStatusMask\r
533                         case 0x07:      // reportNumberOfDTCBySeverityMaskRecord\r
534                         case 0x11:      // reportNumberOfMirrorMemoryDTCByStatusMask\r
535                         case 0x12:      // reportNumberOfEmissionRelatedOBDDTCByStatusMask\r
536                                 responseCode = DspUdsReadDtcInfoSub_0x01_0x07_0x11_0x12();\r
537                                 break;\r
538 \r
539                         case 0x02:      // reportDTCByStatusMask\r
540                         case 0x0A:      // reportSupportedDTC\r
541                         case 0x0F:      // reportMirrorMemoryDTCByStatusMask\r
542                         case 0x13:      // reportEmissionRelatedOBDDTCByStatusMask\r
543                         case 0x15:      // reportDTCWithPermanentStatus\r
544                                 responseCode = DspUdsReadDtcInfoSub_0x02_0x0A_0x0F_0x13_0x15();\r
545                                 break;\r
546 \r
547                         case 0x08:      // reportDTCBySeverityMaskRecord\r
548                                 responseCode = DspUdsReadDtcInfoSub_0x08();\r
549                                 break;\r
550 \r
551                         case 0x09:      // reportSeverityInformationOfDTC\r
552                                 responseCode = DspUdsReadDtcInfoSub_0x09();\r
553                                 break;\r
554 \r
555                         case 0x06:      // reportDTCExtendedDataRecordByDTCNumber\r
556                         case 0x10:      // reportMirrorMemoryDTCExtendedDataRecordByDTCNumber\r
557                                 responseCode = DspUdsReadDtcInfoSub_0x06_0x10();\r
558                                 break;\r
559 \r
560                         case 0x03:      // reportDTCSnapshotIdentidication\r
561                                 responseCode = DspUdsReadDtcInfoSub_0x03();\r
562                                 break;\r
563 \r
564                         case 0x04:      // reportDTCSnapshotByDtcNumber\r
565                                 responseCode = DspUdsReadDtcInfoSub_0x04();\r
566                                 break;\r
567 \r
568                         case 0x05:      // reportDTCSnapshotRecordNumber\r
569                                 responseCode = DspUdsReadDtcInfoSub_0x05();\r
570                                 break;\r
571 \r
572                         case 0x0B:      // reportFirstTestFailedDTC\r
573                         case 0x0C:      // reportFirstConfirmedDTC\r
574                         case 0x0D:      // reportMostRecentTestFailedDTC\r
575                         case 0x0E:      // reportMostRecentConfirmedDTC\r
576                                 responseCode = DspUdsReadDtcInfoSub_0x0B_0x0C_0x0D_0x0E();\r
577                                 break;\r
578 \r
579                         case 0x14:      // reportDTCFaultDetectionCounter\r
580                                 responseCode = DspUdsReadDtcInfoSub_0x14();\r
581                                 break;\r
582 \r
583                         default:\r
584                                 // Unknown sub function\r
585                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
586                                 break;\r
587                         }\r
588                 }\r
589                 else {\r
590                         // Wrong length\r
591                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;     /** @req DCM272.0x19 **/\r
592                 }\r
593         }\r
594         else {\r
595                 // Sub function out of range\r
596                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
597         }\r
598 \r
599         DsdDspProcessingDone(responseCode);\r
600 }\r
601 \r
602 \r
603 void DspUdsSecurityAccess(void)\r
604 {\r
605         /** @req DCM252 **/\r
606         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
607 \r
608         // Check sub function range (0x01 to 0x42)\r
609         if ((dslMsgData.pduRxData->SduDataPtr[1] >= 0x01) && (dslMsgData.pduRxData->SduDataPtr[1] <= 0x42)) {\r
610                 boolean isRequestSeed = dslMsgData.pduRxData->SduDataPtr[1] & 0x01;\r
611                 Dcm_SecLevelType requestedSecurityLevel = (dslMsgData.pduRxData->SduDataPtr[1]-1)/2;\r
612                 Std_ReturnType getSeedResult;\r
613                 Dcm_NegativeResponseCodeType getSeedErrorCode;\r
614                 uint16 i;\r
615 \r
616                 if (isRequestSeed) {\r
617                         // requestSeed message\r
618                         // Check if type exist in security table\r
619                         for (i = 0; (DCM_Config.Dsp->DspSecurity->DspSecurityRow[i].DspSecurityLevel != requestedSecurityLevel) && !DCM_Config.Dsp->DspSecurity->DspSecurityRow[i].Arc_EOL; i++);\r
620 \r
621                         if (!DCM_Config.Dsp->DspSecurity->DspSecurityRow[i].Arc_EOL) {\r
622                                 const Dcm_DspSecurityRowType *requestedSecurity = &DCM_Config.Dsp->DspSecurity->DspSecurityRow[i];\r
623                                 // Check length\r
624                                 if (dslMsgData.pduRxData->SduLength == (2 + requestedSecurity->DspSecurityADRSize)) {   /** @req DCM321.1 **/\r
625                                         Dcm_SecLevelType activeSecLevel;\r
626                                         Dcm_GetSecurityLevel(&activeSecLevel);\r
627                                         if (requestedSecurityLevel == activeSecLevel) {         /** @req DCM323 **/\r
628                                                 // If same level set the seed to zeroes\r
629                                                 for (i = 0; i < requestedSecurity->DspSecuritySeedSize; i++) {\r
630                                                         dslMsgData.pduTxData->SduDataPtr[2+i] = 0;\r
631                                                         dslMsgData.pduTxData->SduLength = 2 + requestedSecurity->DspSecuritySeedSize;\r
632                                                 }\r
633                                         }\r
634                                         else {\r
635                                                 // New security level ask for seed\r
636                                                 getSeedResult = requestedSecurity->GetSeed(&dslMsgData.pduRxData->SduDataPtr[2], &dslMsgData.pduTxData->SduDataPtr[2], &getSeedErrorCode);\r
637                                                 if ((getSeedResult == E_OK) && (getSeedErrorCode == E_OK)) {\r
638                                                         // Everything ok add sub function to tx message and send it.\r
639                                                         dslMsgData.pduTxData->SduDataPtr[1] = dslMsgData.pduRxData->SduDataPtr[1];\r
640                                                         dslMsgData.pduTxData->SduLength = 2 + requestedSecurity->DspSecuritySeedSize;\r
641 \r
642                                                         dspUdsSecurityAccesData.reqSecLevel = requestedSecurityLevel;\r
643                                                         dspUdsSecurityAccesData.reqSecLevelRef = &DCM_Config.Dsp->DspSecurity->DspSecurityRow[i];\r
644                                                         dspUdsSecurityAccesData.reqInProgress = TRUE;\r
645                                                         // TODO: Start security timeout\r
646                                                 }\r
647                                                 else {\r
648                                                         // GetSeed returned not ok\r
649                                                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
650                                                 }\r
651                                         }\r
652                                 }\r
653                                 else {\r
654                                         // Length not ok\r
655                                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
656                                 }\r
657                         }\r
658                         else {\r
659                                 // Requested security level not configured\r
660                                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
661                         }\r
662                 }\r
663                 else {\r
664                         // sendKey message\r
665                         if (dspUdsSecurityAccesData.reqInProgress) {\r
666                                 if (dslMsgData.pduRxData->SduLength == (2 + dspUdsSecurityAccesData.reqSecLevelRef->DspSecurityKeySize)) {      /** @req DCM321 **/\r
667                                         if (requestedSecurityLevel == dspUdsSecurityAccesData.reqSecLevel) {\r
668                                                 Std_ReturnType compareKeyResult;\r
669                                                 compareKeyResult = dspUdsSecurityAccesData.reqSecLevelRef->CompareKey(&dslMsgData.pduRxData->SduDataPtr[2]);\r
670                                                 if (compareKeyResult == E_OK) {\r
671                                                         // Request accepted\r
672                                                         // Kill timer\r
673                                                         DslSetSecurityLevel(dspUdsSecurityAccesData.reqSecLevelRef->DspSecurityLevel);\r
674                                                         dspUdsSecurityAccesData.reqInProgress = FALSE;\r
675                                                         dslMsgData.pduTxData->SduDataPtr[1] = dslMsgData.pduRxData->SduDataPtr[1];\r
676                                                         dslMsgData.pduTxData->SduLength = 2;\r
677                                                 }\r
678                                                 else {\r
679                                                         responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
680                                                 }\r
681                                         }\r
682                                         else {\r
683                                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
684                                         }\r
685                                 }\r
686                                 else {\r
687                                         // Length not ok\r
688                                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
689                                 }\r
690                         }\r
691                         else {\r
692                                 // sendKey request without a preceding requestSeed\r
693                                 responseCode = DCM_E_REQUESTSEQUENCEERROR;\r
694                         }\r
695                 }\r
696         }\r
697         else {\r
698                 responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;\r
699         }\r
700 \r
701         DsdDspProcessingDone(responseCode);\r
702 }\r
703 \r
704 \r
705 void DspUdsTesterPresent(void)\r
706 {\r
707         if (dslMsgData.pduRxData->SduLength == 2) {\r
708                 switch (dslMsgData.pduRxData->SduDataPtr[1])\r
709                 {\r
710                 case ZERO_SUB_FUNCTION:\r
711                         DslResetSessionTimeoutTimer();\r
712                         // Create positive response\r
713                         /** @req DCM039.1 **/\r
714                         dslMsgData.pduTxData->SduDataPtr[1] = ZERO_SUB_FUNCTION;\r
715                         dslMsgData.pduTxData->SduLength = 2;\r
716                         DsdDspProcessingDone(DCM_E_POSITIVERESPONSE); /** @req DCM269.1 **/\r
717                         break;\r
718 \r
719                 default:\r
720                         DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);    /** @req DCM273.1 **/\r
721                         break;\r
722                 }\r
723         }\r
724         else {\r
725                 // Wrong length\r
726                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);      /** @req DCM272.1 **/\r
727         }\r
728 }\r
729 \r
730 \r
731 void DspUdsControlDtcSetting(void)\r
732 {\r
733         Dem_ReturnControlDTCStorageType resultCode;\r
734 \r
735         if (dslMsgData.pduRxData->SduLength == 2) {\r
736                 switch (dslMsgData.pduRxData->SduDataPtr[1])\r
737                 {\r
738                 case 0x01:      // ON   /** @req DCM249.1 **/\r
739                         resultCode = Dem_EnableDTCStorage(DEM_DTC_GROUP_ALL_DTCS, DEM_DTC_KIND_ALL_DTCS);               /** @req DCM304 **/\r
740                         if (resultCode == DEM_CONTROL_DTC_STORAGE_OK) {\r
741                                 dslMsgData.pduTxData->SduDataPtr[1] = 0x01;\r
742                                 dslMsgData.pduTxData->SduLength = 2;\r
743                                 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
744                         }\r
745                         else {\r
746                                 DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);\r
747                         }\r
748                         break;\r
749 \r
750                 case 0x02:      // OFF  /** @req DCM249.2 **/\r
751                         resultCode = Dem_DisableDTCStorage(DEM_DTC_GROUP_ALL_DTCS, DEM_DTC_KIND_ALL_DTCS);              /** @req DCM406 **/\r
752                         if (resultCode == DEM_CONTROL_DTC_STORAGE_OK) {\r
753                                 dslMsgData.pduTxData->SduDataPtr[1] = 0x02;\r
754                                 dslMsgData.pduTxData->SduLength = 2;\r
755                                 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
756                         }\r
757                         else {\r
758                                 DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);\r
759                         }\r
760                         break;\r
761 \r
762                 default:\r
763                         DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);\r
764                         break;\r
765                 }\r
766         }\r
767         else {\r
768                 // Wrong length\r
769                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);\r
770         }\r
771 }\r
772 \r
773 \r
774 void DspDcmConfirmation(PduIdType confirmPduId)\r
775 {\r
776         if (dspUdsEcuResetData.resetPending) {\r
777                 if (confirmPduId == dspUdsEcuResetData.resetPduId) {\r
778                         dspUdsEcuResetData.resetPending = FALSE;\r
779                         Mcu_PerformReset();\r
780                 }\r
781         }\r
782 }\r
783 \r
784 \r
785 \r