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