]> rtime.felk.cvut.cz Git - arc.git/blob - diagnostic/Dcm/Dcm_Dsl.c
Dcm, Fixed problem in read / write memory functions (refactored) that made it inpossi...
[arc.git] / diagnostic / Dcm / Dcm_Dsl.c
1 /* -------------------------------- Arctic Core ------------------------------\r
2  * Arctic Core - the open source AUTOSAR platform http://arccore.com\r
3  *\r
4  * Copyright (C) 2009  ArcCore AB <contact@arccore.com>\r
5  *\r
6  * This source code is free software; you can redistribute it and/or modify it\r
7  * under the terms of the GNU General Public License version 2 as published by the\r
8  * Free Software Foundation; See <http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt>.\r
9  *\r
10  * This program is distributed in the hope that it will be useful, but\r
11  * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\r
12  * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License\r
13  * for more details.\r
14  * -------------------------------- Arctic Core ------------------------------*/\r
15 \r
16 /*\r
17  *  General requirements\r
18  */\r
19 /** @req DCM030 */\r
20 \r
21 \r
22 #include <string.h>\r
23 #include "Dcm.h"\r
24 #include "Dcm_Internal.h"\r
25 #include "MemMap.h"\r
26 #if defined(USE_COMM)\r
27 #include "ComM_Dcm.h"\r
28 #endif\r
29 #include "PduR_Dcm.h"\r
30 #include "ComStack_Types.h"\r
31 #include "Cpu.h"\r
32 //#define USE_DEBUG_PRINTF\r
33 #include "debug.h"\r
34 \r
35 #define DECREMENT(timer) { if (timer > 0){timer--;} }\r
36 #define DCM_CONVERT_MS_TO_MAIN_CYCLES(x)  ((x)/DCM_MAIN_FUNCTION_PERIOD_TIME_MS)\r
37 \r
38 \r
39 #if (DCM_PAGEDBUFFER_ENABLED)\r
40 #error "DCM_PAGEDBUFFER_ENABLED is set to STD_ON, this is not supported by the code."\r
41 #endif\r
42 \r
43 /*\r
44  * Type definitions.\r
45  */\r
46 // #define MAX_PARALLEL_PROTOCOLS_ALLOWED               1\r
47 \r
48 typedef struct {\r
49         boolean initRun;\r
50         //boolean diagnosticRequestPending; // This is a "semaphore" because DSD and DCM can handle multiple/parallel request at the moment.\r
51         const Dcm_DslProtocolRowType *activeProtocol; // Points to the currently active protocol.\r
52 //      const Dcm_DslProtocolRowType *preemptedProtocol; // Points to the currently active protocol - reserved for future use\r
53 //      Dcm_DslRunTimeProtocolParametersType protocolList[MAX_PARALLEL_PROTOCOLS_ALLOWED];      // Reserved for future use\r
54 } DcmDsl_RunTimeDataType;\r
55 \r
56 static DcmDsl_RunTimeDataType DcmDslRunTimeData = {\r
57                 .initRun = FALSE,\r
58                 .activeProtocol = NULL\r
59 //              .preemptedProtocol = NULL,\r
60 //              .protocolList = {}\r
61 };\r
62 \r
63 // ################# HELPER FUNCTIONS START #################\r
64 \r
65 //\r
66 // This function reset/stars the session (S3) timer. See requirement\r
67 // DCM141 when that action should be taken.\r
68 //\r
69 static inline void startS3SessionTimer(Dcm_DslRunTimeProtocolParametersType *runtime, const Dcm_DslProtocolRowType *protocolRow) {\r
70         const Dcm_DslProtocolTimingRowType *timeParams;\r
71         timeParams = protocolRow->DslProtocolTimeLimit;\r
72         runtime->S3ServerTimeoutCount = DCM_CONVERT_MS_TO_MAIN_CYCLES(timeParams->TimStrS3Server);\r
73 }\r
74 \r
75 // - - - - - - - - - - -\r
76 \r
77 //\r
78 // This function reset/stars the session (S3) timer. See requirement\r
79 // DCM141 when that action should be taken.\r
80 //\r
81 static inline void stopS3SessionTimer(Dcm_DslRunTimeProtocolParametersType *runtime) {\r
82         runtime->S3ServerTimeoutCount = 0;\r
83 }\r
84 \r
85 // - - - - - - - - - - -\r
86 \r
87 //\r
88 //      This function implements the requirement DCM139 when\r
89 //      transition from one session to another.\r
90 //\r
91 static void changeDiagnosticSession(Dcm_DslRunTimeProtocolParametersType *runtime, Dcm_SesCtrlType newSession) {\r
92 \r
93         /** @req DCM139 */\r
94 \r
95         switch (runtime->sessionControl) {\r
96         case DCM_DEFAULT_SESSION: // "default".\r
97                 /* to set the dsp buffer to default*/\r
98                 DspInit();\r
99                 break;\r
100 \r
101         case DCM_PROGRAMMING_SESSION:\r
102         case DCM_EXTENDED_DIAGNOSTIC_SESSION:\r
103         case DCM_SAFTEY_SYSTEM_DIAGNOSTIC_SESSION:\r
104         case DCM_ALL_SESSION_LEVEL:\r
105                 runtime->securityLevel = DCM_SEC_LEV_LOCKED; // "0x00".\r
106                 break;\r
107 \r
108         default:\r
109                 DET_REPORTERROR(MODULE_ID_DCM, 0, DCM_CHANGE_DIAGNOSTIC_SESSION_ID, DCM_E_PARAM);\r
110                 //DEBUG(DEBUG_MEDIUM, "Old session invalid");\r
111                 break;\r
112         }\r
113 \r
114         switch (newSession) {\r
115         case DCM_DEFAULT_SESSION: // "default".\r
116         case DCM_PROGRAMMING_SESSION:\r
117         case DCM_EXTENDED_DIAGNOSTIC_SESSION:\r
118         case DCM_SAFTEY_SYSTEM_DIAGNOSTIC_SESSION:\r
119         case DCM_ALL_SESSION_LEVEL:\r
120                 runtime->sessionControl = newSession;\r
121                 break;\r
122 \r
123         default:\r
124                 DET_REPORTERROR(MODULE_ID_DCM, 0, DCM_CHANGE_DIAGNOSTIC_SESSION_ID, DCM_E_PARAM);\r
125                 //DEBUG(DEBUG_MEDIUM, "New session invalid");\r
126                 break;\r
127         }\r
128 }\r
129 \r
130 // - - - - - - - - - - -\r
131 \r
132 void DslResetSessionTimeoutTimer(void) {\r
133         const Dcm_DslProtocolRowType *activeProtocol;\r
134         Dcm_DslRunTimeProtocolParametersType *runtime;\r
135 \r
136         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
137         runtime = activeProtocol->DslRunTimeProtocolParameters;\r
138         startS3SessionTimer(runtime, activeProtocol); /** @req DCM141 */\r
139 }\r
140 \r
141 // - - - - - - - - - - -\r
142 \r
143 void DslGetCurrentServiceTable(const Dcm_DsdServiceTableType **currentServiceTable) { /** @req DCM195 */\r
144         const Dcm_DslProtocolRowType *activeProtocol;\r
145 \r
146         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
147         if (activeProtocol != NULL) {\r
148                 *currentServiceTable = activeProtocol->DslProtocolSIDTable;\r
149         }\r
150 }\r
151 \r
152 // - - - - - - - - - - -\r
153 \r
154 Std_ReturnType DslGetActiveProtocol(Dcm_ProtocolType *protocolId) { /** @req DCM340 */\r
155         Std_ReturnType ret = E_NOT_OK;\r
156         const Dcm_DslProtocolRowType *activeProtocol;\r
157 \r
158         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
159         if (activeProtocol != NULL) {\r
160                 *protocolId = activeProtocol->DslProtocolID;\r
161                 ret = E_OK;\r
162         }\r
163         return ret;\r
164 }\r
165 \r
166 // - - - - - - - - - - -\r
167 \r
168 void DslSetSecurityLevel(Dcm_SecLevelType secLevel) { /** @req DCM020 */\r
169         const Dcm_DslProtocolRowType *activeProtocol;\r
170         Dcm_DslRunTimeProtocolParametersType *runtime;\r
171 \r
172         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
173         runtime = activeProtocol->DslRunTimeProtocolParameters;\r
174         runtime->securityLevel = secLevel;\r
175 }\r
176 \r
177 // - - - - - - - - - - -\r
178 \r
179 Std_ReturnType DslGetSecurityLevel(Dcm_SecLevelType *secLevel) {  /** @req DCM020 *//** @req DCM338 */\r
180         Std_ReturnType ret = E_NOT_OK;\r
181         const Dcm_DslProtocolRowType *activeProtocol;\r
182         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
183 \r
184         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
185         if (activeProtocol != NULL) {\r
186                 runtime = activeProtocol->DslRunTimeProtocolParameters;\r
187                 *secLevel = runtime->securityLevel;\r
188                 ret = E_OK;\r
189         }\r
190         return ret;\r
191 }\r
192 \r
193 // - - - - - - - - - - -\r
194 \r
195 void DslSetSesCtrlType(Dcm_SesCtrlType sesCtrl) {  /** @req DCM022 */\r
196         const Dcm_DslProtocolRowType *activeProtocol;\r
197         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
198 \r
199         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
200         if (activeProtocol != NULL) {\r
201                 runtime = activeProtocol->DslRunTimeProtocolParameters;\r
202                 if (runtime->sessionControl != sesCtrl) {\r
203                         changeDiagnosticSession(runtime, sesCtrl);\r
204                         DslResetSessionTimeoutTimer();\r
205                 }\r
206         }\r
207 }\r
208 \r
209 // - - - - - - - - - - -\r
210 \r
211 Std_ReturnType DslGetSesCtrlType(Dcm_SesCtrlType *sesCtrlType) { /** @req DCM022 *//** @req DCM339 */\r
212         Std_ReturnType ret = E_NOT_OK;\r
213         const Dcm_DslProtocolRowType *activeProtocol;\r
214         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
215 \r
216         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
217         if (activeProtocol != NULL) {\r
218                 runtime = activeProtocol->DslRunTimeProtocolParameters;\r
219                 *sesCtrlType = runtime->sessionControl;\r
220                 ret = E_OK;\r
221         }\r
222         return ret;\r
223 }\r
224 \r
225 // - - - - - - - - - - -\r
226 \r
227 static boolean findRxPduIdParentConfigurationLeafs(PduIdType dcmRxPduId,\r
228                 const Dcm_DslProtocolRxType **protocolRx,\r
229                 const Dcm_DslMainConnectionType **mainConnection,\r
230                 const Dcm_DslConnectionType **connection,\r
231                 const Dcm_DslProtocolRowType **protocolRow,\r
232                 Dcm_DslRunTimeProtocolParametersType **runtime) {\r
233 \r
234         boolean ret = FALSE;\r
235         if (dcmRxPduId < DCM_DSL_RX_PDU_ID_LIST_LENGTH) {\r
236                 *protocolRx = &DCM_Config.Dsl->DslProtocol->DslProtocolRxGlobalList[dcmRxPduId];\r
237                 *mainConnection = (*protocolRx)->DslMainConnectionParent;\r
238                 *connection = (*mainConnection)->DslConnectionParent;\r
239                 *protocolRow = (*connection)->DslProtocolRow;\r
240                 *runtime = (*protocolRow)->DslRunTimeProtocolParameters;\r
241                 ret = TRUE;\r
242         }\r
243         return ret;\r
244 }\r
245 \r
246 // - - - - - - - - - - -\r
247 \r
248 static boolean findTxPduIdParentConfigurationLeafs(PduIdType dcmTxPduId,\r
249                 const Dcm_DslProtocolTxType **protocolTx,\r
250                 const Dcm_DslMainConnectionType **mainConnection,\r
251                 const Dcm_DslConnectionType **connection,\r
252                 const Dcm_DslProtocolRowType **protocolRow,\r
253                 Dcm_DslRunTimeProtocolParametersType **runtime) {\r
254 \r
255         boolean ret = FALSE;\r
256         if (dcmTxPduId < DCM_DSL_TX_PDU_ID_LIST_LENGTH) {\r
257                 *protocolTx = &DCM_Config.Dsl->DslProtocol->DslProtocolTxGlobalList[dcmTxPduId];\r
258                 *mainConnection = (*protocolTx)->DslMainConnectionParent;\r
259                 *connection = (*mainConnection)->DslConnectionParent;\r
260                 *protocolRow = (*connection)->DslProtocolRow;\r
261                 *runtime = (*protocolRow)->DslRunTimeProtocolParameters;\r
262                 ret = TRUE;\r
263         }\r
264         return ret;\r
265 }\r
266 \r
267 // - - - - - - - - - - -\r
268 \r
269 static inline void releaseExternalRxTxBuffers(const Dcm_DslProtocolRowType *protocolRow,\r
270                 Dcm_DslRunTimeProtocolParametersType *runtime) {\r
271 \r
272         protocolRow->DslProtocolTxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;\r
273         protocolRow->DslProtocolRxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;\r
274         runtime->externalTxBufferStatus = NOT_IN_USE; // We are waiting for DSD to return the buffer. qqq.\r
275         runtime->externalRxBufferStatus = NOT_IN_USE; // We are waiting for DSD to return the buffer. qqq.\r
276 }\r
277 \r
278 // - - - - - - - - - - -\r
279 \r
280 \r
281 static inline void releaseExternalRxTxBuffersHelper(PduIdType rxPduIdRef) {\r
282         const Dcm_DslProtocolRxType *protocolRx = NULL;\r
283         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
284         const Dcm_DslConnectionType *connection = NULL;\r
285         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
286         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
287 \r
288         if (findRxPduIdParentConfigurationLeafs(rxPduIdRef, &protocolRx, &mainConnection, &connection, &protocolRow, &runtime)) {\r
289                 releaseExternalRxTxBuffers(protocolRow, runtime);\r
290         }\r
291 }\r
292 \r
293 // - - - - - - - - - - -\r
294 \r
295 /*\r
296  *  This function is called from the DSD module to the DSL when\r
297  *  a response to a diagnostic request has been copied into the\r
298  *  given TX-buffer and is ready for transmission.\r
299  */\r
300 void DslDsdProcessingDone(PduIdType rxPduIdRef, DsdProcessingDoneResultType responseResult) {\r
301         const Dcm_DslProtocolRxType *protocolRx = NULL;\r
302         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
303         const Dcm_DslConnectionType *connection = NULL;\r
304         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
305         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
306 \r
307 //      DEBUG( DEBUG_MEDIUM, "DslDsdProcessingDone rxPduIdRef=%d\n", rxPduIdRef);\r
308 \r
309         if (findRxPduIdParentConfigurationLeafs(rxPduIdRef, &protocolRx, &mainConnection, &connection, &protocolRow, &runtime)) {\r
310             imask_t state;\r
311             Irq_Save(state);\r
312                 switch (responseResult) {\r
313                 case DSD_TX_RESPONSE_READY:\r
314                         runtime->externalTxBufferStatus = DSD_PENDING_RESPONSE_SIGNALED; /** @req DCM114 */\r
315                         break;\r
316                 case DSD_TX_RESPONSE_SUPPRESSED: /** @req DCM238 */\r
317                         //DEBUG( DEBUG_MEDIUM, "DslDsdProcessingDone called with DSD_TX_RESPONSE_SUPPRESSED.\n");\r
318                         releaseExternalRxTxBuffersHelper(rxPduIdRef);\r
319                         break;\r
320                 default:\r
321                         //DEBUG( DEBUG_MEDIUM, "Unknown response result from DslDsdProcessingDone!\n");\r
322                         break;\r
323                 }\r
324             Irq_Restore(state);\r
325         }\r
326 }\r
327 \r
328 // - - - - - - - - - - -\r
329 \r
330 /*\r
331  *      This function preparing transmission of response\r
332  *      pending message to tester.\r
333  */\r
334 static void sendResponse(const Dcm_DslProtocolRowType *protocol,\r
335                 Dcm_NegativeResponseCodeType responseCode) {\r
336         //Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
337         const Dcm_DslProtocolRxType *protocolRx = NULL;\r
338         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
339         const Dcm_DslConnectionType *connection = NULL;\r
340         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
341         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
342         Std_ReturnType transmitResult;\r
343     imask_t state;\r
344 \r
345     Irq_Save(state);\r
346         /** @req DCM119 */\r
347         if (findRxPduIdParentConfigurationLeafs(protocol->DslRunTimeProtocolParameters->diagReqestRxPduId, &protocolRx, &mainConnection, &connection, &protocolRow, &runtime)) {\r
348                 if (runtime->localTxBuffer.status == NOT_IN_USE) {\r
349                         runtime->localTxBuffer.status = PROVIDED_TO_DSD;\r
350                         runtime->localTxBuffer.buffer[0] = SID_NEGATIVE_RESPONSE;\r
351                         runtime->localTxBuffer.buffer[1] = protocol->DslProtocolRxBufferID->pduInfo.SduDataPtr[2];\r
352                         runtime->localTxBuffer.buffer[2] = responseCode;\r
353                         runtime->localTxBuffer.PduInfo.SduDataPtr = runtime->localTxBuffer.buffer;\r
354                         runtime->localTxBuffer.PduInfo.SduLength = 3;\r
355                         runtime->localTxBuffer.status = DCM_TRANSMIT_SIGNALED; // In the DslProvideTxBuffer 'callback' this state signals it is the local buffer we are interested in sending.\r
356                         transmitResult = PduR_DcmTransmit(mainConnection->DslProtocolTx->DcmDslProtocolTxPduId, &(runtime->localTxBuffer.PduInfo));/** @req DCM115.Partially */ /* The P2ServerMin has not been implemented. */\r
357                         if (transmitResult != E_OK) {\r
358                                 // TODO: What to do here?\r
359                         }\r
360                 }\r
361         }\r
362     Irq_Restore(state);\r
363 }\r
364 \r
365 // - - - - - - - - - - -\r
366 \r
367 static Std_ReturnType StartProtocolHelper(Dcm_ProtocolType protocolId) {\r
368         Std_ReturnType ret = E_NOT_OK;\r
369         uint16 i;\r
370 \r
371         for (i = 0; !DCM_Config.Dsl->DslCallbackDCMRequestService[i].Arc_EOL; i++) {\r
372                 if (DCM_Config.Dsl->DslCallbackDCMRequestService[i].StartProtocol != NULL) {\r
373                         ret = DCM_Config.Dsl->DslCallbackDCMRequestService[i]. StartProtocol(protocolId);\r
374                         if (ret != E_OK) {\r
375                                 break;\r
376                         }\r
377                 }\r
378         }\r
379         return ret;\r
380 }\r
381 \r
382 // - - - - - - - - - - -\r
383 \r
384 static boolean isTesterPresentCommand(const PduInfoType *rxPdu) {\r
385         boolean ret = FALSE;\r
386         if ((rxPdu->SduDataPtr[0] == SID_TESTER_PRESENT) && (rxPdu->SduDataPtr[1] & SUPPRESS_POS_RESP_BIT)) {\r
387                 ret = TRUE;\r
388         }\r
389         return ret;\r
390 }\r
391 \r
392 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
393 //      Implements 'void Dcm_Init(void)' for DSL.\r
394 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
395 void DslInit(void) {\r
396         const Dcm_DslProtocolRowType *listEntry;\r
397         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
398 \r
399         listEntry = DCM_Config.Dsl->DslProtocol->DslProtocolRowList;\r
400         while (listEntry->Arc_EOL == FALSE) {\r
401                 runtime = listEntry->DslRunTimeProtocolParameters;\r
402                 runtime->externalRxBufferStatus = DCM_IDLE;\r
403                 runtime->externalTxBufferStatus = DCM_IDLE;\r
404                 runtime->localRxBuffer.status = DCM_IDLE;\r
405                 runtime->localTxBuffer.status = DCM_IDLE;\r
406                 runtime->securityLevel = DCM_SEC_LEV_LOCKED; /** @req DCM033 */\r
407                 runtime->sessionControl = DCM_DEFAULT_SESSION; /** @req DCM034 */\r
408                 listEntry->DslProtocolRxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;\r
409                 listEntry->DslProtocolRxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;\r
410                 listEntry++;\r
411         };\r
412         //DcmDslRunTimeData.diagnosticRequestPending = FALSE;\r
413         DcmDslRunTimeData.initRun = TRUE;\r
414 }\r
415 \r
416 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
417 //      Implements 'void DslInternal_ResponseOnOneDataByPeriodicId(uint8 PericodID)' for simulator a periodic did data.\r
418 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
419 \r
420 Std_ReturnType DslInternal_ResponseOnOneDataByPeriodicId(uint8 PericodID)\r
421 {\r
422         Std_ReturnType ret = E_NOT_OK;\r
423         const Dcm_DslProtocolRowType *protocolRowEntry;\r
424         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
425     PduInfoType  *pPeriodData;\r
426         protocolRowEntry = DCM_Config.Dsl->DslProtocol->DslProtocolRowList;\r
427         while (protocolRowEntry->Arc_EOL == FALSE) \r
428         {\r
429         runtime = protocolRowEntry->DslRunTimeProtocolParameters;\r
430         if(runtime != NULL)     // find the runtime\r
431         {\r
432                 if( BUFREQ_OK == DslProvideRxBufferToPdur(runtime->diagReqestRxPduId, 3, (const PduInfoType **)&pPeriodData)){\r
433                 pPeriodData->SduDataPtr[0] = 0x2a;\r
434                 pPeriodData->SduDataPtr[1] = 0;\r
435                 pPeriodData->SduDataPtr[2] = PericodID;\r
436                 pPeriodData->SduLength = 3;\r
437                 DslRxIndicationFromPduR(0, NTFRSLT_OK);\r
438                 ret = E_OK;\r
439                         break;\r
440                 }\r
441                 else {\r
442                         ret = E_NOT_OK;\r
443                 }\r
444 \r
445                 }\r
446         protocolRowEntry++;\r
447         }\r
448 \r
449         return ret;\r
450 }\r
451 \r
452 \r
453 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
454 //      Implements 'void Dcm_MainFunction(void)' for DSL.\r
455 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
456 void DslMain(void) {\r
457         const Dcm_DslProtocolRowType *protocolRowEntry;\r
458         const Dcm_DslProtocolTimingRowType *timeParams = NULL;\r
459         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
460 \r
461         protocolRowEntry = DCM_Config.Dsl->DslProtocol->DslProtocolRowList;\r
462         while (protocolRowEntry->Arc_EOL == FALSE) {\r
463                 runtime = protocolRowEntry->DslRunTimeProtocolParameters;\r
464                 if (runtime != NULL) {\r
465                         // #### HANDLE THE TESTER PRESENT PRESENCE ####\r
466                         if (runtime->sessionControl != DCM_DEFAULT_SESSION) { // Timeout if tester present is lost.\r
467                                 DECREMENT(runtime->S3ServerTimeoutCount);\r
468                                 if (runtime->S3ServerTimeoutCount == 0) {\r
469                                         changeDiagnosticSession(runtime, DCM_DEFAULT_SESSION); /** @req DCM140 */\r
470                                 }\r
471                         }\r
472                         switch (runtime->externalTxBufferStatus) { // #### TX buffer state. ####\r
473                         case NOT_IN_USE:\r
474                                 //DEBUG( DEBUG_MEDIUM, "state NOT_IN_USE!\n");\r
475                                 break;\r
476                         case PROVIDED_TO_DSD: {\r
477                                 DECREMENT(runtime->stateTimeoutCount);\r
478                                 if (runtime->stateTimeoutCount == 0) {\r
479                                         timeParams = protocolRowEntry->DslProtocolTimeLimit;\r
480                                         runtime->stateTimeoutCount = DCM_CONVERT_MS_TO_MAIN_CYCLES(timeParams->TimStrP2ServerMax); /* Reinitiate timer, see 9.2.2. */\r
481                                         if (DCM_Config.Dsl->DslDiagResp != NULL) {\r
482                                                 if (DCM_Config.Dsl->DslDiagResp->DslDiagRespForceRespPendEn == TRUE) {\r
483                                                         if (runtime->responsePendingCount != 0) {\r
484                                                                 sendResponse(protocolRowEntry, DCM_E_RESPONSEPENDING);  /** @req DCM024 */\r
485                                                                 DECREMENT( runtime->responsePendingCount );\r
486                                                         } else {\r
487                                                                 sendResponse(protocolRowEntry, DCM_E_GENERALREJECT); /** @req DCM120 */\r
488                                                                 releaseExternalRxTxBuffers(protocolRowEntry, runtime);\r
489                                                         }\r
490                                                 } else {\r
491                                 //                      DEBUG( DEBUG_MEDIUM, "Not configured to send response pending, now sending general reject!\n");\r
492                                                         sendResponse(protocolRowEntry, DCM_E_GENERALREJECT);\r
493                                                         releaseExternalRxTxBuffers(protocolRowEntry, runtime);\r
494                                                 }\r
495                                         }\r
496                                 }\r
497                                 break;\r
498                         }\r
499                         case DSD_PENDING_RESPONSE_SIGNALED:\r
500                                 // The DSD has signaled to DSL that the diagnostic response is available in the Tx buffer.\r
501                                 // Make sure that response pending or general reject have not been issued,\r
502                                 // if so we can not transmit to PduR because we would not know from where\r
503                                 // the Tx confirmation resides later.\r
504                         //      DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n");\r
505                                 if (runtime->localTxBuffer.status == NOT_IN_USE) { // Make sure that no TxConfirm could be sent by the local buffer and mixed up with this transmission.\r
506                                         const Dcm_DslProtocolRxType *protocolRx = NULL;\r
507                                         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
508                                         const Dcm_DslConnectionType *connection = NULL;\r
509                                         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
510                                         Std_ReturnType transmitResult;\r
511 \r
512                                         if (findRxPduIdParentConfigurationLeafs(runtime->diagReqestRxPduId, &protocolRx, &mainConnection, &connection, &protocolRow, &runtime)) {\r
513                                                 const PduIdType txPduId = mainConnection->DslProtocolTx->DcmDslProtocolTxPduId;\r
514                                         //      DEBUG( DEBUG_MEDIUM, "runtime->externalTxBufferStatus enter state DCM_TRANSMIT_SIGNALED.\n" );\r
515                                                 runtime->externalTxBufferStatus = DCM_TRANSMIT_SIGNALED;\r
516                                                 transmitResult = PduR_DcmTransmit(txPduId, &runtime->diagnosticResponseFromDsd); /** @req DCM237 *//* Will trigger PduR (CanTP) to call DslProvideTxBuffer(). */\r
517                                                 if (transmitResult != E_OK) {\r
518                                                         // TODO: What to do here?\r
519                                                 }\r
520                                         } else {\r
521                                         //      DEBUG( DEBUG_MEDIUM, "***** WARNING, THIS IS UNEXPECTED !!! ********.\n" );\r
522                                                 const PduIdType txPduId = protocolRowEntry->DslConnection->DslMainConnection->DslProtocolTx->DcmDslProtocolTxPduId;\r
523                                         //      DEBUG( DEBUG_MEDIUM, "runtime->externalTxBufferStatus enter state DSD_PENDING_RESPONSE_SIGNALED.\n", txPduId);\r
524                                                 runtime->externalTxBufferStatus = DCM_TRANSMIT_SIGNALED;\r
525                                         //      DEBUG( DEBUG_MEDIUM, "Calling PduR_DcmTransmit with txPduId = %d from DslMain\n", txPduId);\r
526                                                 transmitResult = PduR_DcmTransmit(txPduId, &runtime->diagnosticResponseFromDsd); /** @req DCM237 *//* Will trigger PduR (CanTP) to call DslProvideTxBuffer(). */\r
527                                                 if (transmitResult != E_OK) {\r
528                                                         // TODO: What to do here?\r
529                                                 }\r
530                                         }\r
531                                 }\r
532                                 break;\r
533                         case DCM_TRANSMIT_SIGNALED:\r
534                                 //DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n");\r
535                                 break;\r
536                         case PROVIDED_TO_PDUR: // The valid data is being transmitted by TP-layer.\r
537                                 //DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n");\r
538                                 break;\r
539                         default:\r
540                                 break;\r
541                         }\r
542                 }\r
543                 protocolRowEntry++;\r
544         }\r
545 }\r
546 \r
547 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
548 //      Implements 'BufReq_ReturnType Dcm_ProvideRxBuffer(PduIdType dcmRxPduId,\r
549 //  PduLengthType tpSduLength, PduInfoType **pduInfoPtr)'.\r
550 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
551 //  This function is called called by the PduR typically when CanTp has\r
552 //  received a FF or a single frame and needs to obtain a buffer from the\r
553 //  receiver so that received data can be forwarded.\r
554 \r
555 BufReq_ReturnType DslProvideRxBufferToPdur(PduIdType dcmRxPduId, PduLengthType tpSduLength, const PduInfoType **pduInfoPtr) {\r
556         BufReq_ReturnType ret = BUFREQ_NOT_OK;\r
557         const Dcm_DslProtocolRxType *protocolRx = NULL;\r
558         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
559         const Dcm_DslConnectionType *connection = NULL;\r
560         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
561         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
562     imask_t state;\r
563 //      DEBUG( DEBUG_MEDIUM, "DslProvideRxBufferToPdur(dcmRxPduId=%d) called!\n", dcmRxPduId);  \r
564     Irq_Save(state);\r
565         if (findRxPduIdParentConfigurationLeafs(dcmRxPduId, &protocolRx, &mainConnection, &connection, &protocolRow, &runtime)) {\r
566                 const Dcm_DslBufferType *externalRxBuffer = protocolRow->DslProtocolRxBufferID;\r
567                 if (externalRxBuffer->pduInfo.SduLength >= tpSduLength) { /** @req DCM443 */\r
568                         if ((runtime->externalRxBufferStatus == NOT_IN_USE) && (externalRxBuffer->externalBufferRuntimeData->status == BUFFER_AVAILABLE)) {\r
569                         //      DEBUG( DEBUG_MEDIUM, "External buffer available!\n");\r
570                                 // ### EXTERNAL BUFFER IS AVAILABLE; GRAB IT AND REMEBER THAT WE OWN IT! ###\r
571                                 externalRxBuffer->externalBufferRuntimeData->status = BUFFER_BUSY;\r
572                                 runtime->diagnosticRequestFromTester.SduDataPtr = externalRxBuffer->pduInfo.SduDataPtr;\r
573                                 runtime->diagnosticRequestFromTester.SduLength = tpSduLength;\r
574                                 *pduInfoPtr = &(runtime->diagnosticRequestFromTester);\r
575                                 runtime->externalRxBufferStatus = PROVIDED_TO_PDUR; /** @req DCM342 */\r
576                                 ret = BUFREQ_OK;\r
577                         } else {\r
578                                 if (runtime->externalRxBufferStatus == PROVIDED_TO_DSD) {\r
579                                         // ### EXTERNAL BUFFER IS IN USE BY THE DSD, TRY TO USE LOCAL BUFFER! ###\r
580                                         if (runtime->localRxBuffer.status == NOT_IN_USE) {\r
581                                                 if (tpSduLength < DCM_DSL_LOCAL_BUFFER_LENGTH) {\r
582                                                         runtime->localRxBuffer.status = PROVIDED_TO_PDUR;\r
583                                                         runtime->localRxBuffer.PduInfo.SduDataPtr = runtime->localRxBuffer.buffer;\r
584                                                         runtime->localRxBuffer.PduInfo.SduLength = tpSduLength;\r
585                                                         *pduInfoPtr = &(runtime->localRxBuffer.PduInfo);\r
586                                                         ret = BUFREQ_OK;\r
587                                                 } else {\r
588                                                         ret = BUFREQ_BUSY;\r
589                                                 }\r
590                                         }\r
591                                 } else {\r
592                                         // The buffer is in use by the PduR, we can not help this because then\r
593                                         // we would have two different Rx-indications with same PduId but we\r
594                                         // will not know which buffer the indication should free.\r
595                                         ret = BUFREQ_BUSY; /** @req DCM445 */\r
596                                 }\r
597                         }\r
598                 } else {\r
599                         ret = BUFREQ_OVFL; /** @req DCM444 */\r
600                 }\r
601                 if (ret == BUFREQ_OK) {\r
602                         stopS3SessionTimer(runtime); /** @req DCM141 */\r
603                 }\r
604         }\r
605     Irq_Restore(state);\r
606         return ret;\r
607 }\r
608 \r
609 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
610 //      Implements 'void Dcm_RxIndication(PduIdType dcmRxPduId, NotifResultType result)'.\r
611 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
612 //      This function is called called by the PduR typically when CanTp has\r
613 //      received the diagnostic request, copied it to the provided buffer and need to indicate\r
614 //      this to the DCM (DSL) module via proprietary API.\r
615 \r
616 void DslRxIndicationFromPduR(PduIdType dcmRxPduId, NotifResultType result) {\r
617         const Dcm_DslProtocolRxType *protocolRx = NULL;\r
618         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
619         const Dcm_DslConnectionType *connection = NULL;\r
620         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
621         const Dcm_DslProtocolTimingRowType *timeParams = NULL;\r
622         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
623         Std_ReturnType higherLayerResp;\r
624         imask_t state;\r
625 \r
626         /** @req DCM345, this needs to be verified when connection to CanIf works. */\r
627 \r
628         if (findRxPduIdParentConfigurationLeafs(dcmRxPduId, &protocolRx, &mainConnection, &connection, &protocolRow, &runtime)) {\r
629                 timeParams = protocolRow->DslProtocolTimeLimit;\r
630                 // We need to find out in what buffer we can find our Rx data (it can\r
631                 // be either in the normal RX-buffer or the 'extra' buffer for implementing\r
632                 // the Concurrent "Test Present" functionality.\r
633             Irq_Save(state);\r
634                 if (runtime->externalRxBufferStatus == PROVIDED_TO_PDUR) {\r
635                         if ( result == NTFRSLT_OK ) { /** @req DCM111 */\r
636                                 if (isTesterPresentCommand(&(protocolRow->DslProtocolRxBufferID->pduInfo))) {\r
637                                         startS3SessionTimer(runtime, protocolRow); /** @req DCM141 *//** @req DCM112 *//** @req DCM113 */\r
638                                         runtime->externalRxBufferStatus = NOT_IN_USE;\r
639                                         protocolRow->DslProtocolRxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;\r
640                                 } else {\r
641                                         if (runtime->protocolStarted == FALSE) {\r
642                                                 higherLayerResp = StartProtocolHelper(protocolRow->DslProtocolID); /** @req DCM036 */\r
643                                                 if (higherLayerResp == E_OK) {\r
644                                                         runtime->protocolStarted = TRUE;\r
645                                                         DcmDslRunTimeData.activeProtocol = protocolRow;\r
646                                                 }\r
647                                         }\r
648                                         if (runtime->protocolStarted == TRUE) {\r
649                                                 if (runtime->diagnosticActiveComM == FALSE) {\r
650 #if defined(USE_COMM)\r
651                                                         ComM_DCM_ActiveDiagnostic(); /** @req DCM163 */\r
652 #endif\r
653                                                         runtime->diagnosticActiveComM = TRUE;\r
654                                                 }\r
655                                                 timeParams = protocolRow->DslProtocolTimeLimit;\r
656                                                 runtime->stateTimeoutCount = DCM_CONVERT_MS_TO_MAIN_CYCLES(timeParams->TimStrP2ServerMax); /* See 9.2.2. */\r
657                                                 runtime->externalRxBufferStatus = PROVIDED_TO_DSD; /** @req DCM241 */\r
658                                                 if (runtime->externalTxBufferStatus == NOT_IN_USE) {\r
659                                                 //      DEBUG( DEBUG_MEDIUM, "External Tx buffer available, we can pass it to DSD.\n");\r
660                                                 } else {\r
661                                                         //DEBUG( DEBUG_MEDIUM, "External buffer not available, a response is being transmitted?\n");\r
662                                                 }\r
663                                                 runtime->externalTxBufferStatus = PROVIDED_TO_DSD; /** @req DCM241 */\r
664                                                 runtime->responsePendingCount = DCM_Config.Dsl->DslDiagResp->DslDiagRespMaxNumRespPend;\r
665                                                 runtime->diagnosticResponseFromDsd.SduDataPtr = protocolRow->DslProtocolTxBufferID->pduInfo.SduDataPtr;\r
666                                                 runtime->diagnosticResponseFromDsd.SduLength = protocolRow->DslProtocolTxBufferID->pduInfo.SduLength;\r
667                                         //      DEBUG( DEBUG_MEDIUM, "DsdDslDataIndication(DcmDslProtocolTxPduId=%d, dcmRxPduId=%d)\n", mainConnection->DslProtocolTx->DcmDslProtocolTxPduId, dcmRxPduId);\r
668                                                 runtime->diagReqestRxPduId = dcmRxPduId;\r
669                                         //      DEBUG(DEBUG_MEDIUM,"\n\n runtime->diagnosticRequestFromTester.SduDataPtr[2]  %x\n\n ",runtime->diagnosticRequestFromTester.SduDataPtr[2]);\r
670                                                 DsdDslDataIndication(  // qqq: We are inside a critical section.\r
671                                                                 &(runtime->diagnosticRequestFromTester),\r
672                                                                 protocolRow->DslProtocolSIDTable,       /** @req DCM035 */\r
673                                                                 protocolRx->DslProtocolAddrType,\r
674                                                                 mainConnection->DslProtocolTx->DcmDslProtocolTxPduId,\r
675                                                                 &(runtime->diagnosticResponseFromDsd),\r
676                                                                 dcmRxPduId);\r
677                                         }\r
678                                 }\r
679                         } else { /** @req DCM344 */\r
680                                 // The indication was not equal to NTFRSLT_OK, release the resources and no forward to DSD.\r
681                                 runtime->externalRxBufferStatus = NOT_IN_USE;\r
682                                 protocolRow->DslProtocolRxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;\r
683                         }\r
684                 } else {\r
685                         // It is the local buffer that was provided to the PduR, that buffer\r
686                         // is only used for tester present reception in parallel to diagnostic\r
687                         // requests.\r
688                         if (runtime->localRxBuffer.status == PROVIDED_TO_PDUR) {\r
689                                 if ( result == NTFRSLT_OK ) { // Make sure that the data in buffer is valid.\r
690                                         if (isTesterPresentCommand(&(runtime->localRxBuffer.PduInfo))) {\r
691                                                 startS3SessionTimer(runtime, protocolRow); /** @req DCM141 *//** @req DCM112 *//** @req DCM113 */\r
692                                         }\r
693                                 }\r
694                                 runtime->localRxBuffer.status = NOT_IN_USE;\r
695                         }\r
696                 }\r
697             Irq_Restore(state);\r
698         }\r
699 }\r
700 \r
701 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
702 //      Implements 'BufReq_ReturnType Dcm_ProvideTxBuffer(PduIdType dcmTxPduId,\r
703 //  PduInfoType **pduInfoPtr, PduLengthType length)'.\r
704 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
705 //  This TX-buffer request is likely triggered by the transport layer (i.e. CanTp)\r
706 //  after PduR_DcmTransmit() has been called (via PduR to CanTp) indicating that something\r
707 //  is to be sent. The PduR_DcmTransmit() call is done from the DSL main function when\r
708 //  it has detected that the pending request has been answered by DSD\r
709 //  (or any other module?).\r
710 \r
711 BufReq_ReturnType DslProvideTxBuffer(PduIdType dcmTxPduId, const PduInfoType **pduInfoPtr, PduLengthType length) {\r
712         BufReq_ReturnType ret = BUFREQ_NOT_OK;\r
713         const Dcm_DslProtocolTxType *protocolTx = NULL;\r
714         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
715         const Dcm_DslConnectionType *connection = NULL;\r
716         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
717         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
718 \r
719         (void)length;           // Currently not used, this is only to remove compilation warnings\r
720 //      DEBUG( DEBUG_MEDIUM, "DslProvideTxBuffer=%d\n", dcmTxPduId);\r
721         if (findTxPduIdParentConfigurationLeafs(dcmTxPduId, &protocolTx, &mainConnection, &connection, &protocolRow, &runtime)) {\r
722                 switch (runtime->externalTxBufferStatus) { // ### EXTERNAL TX BUFFER ###\r
723                 case DCM_TRANSMIT_SIGNALED: {\r
724                         /** @req DCM346 */ /* Length verification is already done if this state is reached. */\r
725                         *pduInfoPtr = &(protocolRow->DslProtocolTxBufferID->pduInfo);\r
726                         runtime->externalTxBufferStatus = PROVIDED_TO_PDUR; /** @req DCM349 */\r
727                         ret = BUFREQ_OK;\r
728                         break;\r
729                 }\r
730                 default:\r
731                         //DEBUG( DEBUG_MEDIUM, "DCM_TRANSMIT_SIGNALED was not signaled in the external buffer\n");\r
732                         ret = BUFREQ_NOT_OK;\r
733                         break;\r
734                 }\r
735                 if (ret == BUFREQ_NOT_OK) {\r
736                         switch (runtime->localTxBuffer.status) { // ### LOCAL TX BUFFER ###\r
737                         case DCM_TRANSMIT_SIGNALED: {\r
738                                 runtime->localTxBuffer.PduInfo.SduDataPtr = runtime->localTxBuffer.buffer;\r
739                                 runtime->localTxBuffer.PduInfo.SduLength = runtime->localTxBuffer.messageLenght;\r
740                                 *pduInfoPtr = &runtime->localTxBuffer.PduInfo;\r
741                                 runtime->localTxBuffer.status = PROVIDED_TO_PDUR; // Now the DSL should not touch this Tx-buffer anymore.\r
742                                 ret = BUFREQ_OK;\r
743                                 break;\r
744                         }\r
745                         default:\r
746                                 //DEBUG( DEBUG_MEDIUM, "DCM_TRANSMIT_SIGNALED was not signaled for the local buffer either\n");\r
747                                 ret = BUFREQ_NOT_OK;\r
748                                 break;\r
749                         }\r
750                 }\r
751         }\r
752         return ret;\r
753 }\r
754 \r
755 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
756 //      Implements 'void Dcm_TxConfirmation(PduIdType dcmTxPduId, NotifResultType result))'.\r
757 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
758 //      This function is called by the PduR (which has been trigged by i.e. CanTp)\r
759 //      when a transmission has been successfully finished, have had errors or\r
760 //      is even stopped.\r
761 \r
762 void DslTxConfirmation(PduIdType dcmTxPduId, NotifResultType result) {\r
763         const Dcm_DslProtocolTxType *protocolTx = NULL;\r
764         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
765         const Dcm_DslConnectionType *connection = NULL;\r
766         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
767         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
768         imask_t state;\r
769 \r
770 //      DEBUG( DEBUG_MEDIUM, "DslTxConfirmation=%d, result=%d\n", dcmTxPduId, result);\r
771         if (findTxPduIdParentConfigurationLeafs(dcmTxPduId, &protocolTx, &mainConnection, &connection, &protocolRow, &runtime)) {\r
772                 boolean externalBufferReleased = FALSE;\r
773 \r
774                 // Free the buffer and free the Pdu runtime data buffer.\r
775             Irq_Save(state);\r
776                 switch (runtime->externalTxBufferStatus) { // ### EXTERNAL TX BUFFER ###\r
777                 case PROVIDED_TO_PDUR: {\r
778 #if defined(USE_COMM)\r
779                         ComM_DCM_InactiveDiagnostic(); /** @req DCM164 */\r
780 #endif\r
781                         startS3SessionTimer(runtime, protocolRow); /** @req DCM141 */\r
782                         releaseExternalRxTxBuffers(protocolRow, runtime); /** @req DCM118 *//** @req DCM352 *//** @req DCM353 *//** @req DCM354 */\r
783                         externalBufferReleased = TRUE;\r
784                 //      DEBUG( DEBUG_MEDIUM, "Released external buffer OK!\n");\r
785                         DsdDataConfirmation(mainConnection->DslProtocolTx->DcmDslProtocolTxPduId, result); /** @req DCM117 *//** @req DCM235 */\r
786                         break;\r
787                 }\r
788                 default:\r
789                         break;\r
790                 }\r
791                 if (!externalBufferReleased) {\r
792                         switch (runtime->localTxBuffer.status) { // ### LOCAL TX BUFFER ###\r
793                         case PROVIDED_TO_PDUR:\r
794                         //      DEBUG( DEBUG_MEDIUM, "Released local buffer buffer OK!\n");\r
795                                 runtime->localTxBuffer.status = DCM_IDLE;\r
796                                 break;\r
797                         default:\r
798                         //      DEBUG( DEBUG_MEDIUM, "WARNING! DslTxConfirmation could not release external or local buffer!\n");\r
799                                 break;\r
800                         }\r
801                 }\r
802             Irq_Restore(state);\r
803         }\r
804 }\r
805 \r