]> rtime.felk.cvut.cz Git - arc.git/blob - diagnostic/Dcm/Dcm_Dsl.c
Updates of Dcm (Dsl).
[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 #include <string.h>\r
17 #include "Mcu.h"\r
18 #include "Dcm_Cfg.h"\r
19 #include "Dcm_Cbk.h"\r
20 #include "Dcm.h"\r
21 #include "Dcm_Internal.h"\r
22 #include "Det.h"\r
23 #include "MemMap.h"\r
24 #include "ComM_Dcm.h"\r
25 #include "PduR_Dcm.h"\r
26 #include "ComStack_Types.h"\r
27 \r
28 #define TIMER_DECREMENT(timer) \\r
29         if (timer > 0) { \\r
30                 timer = timer - 1; \\r
31         } \\r
32 \r
33 #define COUNT_DECREMENT(timer) \\r
34         if (timer > 0) { \\r
35                 timer = timer - 1; \\r
36         } \\r
37 \r
38 /*\r
39  * Type definitions.\r
40  */\r
41 typedef struct {\r
42         const Dcm_DslProtocolRxType *protocolRx;\r
43         const Dcm_DslMainConnectionType *mainConnection;\r
44         const Dcm_DslConnectionType *connection;\r
45         const Dcm_DslProtocolRowType *protocolRow;\r
46 } DcmDsl_ProtocolConfigurationType;\r
47 \r
48 #define MAX_PARALLEL_PROTOCOLS_ALLOWED          1\r
49 \r
50 typedef struct {\r
51         boolean initRun;\r
52         const Dcm_DslProtocolRowType *preemptedProtocol;  // Points to the currently active protocol.\r
53         const Dcm_DslProtocolRowType *activeProtocol;  // Points to the currently active protocol.\r
54         Dcm_DslRunTimeProtocolParametersType\r
55                         protocolList[MAX_PARALLEL_PROTOCOLS_ALLOWED];\r
56 } DcmDsl_RunTimeDataType;\r
57 \r
58 DcmDsl_RunTimeDataType DcmDslRunTimeData = {\r
59                 .initRun = FALSE,\r
60                 .preemptedProtocol = NULL,\r
61                 .activeProtocol = NULL\r
62 };\r
63 \r
64 \r
65 // ################# DUMMIES START #################\r
66 \r
67 /*\r
68  * Local types\r
69  */\r
70 \r
71 // Global service table, set by DSL used by DSD\r
72 Dcm_DsdServiceTableType *DslCurrentServiceTable = NULL;\r
73 \r
74 void ComM_DCM_ActivateDiagnostic() {\r
75         ;\r
76 }\r
77 \r
78 void ComM_DCM_InactivateDiagnostic() {\r
79         ;\r
80 }\r
81 \r
82 void _DsdDslDataIndication(const PduInfoType *pduRxData,\r
83                 const Dcm_DsdServiceTableType *protocolSIDTable,\r
84                 Dcm_ProtocolAddrTypeType addrType,\r
85                 PduIdType rxPduIdRef,\r
86                 PduInfoType *pduTxData) {\r
87         DEBUG( DEBUG_MEDIUM, "_DsdDslDataIndication called!\n");\r
88 \r
89         DEBUG( DEBUG_MEDIUM, "pduRxData->SduLength = %d\n", pduRxData->SduLength );\r
90         for (int i=0; i < pduRxData->SduLength; i++) {\r
91                 DEBUG( DEBUG_MEDIUM, "Data[%d] = %02x\n", i, pduRxData->SduDataPtr[i] );\r
92         }\r
93 \r
94         uint8 *p;\r
95 \r
96         pduTxData->SduLength = 5;\r
97         p = pduTxData->SduDataPtr;\r
98 \r
99 \r
100         for (int i=0; i<pduTxData->SduLength; i++) {\r
101                 *p = i;\r
102                 p++;\r
103         }\r
104 \r
105         // Simulate a diagnostic response.\r
106         DslDsdProcessingDone(rxPduIdRef, DSD_TX_RESPONSE_READY);\r
107 \r
108 }\r
109 \r
110 // ################# HELPER FUNCTIONS START #################\r
111 \r
112 //\r
113 // This function reset/stars the session (S3) timer. See requirement\r
114 // @DCM141 when that action should be taken.\r
115 //\r
116 void startS3SessionTimer(Dcm_DslRunTimeProtocolParametersType *runtime,\r
117                 const Dcm_DslProtocolRowType *protocolRow ) {\r
118         const Dcm_DslProtocolTimingRowType *timeParams;\r
119         timeParams = protocolRow->DslProtocolTimeLimit;\r
120         runtime->S3ServerTimeoutCount =\r
121                         DCM_CONVERT_MS_TO_MAIN_CYCLES(timeParams->TimStrS3Server);\r
122 }\r
123 \r
124 // - - - - - - - - - - -\r
125 \r
126 //\r
127 // This function reset/stars the session (S3) timer. See requirement\r
128 // @DCM141 when that action should be taken.\r
129 //\r
130 void stopS3SessionTimer(Dcm_DslRunTimeProtocolParametersType *runtime) {\r
131         runtime->S3ServerTimeoutCount = 0;\r
132 }\r
133 \r
134 // - - - - - - - - - - -\r
135 \r
136 //\r
137 //      This function implements the requirement @DCM139 when\r
138 //      transition from one session to another.\r
139 //      qqq, strange observation: If S3 timeout we will not change security mode to\r
140 //      locked and that is how I interper the requirement.\r
141 //\r
142 void changeDiagnosticSession( Dcm_DslRunTimeProtocolParametersType *runtime,\r
143                 Dcm_SesCtrlType newSession) {\r
144         switch (runtime->sessionControl) {\r
145         case DCM_DEFAULT_SESSION: // "default".\r
146                 if ( newSession != DCM_DEFAULT_SESSION ) { // "default"\r
147                         runtime->securityLevel = DCM_SEC_LEV_LOCKED; // "0x00".\r
148                         runtime->sessionControl = newSession;\r
149                         runtime->protocolStarted = FALSE;\r
150                         DcmDslRunTimeData.activeProtocol = NULL;\r
151                 }\r
152                 break;\r
153         case DCM_PROGRAMMING_SESSION:\r
154         case DCM_EXTENDED_DIAGNOSTIC_SESSION:\r
155         case DCM_SAFTEY_SYSTEM_DIAGNOSTIC_SESSION:\r
156         case DCM_ALL_SESSION_LEVEL:\r
157                 runtime->securityLevel = DCM_SEC_LEV_LOCKED; // "0x00".\r
158                 runtime->sessionControl = newSession;\r
159                 break;\r
160         default:\r
161                 // qqq: Log this error.\r
162                 break;\r
163         }\r
164 }\r
165 \r
166 \r
167 // - - - - - - - - - - -\r
168 \r
169 void DslResetSessionTimeoutTimer() {\r
170         const Dcm_DslProtocolRowType *activeProtocol = NULL;\r
171         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
172         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
173         runtime = activeProtocol->DslRunTimeProtocolParameters;\r
174         startS3SessionTimer(runtime, activeProtocol); // @DCM141\r
175 }\r
176 \r
177 // - - - - - - - - - - -\r
178 \r
179 void DslGetCurrentServiceTable(const Dcm_DsdServiceTableType **currentServiceTable) {\r
180         const Dcm_DslProtocolRowType *activeProtocol = NULL;\r
181         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
182         if (activeProtocol != NULL) {\r
183                 *currentServiceTable = activeProtocol->DslProtocolSIDTable;\r
184         }\r
185 }\r
186 \r
187 // - - - - - - - - - - -\r
188 \r
189 Std_ReturnType DslGetActiveProtocol(Dcm_ProtocolType *protocolId) {\r
190         Std_ReturnType ret = E_NOT_OK;\r
191         const Dcm_DslProtocolRowType *activeProtocol = NULL;\r
192         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
193         if (activeProtocol != NULL) {\r
194                 *protocolId = activeProtocol->DslProtocolID;\r
195                 ret = E_OK;\r
196         }\r
197         return ret;\r
198 }\r
199 \r
200 // - - - - - - - - - - -\r
201 \r
202 void DslSetSecurityLevel(Dcm_SecLevelType secLevel) {\r
203         const Dcm_DslProtocolRowType *activeProtocol = NULL;\r
204         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
205         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
206         runtime = activeProtocol->DslRunTimeProtocolParameters;\r
207         runtime->securityLevel = secLevel;\r
208 }\r
209 \r
210 // - - - - - - - - - - -\r
211 \r
212 Std_ReturnType DslGetSecurityLevel(Dcm_SecLevelType *secLevel) {\r
213         Std_ReturnType ret = E_NOT_OK;\r
214         const Dcm_DslProtocolRowType *activeProtocol = NULL;\r
215         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
216         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
217         if (activeProtocol != NULL) {\r
218                 runtime = activeProtocol->DslRunTimeProtocolParameters;\r
219                 *secLevel = runtime->securityLevel;\r
220                 ret = E_OK;\r
221         }\r
222         return ret;\r
223 }\r
224 \r
225 // - - - - - - - - - - -\r
226 \r
227 void DslSetSesCtrlType(Dcm_SesCtrlType sesCtrl) {\r
228         const Dcm_DslProtocolRowType *activeProtocol = NULL;\r
229         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
230         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
231         if (activeProtocol != NULL) {\r
232                 runtime = activeProtocol->DslRunTimeProtocolParameters;\r
233                 if (runtime->sessionControl != sesCtrl) {\r
234                         changeDiagnosticSession(runtime, sesCtrl);\r
235                         DslResetSessionTimeoutTimer();\r
236                 }\r
237         }\r
238 }\r
239 \r
240 // - - - - - - - - - - -\r
241 \r
242 Std_ReturnType DslGetSesCtrlType(Dcm_SesCtrlType *sesCtrlType) {\r
243         Std_ReturnType ret = E_NOT_OK;\r
244         const Dcm_DslProtocolRowType *activeProtocol = NULL;\r
245         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
246         activeProtocol = DcmDslRunTimeData.activeProtocol;\r
247         if (activeProtocol != NULL) {\r
248                 runtime = activeProtocol->DslRunTimeProtocolParameters;\r
249                 *sesCtrlType = runtime->sessionControl;\r
250                 ret = E_OK;\r
251         }\r
252         return ret;\r
253 }\r
254 \r
255 // - - - - - - - - - - -\r
256 \r
257 boolean findParentConfigurationLeafs(PduIdType dcmRxPduId,\r
258                 const Dcm_DslProtocolRxType **protocolRx,\r
259                 const Dcm_DslMainConnectionType **mainConnection,\r
260                 const Dcm_DslConnectionType **connection,\r
261                 const Dcm_DslProtocolRowType **protocolRow,\r
262                 Dcm_DslRunTimeProtocolParametersType **runtime) {\r
263 \r
264         boolean ret = FALSE;\r
265         if (dcmRxPduId < DCM_DSL_BUFFER_LIST_LENGTH) {\r
266                 *protocolRx\r
267                                 = &DCM_Config.Dsl->DslProtocol->DslProtocolRxGlobalList[dcmRxPduId];\r
268                 *mainConnection = (*protocolRx)->DslMainConnectionParent;\r
269                 *connection = (*mainConnection)->DslConnectionParent;\r
270                 *protocolRow = (*connection)->DslProtocolRow;\r
271                 *runtime = (*protocolRow)->DslRunTimeProtocolParameters;\r
272                 ret = TRUE;\r
273         }\r
274         return ret;\r
275 }\r
276 \r
277 // - - - - - - - - - - -\r
278 \r
279 void releaseExternalRxTxBuffers( const Dcm_DslProtocolRowType *protocolRow,\r
280                 Dcm_DslRunTimeProtocolParametersType *runtime ) {\r
281 \r
282         protocolRow->DslProtocolTxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;\r
283         protocolRow->DslProtocolRxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;\r
284         runtime->externalTxBufferStatus = NOT_IN_USE; // We are waiting for DSD to return the buffer. qqq.\r
285         runtime->externalRxBufferStatus = NOT_IN_USE; // We are waiting for DSD to return the buffer. qqq.\r
286 }\r
287 \r
288 // - - - - - - - - - - -\r
289 \r
290 \r
291 void releaseExternalRxTxBuffersHelper( PduIdType rxPduIdRef ) {\r
292         const Dcm_DslProtocolRxType *protocolRx = NULL;\r
293         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
294         const Dcm_DslConnectionType *connection = NULL;\r
295         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
296         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
297 \r
298         if (findParentConfigurationLeafs(rxPduIdRef, &protocolRx, &mainConnection,\r
299                         &connection, &protocolRow, &runtime)) {\r
300                 releaseExternalRxTxBuffers( protocolRow, runtime );\r
301         }\r
302 }\r
303 \r
304 \r
305 /*\r
306  *  This function is called from the DSD module to the DSL when\r
307  *  a response to a diagnostic request has been copied into the\r
308  *  given TX-buffer and is ready for transmission.\r
309  */\r
310 void DslDsdProcessingDone(PduIdType rxPduIdRef, DsdProcessingDoneResultType responseResult) {\r
311         const Dcm_DslProtocolRxType *protocolRx = NULL;\r
312         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
313         const Dcm_DslConnectionType *connection = NULL;\r
314         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
315         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
316 \r
317         DEBUG( DEBUG_MEDIUM, "DslDsdProcessingDone!\n");\r
318         if (findParentConfigurationLeafs(rxPduIdRef, &protocolRx, &mainConnection,\r
319                         &connection, &protocolRow, &runtime)) {\r
320                 imask_t state = McuE_EnterCriticalSection();\r
321                 switch ( responseResult ) {\r
322                 case DSD_TX_RESPONSE_READY:\r
323                         runtime->externalTxBufferStatus = DSD_PENDING_RESPONSE_SIGNALED;\r
324                         break;\r
325                 case DSD_TX_RESPONSE_SUPPRESSED:\r
326                         releaseExternalRxTxBuffersHelper( rxPduIdRef );\r
327                         break;\r
328                 default:\r
329                         DEBUG( DEBUG_MEDIUM, "Unknown response result from DslDsdProcessingDone!\n");\r
330                         break;\r
331                 }\r
332                 McuE_ExitCriticalSection(state);\r
333         }\r
334 }\r
335 \r
336 /*\r
337  *      This function preparing transmission of response\r
338  *      pending message to tester.\r
339  */\r
340 void sendResponse(const Dcm_DslProtocolRowType *protocol, Dcm_NegativeResponseCodeType responseCode) {\r
341         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
342         const uint32 txPduId =\r
343                         protocol->DslConnection->DslMainConnection->DslProtocolTx->PduR_DcmDslTxPduId;\r
344         runtime = protocol->DslRunTimeProtocolParameters;\r
345         imask_t state = McuE_EnterCriticalSection();\r
346         if (runtime->localTxBuffer.status == NOT_IN_USE) {\r
347                 runtime->localTxBuffer.status = PROVIDED_TO_DSD; // For readability (yes, it will later be overwritten).\r
348                 runtime->localTxBuffer.buffer[0] = SID_NEGATIVE_RESPONSE;\r
349                 runtime->localTxBuffer.buffer[1]\r
350                                 = protocol->DslProtocolRxBufferID->pduInfo.SduDataPtr[2];\r
351                 runtime->localTxBuffer.buffer[2] = responseCode; // 0x78.\r
352                 runtime->localTxBuffer.PduInfo.SduDataPtr\r
353                                 = 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 intressted in sending.\r
356                 PduR_DcmTransmit(txPduId, &(runtime->localTxBuffer.PduInfo));\r
357         }\r
358         McuE_ExitCriticalSection(state);\r
359 }\r
360 \r
361 // - - - - - - - - - - -\r
362 \r
363 Std_ReturnType StartProtocolHelper(Dcm_ProtocolType protocolId) {\r
364         Std_ReturnType ret = E_NOT_OK;\r
365         uint16 i;\r
366 \r
367         for (i = 0; !DCM_Config.Dsl->DslCallbackDCMRequestService[i].Arc_EOL; i++) {\r
368                 if (DCM_Config.Dsl->DslCallbackDCMRequestService[i].StartProtocol\r
369                                 != NULL) {\r
370                         ret = DCM_Config.Dsl->DslCallbackDCMRequestService[i].\r
371                                         StartProtocol(protocolId);\r
372                         if (ret != E_OK) { // qqq: eqvivalent to DCM_E_OK?\r
373                                 break;\r
374                         }\r
375                 }\r
376         }\r
377         return ret;\r
378 }\r
379 \r
380 // - - - - - - - - - - -\r
381 \r
382 boolean isTesterPresentCommand(const PduInfoType *rxPdu) {\r
383         boolean ret = FALSE;\r
384         if ((rxPdu->SduDataPtr[0] == SID_TESTER_PRESENT) && (rxPdu->SduDataPtr[1]\r
385                         & SUPPRESS_POS_RESP_BIT)) {\r
386                 return TRUE;\r
387         }\r
388         return ret;\r
389 }\r
390 \r
391 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
392 //      Implements 'void Dcm_Init(void)' for DSL.\r
393 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
394 void DslInit(void) {\r
395         const Dcm_DslProtocolRowType *listEntry = NULL;\r
396         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
397 \r
398         listEntry = DCM_Config.Dsl->DslProtocol->DslProtocolRowList;\r
399         while (listEntry->Arc_EOL == FALSE) {\r
400                 runtime = listEntry->DslRunTimeProtocolParameters;\r
401                 runtime->externalRxBufferStatus = IDLE;\r
402                 runtime->externalTxBufferStatus = IDLE;\r
403                 runtime->localRxBuffer.status = IDLE;\r
404                 runtime->localTxBuffer.status = IDLE;\r
405                 runtime->securityLevel = DCM_SEC_LEV_LOCKED;\r
406                 runtime->sessionControl = DCM_DEFAULT_SESSION;\r
407                 listEntry->DslProtocolRxBufferID->externalBufferRuntimeData->status\r
408                                 = BUFFER_AVAILABLE;\r
409                 listEntry->DslProtocolRxBufferID->externalBufferRuntimeData->status\r
410                                 = BUFFER_AVAILABLE;\r
411                 listEntry++;\r
412         };\r
413         DcmDslRunTimeData.initRun = TRUE;\r
414 }\r
415 \r
416 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
417 //      Implements 'void Dcm_MainFunction(void)' for DSL.\r
418 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
419 \r
420 void DslMain(void) {\r
421         const Dcm_DslProtocolRowType *protocolRowEntry = NULL;\r
422         const Dcm_DslProtocolTimingRowType *timeParams = NULL;\r
423         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
424 \r
425         protocolRowEntry = DCM_Config.Dsl->DslProtocol->DslProtocolRowList;\r
426         while (protocolRowEntry->Arc_EOL == FALSE) {\r
427                 runtime = protocolRowEntry->DslRunTimeProtocolParameters;\r
428                 if ( runtime != NULL ) {\r
429                         if (runtime->sessionControl != DCM_DEFAULT_SESSION) { // Timeout if tester present is lost.\r
430                                 TIMER_DECREMENT(runtime->S3ServerTimeoutCount);\r
431                                 if ( runtime->S3ServerTimeoutCount == 0 ) {\r
432                                         changeDiagnosticSession( runtime, DCM_DEFAULT_SESSION );\r
433                                 }\r
434                         }\r
435                         switch (runtime->externalTxBufferStatus) { // #### TX buffer state. ####\r
436                         case NOT_IN_USE:\r
437                                 //DEBUG( DEBUG_MEDIUM, "state NOT_IN_USE!\n");\r
438                                 break;\r
439                         case PROVIDED_TO_DSD:\r
440                         {\r
441                                 TIMER_DECREMENT(runtime->stateTimeoutCount);\r
442                                 DEBUG( DEBUG_MEDIUM, "state PROVIDED_TO_DSD!\n");\r
443                                 if (runtime->stateTimeoutCount == 0) {\r
444                                         timeParams = protocolRowEntry->DslProtocolTimeLimit;\r
445                                         runtime->stateTimeoutCount =\r
446                                                         DCM_CONVERT_MS_TO_MAIN_CYCLES(timeParams->TimStrP2ServerMax); /* Reinitiate timer, see 9.2.2. */\r
447                                         if ( DCM_Config.Dsl->DslDiagResp->DslDiagRespForceRespPendEn == TRUE ) {\r
448                                                 if ( runtime->responsePendingCount != 0 ) {\r
449                                                         DEBUG( DEBUG_MEDIUM, "No response withing timeout, sending response pending!\n");\r
450                                                         sendResponse(protocolRowEntry, DCM_E_RESPONSEPENDING);\r
451                                                         COUNT_DECREMENT( runtime->responsePendingCount );\r
452                                                 } else {\r
453                                                         DEBUG( DEBUG_MEDIUM, "Sent all response pending, now sending general reject!\n");\r
454                                                         sendResponse(protocolRowEntry, DCM_E_GENERALREJECT);\r
455                                                         releaseExternalRxTxBuffers(protocolRowEntry, runtime);\r
456                                                 }\r
457                                         } else {\r
458                                                 DEBUG( DEBUG_MEDIUM, "Not configured to send response pending, now sending general reject!\n");\r
459                                                 sendResponse(protocolRowEntry, DCM_E_GENERALREJECT);\r
460                                                 releaseExternalRxTxBuffers(protocolRowEntry, runtime);\r
461                                         }\r
462                                 }\r
463                                 break;\r
464                         }\r
465                         case DSD_PENDING_RESPONSE_SIGNALED: // The DSD has signaled to DSL that the diagnostic response is available in the Tx buffer.\r
466                                 // Make sure that response pending or general reject have not been issued,\r
467                                 // if so we can not transmit to PduR because we would not know from where\r
468                                 // the Tx confirmation resides later.\r
469                                 DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n");\r
470                                 if (runtime->localTxBuffer.status == NOT_IN_USE) {\r
471                                         const uint32 txPduId =\r
472                                                         protocolRowEntry->DslConnection->DslMainConnection->DslProtocolTx->PduR_DcmDslTxPduId;\r
473                                         runtime->externalTxBufferStatus = DCM_TRANSMIT_SIGNALED;\r
474                                         PduR_DcmTransmit(txPduId, &runtime->diagnosticResponseFromDsd); /** @req DCM237 **//* Will trigger PduR (CanTP) to call DslProvideTxBuffer(). */\r
475                                 }\r
476                                 break;\r
477                         case DCM_TRANSMIT_SIGNALED:\r
478                                 DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n");\r
479                                 break;\r
480                         case PROVIDED_TO_PDUR: // The valid data is being transmitted by TP-layer.\r
481                                 DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n");\r
482                                 break;\r
483                         default:\r
484                                 break;\r
485                         }\r
486                 }\r
487                 protocolRowEntry++;\r
488         }\r
489 }\r
490 \r
491 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
492 //      Implements 'BufReq_ReturnType Dcm_ProvideRxBuffer(PduIdType dcmRxPduId,\r
493 //  PduLengthType tpSduLength, PduInfoType **pduInfoPtr)'.\r
494 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
495 //  This function is called called by the PduR typically when CanTp has\r
496 //  received a FF or a single frame and needs to obtain a buffer from the\r
497 //  receiver so that received data can be forwarded.\r
498 \r
499 BufReq_ReturnType DslProvideRxBufferToPdur(PduIdType dcmRxPduId,\r
500                 PduLengthType tpSduLength, const PduInfoType **pduInfoPtr) {\r
501         BufReq_ReturnType ret = BUFREQ_NOT_OK;\r
502         const Dcm_DslProtocolRxType *protocolRx = NULL;\r
503         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
504         const Dcm_DslConnectionType *connection = NULL;\r
505         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
506         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
507 \r
508   DEBUG( DEBUG_MEDIUM, "DslProvideRxBufferToPdur called!\n");\r
509         imask_t state = McuE_EnterCriticalSection();\r
510         if (findParentConfigurationLeafs(dcmRxPduId, &protocolRx, &mainConnection,\r
511                         &connection, &protocolRow, &runtime)) {\r
512                 const Dcm_DslBufferType *externalRxBuffer =\r
513                                 protocolRow->DslProtocolRxBufferID;\r
514                 if (externalRxBuffer->pduInfo.SduLength >= tpSduLength) { // First validate that we have a chance receiving the chunk of data.\r
515                         if ((runtime->externalRxBufferStatus == NOT_IN_USE)\r
516                                         && (externalRxBuffer->externalBufferRuntimeData->status\r
517                                                         == BUFFER_AVAILABLE)) {\r
518         DEBUG( DEBUG_MEDIUM, "External buffer available!\n");\r
519                                 // ### EXTERNAL BUFFER IS AVAILABLE; GRAB IT AND REMEBER THAT WE OWN IT! ###\r
520                                 externalRxBuffer->externalBufferRuntimeData->status\r
521                                                 = BUFFER_BUSY;\r
522                                 runtime->diagnosticRequestFromTester.SduDataPtr = externalRxBuffer->pduInfo.SduDataPtr;\r
523                                 runtime->diagnosticRequestFromTester.SduLength = tpSduLength;\r
524                                 //*pduInfoPtr = &(externalRxBuffer->pduInfo);\r
525                                 *pduInfoPtr = &(runtime->diagnosticRequestFromTester);\r
526                                 runtime->externalRxBufferStatus = PROVIDED_TO_PDUR;\r
527                                 ret = BUFREQ_OK;\r
528                         } else {\r
529         DEBUG( DEBUG_MEDIUM, "Local buffer available!\n");\r
530                                 if (runtime->externalRxBufferStatus == PROVIDED_TO_DSD) {\r
531                                         // ### EXTERNAL BUFFER IS IN USE BY THE DSD, TRY TO USE LOCAL BUFFER! ###\r
532                                         if (runtime->localRxBuffer.status == NOT_IN_USE) {\r
533                                                 if (tpSduLength < LOCAL_BUFFER_LENGTH) {\r
534                                                         runtime->localRxBuffer.status = PROVIDED_TO_PDUR;\r
535                                                         runtime->localRxBuffer.PduInfo.SduDataPtr\r
536                                                                         = runtime->localRxBuffer.buffer;\r
537                                                         runtime->localRxBuffer.PduInfo.SduLength\r
538                                                                         = tpSduLength;\r
539                                                         *pduInfoPtr = &(runtime->localRxBuffer.PduInfo);\r
540                                                         ret = BUFREQ_OK;\r
541                                                 }\r
542                                         }\r
543                                 } else {\r
544                                         // The buffer is in use by the PduR, we can not help this because then\r
545                                         // we would have two different Rx-indications with same PduId but we\r
546                                         // will not know which buffer the indication should free.\r
547                                         ret = BUFREQ_BUSY;\r
548                                 }\r
549                         }\r
550                 } else {\r
551                         ret = BUFREQ_OVFL; // Required size is too big.\r
552                 }\r
553                 if ( ret == BUFREQ_OK ) {\r
554                         stopS3SessionTimer( runtime );  /** req: DCM141 **/\r
555                 }\r
556         }\r
557         McuE_ExitCriticalSection(state);\r
558         return ret;\r
559 }\r
560 \r
561 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
562 //      Implements 'void Dcm_RxIndication(PduIdType dcmRxPduId, NotifResultType result)'.\r
563 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
564 //      This function is called called by the PduR typically when CanTp has\r
565 //      received the diagnostic request, copied it to the provided buffer and need to indicate\r
566 //      this to the DCM (DSL) module via propritary API.\r
567 \r
568 void DslRxIndicationFromPduR(PduIdType dcmRxPduId, NotifResultType result) {\r
569         const Dcm_DslProtocolRxType *protocolRx = NULL;\r
570         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
571         const Dcm_DslConnectionType *connection = NULL;\r
572         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
573         const Dcm_DslProtocolTimingRowType *timeParams = NULL;\r
574         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
575         Std_ReturnType higherLayerResp;\r
576         imask_t state;\r
577         \r
578         // qqq: handle the actual result code.\r
579         if (findParentConfigurationLeafs(dcmRxPduId, &protocolRx, &mainConnection,\r
580                         &connection, &protocolRow, &runtime)) {\r
581                 timeParams = protocolRow->DslProtocolTimeLimit;\r
582                 // We need to find out in what buffer we can find our Rx data (it can\r
583                 // be either in the normal RX-buffer or the 'extra' buffer for implementing\r
584                 // the Concurrent "Test Present" functionality.\r
585                 if (runtime->externalRxBufferStatus == PROVIDED_TO_PDUR) {\r
586                         if (isTesterPresentCommand(\r
587                                         &(protocolRow->DslProtocolRxBufferID->pduInfo))) {\r
588                                 state = McuE_EnterCriticalSection();\r
589                                 startS3SessionTimer( runtime, protocolRow ); /** @req DCM141 **/ /** @req DCM112 **//** @req DCM113 **/\r
590                                 runtime->externalRxBufferStatus = NOT_IN_USE;\r
591                                 McuE_ExitCriticalSection(state);\r
592                         } else {\r
593                                 if (runtime->protocolStarted == FALSE) {\r
594                                         higherLayerResp = StartProtocolHelper(\r
595                                                         protocolRow->DslProtocolID);\r
596                                         if (higherLayerResp == E_OK) {\r
597                                                 runtime->protocolStarted = TRUE;\r
598                                                 DcmDslRunTimeData.activeProtocol = protocolRow;\r
599                                         }\r
600                                 }\r
601                                 if (runtime->protocolStarted == TRUE) {\r
602                                         if (runtime->diagnosticActiveComM == FALSE) {\r
603                                                 ComM_DCM_ActivateDiagnostic(); /* @DCM163 */\r
604                                                 runtime->diagnosticActiveComM = TRUE;\r
605                                         }\r
606                                         state = McuE_EnterCriticalSection();\r
607                                         runtime->stateTimeoutCount =\r
608                                                         DCM_CONVERT_MS_TO_MAIN_CYCLES(timeParams->TimStrP2ServerMax); /* See 9.2.2. */\r
609                                         runtime->externalRxBufferStatus = PROVIDED_TO_DSD;\r
610                                         runtime->externalTxBufferStatus = PROVIDED_TO_DSD; // Used in main.\r
611                                         timeParams = protocolRow->DslProtocolTimeLimit;\r
612                                         runtime->stateTimeoutCount =\r
613                                                         DCM_CONVERT_MS_TO_MAIN_CYCLES(timeParams->TimStrP2ServerMax); /* Reinitiate timer, see 9.2.2. */          \r
614                                         McuE_ExitCriticalSection(state);\r
615                                         runtime->diagnosticResponseFromDsd.SduDataPtr = protocolRow->DslProtocolTxBufferID->pduInfo.SduDataPtr;\r
616                                         runtime->diagnosticResponseFromDsd.SduLength = protocolRow->DslProtocolTxBufferID->pduInfo.SduLength;\r
617                                         _DsdDslDataIndication(\r
618                                                         //&protocolRow->DslProtocolRxBufferID->pduInfo,\r
619                                                         &(runtime->diagnosticRequestFromTester),\r
620                                                         protocolRow->DslProtocolSIDTable,\r
621                                                         protocolRx->DslProtocolAddrType,\r
622                                                         mainConnection->DslProtocolTx->PduR_DcmDslTxPduId,\r
623                                                         //&protocolRow->DslProtocolTxBufferID->pduInfo);\r
624                                                         &(runtime->diagnosticResponseFromDsd));\r
625                                     \r
626                                 }\r
627                         }\r
628                 } else {\r
629                         // It is the local buffer that was provided to the PduR, that buffer\r
630                         // is only used for tester present reception in parallel to diagnostic\r
631                         // requests.\r
632                         state = McuE_EnterCriticalSection();\r
633                         if (runtime->localRxBuffer.status == PROVIDED_TO_PDUR) {\r
634                                 if (isTesterPresentCommand(&(runtime->localRxBuffer.PduInfo))) {\r
635                                         startS3SessionTimer( runtime, protocolRow ); /** @req DCM141 **/ /** @req DCM112 **//** @req DCM113 **/\r
636                                 }\r
637                                 runtime->localRxBuffer.status = NOT_IN_USE;\r
638                         }\r
639                         McuE_ExitCriticalSection(state);\r
640                 }\r
641         }\r
642 }\r
643 \r
644 \r
645 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
646 //      Implements 'BufReq_ReturnType Dcm_ProvideTxBuffer(PduIdType dcmTxPduId,\r
647 //  PduInfoType **pduInfoPtr, PduLengthType length)'.\r
648 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
649 //  This TX-buffer request is likely triggered by the transport layer (i.e. CanTp)\r
650 //  after PduR_DcmTransmit() has been called (via PduR to CanTp) indicating that something\r
651 //  is to be sent. The PduR_DcmTransmit() call is done from the DSL main function when\r
652 //  it has detected that the pending request has been answered by DSD\r
653 //  (or any other module?).\r
654 \r
655 BufReq_ReturnType DslProvideTxBuffer(PduIdType dcmTxPduId,\r
656                 const PduInfoType **pduInfoPtr, PduLengthType length) {\r
657         BufReq_ReturnType ret = BUFREQ_NOT_OK;\r
658         const Dcm_DslProtocolRxType *protocolRx = NULL;\r
659         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
660         const Dcm_DslConnectionType *connection = NULL;\r
661         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
662         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
663 \r
664         if (findParentConfigurationLeafs(dcmTxPduId, &protocolRx, &mainConnection,\r
665                         &connection, &protocolRow, &runtime)) {\r
666                 switch (runtime->externalTxBufferStatus) { // ### EXTERNAL TX BUFFER ###\r
667                 case DCM_TRANSMIT_SIGNALED: {\r
668                         *pduInfoPtr = &(protocolRow->DslProtocolTxBufferID->pduInfo);\r
669                         runtime->externalTxBufferStatus = PROVIDED_TO_PDUR;\r
670                         ret = BUFREQ_OK;\r
671                         break;\r
672                 }\r
673                 default:\r
674                         ret = BUFREQ_NOT_OK;\r
675                         break;\r
676                 }\r
677                 if (ret == BUFREQ_NOT_OK) {\r
678                         switch (runtime->localTxBuffer.status) { // ### LOCAL TX BUFFER ###\r
679                         case DCM_TRANSMIT_SIGNALED: {\r
680                                 runtime->localTxBuffer.PduInfo.SduDataPtr\r
681                                                 = runtime->localTxBuffer.buffer;\r
682                                 runtime->localTxBuffer.PduInfo.SduLength\r
683                                                 = runtime->localTxBuffer.messageLenght;\r
684                                 *pduInfoPtr = &runtime->localTxBuffer.PduInfo;\r
685                                 runtime->localTxBuffer.status = PROVIDED_TO_PDUR; // Now the DSL should not touch this Tx-buffer anymore.\r
686                                 ret = BUFREQ_OK;\r
687         break;\r
688                         }\r
689                         default:\r
690                                 ret = BUFREQ_NOT_OK;\r
691                                 break;\r
692                         }\r
693                 }\r
694         }\r
695         return ret;\r
696 }\r
697 \r
698 \r
699 \r
700 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
701 //      Implements 'void Dcm_TxConfirmation(PduIdType dcmTxPduId, NotifResultType result))'.\r
702 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\r
703 //      This function is called by the PduR (which has been trigged by i.e. CanTp)\r
704 //      when a transmission has been successfully finished, have had errors or\r
705 //      is even stopped.\r
706 \r
707 void DslTxConfirmation(PduIdType dcmTxPduId, NotifResultType result) {\r
708         const Dcm_DslProtocolRxType *protocolRx = NULL;\r
709         const Dcm_DslMainConnectionType *mainConnection = NULL;\r
710         const Dcm_DslConnectionType *connection = NULL;\r
711         const Dcm_DslProtocolRowType *protocolRow = NULL;\r
712         Dcm_DslRunTimeProtocolParametersType *runtime = NULL;\r
713         imask_t state;\r
714 \r
715         DEBUG( DEBUG_MEDIUM, "DslTxConfirmation called!\n");\r
716         if (findParentConfigurationLeafs(dcmTxPduId, &protocolRx, &mainConnection,\r
717                         &connection, &protocolRow, &runtime)) {\r
718                 boolean externalBufferReleased = FALSE;\r
719 \r
720                 // Free the buffer and free the Pdu runtime data buffer.\r
721                 state = McuE_EnterCriticalSection();\r
722                 switch (runtime->externalTxBufferStatus) { // ### EXTERNAL TX BUFFER ###\r
723                 case PROVIDED_TO_PDUR: {\r
724                         ComM_DCM_InactivateDiagnostic();\r
725                         startS3SessionTimer(runtime, protocolRow); // @DCM141\r
726                         releaseExternalRxTxBuffers(protocolRow, runtime);\r
727  /*\r
728                         protocolRow->DslProtocolTxBufferID->externalBufferRuntimeData->status\r
729                                         = BUFFER_AVAILABLE;\r
730                         protocolRow->DslProtocolRxBufferID->externalBufferRuntimeData->status\r
731                                         = BUFFER_AVAILABLE;          \r
732                         runtime->externalTxBufferStatus = IDLE;\r
733                         runtime->externalRxBufferStatus = IDLE;\r
734 */\r
735                         DEBUG( DEBUG_MEDIUM, "Released external buffer sucessfully!\n");\r
736                         externalBufferReleased = TRUE;\r
737                         DsdDataConfirmation(dcmTxPduId, result); /** @req DCM117 **//** @req DCM235 **/\r
738                         break;\r
739                 }\r
740                 default:\r
741                         break;\r
742                 }\r
743                 if ( externalBufferReleased == FALSE ) {\r
744                         switch (runtime->localTxBuffer.status) { // ### LOCAL TX BUFFER ###\r
745                         case PROVIDED_TO_PDUR:\r
746                                 DEBUG( DEBUG_MEDIUM, "Released local buffer buffer!\n");\r
747                                 runtime->localTxBuffer.status = IDLE;\r
748                                 break;\r
749                         default:\r
750                                 DEBUG( DEBUG_MEDIUM, "WARNING! DslTxConfirmation could not release any buffer!\n");\r
751                                 break;\r
752                         }\r
753                 }\r
754                 McuE_ExitCriticalSection(state);\r
755         }\r
756 }\r
757 \r