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