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