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