]> rtime.felk.cvut.cz Git - arc.git/blob - diagnostic/Dcm/Dcm_Dsp.c
Added additions to Dcm and Dem (new tools required to use this update):
[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 #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 /*\r
36  * Macros\r
37  */\r
38 #define ZERO_SUB_FUNCTION                               0x00\r
39 #define DCM_FORMAT_LOW_MASK                     0x0F\r
40 #define DCM_FORMAT_HIGH_MASK                    0xF0\r
41 #define DCM_MEMORY_ADDRESS_MASK         0xFFFFFF\r
42 #define DCM_DID_HIGH_MASK                               0xFF00                  \r
43 #define DCM_DID_LOW_MASK                                0xFF\r
44 #define DCM_PERODICDID_HIHG_MASK                0xF200\r
45 #define SID_AND_ALFID_LEN2   0x2\r
46 #define SID_AND_ALFID_LEN4   0x4\r
47 #define SID_AND_ALFID_LEN5      0x5\r
48 #define SID_AND_ALFID_LEN6   0x6\r
49 #define SID_AND_ALFID_LEN7   0x7\r
50 \r
51 #define BYTES_TO_DTC(hb, mb, lb)        (((uint32)(hb) << 16) | ((uint32)(mb) << 8) | (uint32)(lb))\r
52 #define DTC_HIGH_BYTE(dtc)                      (((uint32)(dtc) >> 16) & 0xFFu)\r
53 #define DTC_MID_BYTE(dtc)                       (((uint32)(dtc) >> 8) & 0xFFu)\r
54 #define DTC_LOW_BYTE(dtc)                       ((uint32)(dtc) & 0xFFu)\r
55 \r
56 \r
57 typedef struct {\r
58         boolean resetPending;\r
59         PduIdType resetPduId;\r
60 } DspUdsEcuResetDataType;\r
61 \r
62 static DspUdsEcuResetDataType dspUdsEcuResetData;\r
63 static boolean dspWritePending;\r
64 \r
65 typedef struct {\r
66         boolean                                                 reqInProgress;\r
67         Dcm_SecLevelType                                reqSecLevel;\r
68         const Dcm_DspSecurityRowType    *reqSecLevelRef;\r
69 } DspUdsSecurityAccessDataType;\r
70 \r
71 static DspUdsSecurityAccessDataType dspUdsSecurityAccesData;\r
72 \r
73 typedef enum{\r
74         DCM_MEMORY_UNUSED,\r
75         DCM_MEMORY_READ,\r
76         DCM_MEMORY_WRITE,\r
77         DCM_MEMORY_FAILED       \r
78 }Dcm_DspMemoryStateType;\r
79 Dcm_DspMemoryStateType dspMemoryState;\r
80 \r
81 typedef enum{\r
82         DCM_DDD_SOURCE_DEFAULT,\r
83         DCM_DDD_SOURCE_DID,\r
84         DCM_DDD_SOURCE_ADDRESS\r
85 }Dcm_DspDDDTpyeID;\r
86 \r
87 typedef struct{\r
88         uint32 PDidTxCounter;\r
89         uint32 PDidTxCounterNumber;\r
90         uint8  PeriodicDid;\r
91 }Dcm_pDidType;/* a type to save  the periodic DID and cycle */\r
92 \r
93 typedef struct{\r
94         Dcm_pDidType dspPDid[DCM_LIMITNUMBER_PERIODDATA];       /*a buffer to save the periodic DID and cycle   */\r
95         uint8 PDidNr;                                                                           /* note the number of periodic DID is used */\r
96 }Dsp_pDidRefType;\r
97 \r
98 Dsp_pDidRefType dspPDidRef; \r
99 \r
100 typedef struct{\r
101         uint8   formatOrPosition;                                               /*note the formate of address and size*/\r
102         uint32 SourceAddressOrDid;                                                              /*note the memory address */\r
103         uint16 Size;                                                                            /*note the memory size */\r
104         Dcm_DspDDDTpyeID DDDTpyeID;\r
105 }Dcm_DspDDDSourceType;\r
106 \r
107 typedef struct{\r
108         uint16 DynamicallyDid;\r
109         Dcm_DspDDDSourceType DDDSource[DCM_MAX_DDDSOURCE_NUMBER];\r
110 }\r
111 Dcm_DspDDDType;\r
112 \r
113 Dcm_DspDDDType dspDDD[DCM_MAX_DDD_NUMBER];\r
114 \r
115 \r
116 /*\r
117  * * static Function\r
118  */\r
119 \r
120 static boolean lookupReadMemory(uint32 memoryAddress,\r
121                                                                 uint8  memoryAddressFormat,\r
122                                                                 uint32 memorySize,\r
123                                                                 const Dcm_DspMemoryIdInfo **MemoryPtr);\r
124 \r
125 static boolean LookupDDD(uint16 didNr, const Dcm_DspDDDType **DDid);\r
126 \r
127 static boolean checkWriteMemoryByAddress(boolean useId,\r
128                                                  uint32 memoryAddress,\r
129                                                                                  uint8 memoryAddressFormat,\r
130                                                                                  uint32 memorySize,\r
131                                                                                  const Dcm_DspMemoryIdInfo *dspMemory);\r
132 \r
133 \r
134 /*\r
135 *   end  \r
136 */\r
137 \r
138 void DspInit(void)\r
139 {\r
140         dspUdsSecurityAccesData.reqInProgress = FALSE;\r
141         dspUdsEcuResetData.resetPending = FALSE;\r
142 \r
143         dspWritePending = FALSE;\r
144         dspMemoryState=DCM_MEMORY_UNUSED;\r
145         /* clear periodic send buffer */\r
146         memset(&dspPDidRef,0,sizeof(dspPDidRef));\r
147         /* clear dynamically Did buffer */\r
148         memset(&dspDDD[0],0,sizeof(dspDDD)); \r
149 }\r
150 \r
151 void DspMemoryMainFunction(void)\r
152 {\r
153         Dcm_ReturnWriteMemoryType WriteRet;\r
154         Dcm_ReturnReadMemoryType ReadRet;\r
155         switch(dspMemoryState)\r
156         {\r
157                 case DCM_MEMORY_UNUSED:\r
158                         break;\r
159                 case DCM_MEMORY_READ:\r
160                         ReadRet = Dcm_ReadMemory(DCM_PENDING,0,0,0,0);\r
161                         if(ReadRet == DCM_READ_OK)/*asynchronous writing is ok*/\r
162                         {\r
163                                 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
164                                 dspMemoryState = DCM_MEMORY_UNUSED;\r
165                         }\r
166                         if(ReadRet == DCM_READ_FAILED)\r
167                         {\r
168                                 dspMemoryState = DCM_MEMORY_FAILED;\r
169                         }\r
170                         break;\r
171                 case DCM_MEMORY_WRITE:\r
172                         WriteRet = Dcm_WriteMemory(DCM_PENDING,0,0,0,0);\r
173                         if(WriteRet == DCM_WRITE_OK)/*asynchronous writing is ok*/\r
174                         {\r
175                                 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
176                                 dspMemoryState = DCM_MEMORY_UNUSED;\r
177                         }\r
178                         if(WriteRet == DCM_WRITE_FAILED)\r
179                         {\r
180                                 dspMemoryState = DCM_MEMORY_FAILED;\r
181                         }\r
182                         break;\r
183                 case DCM_MEMORY_FAILED:\r
184                         DsdDspProcessingDone(DCM_E_GENERALPROGRAMMINGFAILURE);\r
185                         dspMemoryState = DCM_MEMORY_UNUSED;\r
186                         break;\r
187                         \r
188         }\r
189 }\r
190 void DspPeriodicDIDMainFunction()\r
191 {\r
192         uint8 i;\r
193         for(i = 0;i < dspPDidRef.PDidNr; i++)\r
194         {\r
195                 if(dspPDidRef.dspPDid[i].PDidTxCounterNumber > dspPDidRef.dspPDid[i].PDidTxCounter)\r
196                 {\r
197                         dspPDidRef.dspPDid[i].PDidTxCounter++;\r
198                 }\r
199                 else\r
200                 {\r
201                         dspPDidRef.dspPDid[i].PDidTxCounter = 0;\r
202                         /*AutoSar  DCM  8.10.5 */\r
203                         DslInternal_ResponseOnOneDataByPeriodicId(dspPDidRef.dspPDid[i].PeriodicDid);\r
204                 }       \r
205         }\r
206 }\r
207 void DspMain(void)\r
208 {\r
209         DspMemoryMainFunction();\r
210         DspPeriodicDIDMainFunction();\r
211 }\r
212 \r
213 \r
214 boolean DspCheckSessionLevel(Dcm_DspSessionRowType const* const* sessionLevelRefTable)\r
215 {\r
216         Std_ReturnType returnStatus;\r
217         boolean levelFound = FALSE;\r
218         Dcm_SesCtrlType currentSession;\r
219 \r
220         returnStatus = DslGetSesCtrlType(&currentSession);\r
221         if (returnStatus == E_OK) {\r
222                 while ( ((*sessionLevelRefTable)->DspSessionLevel != currentSession) && (!(*sessionLevelRefTable)->Arc_EOL) ) {\r
223                         sessionLevelRefTable++;\r
224                 }\r
225 \r
226                 if (!(*sessionLevelRefTable)->Arc_EOL) {\r
227                         levelFound = TRUE;\r
228                 }\r
229         }\r
230 \r
231         return levelFound;\r
232 }\r
233 \r
234 \r
235 boolean DspCheckSecurityLevel(Dcm_DspSecurityRowType const* const* securityLevelRefTable)\r
236 {\r
237         Std_ReturnType returnStatus;\r
238         boolean levelFound = FALSE;\r
239         Dcm_SecLevelType currentSecurityLevel;\r
240 \r
241         returnStatus = DslGetSecurityLevel(&currentSecurityLevel);\r
242         if (returnStatus == E_OK) {\r
243                 while ( ((*securityLevelRefTable)->DspSecurityLevel != currentSecurityLevel) && (!(*securityLevelRefTable)->Arc_EOL) ) {\r
244                         securityLevelRefTable++;\r
245                 }\r
246                 if (!(*securityLevelRefTable)->Arc_EOL) {\r
247                         levelFound = TRUE;\r
248                 }\r
249         }\r
250 \r
251         return levelFound;\r
252 }\r
253 \r
254 \r
255 static Std_ReturnType askApplicationForSessionPermission(Dcm_SesCtrlType newSessionLevel)\r
256 {\r
257         Std_ReturnType returnCode = E_OK;\r
258         const Dcm_DslSessionControlType *sesControl = DCM_Config.Dsl->DslSessionControl;\r
259         Dcm_SesCtrlType currentSessionLevel;\r
260         Std_ReturnType result;\r
261 \r
262         while ( (!sesControl->Arc_EOL) && (returnCode != E_SESSION_NOT_ALLOWED)) {\r
263                 if (sesControl->GetSesChgPermission != NULL) {\r
264                         result = Dcm_GetSesCtrlType(&currentSessionLevel);\r
265                         if (result == E_OK) {\r
266                                 result = sesControl->GetSesChgPermission(currentSessionLevel ,newSessionLevel);\r
267                                 if (result != E_OK) {\r
268                                         returnCode = result;\r
269                                 }\r
270                         } else {\r
271                                 returnCode = E_NOT_OK;\r
272                         }\r
273                 }\r
274                 sesControl++;\r
275         }\r
276 \r
277         return returnCode;\r
278 }\r
279 \r
280 \r
281 void DspUdsDiagnosticSessionControl(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
282 {\r
283         /** @req DCM250 */\r
284         const Dcm_DspSessionRowType *sessionRow = DCM_Config.Dsp->DspSession->DspSessionRow;\r
285         Dcm_SesCtrlType reqSessionType;\r
286         Std_ReturnType result;\r
287 \r
288         if (pduRxData->SduLength == 2) {\r
289                 reqSessionType = pduRxData->SduDataPtr[1];\r
290                 // Check if type exist in session table\r
291                 while ((sessionRow->DspSessionLevel != reqSessionType) && (!sessionRow->Arc_EOL) ) {\r
292                         sessionRow++;\r
293                 }\r
294 \r
295                 if (!sessionRow->Arc_EOL) {\r
296                         result = askApplicationForSessionPermission(reqSessionType);\r
297                         if (result == E_OK) {\r
298                                 DslSetSesCtrlType(reqSessionType);              /** @req DCM311 */\r
299                                 // Create positive response\r
300                                 pduTxData->SduDataPtr[1] = reqSessionType;\r
301                                 pduTxData->SduLength = 2;\r
302                                 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
303                         }\r
304                         else {\r
305                                 // TODO: Add handling of special case of E_FORCE_RCRRP (Dcm138)\r
306                                 DsdDspProcessingDone(DCM_E_CONDITIONSNOTCORRECT);       /** @req DCM308 */\r
307                         }\r
308                 }\r
309                 else {\r
310                         DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);    /** @req DCM307 */\r
311                 }\r
312         }\r
313         else {\r
314                 // Wrong length\r
315                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);\r
316         }\r
317 }\r
318 \r
319 \r
320 void DspUdsEcuReset(const PduInfoType *pduRxData, PduIdType txPduId, PduInfoType *pduTxData)\r
321 {\r
322         /** @req DCM260 */\r
323         uint8 reqResetType;\r
324 \r
325         if (pduRxData->SduLength == 2) {\r
326                 reqResetType = pduRxData->SduDataPtr[1];\r
327 \r
328                 switch (reqResetType)\r
329                 {\r
330                 case 0x01:      // Hard reset\r
331                         // TODO: Ask application for permission (Dcm373) (Dcm375) (Dcm377)\r
332 \r
333                         // Schedule the reset\r
334                         dspUdsEcuResetData.resetPending = TRUE;\r
335                         dspUdsEcuResetData.resetPduId = txPduId;\r
336 \r
337                         // Create positive response\r
338                         pduTxData->SduDataPtr[1] = reqResetType;\r
339                         pduTxData->SduLength = 2;\r
340                         DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
341                         break;\r
342 \r
343                 default:\r
344                         DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);\r
345                         break;\r
346                 }\r
347         }\r
348         else {\r
349                 // Wrong length\r
350                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);\r
351         }\r
352 }\r
353 \r
354 \r
355 void DspUdsClearDiagnosticInformation(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
356 {\r
357         /** @req DCM247 */\r
358         uint32 dtc;\r
359         Dem_ReturnClearDTCType result;\r
360 \r
361         if (pduRxData->SduLength == 4) {\r
362                 dtc = BYTES_TO_DTC(pduRxData->SduDataPtr[1], pduRxData->SduDataPtr[2], pduRxData->SduDataPtr[3]);\r
363 \r
364                 result = Dem_ClearDTC(dtc, DEM_DTC_KIND_ALL_DTCS, DEM_DTC_ORIGIN_PRIMARY_MEMORY); /** @req DCM005 */\r
365 \r
366                 switch (result)\r
367                 {\r
368                 case DEM_CLEAR_OK:\r
369                         // Create positive response\r
370                         pduTxData->SduLength = 1;\r
371                         DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
372                         break;\r
373 \r
374                 default:\r
375                         DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);\r
376                         break;\r
377                 }\r
378         }\r
379         else {\r
380                 // Wrong length\r
381                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);\r
382         }\r
383 }\r
384 \r
385 \r
386 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x01_0x07_0x11_0x12(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
387 {\r
388         typedef struct {\r
389                 uint8           SID;\r
390                 uint8           reportType;\r
391                 uint8           dtcStatusAvailabilityMask;\r
392                 uint8           dtcFormatIdentifier;\r
393                 uint8           dtcCountHighByte;\r
394                 uint8           dtcCountLowByte;\r
395         } TxDataType;\r
396 \r
397         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
398         Dem_ReturnSetDTCFilterType setDtcFilterResult;\r
399 \r
400         // Setup the DTC filter\r
401         switch (pduRxData->SduDataPtr[1])       /** @req DCM293 */\r
402         {\r
403         case 0x01:      // reportNumberOfDTCByStatusMask\r
404                 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
405                 break;\r
406 \r
407         case 0x07:      // reportNumberOfDTCBySeverityMaskRecord\r
408                 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
409                 break;\r
410 \r
411         case 0x11:      // reportNumberOfMirrorMemoryDTCByStatusMask\r
412                 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
413                 break;\r
414 \r
415         case 0x12:      // reportNumberOfEmissionRelatedOBDDTCByStatusMask\r
416                 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
417                 break;\r
418 \r
419         default:\r
420                 setDtcFilterResult = DEM_WRONG_FILTER;\r
421                 break;\r
422         }\r
423 \r
424         if (setDtcFilterResult == DEM_FILTER_ACCEPTED) {\r
425                 Std_ReturnType result;\r
426                 Dem_ReturnGetNumberOfFilteredDTCType getNumerResult;\r
427                 uint16 numberOfFilteredDtc;\r
428                 uint8 dtcStatusMask;\r
429                 //lint --e(826) PC-Lint exception - Suspicious pointer conversion\r
430                 //lint --e(927) PC-Lint exception - Pointer to pointer cast\r
431                 TxDataType *txData = (TxDataType*)pduTxData->SduDataPtr;\r
432 \r
433                 /** @req DCM376 */\r
434                 getNumerResult = Dem_GetNumberOfFilteredDtc(&numberOfFilteredDtc);\r
435                 if (getNumerResult == DEM_NUMBER_OK) {\r
436                         result = Dem_GetDTCStatusAvailabilityMask(&dtcStatusMask);\r
437                         if (result != E_OK) {\r
438                                 dtcStatusMask = 0;\r
439                         }\r
440 \r
441                         // Create positive response (ISO 14229-1 table 251)\r
442                         txData->reportType = pduRxData->SduDataPtr[1];                                          // reportType\r
443                         txData->dtcStatusAvailabilityMask = dtcStatusMask;                                      // DTCStatusAvailabilityMask\r
444                         txData->dtcFormatIdentifier = Dem_GetTranslationType();                         // DTCFormatIdentifier\r
445                         txData->dtcCountHighByte = (numberOfFilteredDtc >> 8);                          // DTCCount high byte\r
446                         txData->dtcCountLowByte = (numberOfFilteredDtc & 0xFFu);                        // DTCCount low byte\r
447                         pduTxData->SduLength = 6;\r
448                 } else {\r
449                         // TODO: What to do?\r
450                         responseCode = DCM_E_GENERALREJECT;\r
451                 }\r
452         }\r
453         else {\r
454                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
455         }\r
456 \r
457         return responseCode;\r
458 }\r
459 \r
460 \r
461 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x02_0x0A_0x0F_0x13_0x15(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
462 {\r
463         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
464         Dem_ReturnSetDTCFilterType setDtcFilterResult;\r
465 \r
466         typedef struct {\r
467                 uint8           dtcHighByte;\r
468                 uint8           dtcMiddleByte;\r
469                 uint8           dtcLowByte;\r
470                 uint8           statusOfDtc;\r
471         } dtcAndStatusRecordType;\r
472 \r
473         typedef struct {\r
474                 uint8                                   SID;\r
475                 uint8                                   reportType;\r
476                 uint8                                   dtcStatusAvailabilityMask;\r
477                 dtcAndStatusRecordType  *dtcAndStatusRecord;\r
478         } TxDataType;\r
479 \r
480         // Setup the DTC filter\r
481         switch (pduRxData->SduDataPtr[1])       /** @req DCM378 */\r
482         {\r
483         case 0x02:      // reportDTCByStatusMask\r
484                 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
485                 break;\r
486 \r
487         case 0x0A:      // reportSupportedDTC\r
488                 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
489                 break;\r
490 \r
491         case 0x0F:      // reportMirrorMemoryDTCByStatusMask\r
492                 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
493                 break;\r
494 \r
495         case 0x13:      // reportEmissionRelatedOBDDTCByStatusMask\r
496                 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
497                 break;\r
498 \r
499         case 0x15:      // reportDTCWithPermanentStatus\r
500                 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
501                 break;\r
502 \r
503         default:\r
504                 setDtcFilterResult = DEM_WRONG_FILTER;\r
505                 break;\r
506         }\r
507 \r
508         if (setDtcFilterResult == DEM_FILTER_ACCEPTED) {\r
509                 uint8 dtcStatusMask;\r
510                 //lint --e(826) PC-Lint exception - Suspicious pointer conversion\r
511                 //lint --e(927) PC-Lint exception - Pointer to pointer cast\r
512                 TxDataType *txData = (TxDataType*)pduTxData->SduDataPtr;\r
513                 Dem_ReturnGetNextFilteredDTCType getNextFilteredDtcResult;\r
514                 uint32 dtc;\r
515                 Dem_EventStatusExtendedType dtcStatus;\r
516                 uint16 nrOfDtcs = 0;\r
517                 Std_ReturnType result;\r
518 \r
519                 /** @req DCM377 */\r
520                 result = Dem_GetDTCStatusAvailabilityMask(&dtcStatusMask);\r
521                 if (result != E_OK) {\r
522                         dtcStatusMask = 0;\r
523                 }\r
524 \r
525                 // Create positive response (ISO 14229-1 table 252)\r
526                 txData->reportType = pduRxData->SduDataPtr[1];\r
527                 txData->dtcStatusAvailabilityMask = dtcStatusMask;\r
528 \r
529                 if (dtcStatusMask != 0x00) {    /** @req DCM008 */\r
530                         getNextFilteredDtcResult = Dem_GetNextFilteredDTC(&dtc, &dtcStatus);\r
531                         while (getNextFilteredDtcResult == DEM_FILTERED_OK) {\r
532                                 txData->dtcAndStatusRecord[nrOfDtcs].dtcHighByte = DTC_HIGH_BYTE(dtc);\r
533                                 txData->dtcAndStatusRecord[nrOfDtcs].dtcMiddleByte = DTC_MID_BYTE(dtc);\r
534                                 txData->dtcAndStatusRecord[nrOfDtcs].dtcLowByte = DTC_LOW_BYTE(dtc);\r
535                                 txData->dtcAndStatusRecord[nrOfDtcs].statusOfDtc = dtcStatus;\r
536                                 nrOfDtcs++;\r
537                                 getNextFilteredDtcResult = Dem_GetNextFilteredDTC(&dtc, &dtcStatus);\r
538                         }\r
539 \r
540                         if (getNextFilteredDtcResult != DEM_FILTERED_NO_MATCHING_DTC) {\r
541                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
542                         }\r
543                 }\r
544                 pduTxData->SduLength = (PduLengthType)(3 + (nrOfDtcs * sizeof(dtcAndStatusRecordType)));\r
545         }\r
546         else {\r
547                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
548         }\r
549 \r
550         return responseCode;\r
551 }\r
552 \r
553 // PC-Lint (715 etc): Remove errors until function is filled.\r
554 //lint -e{715, 838, 818}                Symbol not referenced, responseCode not used, txData should be const\r
555 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x08(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
556 {\r
557         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
558 \r
559         // TODO: Not supported yet, (DEM module does not currently support severity).\r
560         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
561 \r
562         return responseCode;\r
563 }\r
564 \r
565 \r
566 // PC-Lint (715 etc): Remove errors until function is filled.\r
567 //lint -e{715, 838, 818}                Symbol not referenced, responseCode not used, txData should be const\r
568 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x09(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
569 {\r
570         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
571 \r
572         // TODO: Not supported yet, (DEM module does not currently support severity).\r
573         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
574 \r
575         return responseCode;\r
576 }\r
577 \r
578 \r
579 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x06_0x10(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
580 {\r
581         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
582         Dem_DTCOriginType dtcOrigin;\r
583         uint8 startRecNum;\r
584         uint8 endRecNum;\r
585 \r
586         // Switch on sub function\r
587         switch (pduRxData->SduDataPtr[1])       /** @req DCM378 */\r
588         {\r
589         case 0x06:      // reportDTCExtendedDataRecordByDTCNumber\r
590                 dtcOrigin = DEM_DTC_ORIGIN_PRIMARY_MEMORY;\r
591                 break;\r
592 \r
593         case 0x10:      // reportMirrorMemoryDTCExtendedDataRecordByDTCNumber\r
594                 dtcOrigin = DEM_DTC_ORIGIN_MIRROR_MEMORY;\r
595                 break;\r
596 \r
597         default:\r
598                 responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;\r
599                 dtcOrigin = 0;\r
600                 break;\r
601         }\r
602 \r
603         // Switch on record number\r
604         switch (pduRxData->SduDataPtr[5])\r
605         {\r
606         case 0xFF:      // Report all Extended Data Records for a particular DTC\r
607                 startRecNum = 0x00;\r
608                 endRecNum = 0xEF;\r
609                 break;\r
610 \r
611         case 0xFE:      // Report all OBD Extended Data Records for a particular DTC\r
612                 startRecNum = 0x90;\r
613                 endRecNum = 0xEF;\r
614                 break;\r
615 \r
616         default:        // Report one specific Extended Data Records for a particular DTC\r
617                 startRecNum = pduRxData->SduDataPtr[5];\r
618                 endRecNum = startRecNum;\r
619                 break;\r
620         }\r
621 \r
622         if (responseCode == DCM_E_POSITIVERESPONSE) {\r
623                 Dem_ReturnGetStatusOfDTCType getStatusOfDtcResult;\r
624                 uint32 dtc;\r
625                 Dem_EventStatusExtendedType statusOfDtc;\r
626 \r
627                 dtc = BYTES_TO_DTC(pduRxData->SduDataPtr[2], pduRxData->SduDataPtr[3], pduRxData->SduDataPtr[4]);\r
628                 getStatusOfDtcResult = Dem_GetStatusOfDTC(dtc, DEM_DTC_KIND_ALL_DTCS, dtcOrigin, &statusOfDtc); /** @req DCM295 */ /** @req DCM475 */\r
629                 if (getStatusOfDtcResult == DEM_STATUS_OK) {\r
630                         Dem_ReturnGetExtendedDataRecordByDTCType getExtendedDataRecordByDtcResult;\r
631                         uint8 recNum;\r
632                         uint16 recLength;\r
633                         uint16 txIndex = 6;\r
634 \r
635                         /** @req DCM297 */ /** @req DCM474 */ /** @req DCM386 */\r
636                         pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1];                    // Sub function\r
637                         pduTxData->SduDataPtr[2] = DTC_HIGH_BYTE(dtc);                                  // DTC high byte\r
638                         pduTxData->SduDataPtr[3] = DTC_MID_BYTE(dtc);                                   // DTC mid byte\r
639                         pduTxData->SduDataPtr[4] = DTC_LOW_BYTE(dtc);                                   // DTC low byte\r
640                         pduTxData->SduDataPtr[5] = statusOfDtc;                                                 // DTC status\r
641                         for (recNum = startRecNum; recNum <= endRecNum; recNum++) {\r
642                                 recLength = pduTxData->SduLength - (txIndex + 1);       // Calculate what's left in buffer\r
643                                 /** @req DCM296 */ /** @req DCM476 */ /** @req DCM382 */\r
644                                 getExtendedDataRecordByDtcResult = Dem_GetExtendedDataRecordByDTC(dtc, DEM_DTC_KIND_ALL_DTCS, dtcOrigin, recNum, &pduTxData->SduDataPtr[txIndex+1], &recLength);\r
645                                 if (getExtendedDataRecordByDtcResult == DEM_RECORD_OK) {\r
646                                         pduTxData->SduDataPtr[txIndex++] = recNum;\r
647                                         /* Instead of calling Dem_GetSizeOfExtendedDataRecordByDTC() the result from Dem_GetExtendedDataRecordByDTC() is used */\r
648                                         /** @req DCM478 */ /** @req DCM479 */ /** @req DCM480 */\r
649                                         txIndex += recLength;\r
650                                 }\r
651                                 else {\r
652                                         // TODO: What to do here?\r
653                                 }\r
654                         }\r
655                         pduTxData->SduLength = txIndex;\r
656                 }\r
657                 else {\r
658                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
659                 }\r
660         }\r
661 \r
662         return responseCode;\r
663 }\r
664 \r
665 \r
666 // PC-Lint (715 etc): Remove errors until function is filled.\r
667 //lint -e{715, 838, 818}                Symbol not referenced, responseCode not used, txData should be const\r
668 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x03(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
669 {\r
670         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
671 \r
672         // TODO: Not supported yet\r
673         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
674 \r
675         return responseCode;\r
676 }\r
677 \r
678 \r
679 // PC-Lint (715 etc): Remove errors until function is filled.\r
680 //lint -e{715, 838, 818}                Symbol not referenced, responseCode not used, txData should be const\r
681 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x04(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
682 {\r
683         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
684 \r
685         // TODO: Not supported yet\r
686         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
687 \r
688         return responseCode;\r
689 }\r
690 \r
691 \r
692 // PC-Lint (715 etc): Remove errors until function is filled.\r
693 //lint -e{715, 838, 818}                Symbol not referenced, responseCode not used, txData should be const\r
694 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x05(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
695 {\r
696         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
697 \r
698         // TODO: Not supported yet\r
699         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
700 \r
701         return responseCode;\r
702 }\r
703 \r
704 \r
705 // PC-Lint (715 etc): Remove errors until function is filled.\r
706 //lint -e{715, 838, 818}                Symbol not referenced, responseCode not used, txData should be const\r
707 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x0B_0x0C_0x0D_0x0E(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
708 {\r
709         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
710 \r
711         // TODO: Not supported yet\r
712         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
713 \r
714         return responseCode;\r
715 }\r
716 \r
717 \r
718 // PC-Lint (715 etc): Remove errors until function is filled.\r
719 //lint -e{715, 838, 818}                Symbol not referenced, responseCode not used, txData should be const\r
720 static Dcm_NegativeResponseCodeType udsReadDtcInfoSub_0x14(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
721 {\r
722         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
723 \r
724         // TODO: Not supported yet\r
725         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
726 \r
727         return responseCode;\r
728 }\r
729 \r
730 \r
731 void DspUdsReadDtcInformation(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
732 {\r
733         /** @req DCM248 */\r
734         // 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
735         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
736 \r
737         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
738 \r
739         uint8 subFunctionNumber = pduRxData->SduDataPtr[1];\r
740 \r
741         // Check length\r
742         if (subFunctionNumber <= 0x15) {\r
743                 if (pduRxData->SduLength == sduLength[subFunctionNumber]) {\r
744                         switch (subFunctionNumber)\r
745                         {\r
746                         case 0x01:      // reportNumberOfDTCByStatusMask\r
747                         case 0x07:      // reportNumberOfDTCBySeverityMaskRecord\r
748                         case 0x11:      // reportNumberOfMirrorMemoryDTCByStatusMask\r
749                         case 0x12:      // reportNumberOfEmissionRelatedOBDDTCByStatusMask\r
750                                 responseCode = udsReadDtcInfoSub_0x01_0x07_0x11_0x12(pduRxData, pduTxData);\r
751                                 break;\r
752 \r
753                         case 0x02:      // reportDTCByStatusMask\r
754                         case 0x0A:      // reportSupportedDTC\r
755                         case 0x0F:      // reportMirrorMemoryDTCByStatusMask\r
756                         case 0x13:      // reportEmissionRelatedOBDDTCByStatusMask\r
757                         case 0x15:      // reportDTCWithPermanentStatus\r
758                                 responseCode = udsReadDtcInfoSub_0x02_0x0A_0x0F_0x13_0x15(pduRxData, pduTxData);\r
759                                 break;\r
760 \r
761                         case 0x08:      // reportDTCBySeverityMaskRecord\r
762                                 responseCode = udsReadDtcInfoSub_0x08(pduRxData, pduTxData);\r
763                                 break;\r
764 \r
765                         case 0x09:      // reportSeverityInformationOfDTC\r
766                                 responseCode = udsReadDtcInfoSub_0x09(pduRxData, pduTxData);\r
767                                 break;\r
768 \r
769                         case 0x06:      // reportDTCExtendedDataRecordByDTCNumber\r
770                         case 0x10:      // reportMirrorMemoryDTCExtendedDataRecordByDTCNumber\r
771                                 responseCode = udsReadDtcInfoSub_0x06_0x10(pduRxData, pduTxData);\r
772                                 break;\r
773 \r
774                         case 0x03:      // reportDTCSnapshotIdentidication\r
775                                 responseCode = udsReadDtcInfoSub_0x03(pduRxData, pduTxData);\r
776                                 break;\r
777 \r
778                         case 0x04:      // reportDTCSnapshotByDtcNumber\r
779                                 responseCode = udsReadDtcInfoSub_0x04(pduRxData, pduTxData);\r
780                                 break;\r
781 \r
782                         case 0x05:      // reportDTCSnapshotRecordNumber\r
783                                 responseCode = udsReadDtcInfoSub_0x05(pduRxData, pduTxData);\r
784                                 break;\r
785 \r
786                         case 0x0B:      // reportFirstTestFailedDTC\r
787                         case 0x0C:      // reportFirstConfirmedDTC\r
788                         case 0x0D:      // reportMostRecentTestFailedDTC\r
789                         case 0x0E:      // reportMostRecentConfirmedDTC\r
790                                 responseCode = udsReadDtcInfoSub_0x0B_0x0C_0x0D_0x0E(pduRxData, pduTxData);\r
791                                 break;\r
792 \r
793                         case 0x14:      // reportDTCFaultDetectionCounter\r
794                                 responseCode = udsReadDtcInfoSub_0x14(pduRxData, pduTxData);\r
795                                 break;\r
796 \r
797                         default:\r
798                                 // Unknown sub function\r
799                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
800                                 break;\r
801                         }\r
802                 }\r
803                 else {\r
804                         // Wrong length\r
805                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
806                 }\r
807         }\r
808         else {\r
809                 // Sub function out of range\r
810                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
811         }\r
812 \r
813         DsdDspProcessingDone(responseCode);\r
814 }\r
815 /**\r
816 **              This Function for check the pointer of Dynamically Did Sourced by Did buffer using a didNr\r
817 **/\r
818 static boolean LookupDDD(uint16 didNr,  const Dcm_DspDDDType **DDid )   \r
819 {\r
820         uint8 i;\r
821         boolean ret = FALSE;\r
822         const Dcm_DspDDDType* DDidptr = &dspDDD[0];\r
823         \r
824         for(i = 0;((i < DCM_MAX_DDD_NUMBER) && (ret == FALSE)); i++)\r
825         {\r
826                 if(DDidptr->DynamicallyDid == didNr)\r
827                 {\r
828                         ret = TRUE;\r
829                 \r
830                 }\r
831                 else\r
832                 {\r
833                         DDidptr++;\r
834                 }\r
835         }\r
836         if(ret == TRUE)\r
837         {\r
838                 *DDid = DDidptr;\r
839         }\r
840 \r
841         return ret;\r
842 }\r
843 \r
844 static boolean lookupDid(uint16 didNr, const Dcm_DspDidType **didPtr)\r
845 {\r
846         const Dcm_DspDidType *dspDid = DCM_Config.Dsp->DspDid;\r
847         boolean didFound = FALSE;\r
848 \r
849         while ((dspDid->DspDidIdentifier != didNr) &&  (!dspDid->Arc_EOL)) {\r
850                 dspDid++;\r
851         }\r
852 \r
853         if (!dspDid->Arc_EOL) {\r
854                 didFound = TRUE;\r
855                 *didPtr = dspDid;\r
856         }\r
857 \r
858         return didFound;\r
859 }\r
860 \r
861 \r
862 static Dcm_NegativeResponseCodeType readDidData(const Dcm_DspDidType *didPtr, PduInfoType *pduTxData, uint16 *txPos)\r
863 {\r
864         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
865 \r
866         if ((didPtr->DspDidInfoRef->DspDidAccess.DspDidRead != NULL) && (didPtr->DspDidConditionCheckReadFnc != NULL) && (didPtr->DspDidReadDataFnc != NULL)) { /** @req DCM433 */\r
867                 if (DspCheckSessionLevel(didPtr->DspDidInfoRef->DspDidAccess.DspDidRead->DspDidReadSessionRef)) { /** @req DCM434 */\r
868                         if (DspCheckSecurityLevel(didPtr->DspDidInfoRef->DspDidAccess.DspDidRead->DspDidReadSecurityLevelRef)) { /** @req DCM435 */\r
869                                 Std_ReturnType result;\r
870                                 Dcm_NegativeResponseCodeType errorCode;\r
871                                 result = didPtr->DspDidConditionCheckReadFnc(&errorCode);\r
872                                 if ((result == E_OK) && (errorCode == DCM_E_POSITIVERESPONSE)) {        /** @req DCM439 */\r
873                                         uint16 didLen = 0;\r
874                                         result = E_NOT_OK;\r
875                                         if (didPtr->DspDidInfoRef->DspDidFixedLength) { /** @req DCM436 */\r
876                                                 didLen = didPtr->DspDidSize;\r
877                                                 result = E_OK;\r
878                                         }\r
879                                         else {\r
880                                                 if (didPtr->DspDidReadDataLengthFnc != NULL) {\r
881                                                         result = didPtr->DspDidReadDataLengthFnc(&didLen);\r
882                                                 }\r
883                                         }\r
884 \r
885                                         if (result == E_OK) {\r
886                                                 // Now ready for reading the data!\r
887                                                 if ((*txPos + didLen + 2) <= pduTxData->SduLength) {\r
888                                                         pduTxData->SduDataPtr[*txPos] = (didPtr->DspDidIdentifier >> 8) & 0xFFu;\r
889                                                         (*txPos)++;\r
890                                                         pduTxData->SduDataPtr[*txPos] = didPtr->DspDidIdentifier & 0xFFu;\r
891                                                         (*txPos)++;\r
892                                                         result = didPtr->DspDidReadDataFnc(&pduTxData->SduDataPtr[*txPos]);     /** @req DCM437 */\r
893                                                         *txPos += didLen;\r
894 \r
895                                                         if (result != E_OK) {\r
896                                                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
897                                                         }\r
898                                                 }\r
899                                                 else { // tx buffer full\r
900                                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
901                                                 }\r
902                                         }\r
903                                         else {  // Not possible to obtain did length\r
904                                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
905                                         }\r
906                                 }\r
907                                 else {  // CheckRead failed\r
908                                         responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
909                                 }\r
910                         }\r
911                         else {  // Not allowed in current security level\r
912                                 responseCode = DCM_E_SECUTITYACCESSDENIED;\r
913                         }\r
914                 }\r
915                 else {  // Not allowed in current session\r
916                         responseCode = DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION;\r
917                 }\r
918         }\r
919         else {  // Read access not configured\r
920                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
921         }\r
922 \r
923         if (responseCode == DCM_E_POSITIVERESPONSE) {\r
924                 // Recurse trough the rest of the dids.         /** @req DCM440 */\r
925                 uint16 i;\r
926                 for (i=0; (!didPtr->DspDidRef[i]->Arc_EOL) && (responseCode == DCM_E_POSITIVERESPONSE); i++) {\r
927                         responseCode = readDidData(didPtr->DspDidRef[i], pduTxData, txPos);\r
928                 }\r
929         }\r
930 \r
931         return responseCode;\r
932 }\r
933 \r
934 /**\r
935 **              This Function for read Dynamically Did data buffer Sourced by Memory address using a didNr\r
936 **/\r
937 static Dcm_NegativeResponseCodeType readDDDData( Dcm_DspDDDType *PDidPtr, uint8 *Data,uint16 *Length)\r
938 {\r
939         uint8 i;\r
940         uint8 dataCount;\r
941         uint8 AddressFormat;\r
942         uint16 SourceDataLength = 0;\r
943         const Dcm_DspMemoryIdInfo *SourceMemoryInfoptr = NULL;\r
944         const Dcm_DspDidType *SourceDidPtr = NULL;\r
945         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
946         *Length = 0;\r
947 \r
948         for(i = 0;(i < DCM_MAX_DDDSOURCE_NUMBER) && (PDidPtr->DDDSource[i].formatOrPosition != 0)\r
949                 &&(responseCode == DCM_E_POSITIVERESPONSE);i++)\r
950         {\r
951                 if(PDidPtr->DDDSource[i].DDDTpyeID == DCM_DDD_SOURCE_ADDRESS)\r
952                 {\r
953 \r
954                         AddressFormat = PDidPtr->DDDSource[i].formatOrPosition&DCM_FORMAT_HIGH_MASK >> 4;\r
955                         if(TRUE == lookupReadMemory(PDidPtr->DDDSource[i].SourceAddressOrDid,AddressFormat,\r
956                                 PDidPtr->DDDSource[i].Size, &SourceMemoryInfoptr))\r
957                         {\r
958                                 if(DspCheckSecurityLevel(SourceMemoryInfoptr->pReadMemoryInfo->pSecurityLevel) != TRUE)\r
959                                 {\r
960                                         responseCode = DCM_E_SECUTITYACCESSDENIED;\r
961                                 }\r
962                         }\r
963                         else\r
964                         {\r
965                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
966                         }\r
967                         if(responseCode == DCM_E_POSITIVERESPONSE)\r
968                         {\r
969                                 Dcm_ReadMemory(DCM_INITIAL,SourceMemoryInfoptr->MemoryIdValue,\r
970                                                                                 PDidPtr->DDDSource[i].SourceAddressOrDid,\r
971                                                                                 PDidPtr->DDDSource[i].Size,\r
972                                                                                 (Data + *Length));\r
973                                 *Length = *Length + PDidPtr->DDDSource[i].Size;\r
974                         }\r
975                 }\r
976                 else if(PDidPtr->DDDSource[i].DDDTpyeID == DCM_DDD_SOURCE_DID)\r
977                 {\r
978                         \r
979                         if(lookupDid(PDidPtr->DDDSource[i].SourceAddressOrDid,&SourceDidPtr) == TRUE)\r
980                         {\r
981                                 if(DspCheckSecurityLevel(SourceDidPtr->DspDidInfoRef->DspDidAccess.DspDidRead->DspDidReadSecurityLevelRef) != TRUE)\r
982                                 {\r
983                                         responseCode = DCM_E_SECUTITYACCESSDENIED;\r
984                                 }\r
985                                 if(SourceDidPtr->DspDidInfoRef->DspDidFixedLength == TRUE)\r
986                                 {\r
987                                         SourceDataLength = SourceDidPtr->DspDidSize;\r
988                                 }\r
989                                 else\r
990                                 {\r
991                                         if(SourceDidPtr->DspDidReadDataLengthFnc != NULL)\r
992                                         {\r
993                                                 SourceDidPtr->DspDidReadDataLengthFnc(&SourceDataLength);\r
994                                         }\r
995                                 }\r
996                                 if((SourceDidPtr->DspDidReadDataFnc != NULL) && (SourceDataLength != 0) && (DCM_E_POSITIVERESPONSE == responseCode))\r
997                                 {\r
998                                 \r
999                                         SourceDidPtr->DspDidReadDataFnc((Data + *Length));\r
1000                                         for(dataCount = 0;dataCount < SourceDataLength;dataCount++)\r
1001                                         {\r
1002                                                 if(dataCount < PDidPtr->DDDSource[i].Size)\r
1003                                                 {\r
1004                                                         *(Data + *Length + dataCount) = *(Data + *Length + dataCount + PDidPtr->DDDSource[i].formatOrPosition - 1);\r
1005                                                 }\r
1006                                                 else\r
1007                                                 {\r
1008                                                         *(Data + *Length + dataCount) = 0;      \r
1009                                                 }\r
1010                                         }\r
1011                                         *Length = *Length + PDidPtr->DDDSource[i].Size;\r
1012                                 }\r
1013                                 else\r
1014                                 {\r
1015                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
1016                                 }\r
1017                         }\r
1018                         else\r
1019                         {\r
1020                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
1021                         }\r
1022                 }\r
1023                 else\r
1024                 {\r
1025                         \r
1026                         responseCode = DCM_E_REQUESTOUTOFRANGE; \r
1027                 }\r
1028         }\r
1029         return responseCode;\r
1030 }\r
1031 \r
1032 void DspUdsReadDataByIdentifier(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
1033 {\r
1034         /** @req DCM253 */\r
1035         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
1036         uint16 nrOfDids;\r
1037         uint16 didNr;\r
1038         const Dcm_DspDidType *didPtr = NULL;\r
1039         Dcm_DspDDDType *DDidPtr=NULL;\r
1040         uint16 txPos = 1;\r
1041         uint16 i;\r
1042         uint16 Length;\r
1043 \r
1044         if ( ((pduRxData->SduLength - 1) % 2) == 0 ) {\r
1045                 nrOfDids = (pduRxData->SduLength - 1) / 2;\r
1046 \r
1047                 for (i = 0; (i < nrOfDids) && (responseCode == DCM_E_POSITIVERESPONSE); i++) \r
1048                         {\r
1049                         didNr = (uint16)((uint16)pduRxData->SduDataPtr[1 + (i * 2)] << 8) + pduRxData->SduDataPtr[2 + (i * 2)];\r
1050                         if (lookupDid(didNr, &didPtr)) {        /** @req DCM438 */\r
1051                                 responseCode = readDidData(didPtr, pduTxData, &txPos);\r
1052                         }\r
1053 \r
1054                         else if(LookupDDD(didNr,&DDidPtr) == TRUE)\r
1055                         {\r
1056                                 /*DCM 651,DCM 652*/\r
1057                                 pduTxData->SduDataPtr[txPos] = (DDidPtr->DynamicallyDid>>8) & 0xFF;\r
1058                                 txPos++;\r
1059                                 pduTxData->SduDataPtr[txPos] = (uint8)(DDidPtr->DynamicallyDid & 0xFF);\r
1060                                 txPos++;\r
1061                                 responseCode = readDDDData(DDidPtr,&(pduTxData->SduDataPtr[txPos]), &Length);\r
1062                                 txPos = txPos + Length;\r
1063                         }\r
1064 \r
1065                         else\r
1066                         { // DID not found\r
1067                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
1068                         }\r
1069                 }\r
1070         }\r
1071         else {\r
1072                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
1073         }\r
1074 \r
1075         if (responseCode == DCM_E_POSITIVERESPONSE) {\r
1076                 pduTxData->SduLength = txPos;\r
1077         }\r
1078 \r
1079         DsdDspProcessingDone(responseCode);\r
1080 }\r
1081 \r
1082 \r
1083 static Dcm_NegativeResponseCodeType readDidScalingData(const Dcm_DspDidType *didPtr, const PduInfoType *pduTxData, uint16 *txPos)\r
1084 {\r
1085         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
1086 \r
1087         if (didPtr->DspDidGetScalingInfoFnc != NULL) {\r
1088                 uint16 scalingInfoLen;\r
1089 \r
1090                 scalingInfoLen = didPtr->DspDidInfoRef->DspDidScalingInfoSize;\r
1091                 if ((*txPos + scalingInfoLen + 2) <= pduTxData->SduLength) {\r
1092                         Std_ReturnType result;\r
1093                         Dcm_NegativeResponseCodeType errorCode;\r
1094 \r
1095                         pduTxData->SduDataPtr[*txPos] = (didPtr->DspDidIdentifier >> 8) & 0xFFu;\r
1096                         (*txPos)++;\r
1097                         pduTxData->SduDataPtr[*txPos] = didPtr->DspDidIdentifier & 0xFFu;\r
1098                         (*txPos)++;\r
1099                         result = didPtr->DspDidGetScalingInfoFnc(&pduTxData->SduDataPtr[*txPos], &errorCode);   /** @req DCM394 */\r
1100                         *txPos += scalingInfoLen;\r
1101 \r
1102                         if ((result != E_OK) || (errorCode != DCM_E_POSITIVERESPONSE)) {\r
1103                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1104                         }\r
1105                 }\r
1106                 else { // tx buffer full\r
1107                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
1108                 }\r
1109         }\r
1110         else {  // DspDidGetScalingInfoFnc null pointer\r
1111                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1112         }\r
1113 \r
1114         return responseCode;\r
1115 }\r
1116 \r
1117 void DspUdsReadScalingDataByIdentifier(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
1118 {\r
1119         /** @req DCM258 */\r
1120         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
1121         uint16 didNr;\r
1122         const Dcm_DspDidType *didPtr = NULL;\r
1123 \r
1124         uint16 txPos = 1;\r
1125 \r
1126         if (pduRxData->SduLength == 3) {\r
1127                 didNr = (uint16)((uint16)pduRxData->SduDataPtr[1] << 8) + pduRxData->SduDataPtr[2];\r
1128                 if (lookupDid(didNr, &didPtr)) {\r
1129                         responseCode = readDidScalingData(didPtr, pduTxData, &txPos);\r
1130                 }\r
1131                 else { // DID not found\r
1132                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
1133                 }\r
1134 \r
1135                 if (responseCode == DCM_E_POSITIVERESPONSE) {\r
1136                         pduTxData->SduLength = txPos;\r
1137                 }\r
1138         }\r
1139         else {\r
1140                 // Length not ok\r
1141                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
1142         }\r
1143 \r
1144         DsdDspProcessingDone(responseCode);\r
1145 }\r
1146 \r
1147 \r
1148 static Dcm_NegativeResponseCodeType writeDidData(const Dcm_DspDidType *didPtr, const PduInfoType *pduRxData, uint16 writeDidLen)\r
1149 {\r
1150         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
1151 \r
1152         if ((didPtr->DspDidInfoRef->DspDidAccess.DspDidWrite != NULL) && (didPtr->DspDidConditionCheckWriteFnc != NULL) && (didPtr->DspDidWriteDataFnc != NULL)) {      /** @req DCM468 */\r
1153                 if (DspCheckSessionLevel(didPtr->DspDidInfoRef->DspDidAccess.DspDidWrite->DspDidWriteSessionRef)) { /** @req DCM469 */\r
1154                         if (DspCheckSecurityLevel(didPtr->DspDidInfoRef->DspDidAccess.DspDidWrite->DspDidWriteSecurityLevelRef)) { /** @req DCM470 */\r
1155                                 Std_ReturnType result;\r
1156                                 Dcm_NegativeResponseCodeType errorCode;\r
1157                                 result = didPtr->DspDidConditionCheckWriteFnc(&errorCode);      /** @req DCM471 */\r
1158                                 if ((result == E_OK) && (errorCode == DCM_E_POSITIVERESPONSE)) {\r
1159                                         uint16 didLen = 0;\r
1160                                         result = E_NOT_OK;\r
1161                                         if (didPtr->DspDidInfoRef->DspDidFixedLength) { /** @req DCM472 */\r
1162                                                 didLen = didPtr->DspDidSize;\r
1163                                                 result = E_OK;\r
1164                                         }\r
1165                                         else {\r
1166                                                 if (didPtr->DspDidReadDataLengthFnc != NULL) {\r
1167                                                         result = didPtr->DspDidReadDataLengthFnc(&didLen);\r
1168                                                 }                                       }\r
1169 \r
1170                                         if (result == E_OK) {\r
1171                                                 if (didLen == writeDidLen) {    /** @req DCM473 */\r
1172                                                         result = didPtr->DspDidWriteDataFnc(&pduRxData->SduDataPtr[3], (uint8)didLen, &errorCode);      /** @req DCM395 */\r
1173                                                         if ((result != E_OK) || (errorCode != DCM_E_POSITIVERESPONSE)) {\r
1174                                                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1175                                                         }\r
1176                                                 }\r
1177                                                 else {\r
1178                                                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
1179                                                 }\r
1180                                         }\r
1181                                         else {  // Not possible to obtain did length\r
1182                                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1183                                         }\r
1184                                 }\r
1185                                 else {  // CheckRead failed\r
1186                                         responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1187                                 }\r
1188                         }\r
1189                         else {  // Not allowed in current security level\r
1190                                 responseCode = DCM_E_SECUTITYACCESSDENIED;\r
1191                         }\r
1192                 }\r
1193                 else {  // Not allowed in current session\r
1194                         responseCode = DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION;\r
1195                 }\r
1196         }\r
1197         else {  // Read access not configured\r
1198                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
1199         }\r
1200 \r
1201         return responseCode;\r
1202 }\r
1203 \r
1204 void DspUdsWriteDataByIdentifier(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
1205 {\r
1206         /** @req DCM255 */\r
1207         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
1208         uint16 didNr;\r
1209         const Dcm_DspDidType *didPtr = NULL;\r
1210 \r
1211         uint16 didDataLength;\r
1212 \r
1213         didDataLength = pduRxData->SduLength - 3;\r
1214         didNr = (uint16)((uint16)pduRxData->SduDataPtr[1] << 8) + pduRxData->SduDataPtr[2];\r
1215         if (lookupDid(didNr, &didPtr)) {        /** @req DCM467 */\r
1216                 responseCode = writeDidData(didPtr, pduRxData, didDataLength);\r
1217         }\r
1218         else { // DID not found\r
1219                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
1220         }\r
1221 \r
1222         if (responseCode == DCM_E_POSITIVERESPONSE) {\r
1223                 pduTxData->SduLength = 3;\r
1224                 pduTxData->SduDataPtr[1] = (didNr >> 8) & 0xFFu;\r
1225                 pduTxData->SduDataPtr[2] = didNr & 0xFFu;\r
1226         }\r
1227 \r
1228         DsdDspProcessingDone(responseCode);\r
1229 }\r
1230 \r
1231 \r
1232 void DspUdsSecurityAccess(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
1233 {\r
1234         /** @req DCM252 */\r
1235         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
1236 \r
1237         // Check sub function range (0x01 to 0x42)\r
1238         if ((pduRxData->SduDataPtr[1] >= 0x01) && (pduRxData->SduDataPtr[1] <= 0x42)) {\r
1239                 boolean isRequestSeed = pduRxData->SduDataPtr[1] & 0x01u;\r
1240                 Dcm_SecLevelType requestedSecurityLevel = (pduRxData->SduDataPtr[1]-1)/2;\r
1241                 Dcm_NegativeResponseCodeType getSeedErrorCode;\r
1242 \r
1243                 if (isRequestSeed) {\r
1244                         // requestSeed message\r
1245                         // Check if type exist in security table\r
1246                         const Dcm_DspSecurityRowType *securityRow = &DCM_Config.Dsp->DspSecurity->DspSecurityRow[0];\r
1247                         while ((securityRow->DspSecurityLevel != requestedSecurityLevel) && (!securityRow->Arc_EOL)) {\r
1248                                 securityRow++;\r
1249                         }\r
1250                         if (!securityRow->Arc_EOL) {\r
1251                                 // Check length\r
1252                                 if (pduRxData->SduLength == (2 + securityRow->DspSecurityADRSize)) {    /** @req DCM321.RequestSeed */\r
1253                                         Dcm_SecLevelType activeSecLevel;\r
1254                                         Std_ReturnType result;\r
1255                                         result = Dcm_GetSecurityLevel(&activeSecLevel);\r
1256                                         if (result == E_OK) {\r
1257                                                 if (requestedSecurityLevel == activeSecLevel) {         /** @req DCM323 */\r
1258                                                         pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1];\r
1259                                                         // If same level set the seed to zeroes\r
1260                                                         memset(&pduTxData->SduDataPtr[2], 0, securityRow->DspSecuritySeedSize);\r
1261                                                         pduTxData->SduLength = 2 + securityRow->DspSecuritySeedSize;\r
1262                                                 } else {\r
1263                                                         // New security level ask for seed\r
1264                                                         if (securityRow->GetSeed != NULL) {\r
1265                                                                 Std_ReturnType getSeedResult;\r
1266                                                                 getSeedResult = securityRow->GetSeed(&pduRxData->SduDataPtr[2], &pduTxData->SduDataPtr[2], &getSeedErrorCode); /** @req DCM324.RequestSeed */\r
1267                                                                 if ((getSeedResult == E_OK) && (getSeedErrorCode == E_OK)) {\r
1268                                                                         // Everything ok add sub function to tx message and send it.\r
1269                                                                         pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1];\r
1270                                                                         pduTxData->SduLength = 2 + securityRow->DspSecuritySeedSize;\r
1271 \r
1272                                                                         dspUdsSecurityAccesData.reqSecLevel = requestedSecurityLevel;\r
1273                                                                         dspUdsSecurityAccesData.reqSecLevelRef = securityRow;\r
1274                                                                         dspUdsSecurityAccesData.reqInProgress = TRUE;\r
1275                                                                 }\r
1276                                                                 else {\r
1277                                                                         // GetSeed returned not ok\r
1278                                                                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
1279                                                                 }\r
1280                                                         } else {\r
1281                                                                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
1282                                                         }\r
1283                                                 }\r
1284                                         } else {\r
1285                                                 // TODO: What to do?\r
1286                                                 responseCode = DCM_E_GENERALREJECT;\r
1287                                         }\r
1288 \r
1289                                 }\r
1290                                 else {\r
1291                                         // Length not ok\r
1292                                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
1293                                 }\r
1294                         }\r
1295                         else {\r
1296                                 // Requested security level not configured\r
1297                                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
1298                         }\r
1299                 }\r
1300                 else {\r
1301                         // sendKey message\r
1302                         if (dspUdsSecurityAccesData.reqInProgress) {\r
1303                                 if (pduRxData->SduLength == (2 + dspUdsSecurityAccesData.reqSecLevelRef->DspSecurityKeySize)) { /** @req DCM321.SendKey */\r
1304                                         if (requestedSecurityLevel == dspUdsSecurityAccesData.reqSecLevel) {\r
1305                                                 if (dspUdsSecurityAccesData.reqSecLevelRef->CompareKey != NULL) {\r
1306                                                         Std_ReturnType compareKeyResult;\r
1307                                                         compareKeyResult = dspUdsSecurityAccesData.reqSecLevelRef->CompareKey(&pduRxData->SduDataPtr[2]); /** @req DCM324.SendKey */\r
1308                                                         if (compareKeyResult == E_OK) {\r
1309                                                                 // Request accepted\r
1310                                                                 // Kill timer\r
1311                                                                 DslSetSecurityLevel(dspUdsSecurityAccesData.reqSecLevelRef->DspSecurityLevel); /** @req DCM325 */\r
1312                                                                 dspUdsSecurityAccesData.reqInProgress = FALSE;\r
1313                                                                 pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1];\r
1314                                                                 pduTxData->SduLength = 2;\r
1315                                                         }\r
1316                                                         else {\r
1317                                                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1318                                                         }\r
1319                                                 } else {\r
1320                                                         responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1321                                                 }\r
1322                                         }\r
1323                                         else {\r
1324                                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1325                                         }\r
1326                                 }\r
1327                                 else {\r
1328                                         // Length not ok\r
1329                                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
1330                                 }\r
1331                         }\r
1332                         else {\r
1333                                 // sendKey request without a preceding requestSeed\r
1334                                 responseCode = DCM_E_REQUESTSEQUENCEERROR;\r
1335                         }\r
1336                 }\r
1337         }\r
1338         else {\r
1339                 responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;\r
1340         }\r
1341 \r
1342         DsdDspProcessingDone(responseCode);\r
1343 }\r
1344 \r
1345 \r
1346 static boolean lookupRoutine(uint16 routineId, const Dcm_DspRoutineType **routinePtr)\r
1347 {\r
1348         const Dcm_DspRoutineType *dspRoutine = DCM_Config.Dsp->DspRoutine;\r
1349         boolean routineFound = FALSE;\r
1350 \r
1351         while ((dspRoutine->DspRoutineIdentifier != routineId) &&  (!dspRoutine->Arc_EOL)) {\r
1352                 dspRoutine++;\r
1353         }\r
1354 \r
1355         if (!dspRoutine->Arc_EOL) {\r
1356                 routineFound = TRUE;\r
1357                 *routinePtr = dspRoutine;\r
1358         }\r
1359 \r
1360         return routineFound;\r
1361 }\r
1362 \r
1363 \r
1364 static Dcm_NegativeResponseCodeType startRoutine(const Dcm_DspRoutineType *routinePtr, const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
1365 {\r
1366         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
1367         Std_ReturnType routineResult;\r
1368 \r
1369         // startRoutine\r
1370         if ((routinePtr->DspStartRoutineFnc != NULL) && (routinePtr->DspRoutineInfoRef->DspStartRoutine != NULL)) {\r
1371                 if (((routinePtr->DspRoutineInfoRef->DspStartRoutine->DspStartRoutineCtrlOptRecSize + 4) == pduRxData->SduLength)\r
1372                         && ((routinePtr->DspRoutineInfoRef->DspStartRoutine->DspStartRoutineStsOptRecSize + 4) <= pduTxData->SduLength)) {\r
1373                         pduTxData->SduLength = routinePtr->DspRoutineInfoRef->DspStartRoutine->DspStartRoutineStsOptRecSize + 4;\r
1374                         routineResult = routinePtr->DspStartRoutineFnc(&pduRxData->SduDataPtr[4], &pduTxData->SduDataPtr[4], &responseCode);    /** @req DCM400 */ /** @req DCM401 */\r
1375                         if (routineResult != E_OK) {\r
1376                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1377                         }\r
1378                 }\r
1379                 else {\r
1380                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
1381                 }\r
1382         }\r
1383         else {\r
1384                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1385         }\r
1386 \r
1387         return responseCode;\r
1388 }\r
1389 \r
1390 \r
1391 static Dcm_NegativeResponseCodeType stopRoutine(const Dcm_DspRoutineType *routinePtr, const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
1392 {\r
1393         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
1394         Std_ReturnType routineResult;\r
1395 \r
1396         // stopRoutine\r
1397         if ((routinePtr->DspStopRoutineFnc != NULL) && (routinePtr->DspRoutineInfoRef->DspRoutineStop != NULL)) {\r
1398                 if (((routinePtr->DspRoutineInfoRef->DspRoutineStop->DspStopRoutineCtrlOptRecSize + 4) == pduRxData->SduLength)\r
1399                         && ((routinePtr->DspRoutineInfoRef->DspRoutineStop->DspStopRoutineStsOptRecSize + 4) <= pduTxData->SduLength)) {\r
1400                         pduTxData->SduLength = routinePtr->DspRoutineInfoRef->DspRoutineStop->DspStopRoutineStsOptRecSize + 4;\r
1401                         routineResult = routinePtr->DspStopRoutineFnc(&pduRxData->SduDataPtr[4], &pduTxData->SduDataPtr[4], &responseCode);     /** @req DCM402 */ /** @req DCM403 */\r
1402                         if (routineResult != E_OK) {\r
1403                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1404                         }\r
1405                 }\r
1406                 else {\r
1407                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
1408                 }\r
1409         }\r
1410         else {\r
1411                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1412         }\r
1413 \r
1414         return responseCode;\r
1415 }\r
1416 \r
1417 \r
1418 static Dcm_NegativeResponseCodeType requestRoutineResults(const Dcm_DspRoutineType *routinePtr, PduInfoType *pduTxData)\r
1419 {\r
1420         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
1421         Std_ReturnType routineResult;\r
1422 \r
1423         // requestRoutineResults\r
1424         if ((routinePtr->DspRequestResultRoutineFnc != NULL) && (routinePtr->DspRoutineInfoRef->DspRoutineRequestRes != NULL)) {\r
1425                 if ((routinePtr->DspRoutineInfoRef->DspRoutineRequestRes->DspReqResRtnCtrlOptRecSize + 4) <= pduTxData->SduLength) {\r
1426                         pduTxData->SduLength = routinePtr->DspRoutineInfoRef->DspRoutineRequestRes->DspReqResRtnCtrlOptRecSize + 4;\r
1427                         routineResult = routinePtr->DspRequestResultRoutineFnc(&pduTxData->SduDataPtr[4], &responseCode);       /** @req DCM404 */ /** @req DCM405 */\r
1428                         if (routineResult != E_OK) {\r
1429                                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1430                         }\r
1431                 }\r
1432                 else {\r
1433                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
1434                 }\r
1435         }\r
1436         else {\r
1437                 responseCode = DCM_E_CONDITIONSNOTCORRECT;\r
1438         }\r
1439 \r
1440         return responseCode;\r
1441 }\r
1442 \r
1443 \r
1444 void DspUdsRoutineControl(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
1445 {\r
1446         /** @req DCM257 */\r
1447         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
1448         uint8 subFunctionNumber = 0;\r
1449         uint16 routineId = 0;\r
1450         const Dcm_DspRoutineType *routinePtr = NULL;\r
1451 \r
1452         if (pduRxData->SduLength >= 4) {\r
1453                 subFunctionNumber = pduRxData->SduDataPtr[1];\r
1454                 if ((subFunctionNumber > 0) && (subFunctionNumber < 4)) {\r
1455                         routineId = (uint16)((uint16)pduRxData->SduDataPtr[2] << 8) + pduRxData->SduDataPtr[3];\r
1456                         if (lookupRoutine(routineId, &routinePtr)) {\r
1457                                 if (DspCheckSessionLevel(routinePtr->DspRoutineInfoRef->DspRoutineAuthorization.DspRoutineSessionRef)) {\r
1458                                         if (DspCheckSecurityLevel(routinePtr->DspRoutineInfoRef->DspRoutineAuthorization.DspRoutineSecurityLevelRef)) {\r
1459                                                 switch (subFunctionNumber) {\r
1460                                                 case 0x01:      // startRoutine\r
1461                                                         responseCode = startRoutine(routinePtr, pduRxData, pduTxData);\r
1462                                                         break;\r
1463 \r
1464                                                 case 0x02:      // stopRoutine\r
1465                                                         responseCode = stopRoutine(routinePtr, pduRxData, pduTxData);\r
1466                                                         break;\r
1467 \r
1468                                                 case 0x03:      // requestRoutineResults\r
1469                                                         responseCode =  requestRoutineResults(routinePtr, pduTxData);\r
1470                                                         break;\r
1471 \r
1472                                                 default:        // This shall never happen\r
1473                                                         responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;\r
1474                                                         break;\r
1475                                                 }\r
1476                                         }\r
1477                                         else {  // Not allowed in current security level\r
1478                                                 responseCode = DCM_E_SECUTITYACCESSDENIED;\r
1479                                         }\r
1480                                 }\r
1481                                 else {  // Not allowed in current session\r
1482                                         responseCode = DCM_E_SERVICENOTSUPPORTEDINACTIVESESSION;\r
1483                                 }\r
1484                         }\r
1485                         else {  // Unknown routine identifier\r
1486                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
1487                         }\r
1488                 }\r
1489                 else {  // Sub function not supported\r
1490                         responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;\r
1491                 }\r
1492         }\r
1493         else {\r
1494                 // Wrong length\r
1495                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
1496         }\r
1497 \r
1498         if (responseCode == DCM_E_POSITIVERESPONSE) {\r
1499                 // Add header to the positive response message\r
1500                 pduTxData->SduDataPtr[1] = subFunctionNumber;\r
1501                 pduTxData->SduDataPtr[2] = (routineId >> 8) & 0xFFu;\r
1502                 pduTxData->SduDataPtr[3] = routineId & 0xFFu;\r
1503         }\r
1504 \r
1505         DsdDspProcessingDone(responseCode);\r
1506 }\r
1507 \r
1508 \r
1509 void DspUdsTesterPresent(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
1510 {\r
1511         /** @req DCM251 */\r
1512         if (pduRxData->SduLength == 2) {\r
1513                 switch (pduRxData->SduDataPtr[1])\r
1514                 {\r
1515                 case ZERO_SUB_FUNCTION:\r
1516                         DslResetSessionTimeoutTimer();\r
1517                         // Create positive response\r
1518                         pduTxData->SduDataPtr[1] = ZERO_SUB_FUNCTION;\r
1519                         pduTxData->SduLength = 2;\r
1520                         DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
1521                         break;\r
1522 \r
1523                 default:\r
1524                         DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);\r
1525                         break;\r
1526                 }\r
1527         }\r
1528         else {\r
1529                 // Wrong length\r
1530                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);\r
1531         }\r
1532 }\r
1533 \r
1534 \r
1535 void DspUdsControlDtcSetting(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
1536 {\r
1537         /** @req DCM249 */\r
1538         Dem_ReturnControlDTCStorageType resultCode;\r
1539 \r
1540         if (pduRxData->SduLength == 2) {\r
1541                 switch (pduRxData->SduDataPtr[1])\r
1542                 {\r
1543                 case 0x01:      // ON\r
1544                         resultCode = Dem_EnableDTCStorage(DEM_DTC_GROUP_ALL_DTCS, DEM_DTC_KIND_ALL_DTCS);               /** @req DCM304 */\r
1545                         if (resultCode == DEM_CONTROL_DTC_STORAGE_OK) {\r
1546                                 pduTxData->SduDataPtr[1] = 0x01;\r
1547                                 pduTxData->SduLength = 2;\r
1548                                 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
1549                         }\r
1550                         else {\r
1551                                 DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);\r
1552                         }\r
1553                         break;\r
1554 \r
1555                 case 0x02:      // OFF\r
1556                         resultCode = Dem_DisableDTCStorage(DEM_DTC_GROUP_ALL_DTCS, DEM_DTC_KIND_ALL_DTCS);              /** @req DCM406 */\r
1557                         if (resultCode == DEM_CONTROL_DTC_STORAGE_OK) {\r
1558                                 pduTxData->SduDataPtr[1] = 0x02;\r
1559                                 pduTxData->SduLength = 2;\r
1560                                 DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
1561                         }\r
1562                         else {\r
1563                                 DsdDspProcessingDone(DCM_E_REQUESTOUTOFRANGE);\r
1564                         }\r
1565                         break;\r
1566 \r
1567                 default:\r
1568                         DsdDspProcessingDone(DCM_E_SUBFUNCTIONNOTSUPPORTED);\r
1569                         break;\r
1570                 }\r
1571         }\r
1572         else {\r
1573                 // Wrong length\r
1574                 DsdDspProcessingDone(DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT);\r
1575         }\r
1576 }\r
1577 \r
1578 \r
1579 void DspDcmConfirmation(PduIdType confirmPduId)\r
1580 {\r
1581         if (dspUdsEcuResetData.resetPending) {\r
1582                 if (confirmPduId == dspUdsEcuResetData.resetPduId) {\r
1583                         dspUdsEcuResetData.resetPending = FALSE;\r
1584 #if defined(USE_MCU) && ( MCU_PERFORM_RESET_API == STD_ON )\r
1585                         Mcu_PerformReset();\r
1586 #else\r
1587                         DET_REPORTERROR(MODULE_ID_DCM, 0, DCM_UDS_RESET_ID, DCM_E_NOT_SUPPORTED);\r
1588 #endif\r
1589                 }\r
1590         }\r
1591 }\r
1592 \r
1593 \r
1594 /* REVIEW JB 2012-06-05: Removed iSoft function header - please don't add iSoft specific headers in the future */\r
1595 static boolean CheckReadMemoryByAddress( boolean useId,uint32 memoryAddress,\r
1596                                                                                 uint8 memoryAddressFormat,\r
1597                                                                                 uint32 memorySize,\r
1598                                                                                 const Dcm_DspMemoryIdInfo  *dspMemory)\r
1599 {\r
1600         boolean ret = FALSE;\r
1601         uint8 MemoryId;\r
1602 \r
1603         if(useId == FALSE)\r
1604         {\r
1605                 /*@req DCM493*/\r
1606                 if((memoryAddress >= dspMemory->pReadMemoryInfo->MemoryAddressLow)\r
1607                         && (memoryAddress <= dspMemory->pReadMemoryInfo->MemoryAddressHigh)\r
1608                         && (memoryAddress + memorySize - 1 <= dspMemory->pReadMemoryInfo->MemoryAddressHigh))\r
1609                 {\r
1610                         ret = TRUE;\r
1611                 }\r
1612         }\r
1613         else\r
1614         {\r
1615                 MemoryId = (uint8)(memoryAddress >> ((memoryAddressFormat - 1)*8));\r
1616                 memoryAddress = (uint32)(memoryAddress & DCM_MEMORY_ADDRESS_MASK);\r
1617 \r
1618                 if((MemoryId == dspMemory->MemoryIdValue)&&\r
1619                         (memoryAddress >= dspMemory->pReadMemoryInfo->MemoryAddressLow)\r
1620                         && (memoryAddress <= dspMemory->pReadMemoryInfo->MemoryAddressHigh)\r
1621                         && (memoryAddress + memorySize - 1 <= dspMemory->pReadMemoryInfo->MemoryAddressHigh))\r
1622                 {\r
1623                         ret = TRUE;\r
1624                 }\r
1625         }\r
1626         \r
1627         return ret;\r
1628 }\r
1629 \r
1630 static boolean lookupReadMemory(uint32 memoryAddress,\r
1631                                                                 uint8  memoryAddressFormat,\r
1632                                                                 uint32 memorySize,\r
1633                                                                 const Dcm_DspMemoryIdInfo  **MemoryInfoPtr)\r
1634 {\r
1635         uint8 i;\r
1636         boolean memoryFound = FALSE;\r
1637         const Dcm_DspMemoryIdInfo *dspMemoryInfo = DCM_Config.Dsp->DspMemory->DspMemoryIdInfo;\r
1638 \r
1639         for(i = 0; (dspMemoryInfo->Arc_EOL == FALSE) && (memoryFound == FALSE); i++)\r
1640         {\r
1641                 if(TRUE == CheckReadMemoryByAddress(DCM_Config.Dsp->DspMemory->DcmDspUseMemoryId,memoryAddress,memoryAddressFormat,memorySize,dspMemoryInfo))\r
1642                 {\r
1643                         memoryFound = TRUE;\r
1644                 }\r
1645                 else\r
1646                 {\r
1647                         (Dcm_DspMemoryIdInfo *)dspMemoryInfo++;\r
1648                 }\r
1649         }\r
1650         if (memoryFound == TRUE)\r
1651         {\r
1652                 *MemoryInfoPtr = dspMemoryInfo;\r
1653         }\r
1654         \r
1655         return memoryFound;\r
1656 }\r
1657 \r
1658 static Dcm_NegativeResponseCodeType readMemoryData( Dcm_OpStatusType *OpStatus,\r
1659                                                                                                         const Dcm_DspMemoryIdInfo *MemoryPtr,\r
1660                                                                                                         uint32 MemoryAddress,\r
1661                                                                                                         uint32 MemorySize,\r
1662                                                                                                         PduInfoType *pduTxData)\r
1663 {\r
1664         Dcm_ReturnReadMemoryType ReadRet;\r
1665         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
1666         ReadRet = Dcm_ReadMemory(*OpStatus,MemoryPtr->MemoryIdValue,\r
1667                                                                         MemoryAddress,\r
1668                                                                         MemorySize,\r
1669                                                                         &pduTxData->SduDataPtr[1]);\r
1670         if(DCM_READ_FAILED == ReadRet)\r
1671         {\r
1672                 responseCode = DCM_E_GENERALPROGRAMMINGFAILURE;  /*@req Dcm644*/\r
1673         }\r
1674         if (DCM_READ_PENDING == ReadRet)\r
1675         {\r
1676                 *OpStatus = DCM_READ_PENDING;\r
1677         }       \r
1678         return responseCode;\r
1679 }\r
1680 \r
1681 /*@req Dcm442,DCM492*/\r
1682 void DspUdsReadMemoryByAddress(const PduInfoType *pduRxData, PduInfoType *pduTxData)\r
1683 {\r
1684         typedef struct{\r
1685                 uint32 MemoryAddressStart;                                      /*  low  address of a  memory block to read or write*/\r
1686                 uint32 MemoryIdValue;                                           /*  memory ID  to read or write uint used by parameter */\r
1687                 const Dcm_DspMemoryIdInfo *MemoryIdConfigPtr;           \r
1688                 Dcm_NegativeResponseCodeType ResponseCode; \r
1689                 uint8 MemorySizeFormat;\r
1690                 uint8 MemoryAddressFormat;\r
1691                 uint32 MemorySize;\r
1692                 uint16 MessageLength;\r
1693         }DspUdsReadMemoryByAddressType; /*the typed used for  SID read memory by address*/\r
1694         uint8 i;\r
1695         DspUdsReadMemoryByAddressType dspReadMemoryByAddress;\r
1696         Dcm_OpStatusType OpStatus = 0;\r
1697         dspReadMemoryByAddress.MemoryAddressStart = 0;\r
1698         dspReadMemoryByAddress.MemorySize = 0;\r
1699         dspReadMemoryByAddress.MemoryIdConfigPtr = NULL;\r
1700         dspReadMemoryByAddress.ResponseCode = DCM_E_POSITIVERESPONSE;\r
1701         dspReadMemoryByAddress.MemorySizeFormat = ((uint8)(pduRxData->SduDataPtr[1] & DCM_FORMAT_HIGH_MASK)) >> 4;      /*@req UDS_REQ_0x23_1 & UDS_REQ_0x23_5*/\r
1702         dspReadMemoryByAddress.MemoryAddressFormat = ((uint8)(pduRxData->SduDataPtr[1])) & 0x0Fu;   /*@req UDS_REQ_0x23_1 & UDS_REQ_0x23_5*/\r
1703 \r
1704         if((dspReadMemoryByAddress.MemoryAddressFormat == 0)||(dspReadMemoryByAddress.MemorySizeFormat == 0))\r
1705         {\r
1706                 dspReadMemoryByAddress.ResponseCode = DCM_E_REQUESTOUTOFRANGE;  /*UDS_REQ_0x23_10*/\r
1707         }\r
1708         else\r
1709         {\r
1710                 dspReadMemoryByAddress.MessageLength = (uint16)(dspReadMemoryByAddress.MemoryAddressFormat + dspReadMemoryByAddress.MemorySizeFormat + SID_AND_ALFID_LEN2);\r
1711                 if(dspReadMemoryByAddress.MessageLength == (uint16)(pduRxData->SduLength))\r
1712                 {\r
1713                         /*take start address out */\r
1714                         for(i = 0; i < dspReadMemoryByAddress.MemoryAddressFormat; i++)\r
1715                         {\r
1716                                 dspReadMemoryByAddress.MemoryAddressStart <<= 8;\r
1717                                 dspReadMemoryByAddress.MemoryAddressStart += (uint32)(pduRxData->SduDataPtr[SID_AND_ALFID_LEN2 + i]);\r
1718                         }\r
1719 \r
1720                         /*take value of MemorySize out */\r
1721                         for(i = 0; i < dspReadMemoryByAddress.MemorySizeFormat; i++)\r
1722                         {\r
1723                                 dspReadMemoryByAddress.MemorySize <<= 8;\r
1724                                 dspReadMemoryByAddress.MemorySize += (uint32)(pduRxData->SduDataPtr[2 + i + dspReadMemoryByAddress.MemoryAddressFormat]);\r
1725                         }\r
1726                         if(dspReadMemoryByAddress.MemorySize < DCM_PROTOCAL_TP_MAX_LENGTH)\r
1727                         {\r
1728                                 if(TRUE == lookupReadMemory(dspReadMemoryByAddress.MemoryAddressStart,\r
1729                                                                                         dspReadMemoryByAddress.MemoryAddressFormat,\r
1730                                                                                         dspReadMemoryByAddress.MemorySize,\r
1731                                                                                         &dspReadMemoryByAddress.MemoryIdConfigPtr))\r
1732                                 {\r
1733                                         if (DspCheckSecurityLevel(dspReadMemoryByAddress.MemoryIdConfigPtr->pReadMemoryInfo->pSecurityLevel) == TRUE)\r
1734                                         {\r
1735                                                 dspReadMemoryByAddress.ResponseCode = readMemoryData(&OpStatus,dspReadMemoryByAddress.MemoryIdConfigPtr,\r
1736                                                                                                                                                         dspReadMemoryByAddress.MemoryAddressStart,\r
1737                                                                                                                                                         dspReadMemoryByAddress.MemorySize,pduTxData);/*@req UDS_REQ_0x23_9*/\r
1738                                         \r
1739                                         }\r
1740                                         else\r
1741                                         {\r
1742                                                 dspReadMemoryByAddress.ResponseCode = DCM_E_SECUTITYACCESSDENIED;/*@req UDS_REQ_0x23_11,@req DCM494*/\r
1743                                         }\r
1744                                 }\r
1745                                 else\r
1746                                 {\r
1747                                         dspReadMemoryByAddress.ResponseCode = DCM_E_REQUESTOUTOFRANGE;      /*@req UDS_REQ_0x23_7,UDS_REQ_0x23_8*/\r
1748                                 }\r
1749                         }\r
1750                         else\r
1751                         {\r
1752                                 dspReadMemoryByAddress.ResponseCode = DCM_E_REQUESTOUTOFRANGE;\r
1753                         }\r
1754                 }\r
1755                 else\r
1756                 {\r
1757                         dspReadMemoryByAddress.ResponseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT; /*@req UDS_REQ_0x23_6*/\r
1758                 }\r
1759         }\r
1760         if(DCM_E_POSITIVERESPONSE == dspReadMemoryByAddress.ResponseCode)\r
1761         {\r
1762                 pduTxData->SduLength = 1 + dspReadMemoryByAddress.MemorySize;\r
1763                 if(OpStatus == DCM_READ_PENDING)\r
1764                 {\r
1765                         dspMemoryState = DCM_MEMORY_READ;\r
1766                 }\r
1767                 else\r
1768                 {\r
1769                         DsdDspProcessingDone(DCM_E_POSITIVERESPONSE);\r
1770                 }\r
1771         }\r
1772         else\r
1773         {\r
1774                 DsdDspProcessingDone(dspReadMemoryByAddress.ResponseCode);\r
1775         }\r
1776 }\r
1777 \r
1778 static boolean checkWriteMemoryByAddress(boolean useId,uint32 memoryAddress,\r
1779                                                                                 uint8 memoryAddressFormat,\r
1780                                                                                 uint32 memorySize,\r
1781                                                                                 const Dcm_DspMemoryIdInfo *dspMemory)\r
1782 {\r
1783         boolean ret = FALSE;\r
1784         uint8 MemoryId;\r
1785         \r
1786         if(useId == FALSE)\r
1787         {\r
1788                 if((memoryAddress >= dspMemory->pWriteMemoryInfo->MemoryAddressLow)\r
1789                         && (memoryAddress <= dspMemory->pWriteMemoryInfo->MemoryAddressHigh)\r
1790                         && (memoryAddress + memorySize - 1 <= dspMemory->pWriteMemoryInfo->MemoryAddressHigh))\r
1791                 {\r
1792                         ret = TRUE;\r
1793                 }\r
1794         }\r
1795         else\r
1796         {\r
1797                 MemoryId = (uint8)(memoryAddress >> ((memoryAddressFormat - 1)*8));\r
1798                 /* REVIEW JB 2012-06-05: See comment for corresponding read function */\r
1799                 memoryAddress = memoryAddress & DCM_MEMORY_ADDRESS_MASK;\r
1800 \r
1801                 if((MemoryId == dspMemory->MemoryIdValue) &&\r
1802                         (memoryAddress >= dspMemory->pWriteMemoryInfo->MemoryAddressLow)\r
1803                         && (memoryAddress <= dspMemory->pWriteMemoryInfo->MemoryAddressHigh)\r
1804                         && (memoryAddress + memorySize -1 <= dspMemory->pWriteMemoryInfo->MemoryAddressHigh))\r
1805                 {\r
1806                         ret = TRUE;\r
1807                 }\r
1808 \r
1809         }\r
1810         \r
1811         return ret;\r
1812 }\r
1813 \r
1814 static boolean lookupWriteMemory(uint32 memoryAddress,\r
1815                                                                 uint8 memoryAddressFormat,\r
1816                                                                 uint32 memorySize,\r
1817                                                                 const Dcm_DspMemoryIdInfo **MemoryIdConfigPtr)\r
1818 {\r
1819         uint8 i;\r
1820         const Dcm_DspMemoryIdInfo *dspMemoryInfo = DCM_Config.Dsp->DspMemory->DspMemoryIdInfo;\r
1821         boolean memoryFound = FALSE;\r
1822 \r
1823         for(i = 0;(dspMemoryInfo->Arc_EOL == FALSE) && (memoryFound == FALSE);i++)\r
1824         {\r
1825                 if(TRUE == checkWriteMemoryByAddress(DCM_Config.Dsp->DspMemory->DcmDspUseMemoryId, memoryAddress,memoryAddressFormat,memorySize,dspMemoryInfo))\r
1826                 {\r
1827                         memoryFound = TRUE;\r
1828                 }\r
1829                 else\r
1830                 {\r
1831                         dspMemoryInfo++;\r
1832                 }\r
1833         }\r
1834         if (memoryFound == TRUE)\r
1835         {\r
1836                 *MemoryIdConfigPtr = dspMemoryInfo;\r
1837         }\r
1838         \r
1839         return memoryFound;\r
1840 }\r
1841 \r
1842 static Dcm_NegativeResponseCodeType writeMemoryData(Dcm_OpStatusType* OpStatus,\r
1843                                                                                                 const Dcm_DspMemoryIdInfo *MemoryIdConfigPtr,\r
1844                                                                                                 uint32 MemoryAddress,\r
1845                                                                                                 uint32 MemorySize,\r
1846                                                                                                 uint8 *SourceData)\r
1847 {\r
1848         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
1849         Dcm_ReturnWriteMemoryType writeRet;\r
1850         writeRet = Dcm_WriteMemory(*OpStatus,\r
1851                                                                 MemoryIdConfigPtr->MemoryIdValue,\r
1852                                                                 MemoryAddress,\r
1853                                                                 MemorySize,\r
1854                                                                 SourceData);\r
1855         if(DCM_READ_FAILED == writeRet)\r
1856         {\r
1857                 responseCode = DCM_E_GENERALPROGRAMMINGFAILURE;   /*@req UDS_REQ_0X3D_16,DCM643*/\r
1858         }\r
1859         else if(DCM_WRITE_PENDING == writeRet)\r
1860         {\r
1861                 *OpStatus = DCM_PENDING;\r
1862         }\r
1863         else\r
1864         {\r
1865                 responseCode = DCM_E_POSITIVERESPONSE;\r
1866         }\r
1867         \r
1868         return responseCode;\r
1869 }\r
1870 \r
1871 void DspUdsWriteMemoryByAddress(const PduInfoType* pduRxData, PduInfoType* pduTxData)\r
1872 {\r
1873           typedef struct{\r
1874                 uint32 MemoryAddressStart;\r
1875                 uint32 MemoryIdValue;\r
1876                 const Dcm_DspMemoryIdInfo *MemoryIdConfigPtr;\r
1877                 Dcm_NegativeResponseCodeType ResponseCode;\r
1878                 uint8 MemorySizeFormat;\r
1879                 uint8 MemoryAddressFormat;\r
1880                 uint32 MemorySize ;\r
1881                 uint16 MessageLength;\r
1882           }DspUdsWriteMemoryType;\r
1883         uint8 i;\r
1884         DspUdsWriteMemoryType dspUdsWriteMemory;\r
1885         Dcm_OpStatusType OpStatus = DCM_INITIAL;\r
1886         dspUdsWriteMemory.MemoryAddressStart = 0;\r
1887         dspUdsWriteMemory.MemoryIdConfigPtr = NULL;\r
1888         dspUdsWriteMemory.ResponseCode = DCM_E_POSITIVERESPONSE;\r
1889         dspUdsWriteMemory.MemorySizeFormat = ((uint8)(pduRxData->SduDataPtr[1] & DCM_FORMAT_HIGH_MASK)) >> 4;   /*@req UDS_REQ_0x3D_3 & UDS_REQ_0x3D_5*/\r
1890         dspUdsWriteMemory.MemoryAddressFormat = ((uint8)pduRxData->SduDataPtr[1]) & DCM_FORMAT_LOW_MASK;                /*@req UDS_REQ_0x3D_3& UDS_REQ_0x3D_4*/\r
1891         dspUdsWriteMemory.MemorySize = 0;\r
1892 \r
1893         if((dspUdsWriteMemory.MemoryAddressFormat == 0) || (dspUdsWriteMemory.MemorySizeFormat == 0))  /*@req UDS_REQ_0x3D_14*/\r
1894         {\r
1895                 dspUdsWriteMemory.ResponseCode = DCM_E_REQUESTOUTOFRANGE;\r
1896         }\r
1897         else\r
1898         {\r
1899                 /*take value of MemorySize out */\r
1900                 for(i = 0; i < dspUdsWriteMemory.MemorySizeFormat; i++)\r
1901                 {\r
1902                         dspUdsWriteMemory.MemorySize <<= 8;\r
1903                         dspUdsWriteMemory.MemorySize += (uint32)(pduRxData->SduDataPtr[2 + i +dspUdsWriteMemory.MemoryAddressFormat]);\r
1904                 }\r
1905                 dspUdsWriteMemory.MessageLength = (uint16)(2 + dspUdsWriteMemory.MemoryAddressFormat + dspUdsWriteMemory.MemorySizeFormat + dspUdsWriteMemory.MemorySize);\r
1906                 if(dspUdsWriteMemory.MessageLength == pduRxData->SduLength)\r
1907                 {\r
1908                         /*take Start Address out */\r
1909                         for(i = 0; i < dspUdsWriteMemory.MemoryAddressFormat; i++)\r
1910                         {\r
1911                                 dspUdsWriteMemory.MemoryAddressStart <<= 8;\r
1912                                 dspUdsWriteMemory.MemoryAddressStart += (uint32)(pduRxData->SduDataPtr[2 + i]);\r
1913                         }\r
1914                         if(TRUE == lookupWriteMemory(dspUdsWriteMemory.MemoryAddressStart,\r
1915                                                                                 dspUdsWriteMemory.MemoryAddressFormat,\r
1916                                                                                 dspUdsWriteMemory.MemorySize,\r
1917                                                                                 &dspUdsWriteMemory.MemoryIdConfigPtr))\r
1918                         {\r
1919                                 if (DspCheckSecurityLevel(dspUdsWriteMemory.MemoryIdConfigPtr->pReadMemoryInfo->pSecurityLevel) == TRUE)\r
1920                                 {\r
1921                                         dspUdsWriteMemory.ResponseCode = writeMemoryData(&OpStatus,\r
1922                                                                                                                                         dspUdsWriteMemory.MemoryIdConfigPtr, \r
1923                                                                                                                                         dspUdsWriteMemory.MemoryAddressStart,\r
1924                                                                                                                                         dspUdsWriteMemory.MemorySize,\r
1925                                                                                                                                         &pduRxData->SduDataPtr[2 + dspUdsWriteMemory.MemoryAddressFormat + dspUdsWriteMemory.MemorySizeFormat]);\r
1926                                 }\r
1927                                 else\r
1928                                 {\r
1929                                         dspUdsWriteMemory.ResponseCode = DCM_E_SECUTITYACCESSDENIED;    /*@req UDS_REQ_0X3D_15,Dcm490*/\r
1930                                 }\r
1931                         }\r
1932                         else\r
1933                         {\r
1934                                 dspUdsWriteMemory.ResponseCode = DCM_E_REQUESTOUTOFRANGE;                /*@req UDS_REQ_0x3D_11,UDS_REQ_0x3D_12,Dcm489*/\r
1935                         }\r
1936                 }\r
1937                 else\r
1938                 {\r
1939                         dspUdsWriteMemory.ResponseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;/*@req UDS_REQ_0x3D_9*/\r
1940                 }       \r
1941         }\r
1942         if(DCM_E_POSITIVERESPONSE == dspUdsWriteMemory.ResponseCode)\r
1943         {\r
1944                 pduTxData->SduLength = 2 + dspUdsWriteMemory.MemorySizeFormat + dspUdsWriteMemory.MemoryAddressFormat;\r
1945                 pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1];\r
1946                 for(i = 0; i < dspUdsWriteMemory.MemorySizeFormat + dspUdsWriteMemory.MemoryAddressFormat; i++)\r
1947                 {\r
1948                         pduTxData->SduDataPtr[2 + i] = pduRxData->SduDataPtr[2 + i];\r
1949                         if(OpStatus != DCM_PENDING)\r
1950                         {\r
1951                                 DsdDspProcessingDone(dspUdsWriteMemory.ResponseCode);\r
1952                         }\r
1953                         else\r
1954                         {\r
1955                         dspMemoryState=DCM_MEMORY_WRITE;\r
1956                         }\r
1957                 }\r
1958         }\r
1959         else\r
1960         {\r
1961                 DsdDspProcessingDone(dspUdsWriteMemory.ResponseCode);\r
1962         }\r
1963 }\r
1964 \r
1965 static boolean checkPeriodicIdentifierBuffer(uint8 PeriodicDid,uint8 Length,uint8 *postion)\r
1966 {\r
1967         uint8 i;\r
1968         boolean ret = FALSE;\r
1969         for(i = 0;(i < Length) && (ret == FALSE);i++)\r
1970         {\r
1971                 if(PeriodicDid == dspPDidRef.dspPDid[i].PeriodicDid)\r
1972                 {\r
1973                         ret = TRUE;\r
1974                         *postion = i;\r
1975                 }\r
1976         }\r
1977         \r
1978         return ret;\r
1979 }\r
1980 \r
1981 /* REVIEW JB 2012-06-05: Please describe the buffer algorithm because it is not obvious when looking at this function. */\r
1982 static void ClearPeriodicIdentifierBuffer(uint8 BufferEnd,uint8 postion)\r
1983 {\r
1984         dspPDidRef.dspPDid[postion].PeriodicDid = dspPDidRef.dspPDid[BufferEnd ].PeriodicDid;\r
1985         dspPDidRef.dspPDid[postion].PDidTxCounter = dspPDidRef.dspPDid[BufferEnd].PDidTxCounter;\r
1986         dspPDidRef.dspPDid[postion].PDidTxCounterNumber = dspPDidRef.dspPDid[BufferEnd].PDidTxCounterNumber;\r
1987         dspPDidRef.dspPDid[BufferEnd].PeriodicDid = 0;\r
1988         dspPDidRef.dspPDid[BufferEnd].PDidTxCounter = 0;\r
1989         dspPDidRef.dspPDid[BufferEnd ].PDidTxCounterNumber = 0;\r
1990 }\r
1991 \r
1992 static Dcm_NegativeResponseCodeType readPeriodDidData(const Dcm_DspDidType *PDidPtr, uint8 *Data,uint16 *Length)\r
1993 {\r
1994         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
1995         if ((PDidPtr->DspDidInfoRef->DspDidAccess.DspDidRead != NULL) \r
1996                 && (PDidPtr->DspDidConditionCheckReadFnc != NULL) \r
1997                 && (PDidPtr->DspDidReadDataFnc != NULL) ) \r
1998         {       \r
1999                 if (DspCheckSessionLevel(PDidPtr->DspDidInfoRef->DspDidAccess.DspDidRead->DspDidReadSessionRef)) \r
2000                 { \r
2001                         if (DspCheckSecurityLevel(PDidPtr->DspDidInfoRef->DspDidAccess.DspDidRead->DspDidReadSecurityLevelRef)) \r
2002                         {\r
2003                                 Std_ReturnType result = E_NOT_OK;\r
2004                                 Dcm_NegativeResponseCodeType errorCode = DCM_E_POSITIVERESPONSE;\r
2005                                 result = PDidPtr->DspDidConditionCheckReadFnc(&errorCode);\r
2006                                 if ((result == E_OK) && (errorCode == DCM_E_POSITIVERESPONSE))\r
2007                                 {\r
2008                                         result = E_NOT_OK;\r
2009                                         if (PDidPtr->DspDidInfoRef->DspDidFixedLength)\r
2010                                         {       \r
2011                                                 *Length= PDidPtr->DspDidSize;\r
2012                                                 result = E_OK;\r
2013                                         }\r
2014                                         else\r
2015                                         {\r
2016                                                 if(PDidPtr->DspDidReadDataLengthFnc!=NULL)\r
2017                                                 {\r
2018                                                         result = PDidPtr->DspDidReadDataLengthFnc(Length);\r
2019                                                 }\r
2020                                                 else\r
2021                                                 {\r
2022                                                         responseCode = DCM_E_GENERALREJECT;\r
2023                                                 }\r
2024                                         }\r
2025                                         if (result == E_OK) \r
2026                                         {\r
2027                                                 result = PDidPtr->DspDidReadDataFnc(Data);\r
2028                                                 if (result != E_OK)\r
2029                                                 {\r
2030                                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2031                                                 }\r
2032                                         }\r
2033                                         else\r
2034                                         {\r
2035                                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2036                                         }\r
2037                                 }\r
2038                                 else\r
2039                                 {\r
2040                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2041                                 }\r
2042                         }\r
2043                         else\r
2044                         {\r
2045                                 responseCode = DCM_E_SECUTITYACCESSDENIED;\r
2046                         }\r
2047                 }\r
2048                 else\r
2049                 {\r
2050                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2051                 }\r
2052         }\r
2053         else\r
2054         {\r
2055                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2056         }\r
2057         return responseCode;\r
2058 }\r
2059 \r
2060 static Dcm_NegativeResponseCodeType DspSavePeriodicData(uint16 didNr, uint32 periodicTransmitCounter,uint8 PdidBufferNr)\r
2061 {\r
2062         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
2063         const Dcm_DspDidType *SourceDid = NULL;\r
2064         Dcm_DspDDDType *DDidPtr = NULL;\r
2065 \r
2066         if (TRUE == lookupDid(didNr, &SourceDid))\r
2067         {\r
2068                 if(DspCheckSessionLevel(SourceDid->DspDidInfoRef->DspDidAccess.DspDidRead->DspDidReadSessionRef) == TRUE)\r
2069                 {\r
2070                         if(DspCheckSecurityLevel(SourceDid->DspDidInfoRef->DspDidAccess.DspDidRead->DspDidReadSecurityLevelRef) == TRUE)\r
2071                         {\r
2072                                 Std_ReturnType result = E_NOT_OK;\r
2073                                 Dcm_NegativeResponseCodeType errorCode = DCM_E_POSITIVERESPONSE;\r
2074                                 \r
2075                                 if(SourceDid->DspDidConditionCheckReadFnc != NULL)\r
2076                                 {\r
2077                                         result = SourceDid->DspDidConditionCheckReadFnc(&errorCode);\r
2078                                 }\r
2079                                 if ((result != E_OK) || (errorCode != DCM_E_POSITIVERESPONSE))\r
2080                                 {\r
2081                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2082                                 }\r
2083                                 if((SourceDid->DspDidInfoRef->DspDidFixedLength!=TRUE) && (SourceDid->DspDidReadDataLengthFnc == NULL))\r
2084                                 {\r
2085                                         responseCode = DCM_E_GENERALREJECT;\r
2086                                 }\r
2087                         }\r
2088                         else\r
2089                         {\r
2090                                 responseCode = DCM_E_SECUTITYACCESSDENIED;\r
2091                         }\r
2092                 }\r
2093                 else\r
2094                 {\r
2095                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2096                 }\r
2097         }\r
2098         else if(LookupDDD(didNr,&DDidPtr) == TRUE)\r
2099         {\r
2100                 responseCode = DCM_E_POSITIVERESPONSE;\r
2101         }\r
2102         else\r
2103         {\r
2104                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2105         }\r
2106         if(responseCode == DCM_E_POSITIVERESPONSE)\r
2107         {\r
2108                 dspPDidRef.dspPDid[PdidBufferNr].PeriodicDid = (uint8)didNr & DCM_DID_LOW_MASK;\r
2109                         /* REVIEW JB 2012-06-05: Why is TxCounter set to PdidBufferNr - it seems wrong. */\r
2110                 dspPDidRef.dspPDid[PdidBufferNr].PDidTxCounter = PdidBufferNr*3;\r
2111 \r
2112                 dspPDidRef.dspPDid[PdidBufferNr].PDidTxCounterNumber = periodicTransmitCounter;\r
2113         }\r
2114         return responseCode;\r
2115 }\r
2116 static void ClearPeriodicIdentifier(const PduInfoType *pduRxData,PduInfoType *pduTxData )\r
2117 {\r
2118         uint16 PdidNumber;\r
2119         uint8 PDidLowByte;\r
2120         uint8 PdidBufferNr;\r
2121         uint8 PdidPostion;\r
2122         uint8 i;\r
2123         if( pduRxData->SduDataPtr[1] == DCM_PERIODICTRANSMIT_STOPSENDING_MODE )\r
2124         {\r
2125                 PdidNumber = pduRxData->SduLength - 2;\r
2126                 for(i = 0;i < PdidNumber;i++)\r
2127                 {\r
2128                         PDidLowByte = pduRxData->SduDataPtr[2];\r
2129                         if(checkPeriodicIdentifierBuffer(PDidLowByte,dspPDidRef.PDidNr,&PdidPostion) == TRUE)\r
2130                         {\r
2131                                 dspPDidRef.PDidNr--;\r
2132                                 ClearPeriodicIdentifierBuffer(dspPDidRef.PDidNr, PdidPostion);\r
2133                                 \r
2134                         }               \r
2135                 }\r
2136                 pduTxData->SduLength = 1;\r
2137         }\r
2138 }\r
2139 /*\r
2140         DESCRIPTION:\r
2141                  UDS Service 0x2a - Read Data By Periodic Identifier\r
2142 */\r
2143 void DspReadDataByPeriodicIdentifier(const PduInfoType *pduRxData,PduInfoType *pduTxData)\r
2144 {\r
2145         /** @req DCM254 */\r
2146         uint8 PDidLowByte;\r
2147         uint16 PdidNumber;\r
2148         uint8 PdidPostion;\r
2149         uint16 i;\r
2150         uint8 PdidBufferNr;\r
2151         uint32 periodicTransmitCounter;\r
2152         uint16 DataLength;\r
2153         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
2154         const Dcm_DspDidType *PDidPtr = NULL;\r
2155         Dcm_DspDDDType *DDidPtr = NULL;\r
2156         PdidBufferNr = dspPDidRef.PDidNr;\r
2157         if(pduRxData->SduLength > 2)\r
2158         {\r
2159                 \r
2160                 switch(pduRxData->SduDataPtr[1])\r
2161                 {\r
2162                         case DCM_PERIODICTRANSMIT_DEFAULT_MODE:\r
2163                                 periodicTransmitCounter = 0;\r
2164                                 break;\r
2165                         case DCM_PERIODICTRANSMIT_SLOWRATE_MODE:\r
2166                                 periodicTransmitCounter = DCM_PERIODICTRANSMIT_SLOW;\r
2167                                 break;\r
2168                                 case DCM_PERIODICTRANSMIT_MEDIUM_MODE:\r
2169                                         periodicTransmitCounter = DCM_PERIODICTRANSMIT_MEDIUM;\r
2170                                 break;\r
2171                         case DCM_PERIODICTRANSMIT_FAST_MODE:\r
2172                                 periodicTransmitCounter = DCM_PERIODICTRANSMIT_FAST;\r
2173                                 break;\r
2174                         case DCM_PERIODICTRANSMIT_STOPSENDING_MODE:\r
2175                                 ClearPeriodicIdentifier(pduRxData,pduTxData);\r
2176                                 break;\r
2177                         default:\r
2178                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2179                                 break;\r
2180                 }\r
2181                 if(pduRxData->SduDataPtr[1] != DCM_PERIODICTRANSMIT_STOPSENDING_MODE)\r
2182                 {\r
2183                         PdidNumber = pduRxData->SduLength - 2;\r
2184                         if(1 == PdidNumber)\r
2185                         {\r
2186                                 PDidLowByte = pduRxData->SduDataPtr[2];                 \r
2187                                 if(checkPeriodicIdentifierBuffer(PDidLowByte,dspPDidRef.PDidNr,&PdidPostion) == TRUE)\r
2188                                 {\r
2189                                         if(0 == periodicTransmitCounter)\r
2190                                         {\r
2191                                                 if (TRUE == lookupDid(((uint16)PDidLowByte + 0xF200), &PDidPtr))   /*UDS_REQ_0x2A_1*/\r
2192                                                 {\r
2193                                                         pduTxData->SduDataPtr[1] = PDidLowByte; \r
2194                                                         responseCode = readPeriodDidData(PDidPtr,&pduTxData->SduDataPtr[2],&DataLength);\r
2195                                                         pduTxData->SduLength = DataLength + 2;\r
2196                                                 }\r
2197                                                 else if(TRUE == LookupDDD((0xF200 + (uint16)PDidLowByte),&DDidPtr))\r
2198                                                 {\r
2199                                                         pduTxData->SduDataPtr[1] = PDidLowByte;\r
2200                                                         responseCode = readDDDData(DDidPtr,&pduTxData->SduDataPtr[2],&DataLength);\r
2201                                                         pduTxData->SduLength = DataLength + 2;\r
2202                                                 }\r
2203                                                 else\r
2204                                                 {\r
2205                                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2206                                                 }\r
2207                                                 if(responseCode != DCM_E_POSITIVERESPONSE)\r
2208                                                 {\r
2209                                                         dspPDidRef.PDidNr--;\r
2210                                                         ClearPeriodicIdentifierBuffer(dspPDidRef.PDidNr,PdidPostion);\r
2211                                                 }\r
2212                                         }\r
2213                                         else\r
2214                                         {\r
2215                                                 dspPDidRef.dspPDid[PdidPostion].PDidTxCounterNumber = periodicTransmitCounter;\r
2216                                                 pduTxData->SduLength = 1;\r
2217                                         }\r
2218                                 }\r
2219                                 else\r
2220                                 {       \r
2221                                         responseCode = DspSavePeriodicData((DCM_PERODICDID_HIHG_MASK + (uint16)PDidLowByte),periodicTransmitCounter,PdidBufferNr);\r
2222                                         PdidBufferNr++;\r
2223                                         pduTxData->SduLength = 1;\r
2224                                 }\r
2225                         }\r
2226                         else if((PdidNumber + PdidBufferNr) <= DCM_LIMITNUMBER_PERIODDATA)      /*UDS_REQ_0x2A_6*/\r
2227                         {       \r
2228                                 for(i = 0;(i < PdidNumber)&&(responseCode == DCM_E_POSITIVERESPONSE);i++)\r
2229                                 {\r
2230                                         PDidLowByte = pduRxData->SduDataPtr[2 + i];\r
2231                                         if(checkPeriodicIdentifierBuffer(PDidLowByte,PdidBufferNr,&PdidPostion) == TRUE)\r
2232                                         {\r
2233                                                 if(dspPDidRef.dspPDid[PdidPostion].PDidTxCounterNumber != periodicTransmitCounter)\r
2234                                                 {\r
2235                                                         dspPDidRef.dspPDid[PdidPostion].PDidTxCounterNumber = periodicTransmitCounter;\r
2236                                                 }\r
2237                                         }\r
2238                                         else\r
2239                                         {\r
2240                                                 responseCode = DspSavePeriodicData((0xF200 + (uint16)PDidLowByte),periodicTransmitCounter,PdidBufferNr);\r
2241                                                 PdidBufferNr++;\r
2242                                         }\r
2243                                                 pduTxData->SduLength = 1;\r
2244                                 }\r
2245                         }\r
2246                         else\r
2247                         {\r
2248                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2249                         }\r
2250                         if(responseCode == DCM_E_POSITIVERESPONSE)\r
2251                         {                                       \r
2252                                 dspPDidRef.PDidNr = PdidBufferNr;                               \r
2253                         }\r
2254                 }                                                       \r
2255         }\r
2256         else if((pduRxData->SduLength == 2)&&(pduRxData->SduDataPtr[1] == DCM_PERIODICTRANSMIT_STOPSENDING_MODE))\r
2257         {\r
2258                 memset(&dspPDidRef,0,sizeof(dspPDidRef));\r
2259                 pduTxData->SduLength = 1;\r
2260         }\r
2261         else\r
2262         {\r
2263                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
2264         }\r
2265         DsdDspProcessingDone(responseCode);\r
2266 }\r
2267 \r
2268 static Dcm_NegativeResponseCodeType dynamicallyDefineDataIdentifierbyDid(uint16 DDIdentifier,const PduInfoType *pduRxData,PduInfoType *pduTxData)\r
2269 {\r
2270         uint8 i;\r
2271         uint16 SourceDidNr;\r
2272         const Dcm_DspDidType *SourceDid = NULL;\r
2273         Dcm_DspDDDType *DDid = NULL;\r
2274         uint16 SourceLength = 0;\r
2275         uint16 DidLength = 0;\r
2276         uint16 Length = 0;\r
2277         uint8 Num = 0;\r
2278         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
2279 \r
2280         if(FALSE == LookupDDD(DDIdentifier, &DDid))\r
2281         {\r
2282                 while((Num < DCM_MAX_DDD_NUMBER) && (dspDDD[Num].DynamicallyDid != 0 ))\r
2283                 {\r
2284                         Num++;\r
2285                 }\r
2286                 if(Num >= DCM_MAX_DDD_NUMBER)\r
2287                 {\r
2288                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2289                 }\r
2290                 else\r
2291                 {\r
2292                         DDid = &dspDDD[Num];\r
2293                 }\r
2294         }\r
2295         else\r
2296         {\r
2297                 while((SourceLength < DCM_MAX_DDDSOURCE_NUMBER) && (DDid->DDDSource[SourceLength].formatOrPosition != 0 ))\r
2298                 {\r
2299                         SourceLength++;\r
2300                 }\r
2301                 if(SourceLength > DCM_MAX_DDDSOURCE_NUMBER)\r
2302                 {\r
2303                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2304                 }\r
2305         }\r
2306         if(responseCode == DCM_E_POSITIVERESPONSE)\r
2307         {\r
2308                 Length = (pduRxData->SduLength - SID_AND_ALFID_LEN4) /SID_AND_ALFID_LEN4;\r
2309                 if(((Length*SID_AND_ALFID_LEN4) == (pduRxData->SduLength - SID_AND_ALFID_LEN4)) && (Length != 0))\r
2310                 {\r
2311                         if((Length + SourceLength) <= DCM_MAX_DDDSOURCE_NUMBER)\r
2312                         {\r
2313                                 for(i = 0;(i < Length) && (responseCode == DCM_E_POSITIVERESPONSE);i++)\r
2314                                 {\r
2315                                         SourceDidNr = (((uint16)pduRxData->SduDataPtr[SID_AND_ALFID_LEN4 + i*SID_AND_ALFID_LEN4] << 8) & DCM_DID_HIGH_MASK) + (((uint16)pduRxData->SduDataPtr[(5 + i*SID_AND_ALFID_LEN4)]) & DCM_DID_LOW_MASK);\r
2316                                         if(TRUE == lookupDid(SourceDidNr, &SourceDid))/*UDS_REQ_0x2C_4*/\r
2317                                         {       \r
2318                                                 if(DspCheckSessionLevel(SourceDid->DspDidInfoRef->DspDidAccess.DspDidRead->DspDidReadSessionRef))\r
2319                                                 {\r
2320                                                         if(DspCheckSecurityLevel(SourceDid->DspDidInfoRef->DspDidAccess.DspDidRead->DspDidReadSecurityLevelRef))\r
2321                                                         {\r
2322                                                                 if(SourceDid->DspDidInfoRef->DspDidFixedLength == TRUE)\r
2323                                                                 {\r
2324                                                                         DidLength = SourceDid->DspDidSize;\r
2325                                                                 }\r
2326                                                                 else\r
2327                                                                 {\r
2328                                                                         if(     SourceDid->DspDidReadDataLengthFnc != NULL)\r
2329                                                                         {\r
2330                                                                                 SourceDid->DspDidReadDataLengthFnc(&DidLength);\r
2331                                                                         }\r
2332                                                                 }\r
2333                                                                 if(DidLength != 0)\r
2334                                                                 {\r
2335                                                                         if((pduRxData->SduDataPtr[SID_AND_ALFID_LEN6 + i*SID_AND_ALFID_LEN4] != 0) &&\r
2336                                                                                 (pduRxData->SduDataPtr[SID_AND_ALFID_LEN7 + i*SID_AND_ALFID_LEN4] != 0) &&\r
2337                                                                                 (((uint16)pduRxData->SduDataPtr[SID_AND_ALFID_LEN6 + i*SID_AND_ALFID_LEN4] + (uint16)pduRxData->SduDataPtr[SID_AND_ALFID_LEN7 + i*SID_AND_ALFID_LEN4] - 1) <= DidLength))\r
2338                                                                         {\r
2339                                                                                 DDid->DDDSource[i + SourceLength].formatOrPosition = pduRxData->SduDataPtr[SID_AND_ALFID_LEN6 + i*SID_AND_ALFID_LEN4];\r
2340                                                                                 DDid->DDDSource[i + SourceLength].Size = pduRxData->SduDataPtr[SID_AND_ALFID_LEN7 + i*SID_AND_ALFID_LEN4];\r
2341                                                                                 DDid->DDDSource[i + SourceLength].SourceAddressOrDid = SourceDid->DspDidIdentifier;\r
2342                                                                                 DDid->DDDSource[i + SourceLength].DDDTpyeID = DCM_DDD_SOURCE_DID;\r
2343                                                                         }\r
2344                                                                         else\r
2345                                                                         {\r
2346                                                                                 /*UDS_REQ_0x2C_6*/\r
2347                                                                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2348                                                                         }\r
2349                                                                         \r
2350                                                                 }\r
2351                                                                 else\r
2352                                                                 {\r
2353                                                                         /*UDS_REQ_0x2C_14*/\r
2354                                                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2355                                                                 }\r
2356                                                         }\r
2357                                                         else\r
2358                                                         {\r
2359                                                                 responseCode = DCM_E_SECUTITYACCESSDENIED;\r
2360                                                         }\r
2361                                                 }\r
2362                                                 else\r
2363                                                 {\r
2364                                                         /*UDS_REQ_0x2C_19,DCM726*/\r
2365                                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2366                                                 }\r
2367                                         }\r
2368                                         else\r
2369                                         {\r
2370                                                 /*DCM725*/\r
2371                                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2372                                         }\r
2373                                 }\r
2374                         }\r
2375                         else\r
2376                         {\r
2377                                 /*UDS_REQ_0x2C_13*/\r
2378                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2379                         }\r
2380                 }\r
2381                 else\r
2382                 {\r
2383                         /*UDS_REQ_0x2C_11*/\r
2384                         responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
2385                 }\r
2386                 if(responseCode == DCM_E_POSITIVERESPONSE)\r
2387                 {\r
2388                         DDid->DynamicallyDid = DDIdentifier;\r
2389                         pduTxData->SduDataPtr[1] = DCM_DDD_SUBFUNCTION_DEFINEBYDID;\r
2390                 }\r
2391         }\r
2392         if(responseCode == DCM_E_POSITIVERESPONSE)\r
2393         {\r
2394                 pduTxData->SduDataPtr[1] = DCM_DDD_SUBFUNCTION_DEFINEBYDID;\r
2395         }\r
2396         \r
2397         return responseCode;\r
2398 }\r
2399 \r
2400 static Dcm_NegativeResponseCodeType dynamicallyDefineDataIdentifierbyAddress(uint16 DDIdentifier,const PduInfoType *pduRxData,PduInfoType *pduTxData)\r
2401 {\r
2402         uint8 LengthCount;\r
2403         uint8 SourceCount;\r
2404         uint16 Length;\r
2405         uint8 AddressFormat;\r
2406         uint8 MemorySizeFormat;\r
2407         uint32 MemoryAddress = 0;\r
2408         uint16 MemorySize = 0;\r
2409         uint16 SourceLength = 0;\r
2410         Dcm_DspDDDType *DDid = NULL;\r
2411         const Dcm_DspMemoryIdInfo *SourceMemoryInfo = NULL;\r
2412         uint8 Num = 0;\r
2413         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
2414         \r
2415         if(FALSE == LookupDDD(DDIdentifier,&DDid))\r
2416         {\r
2417                 while((Num < DCM_MAX_DDD_NUMBER) && (dspDDD[Num].DynamicallyDid != 0 ))\r
2418                 {\r
2419                         Num++;\r
2420                 }\r
2421                 if(Num >= DCM_MAX_DDD_NUMBER)\r
2422                 {\r
2423                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2424                 }\r
2425                 else\r
2426                 {\r
2427                         DDid = &dspDDD[Num];\r
2428                 }\r
2429         }\r
2430         else\r
2431         {\r
2432                 while((SourceLength < DCM_MAX_DDDSOURCE_NUMBER) && (DDid->DDDSource[SourceLength].formatOrPosition != 0 ))\r
2433                 {\r
2434                         SourceLength++;\r
2435                 }\r
2436                 if(SourceLength >= DCM_MAX_DDDSOURCE_NUMBER)\r
2437                 {\r
2438                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2439                 }\r
2440         }\r
2441         if(responseCode == DCM_E_POSITIVERESPONSE)\r
2442         {\r
2443                 AddressFormat = (uint8)pduRxData->SduDataPtr[4] & DCM_FORMAT_LOW_MASK;\r
2444                 MemorySizeFormat = (uint8)(pduRxData->SduDataPtr[4] >> 4) & DCM_FORMAT_LOW_MASK;\r
2445                 if((AddressFormat+MemorySizeFormat) != 0)\r
2446                 {\r
2447                         Length = (pduRxData->SduLength - SID_AND_ALFID_LEN5) / (AddressFormat + MemorySizeFormat);\r
2448                 }\r
2449                 if((AddressFormat != 0) && (MemorySizeFormat != 0) && ((SourceLength+Length) <= DCM_MAX_DDDSOURCE_NUMBER))\r
2450                 {\r
2451                         if((Length != 0)&&( Length * (AddressFormat + MemorySizeFormat) == (pduRxData->SduLength - 5) ))\r
2452                         {\r
2453                                 /* REVIEW JB 2012-06-05: Use better names than i and j to increase readability */\r
2454                                 for(LengthCount = 0; (LengthCount < Length) && (responseCode == DCM_E_POSITIVERESPONSE); LengthCount++)\r
2455                                 {\r
2456                                         MemoryAddress = 0;\r
2457                                         for(SourceCount = 0; SourceCount < AddressFormat; SourceCount++)\r
2458                                         {\r
2459                                                 MemoryAddress = MemoryAddress << 8;\r
2460                                                 MemoryAddress += (uint32)(pduRxData->SduDataPtr[5 + SourceCount + LengthCount * (AddressFormat + MemorySizeFormat)]);\r
2461                                         }\r
2462 \r
2463                                         /*take value of MemorySize out */\r
2464                                         MemorySize = 0;\r
2465                                         for(SourceCount = 0; SourceCount < MemorySizeFormat; SourceCount++)\r
2466                                         {\r
2467                                                 MemorySize = MemorySize << 8;\r
2468                                                 MemorySize += (uint32)(pduRxData->SduDataPtr[5 + SourceCount + AddressFormat + LengthCount * (AddressFormat + MemorySizeFormat)]);\r
2469                                         }\r
2470                                         if(TRUE == lookupReadMemory(MemoryAddress, AddressFormat,MemorySize,&SourceMemoryInfo))\r
2471                                         {\r
2472                                                 if(DspCheckSecurityLevel(SourceMemoryInfo->pReadMemoryInfo->pSecurityLevel) == TRUE)\r
2473                                                 {\r
2474                                                         DDid->DDDSource[LengthCount + SourceLength].formatOrPosition = pduRxData->SduDataPtr[4];\r
2475                                                         DDid->DDDSource[LengthCount + SourceLength].SourceAddressOrDid = MemoryAddress;\r
2476                                                         DDid->DDDSource[LengthCount + SourceLength].Size = MemorySize;\r
2477                                                         DDid->DDDSource[LengthCount + SourceLength].DDDTpyeID = DCM_DDD_SOURCE_ADDRESS;\r
2478                                                         /*UDS_REQ_0x2C_6*/\r
2479                                                 }\r
2480                                                 else\r
2481                                                 {\r
2482                                                         /*UDS_REQ_0x2C_19,DCM726*/\r
2483                                                         responseCode = DCM_E_SECUTITYACCESSDENIED;\r
2484                                                 }\r
2485                                         }\r
2486                                         else\r
2487                                         {\r
2488                                                 /*UDS_REQ_0x2C_15,UDS_REQ_0x2C_16*/\r
2489                                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2490                                         }\r
2491                                 }\r
2492                                 if(responseCode == DCM_E_POSITIVERESPONSE)\r
2493                                 {\r
2494                                         DDid->DynamicallyDid = DDIdentifier;\r
2495                                 }\r
2496                         }\r
2497                         else\r
2498                         {\r
2499                                 /*UDS_REQ_0x2C_11*/\r
2500                                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
2501                         }\r
2502                 }\r
2503                 else\r
2504                 {\r
2505                         /*UDS_REQ_0x2C_17, UDS_REQ_0x2C_18*/\r
2506                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2507                 }\r
2508 \r
2509         }\r
2510         if(responseCode == DCM_E_POSITIVERESPONSE)\r
2511         {\r
2512                 pduTxData->SduDataPtr[1] = DCM_DDD_SUBFUNCTION_DEFINEBYADDRESS;\r
2513         }\r
2514         \r
2515         return responseCode;\r
2516 }\r
2517 \r
2518 \r
2519 /*\r
2520         DESCRIPTION:\r
2521                  UDS Service 0x2c - Clear dynamically Did\r
2522 */\r
2523 static Dcm_NegativeResponseCodeType CleardynamicallyDid(uint16 DDIdentifier,const PduInfoType *pduRxData, PduInfoType * pduTxData)\r
2524 {\r
2525         /*UDS_REQ_0x2C_5*/\r
2526         uint8 i;\r
2527         uint8 ClearCount;\r
2528         uint8 position;\r
2529         uint8 ClearNum = 0;\r
2530         Dcm_DspDDDType *DDid = NULL;\r
2531         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
2532         \r
2533         if(pduRxData->SduLength == 4)\r
2534         {\r
2535                 if(TRUE == LookupDDD(DDIdentifier,&DDid))\r
2536                 {\r
2537                         \r
2538                         if((checkPeriodicIdentifierBuffer(pduRxData->SduDataPtr[3], dspPDidRef.PDidNr, &position) == TRUE)&&(pduRxData->SduDataPtr[2] == 0xF2))\r
2539                         {\r
2540                                 /*UDS_REQ_0x2C_9*/\r
2541                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2542                         }\r
2543                         else\r
2544                         {\r
2545                                 for(i = 1;i < DCM_MAX_DDD_NUMBER;i++)\r
2546                                 {\r
2547                                         if(0 == dspDDD[i].DynamicallyDid)\r
2548                                         {\r
2549                                                 ClearNum = i - 1;\r
2550                                                 DDid->DynamicallyDid = dspDDD[ClearNum].DynamicallyDid;\r
2551                                                 dspDDD[ClearNum].DynamicallyDid = 0;\r
2552                                                 for(ClearCount = 0;ClearCount < DCM_MAX_DDDSOURCE_NUMBER;ClearCount++)\r
2553                                                 {\r
2554                                                         /*DCM647*/\r
2555                                                         DDid->DDDSource[ClearCount].DDDTpyeID = dspDDD[ClearNum].DDDSource[ClearCount].DDDTpyeID;\r
2556                                                         DDid->DDDSource[ClearCount].formatOrPosition = dspDDD[ClearNum].DDDSource[ClearCount].formatOrPosition;\r
2557                                                         DDid->DDDSource[ClearCount].SourceAddressOrDid = dspDDD[ClearNum].DDDSource[ClearCount].SourceAddressOrDid;\r
2558                                                         DDid->DDDSource[ClearCount].Size = dspDDD[ClearNum].DDDSource[ClearCount].Size;\r
2559                                                         dspDDD[ClearNum].DDDSource[ClearCount].DDDTpyeID = 0;\r
2560                                                         dspDDD[ClearNum].DDDSource[ClearCount].formatOrPosition = 0;\r
2561                                                         dspDDD[ClearNum].DDDSource[ClearCount].SourceAddressOrDid = 0;\r
2562                                                         dspDDD[ClearNum].DDDSource[ClearCount].Size = 0;\r
2563                                                 }       \r
2564                                         }       \r
2565                                 }\r
2566                         }\r
2567                 }               \r
2568         }\r
2569         else\r
2570         {\r
2571                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
2572         }\r
2573         if(responseCode == DCM_E_POSITIVERESPONSE)\r
2574         {\r
2575                 pduTxData->SduDataPtr[1] = DCM_DDD_SUBFUNCTION_CLEAR;\r
2576                 pduTxData->SduLength = 2;\r
2577         }\r
2578         \r
2579         return responseCode;\r
2580 }\r
2581 \r
2582 void DspDynamicallyDefineDataIdentifier(const PduInfoType *pduRxData,PduInfoType *pduTxData)\r
2583 {\r
2584         /*UDS_REQ_0x2C_1,DCM 259*/\r
2585         uint16 i;\r
2586         uint8 Position;\r
2587         boolean PeriodicdUse = FALSE;\r
2588         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
2589         uint16 DDIdentifier = ((((uint16)pduRxData->SduDataPtr[2]) << 8) & DCM_DID_HIGH_MASK) + (pduRxData->SduDataPtr[3] & DCM_DID_LOW_MASK);\r
2590         if(pduRxData->SduLength > 2)\r
2591         {\r
2592                 /* REVIEW JB 2012-06-05: Clarify that F2 and F3 is included by comment */\r
2593                 if((pduRxData->SduDataPtr[2] & 0xF2) == 0xF2)\r
2594                 {\r
2595                         switch(pduRxData->SduDataPtr[1])        /*UDS_REQ_0x2C_2,DCM 646*/\r
2596                         {\r
2597                                 case DCM_DDD_SUBFUNCTION_DEFINEBYDID:\r
2598                                         responseCode  = dynamicallyDefineDataIdentifierbyDid(DDIdentifier,pduRxData,pduTxData);\r
2599                                         break;\r
2600                                 case DCM_DDD_SUBFUNCTION_DEFINEBYADDRESS:\r
2601                                         responseCode = dynamicallyDefineDataIdentifierbyAddress(DDIdentifier,pduRxData,pduTxData);\r
2602                                         break;\r
2603                                 case DCM_DDD_SUBFUNCTION_CLEAR:\r
2604                                         responseCode = CleardynamicallyDid(DDIdentifier,pduRxData,pduTxData);\r
2605                                         break;\r
2606                                 default:\r
2607                                         responseCode = DCM_E_SUBFUNCTIONNOTSUPPORTED;\r
2608                                         /*UDS_REQ_0x2C_10*/\r
2609                                         break;          \r
2610                         }\r
2611                 }\r
2612                 else\r
2613                 {\r
2614                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2615                 }\r
2616                 if(responseCode == DCM_E_POSITIVERESPONSE)\r
2617                 {\r
2618                         pduTxData->SduDataPtr[2] = pduRxData->SduDataPtr[2];\r
2619                         pduTxData->SduDataPtr[3] = pduRxData->SduDataPtr[3];\r
2620                         pduTxData->SduLength = 4;\r
2621                 }\r
2622         }\r
2623         else if((pduRxData->SduLength == 2)&&(pduRxData->SduDataPtr[1] == DCM_DDD_SUBFUNCTION_CLEAR))\r
2624         {\r
2625                 /*UDS_REQ_0x2C_7*/\r
2626                 for(i = 0;i < DCM_MAX_DDD_NUMBER;i++)\r
2627                 {\r
2628                         if(checkPeriodicIdentifierBuffer((uint8)(dspDDD[i].DynamicallyDid & DCM_DID_LOW_MASK),dspPDidRef.PDidNr,&Position) == TRUE)\r
2629                         {\r
2630                                 PeriodicdUse = TRUE;\r
2631                         }\r
2632                 }\r
2633                 if(PeriodicdUse == FALSE)\r
2634                 {\r
2635                         memset(dspDDD,0,sizeof(dspDDD));\r
2636                         pduTxData->SduDataPtr[1] = DCM_DDD_SUBFUNCTION_CLEAR;\r
2637                         pduTxData->SduLength = 2;\r
2638                 }\r
2639                 else\r
2640                 {\r
2641                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2642                 }\r
2643         }\r
2644         else\r
2645         {\r
2646                 /*UDS_REQ_0x2C_11*/\r
2647                 responseCode =  DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
2648         }\r
2649         DsdDspProcessingDone(responseCode);\r
2650 }\r
2651 \r
2652 static Dcm_NegativeResponseCodeType DspIOControlReturnControlToECU(const Dcm_DspDidType *DidPtr,const PduInfoType *pduRxData,PduInfoType *pduTxData)\r
2653 {\r
2654         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
2655         if(DidPtr->DspDidInfoRef->DspDidAccess.DspDidControl->DspDidReturnControlToEcu == TRUE)\r
2656         {\r
2657                 if(pduRxData->SduLength > 4)\r
2658                 {\r
2659                         if(DidPtr->DspDidInfoRef->DspDidAccess.DspDidControl != NULL)\r
2660                         {\r
2661                                 if(((DidPtr->DspDidControlRecordSize->DspDidControlRecordSize + 7) >> 3) == (pduRxData->SduLength - 4))\r
2662                                 {\r
2663                                         if(DidPtr->DspDidReturnControlToEcuFnc != NULL)\r
2664                                         {\r
2665                                                 DidPtr->DspDidReturnControlToEcuFnc(NULL,&pduRxData->SduDataPtr[4],&pduTxData->SduDataPtr[4],&responseCode);\r
2666                                                 \r
2667                                         }\r
2668                                         else\r
2669                                         {\r
2670                                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2671                                         }\r
2672                                 }\r
2673                                 else\r
2674                                 {\r
2675                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2676                                 }\r
2677                         }\r
2678                         else\r
2679                         {\r
2680                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2681                         }\r
2682                 }\r
2683                 else\r
2684                 {\r
2685                         if(DidPtr->DspDidReturnControlToEcuFnc != NULL)\r
2686                         {\r
2687 \r
2688                                 if(DidPtr->DspDidControlRecordSize != NULL)\r
2689                                 {\r
2690                                         DidPtr->DspDidReturnControlToEcuFnc(NULL,NULL,&pduTxData->SduDataPtr[4],&responseCode);\r
2691                                         pduTxData->SduLength = DidPtr->DspDidControlRecordSize->DspDidControlStatusRecordSize + 4;\r
2692                                 }\r
2693                                 else\r
2694                                 {\r
2695                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2696                                 }\r
2697                         }\r
2698                         else\r
2699                         {\r
2700                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2701                         }\r
2702                 }\r
2703         }\r
2704         else\r
2705         {\r
2706                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2707         }\r
2708         if(responseCode == DCM_E_POSITIVERESPONSE)\r
2709         {\r
2710                 pduTxData->SduLength = DidPtr->DspDidControlRecordSize->DspDidControlStatusRecordSize + 4;\r
2711                 pduTxData->SduDataPtr[3] = DCM_RETURN_CONTROL_TO_ECU;\r
2712         }\r
2713         \r
2714         return responseCode;\r
2715 }\r
2716 \r
2717 static Dcm_NegativeResponseCodeType DspIOControlResetToDefault(const Dcm_DspDidType *DidPtr,const PduInfoType *pduRxData,PduInfoType *pduTxData)\r
2718 {\r
2719         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
2720         if(DidPtr->DspDidInfoRef->DspDidAccess.DspDidControl->DspDidResetToDefault == TRUE)\r
2721         {\r
2722                 if(pduRxData->SduLength > 4)\r
2723                 {\r
2724                         if(DidPtr->DspDidInfoRef->DspDidAccess.DspDidControl != NULL)\r
2725                         {\r
2726                                 if(((DidPtr->DspDidControlRecordSize->DspDidControlRecordSize + 7) >> 3) == (pduRxData->SduLength - 4))\r
2727                                 {\r
2728                                         if(DidPtr->DspDidReturnControlToEcuFnc != NULL)\r
2729                                         {\r
2730                                                 DidPtr->DspDidResetToDeaultFnc(NULL,&pduRxData->SduDataPtr[4],&pduTxData->SduDataPtr[4],&responseCode);\r
2731                                         }\r
2732                                         else\r
2733                                         {\r
2734                                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2735                                         }\r
2736                                 }\r
2737                                 else\r
2738                                 {\r
2739                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2740                                 }\r
2741                         }\r
2742                         else\r
2743                         {\r
2744                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2745                         }\r
2746                 }\r
2747                 else\r
2748                 {\r
2749                         if(DidPtr->DspDidResetToDeaultFnc != NULL)\r
2750                         {\r
2751 \r
2752                                 if(DidPtr->DspDidControlRecordSize != NULL)\r
2753                                 {\r
2754                                         DidPtr->DspDidResetToDeaultFnc(NULL,NULL,&pduTxData->SduDataPtr[4],&responseCode);\r
2755                                         pduTxData->SduLength = DidPtr->DspDidControlRecordSize->DspDidControlStatusRecordSize + 4;\r
2756                                 }\r
2757                                 else\r
2758                                 {\r
2759                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2760                                 }\r
2761                         }\r
2762                         else\r
2763                         {\r
2764                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2765                         }\r
2766                 }\r
2767         }\r
2768         else\r
2769         {\r
2770                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2771         }\r
2772         if(responseCode == DCM_E_POSITIVERESPONSE)\r
2773         {\r
2774                 pduTxData->SduLength = DidPtr->DspDidControlRecordSize->DspDidControlStatusRecordSize+4;\r
2775                 pduTxData->SduDataPtr[3] = DCM_RESET_TO_DEFAULT;\r
2776         }\r
2777         return responseCode;\r
2778 }\r
2779 /*\r
2780         DESCRIPTION:\r
2781                  UDS Service 0x2F -  IOControl Freeze Current State\r
2782 */\r
2783 static Dcm_NegativeResponseCodeType DspIOControlFreezeCurrentState(const Dcm_DspDidType *DidPtr,const PduInfoType *pduRxData,PduInfoType *pduTxData)\r
2784 {\r
2785         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
2786         if(DidPtr->DspDidInfoRef->DspDidAccess.DspDidControl->DspDidFreezeCurrentState == TRUE)\r
2787         {\r
2788                 if(pduRxData->SduLength > 4)\r
2789                 {\r
2790                         if(DidPtr->DspDidInfoRef->DspDidAccess.DspDidControl != NULL)\r
2791                         {\r
2792                                 if(((DidPtr->DspDidControlRecordSize->DspDidControlRecordSize + 7) >> 3) == (pduRxData->SduLength - 4))\r
2793                                 {\r
2794                                         if(DidPtr->DspDidFreezeCurrentStateFnc != NULL)\r
2795                                         {\r
2796                                                 DidPtr->DspDidFreezeCurrentStateFnc(NULL,&pduRxData->SduDataPtr[4],&pduTxData->SduDataPtr[4],&responseCode);\r
2797                                         }\r
2798                                         else\r
2799                                         {\r
2800                                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2801                                         }\r
2802                                 }\r
2803                                 else\r
2804                                 {\r
2805                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2806                                 }\r
2807                         }\r
2808                         else\r
2809                         {\r
2810                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2811                         }\r
2812                 }\r
2813                 else\r
2814                 {\r
2815                         if(DidPtr->DspDidFreezeCurrentStateFnc != NULL)\r
2816                         {\r
2817 \r
2818                                 if(DidPtr->DspDidControlRecordSize != 0)\r
2819                                 {\r
2820                                         DidPtr->DspDidFreezeCurrentStateFnc(NULL,NULL,&pduTxData->SduDataPtr[4],&responseCode);\r
2821                                         pduTxData->SduLength = DidPtr->DspDidControlRecordSize->DspDidControlStatusRecordSize + 4;\r
2822                                 }\r
2823                                 else\r
2824                                 {\r
2825                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2826                                 }\r
2827                         }\r
2828                         else\r
2829                         {\r
2830                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2831                         }\r
2832                 }\r
2833         }\r
2834         else\r
2835         {\r
2836                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2837         }\r
2838         if(responseCode == DCM_E_POSITIVERESPONSE)\r
2839         {\r
2840                 pduTxData->SduLength = DidPtr->DspDidControlRecordSize->DspDidControlStatusRecordSize + 4;\r
2841                 pduTxData->SduDataPtr[3] = DCM_FREEZE_CURRENT_STATE;\r
2842         }\r
2843         \r
2844         return responseCode;\r
2845 }\r
2846 \r
2847 static Dcm_NegativeResponseCodeType DspIOControlShortTeamAdjustment(const Dcm_DspDidType *DidPtr,const PduInfoType *pduRxData,PduInfoType *pduTxData)\r
2848 {\r
2849         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
2850         uint8 didControlOptionRecordSize = DidPtr->DspDidControlRecordSize->DspDidControlOptionRecordSize;\r
2851         if(DidPtr->DspDidInfoRef->DspDidAccess.DspDidControl->DspDidShortTermAdjustment == TRUE)\r
2852         {\r
2853                 if(pduRxData->SduLength > 4)\r
2854                 {\r
2855                         if(DidPtr->DspDidInfoRef->DspDidAccess.DspDidControl != NULL)\r
2856                         {\r
2857                                 if(((((DidPtr->DspDidControlRecordSize->DspDidControlRecordSize + 7)) >> 3) + (didControlOptionRecordSize)) == (pduRxData->SduLength - 4))\r
2858                                 {\r
2859                                         if(DidPtr->DspDidShortTermAdjustmentFnc != NULL)\r
2860                                         {\r
2861                                                 DidPtr->DspDidShortTermAdjustmentFnc(&pduRxData->SduDataPtr[4],&pduRxData->SduDataPtr[4 + didControlOptionRecordSize],&pduTxData->SduDataPtr[4],&responseCode);\r
2862                                         }\r
2863                                         else\r
2864                                         {\r
2865                                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2866                                         }\r
2867                                 }\r
2868                                 else if((didControlOptionRecordSize) == (pduRxData->SduLength - 4))\r
2869                                 {\r
2870                                         if(DidPtr->DspDidShortTermAdjustmentFnc != NULL)\r
2871                                         {\r
2872                                                 DidPtr->DspDidShortTermAdjustmentFnc(&pduRxData->SduDataPtr[4],NULL,&pduTxData->SduDataPtr[4],&responseCode);\r
2873                                         }\r
2874                                         else\r
2875                                         {\r
2876                                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2877                                         }\r
2878                                 }\r
2879                                 else\r
2880                                 {\r
2881                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2882                                 }\r
2883                         }\r
2884                         else \r
2885                         {\r
2886                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2887                         }\r
2888                 }\r
2889                 else\r
2890                 {\r
2891                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2892                 }\r
2893         }\r
2894         else\r
2895         {\r
2896                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2897         }\r
2898         if(responseCode == DCM_E_POSITIVERESPONSE)\r
2899         {\r
2900                 pduTxData->SduLength = DidPtr->DspDidControlRecordSize->DspDidControlStatusRecordSize + 4;\r
2901                 pduTxData->SduDataPtr[3] = DCM_SHORT_TERM_ADJUSTMENT;\r
2902         }\r
2903         \r
2904         return responseCode;\r
2905 }\r
2906 \r
2907 void DspIOControlByDataIdentifier(const PduInfoType *pduRxData,PduInfoType *pduTxData)\r
2908 {\r
2909         uint16 didNr;\r
2910         const Dcm_DspDidType *DidPtr = NULL;\r
2911         Dcm_NegativeResponseCodeType responseCode = DCM_E_POSITIVERESPONSE;\r
2912         didNr = (pduRxData->SduDataPtr[1] << 8 & DCM_DID_HIGH_MASK) + (pduRxData->SduDataPtr[2] & DCM_DID_LOW_MASK);\r
2913         if(pduRxData->SduLength > 3)\r
2914         {\r
2915                 if(TRUE == lookupDid(didNr, &DidPtr))\r
2916                 {\r
2917                         if(FALSE == DidPtr->DspDidUsePort)\r
2918                         {\r
2919                                 if(NULL != DidPtr->DspDidInfoRef->DspDidAccess.DspDidControl)\r
2920                                 {\r
2921                                         if(TRUE == DspCheckSessionLevel(DidPtr->DspDidInfoRef->DspDidAccess.DspDidControl->DspDidControlSessionRef))\r
2922                                         {\r
2923                                                 if(TRUE == DspCheckSecurityLevel(DidPtr->DspDidInfoRef->DspDidAccess.DspDidControl->DspDidControlSecurityLevelRef))\r
2924                                                 {\r
2925                                                         switch(pduRxData->SduDataPtr[3])\r
2926                                                         {\r
2927                                                                 case DCM_RETURN_CONTROL_TO_ECU:\r
2928                                                                         responseCode = DspIOControlReturnControlToECU(DidPtr,pduRxData,pduTxData);\r
2929                                                                         break;\r
2930                                                                 case DCM_RESET_TO_DEFAULT:\r
2931                                                                         responseCode = DspIOControlResetToDefault(DidPtr,pduRxData,pduTxData);                                                          \r
2932                                                                         break;\r
2933                                                                 case DCM_FREEZE_CURRENT_STATE:\r
2934                                                                         responseCode = DspIOControlFreezeCurrentState(DidPtr,pduRxData,pduTxData);\r
2935                                                                         break;\r
2936                                                                 case DCM_SHORT_TERM_ADJUSTMENT:\r
2937                                                                         responseCode = DspIOControlShortTeamAdjustment(DidPtr,pduRxData,pduTxData);\r
2938                                                                         break;\r
2939                                                                 default:\r
2940                                                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2941                                                                         break;\r
2942                                                                 \r
2943                                                         }\r
2944                                                 }\r
2945                                                 else\r
2946                                                 {\r
2947                                                         responseCode = DCM_E_SECUTITYACCESSDENIED;\r
2948                                                 }\r
2949                                         }\r
2950                                         else\r
2951                                         {\r
2952                                                 responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2953                                         }\r
2954                                 }\r
2955                                 else\r
2956                                 {\r
2957                                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2958                                 }\r
2959                         }\r
2960                         else\r
2961                         {\r
2962                                 /* if UsePort == True, NRC 0x10 */\r
2963                                 responseCode = DCM_E_GENERALREJECT;\r
2964                         }\r
2965                 }\r
2966                 else\r
2967                 {\r
2968                         responseCode = DCM_E_REQUESTOUTOFRANGE;\r
2969                 }\r
2970         }\r
2971         else\r
2972         {\r
2973                 responseCode = DCM_E_INCORRECTMESSAGELENGTHORINVALIDFORMAT;\r
2974         }\r
2975         if(responseCode == DCM_E_POSITIVERESPONSE)\r
2976         {\r
2977                 pduTxData->SduDataPtr[1] = pduRxData->SduDataPtr[1];\r
2978                 pduTxData->SduDataPtr[2] = pduRxData->SduDataPtr[2];\r
2979         }\r
2980         DsdDspProcessingDone(responseCode);\r
2981 }\r