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