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