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