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