1 /* -------------------------------- Arctic Core ------------------------------
\r
2 * Arctic Core - the open source AUTOSAR platform http://arccore.com
\r
4 * Copyright (C) 2009 ArcCore AB <contact@arccore.com>
\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
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
14 * -------------------------------- Arctic Core ------------------------------*/
\r
18 #include "Dcm_Cfg.h"
\r
19 #include "Dcm_Cbk.h"
\r
21 #include "Dcm_Internal.h"
\r
24 #include "ComM_Dcm.h"
\r
25 #include "PduR_Dcm.h"
\r
26 #include "ComStack_Types.h"
\r
28 #define TIMER_DECREMENT(timer) \
\r
30 timer = timer - 1; \
\r
33 #define COUNT_DECREMENT(timer) \
\r
35 timer = timer - 1; \
\r
42 const Dcm_DslProtocolRxType *protocolRx;
\r
43 const Dcm_DslMainConnectionType *mainConnection;
\r
44 const Dcm_DslConnectionType *connection;
\r
45 const Dcm_DslProtocolRowType *protocolRow;
\r
46 } DcmDsl_ProtocolConfigurationType;
\r
48 #define MAX_PARALLEL_PROTOCOLS_ALLOWED 1
\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
58 DcmDsl_RunTimeDataType DcmDslRunTimeData = {
\r
60 .preemptedProtocol = NULL,
\r
61 .activeProtocol = NULL
\r
65 // ################# DUMMIES START #################
\r
71 // Global service table, set by DSL used by DSD
\r
72 Dcm_DsdServiceTableType *DslCurrentServiceTable = NULL;
\r
74 void ComM_DCM_ActivateDiagnostic() {
\r
78 void ComM_DCM_InactivateDiagnostic() {
\r
82 void _DsdDslDataIndication(const PduInfoType *pduRxData,
\r
83 const Dcm_DsdServiceTableType *protocolSIDTable,
\r
84 Dcm_ProtocolAddrTypeType addrType,
\r
85 PduIdType rxPduIdRef,
\r
86 PduInfoType *pduTxData) {
\r
87 DEBUG( DEBUG_MEDIUM, "_DsdDslDataIndication called!\n");
\r
89 DEBUG( DEBUG_MEDIUM, "pduRxData->SduLength = %d\n", pduRxData->SduLength );
\r
90 for (int i=0; i < pduRxData->SduLength; i++) {
\r
91 DEBUG( DEBUG_MEDIUM, "Data[%d] = %02x\n", i, pduRxData->SduDataPtr[i] );
\r
96 pduTxData->SduLength = 5;
\r
97 p = pduTxData->SduDataPtr;
\r
100 for (int i=0; i<pduTxData->SduLength; i++) {
\r
105 // Simulate a diagnostic response.
\r
106 DslDsdProcessingDone(rxPduIdRef, DSD_TX_RESPONSE_READY);
\r
110 // ################# HELPER FUNCTIONS START #################
\r
113 // This function reset/stars the session (S3) timer. See requirement
\r
114 // @DCM141 when that action should be taken.
\r
116 void startS3SessionTimer(Dcm_DslRunTimeProtocolParametersType *runtime,
\r
117 const Dcm_DslProtocolRowType *protocolRow ) {
\r
118 const Dcm_DslProtocolTimingRowType *timeParams;
\r
119 timeParams = protocolRow->DslProtocolTimeLimit;
\r
120 runtime->S3ServerTimeoutCount =
\r
121 DCM_CONVERT_MS_TO_MAIN_CYCLES(timeParams->TimStrS3Server);
\r
124 // - - - - - - - - - - -
\r
127 // This function reset/stars the session (S3) timer. See requirement
\r
128 // @DCM141 when that action should be taken.
\r
130 void stopS3SessionTimer(Dcm_DslRunTimeProtocolParametersType *runtime) {
\r
131 runtime->S3ServerTimeoutCount = 0;
\r
134 // - - - - - - - - - - -
\r
137 // This function implements the requirement @DCM139 when
\r
138 // transition from one session to another.
\r
139 // qqq, strange observation: If S3 timeout we will not change security mode to
\r
140 // locked and that is how I interper the requirement.
\r
142 void changeDiagnosticSession( Dcm_DslRunTimeProtocolParametersType *runtime,
\r
143 Dcm_SesCtrlType newSession) {
\r
144 switch (runtime->sessionControl) {
\r
145 case DCM_DEFAULT_SESSION: // "default".
\r
146 if ( newSession != DCM_DEFAULT_SESSION ) { // "default"
\r
147 runtime->securityLevel = DCM_SEC_LEV_LOCKED; // "0x00".
\r
148 runtime->sessionControl = newSession;
\r
149 runtime->protocolStarted = FALSE;
\r
150 DcmDslRunTimeData.activeProtocol = NULL;
\r
153 case DCM_PROGRAMMING_SESSION:
\r
154 case DCM_EXTENDED_DIAGNOSTIC_SESSION:
\r
155 case DCM_SAFTEY_SYSTEM_DIAGNOSTIC_SESSION:
\r
156 case DCM_ALL_SESSION_LEVEL:
\r
157 runtime->securityLevel = DCM_SEC_LEV_LOCKED; // "0x00".
\r
158 runtime->sessionControl = newSession;
\r
161 // qqq: Log this error.
\r
167 // - - - - - - - - - - -
\r
169 void DslResetSessionTimeoutTimer() {
\r
170 const Dcm_DslProtocolRowType *activeProtocol = NULL;
\r
171 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
172 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
173 runtime = activeProtocol->DslRunTimeProtocolParameters;
\r
174 startS3SessionTimer(runtime, activeProtocol); // @DCM141
\r
177 // - - - - - - - - - - -
\r
179 void DslGetCurrentServiceTable(const Dcm_DsdServiceTableType **currentServiceTable) {
\r
180 const Dcm_DslProtocolRowType *activeProtocol = NULL;
\r
181 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
182 if (activeProtocol != NULL) {
\r
183 *currentServiceTable = activeProtocol->DslProtocolSIDTable;
\r
187 // - - - - - - - - - - -
\r
189 Std_ReturnType DslGetActiveProtocol(Dcm_ProtocolType *protocolId) {
\r
190 Std_ReturnType ret = E_NOT_OK;
\r
191 const Dcm_DslProtocolRowType *activeProtocol = NULL;
\r
192 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
193 if (activeProtocol != NULL) {
\r
194 *protocolId = activeProtocol->DslProtocolID;
\r
200 // - - - - - - - - - - -
\r
202 void DslSetSecurityLevel(Dcm_SecLevelType secLevel) {
\r
203 const Dcm_DslProtocolRowType *activeProtocol = NULL;
\r
204 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
205 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
206 runtime = activeProtocol->DslRunTimeProtocolParameters;
\r
207 runtime->securityLevel = secLevel;
\r
210 // - - - - - - - - - - -
\r
212 Std_ReturnType DslGetSecurityLevel(Dcm_SecLevelType *secLevel) {
\r
213 Std_ReturnType ret = E_NOT_OK;
\r
214 const Dcm_DslProtocolRowType *activeProtocol = NULL;
\r
215 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
216 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
217 if (activeProtocol != NULL) {
\r
218 runtime = activeProtocol->DslRunTimeProtocolParameters;
\r
219 *secLevel = runtime->securityLevel;
\r
225 // - - - - - - - - - - -
\r
227 void DslSetSesCtrlType(Dcm_SesCtrlType sesCtrl) {
\r
228 const Dcm_DslProtocolRowType *activeProtocol = NULL;
\r
229 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
230 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
231 if (activeProtocol != NULL) {
\r
232 runtime = activeProtocol->DslRunTimeProtocolParameters;
\r
233 if (runtime->sessionControl != sesCtrl) {
\r
234 changeDiagnosticSession(runtime, sesCtrl);
\r
235 DslResetSessionTimeoutTimer();
\r
240 // - - - - - - - - - - -
\r
242 Std_ReturnType DslGetSesCtrlType(Dcm_SesCtrlType *sesCtrlType) {
\r
243 Std_ReturnType ret = E_NOT_OK;
\r
244 const Dcm_DslProtocolRowType *activeProtocol = NULL;
\r
245 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
246 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
247 if (activeProtocol != NULL) {
\r
248 runtime = activeProtocol->DslRunTimeProtocolParameters;
\r
249 *sesCtrlType = runtime->sessionControl;
\r
255 // - - - - - - - - - - -
\r
257 boolean findParentConfigurationLeafs(PduIdType dcmRxPduId,
\r
258 const Dcm_DslProtocolRxType **protocolRx,
\r
259 const Dcm_DslMainConnectionType **mainConnection,
\r
260 const Dcm_DslConnectionType **connection,
\r
261 const Dcm_DslProtocolRowType **protocolRow,
\r
262 Dcm_DslRunTimeProtocolParametersType **runtime) {
\r
264 boolean ret = FALSE;
\r
265 if (dcmRxPduId < DCM_DSL_BUFFER_LIST_LENGTH) {
\r
267 = &DCM_Config.Dsl->DslProtocol->DslProtocolRxGlobalList[dcmRxPduId];
\r
268 *mainConnection = (*protocolRx)->DslMainConnectionParent;
\r
269 *connection = (*mainConnection)->DslConnectionParent;
\r
270 *protocolRow = (*connection)->DslProtocolRow;
\r
271 *runtime = (*protocolRow)->DslRunTimeProtocolParameters;
\r
277 // - - - - - - - - - - -
\r
279 void releaseExternalRxTxBuffers( const Dcm_DslProtocolRowType *protocolRow,
\r
280 Dcm_DslRunTimeProtocolParametersType *runtime ) {
\r
282 protocolRow->DslProtocolTxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;
\r
283 protocolRow->DslProtocolRxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;
\r
284 runtime->externalTxBufferStatus = NOT_IN_USE; // We are waiting for DSD to return the buffer. qqq.
\r
285 runtime->externalRxBufferStatus = NOT_IN_USE; // We are waiting for DSD to return the buffer. qqq.
\r
288 // - - - - - - - - - - -
\r
291 void releaseExternalRxTxBuffersHelper( PduIdType rxPduIdRef ) {
\r
292 const Dcm_DslProtocolRxType *protocolRx = NULL;
\r
293 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
294 const Dcm_DslConnectionType *connection = NULL;
\r
295 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
296 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
298 if (findParentConfigurationLeafs(rxPduIdRef, &protocolRx, &mainConnection,
\r
299 &connection, &protocolRow, &runtime)) {
\r
300 releaseExternalRxTxBuffers( protocolRow, runtime );
\r
306 * This function is called from the DSD module to the DSL when
\r
307 * a response to a diagnostic request has been copied into the
\r
308 * given TX-buffer and is ready for transmission.
\r
310 void DslDsdProcessingDone(PduIdType rxPduIdRef, DsdProcessingDoneResultType responseResult) {
\r
311 const Dcm_DslProtocolRxType *protocolRx = NULL;
\r
312 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
313 const Dcm_DslConnectionType *connection = NULL;
\r
314 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
315 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
317 DEBUG( DEBUG_MEDIUM, "DslDsdProcessingDone!\n");
\r
318 if (findParentConfigurationLeafs(rxPduIdRef, &protocolRx, &mainConnection,
\r
319 &connection, &protocolRow, &runtime)) {
\r
320 imask_t state = McuE_EnterCriticalSection();
\r
321 switch ( responseResult ) {
\r
322 case DSD_TX_RESPONSE_READY:
\r
323 runtime->externalTxBufferStatus = DSD_PENDING_RESPONSE_SIGNALED;
\r
325 case DSD_TX_RESPONSE_SUPPRESSED:
\r
326 releaseExternalRxTxBuffersHelper( rxPduIdRef );
\r
329 DEBUG( DEBUG_MEDIUM, "Unknown response result from DslDsdProcessingDone!\n");
\r
332 McuE_ExitCriticalSection(state);
\r
337 * This function preparing transmission of response
\r
338 * pending message to tester.
\r
340 void sendResponse(const Dcm_DslProtocolRowType *protocol, Dcm_NegativeResponseCodeType responseCode) {
\r
341 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
342 const uint32 txPduId =
\r
343 protocol->DslConnection->DslMainConnection->DslProtocolTx->PduR_DcmDslTxPduId;
\r
344 runtime = protocol->DslRunTimeProtocolParameters;
\r
345 imask_t state = McuE_EnterCriticalSection();
\r
346 if (runtime->localTxBuffer.status == NOT_IN_USE) {
\r
347 runtime->localTxBuffer.status = PROVIDED_TO_DSD; // For readability (yes, it will later be overwritten).
\r
348 runtime->localTxBuffer.buffer[0] = SID_NEGATIVE_RESPONSE;
\r
349 runtime->localTxBuffer.buffer[1]
\r
350 = protocol->DslProtocolRxBufferID->pduInfo.SduDataPtr[2];
\r
351 runtime->localTxBuffer.buffer[2] = responseCode; // 0x78.
\r
352 runtime->localTxBuffer.PduInfo.SduDataPtr
\r
353 = runtime->localTxBuffer.buffer;
\r
354 runtime->localTxBuffer.PduInfo.SduLength = 3;
\r
355 runtime->localTxBuffer.status = DCM_TRANSMIT_SIGNALED; // In the DslProvideTxBuffer 'callback' this state signals it is the local buffer we are intressted in sending.
\r
356 PduR_DcmTransmit(txPduId, &(runtime->localTxBuffer.PduInfo));
\r
358 McuE_ExitCriticalSection(state);
\r
361 // - - - - - - - - - - -
\r
363 Std_ReturnType StartProtocolHelper(Dcm_ProtocolType protocolId) {
\r
364 Std_ReturnType ret = E_NOT_OK;
\r
367 for (i = 0; !DCM_Config.Dsl->DslCallbackDCMRequestService[i].Arc_EOL; i++) {
\r
368 if (DCM_Config.Dsl->DslCallbackDCMRequestService[i].StartProtocol
\r
370 ret = DCM_Config.Dsl->DslCallbackDCMRequestService[i].
\r
371 StartProtocol(protocolId);
\r
372 if (ret != E_OK) { // qqq: eqvivalent to DCM_E_OK?
\r
380 // - - - - - - - - - - -
\r
382 boolean isTesterPresentCommand(const PduInfoType *rxPdu) {
\r
383 boolean ret = FALSE;
\r
384 if ((rxPdu->SduDataPtr[0] == SID_TESTER_PRESENT) && (rxPdu->SduDataPtr[1]
\r
385 & SUPPRESS_POS_RESP_BIT)) {
\r
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
398 listEntry = DCM_Config.Dsl->DslProtocol->DslProtocolRowList;
\r
399 while (listEntry->Arc_EOL == FALSE) {
\r
400 runtime = listEntry->DslRunTimeProtocolParameters;
\r
401 runtime->externalRxBufferStatus = IDLE;
\r
402 runtime->externalTxBufferStatus = IDLE;
\r
403 runtime->localRxBuffer.status = IDLE;
\r
404 runtime->localTxBuffer.status = IDLE;
\r
405 runtime->securityLevel = DCM_SEC_LEV_LOCKED;
\r
406 runtime->sessionControl = DCM_DEFAULT_SESSION;
\r
407 listEntry->DslProtocolRxBufferID->externalBufferRuntimeData->status
\r
408 = BUFFER_AVAILABLE;
\r
409 listEntry->DslProtocolRxBufferID->externalBufferRuntimeData->status
\r
410 = BUFFER_AVAILABLE;
\r
413 DcmDslRunTimeData.initRun = TRUE;
\r
416 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
417 // Implements 'void Dcm_MainFunction(void)' for DSL.
\r
418 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
420 void DslMain(void) {
\r
421 const Dcm_DslProtocolRowType *protocolRowEntry = NULL;
\r
422 const Dcm_DslProtocolTimingRowType *timeParams = NULL;
\r
423 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
425 protocolRowEntry = DCM_Config.Dsl->DslProtocol->DslProtocolRowList;
\r
426 while (protocolRowEntry->Arc_EOL == FALSE) {
\r
427 runtime = protocolRowEntry->DslRunTimeProtocolParameters;
\r
428 if ( runtime != NULL ) {
\r
429 if (runtime->sessionControl != DCM_DEFAULT_SESSION) { // Timeout if tester present is lost.
\r
430 TIMER_DECREMENT(runtime->S3ServerTimeoutCount);
\r
431 if ( runtime->S3ServerTimeoutCount == 0 ) {
\r
432 changeDiagnosticSession( runtime, DCM_DEFAULT_SESSION );
\r
435 switch (runtime->externalTxBufferStatus) { // #### TX buffer state. ####
\r
437 //DEBUG( DEBUG_MEDIUM, "state NOT_IN_USE!\n");
\r
439 case PROVIDED_TO_DSD:
\r
441 TIMER_DECREMENT(runtime->stateTimeoutCount);
\r
442 DEBUG( DEBUG_MEDIUM, "state PROVIDED_TO_DSD!\n");
\r
443 if (runtime->stateTimeoutCount == 0) {
\r
444 timeParams = protocolRowEntry->DslProtocolTimeLimit;
\r
445 runtime->stateTimeoutCount =
\r
446 DCM_CONVERT_MS_TO_MAIN_CYCLES(timeParams->TimStrP2ServerMax); /* Reinitiate timer, see 9.2.2. */
\r
447 if ( DCM_Config.Dsl->DslDiagResp->DslDiagRespForceRespPendEn == TRUE ) {
\r
448 if ( runtime->responsePendingCount != 0 ) {
\r
449 DEBUG( DEBUG_MEDIUM, "No response withing timeout, sending response pending!\n");
\r
450 sendResponse(protocolRowEntry, DCM_E_RESPONSEPENDING);
\r
451 COUNT_DECREMENT( runtime->responsePendingCount );
\r
453 DEBUG( DEBUG_MEDIUM, "Sent all response pending, now sending general reject!\n");
\r
454 sendResponse(protocolRowEntry, DCM_E_GENERALREJECT);
\r
455 releaseExternalRxTxBuffers(protocolRowEntry, runtime);
\r
458 DEBUG( DEBUG_MEDIUM, "Not configured to send response pending, now sending general reject!\n");
\r
459 sendResponse(protocolRowEntry, DCM_E_GENERALREJECT);
\r
460 releaseExternalRxTxBuffers(protocolRowEntry, runtime);
\r
465 case DSD_PENDING_RESPONSE_SIGNALED: // The DSD has signaled to DSL that the diagnostic response is available in the Tx buffer.
\r
466 // Make sure that response pending or general reject have not been issued,
\r
467 // if so we can not transmit to PduR because we would not know from where
\r
468 // the Tx confirmation resides later.
\r
469 DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n");
\r
470 if (runtime->localTxBuffer.status == NOT_IN_USE) {
\r
471 const uint32 txPduId =
\r
472 protocolRowEntry->DslConnection->DslMainConnection->DslProtocolTx->PduR_DcmDslTxPduId;
\r
473 runtime->externalTxBufferStatus = DCM_TRANSMIT_SIGNALED;
\r
474 PduR_DcmTransmit(txPduId, &runtime->diagnosticResponseFromDsd); /** @req DCM237 **//* Will trigger PduR (CanTP) to call DslProvideTxBuffer(). */
\r
477 case DCM_TRANSMIT_SIGNALED:
\r
478 DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n");
\r
480 case PROVIDED_TO_PDUR: // The valid data is being transmitted by TP-layer.
\r
481 DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n");
\r
487 protocolRowEntry++;
\r
491 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
492 // Implements 'BufReq_ReturnType Dcm_ProvideRxBuffer(PduIdType dcmRxPduId,
\r
493 // PduLengthType tpSduLength, PduInfoType **pduInfoPtr)'.
\r
494 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
495 // This function is called called by the PduR typically when CanTp has
\r
496 // received a FF or a single frame and needs to obtain a buffer from the
\r
497 // receiver so that received data can be forwarded.
\r
499 BufReq_ReturnType DslProvideRxBufferToPdur(PduIdType dcmRxPduId,
\r
500 PduLengthType tpSduLength, const PduInfoType **pduInfoPtr) {
\r
501 BufReq_ReturnType ret = BUFREQ_NOT_OK;
\r
502 const Dcm_DslProtocolRxType *protocolRx = NULL;
\r
503 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
504 const Dcm_DslConnectionType *connection = NULL;
\r
505 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
506 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
508 DEBUG( DEBUG_MEDIUM, "DslProvideRxBufferToPdur called!\n");
\r
509 imask_t state = McuE_EnterCriticalSection();
\r
510 if (findParentConfigurationLeafs(dcmRxPduId, &protocolRx, &mainConnection,
\r
511 &connection, &protocolRow, &runtime)) {
\r
512 const Dcm_DslBufferType *externalRxBuffer =
\r
513 protocolRow->DslProtocolRxBufferID;
\r
514 if (externalRxBuffer->pduInfo.SduLength >= tpSduLength) { // First validate that we have a chance receiving the chunk of data.
\r
515 if ((runtime->externalRxBufferStatus == NOT_IN_USE)
\r
516 && (externalRxBuffer->externalBufferRuntimeData->status
\r
517 == BUFFER_AVAILABLE)) {
\r
518 DEBUG( DEBUG_MEDIUM, "External buffer available!\n");
\r
519 // ### EXTERNAL BUFFER IS AVAILABLE; GRAB IT AND REMEBER THAT WE OWN IT! ###
\r
520 externalRxBuffer->externalBufferRuntimeData->status
\r
522 runtime->diagnosticRequestFromTester.SduDataPtr = externalRxBuffer->pduInfo.SduDataPtr;
\r
523 runtime->diagnosticRequestFromTester.SduLength = tpSduLength;
\r
524 //*pduInfoPtr = &(externalRxBuffer->pduInfo);
\r
525 *pduInfoPtr = &(runtime->diagnosticRequestFromTester);
\r
526 runtime->externalRxBufferStatus = PROVIDED_TO_PDUR;
\r
529 DEBUG( DEBUG_MEDIUM, "Local buffer available!\n");
\r
530 if (runtime->externalRxBufferStatus == PROVIDED_TO_DSD) {
\r
531 // ### EXTERNAL BUFFER IS IN USE BY THE DSD, TRY TO USE LOCAL BUFFER! ###
\r
532 if (runtime->localRxBuffer.status == NOT_IN_USE) {
\r
533 if (tpSduLength < LOCAL_BUFFER_LENGTH) {
\r
534 runtime->localRxBuffer.status = PROVIDED_TO_PDUR;
\r
535 runtime->localRxBuffer.PduInfo.SduDataPtr
\r
536 = runtime->localRxBuffer.buffer;
\r
537 runtime->localRxBuffer.PduInfo.SduLength
\r
539 *pduInfoPtr = &(runtime->localRxBuffer.PduInfo);
\r
544 // The buffer is in use by the PduR, we can not help this because then
\r
545 // we would have two different Rx-indications with same PduId but we
\r
546 // will not know which buffer the indication should free.
\r
551 ret = BUFREQ_OVFL; // Required size is too big.
\r
553 if ( ret == BUFREQ_OK ) {
\r
554 stopS3SessionTimer( runtime ); /** req: DCM141 **/
\r
557 McuE_ExitCriticalSection(state);
\r
561 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
562 // Implements 'void Dcm_RxIndication(PduIdType dcmRxPduId, NotifResultType result)'.
\r
563 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
564 // This function is called called by the PduR typically when CanTp has
\r
565 // received the diagnostic request, copied it to the provided buffer and need to indicate
\r
566 // this to the DCM (DSL) module via propritary API.
\r
568 void DslRxIndicationFromPduR(PduIdType dcmRxPduId, NotifResultType result) {
\r
569 const Dcm_DslProtocolRxType *protocolRx = NULL;
\r
570 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
571 const Dcm_DslConnectionType *connection = NULL;
\r
572 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
573 const Dcm_DslProtocolTimingRowType *timeParams = NULL;
\r
574 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
575 Std_ReturnType higherLayerResp;
\r
578 // qqq: handle the actual result code.
\r
579 if (findParentConfigurationLeafs(dcmRxPduId, &protocolRx, &mainConnection,
\r
580 &connection, &protocolRow, &runtime)) {
\r
581 timeParams = protocolRow->DslProtocolTimeLimit;
\r
582 // We need to find out in what buffer we can find our Rx data (it can
\r
583 // be either in the normal RX-buffer or the 'extra' buffer for implementing
\r
584 // the Concurrent "Test Present" functionality.
\r
585 if (runtime->externalRxBufferStatus == PROVIDED_TO_PDUR) {
\r
586 if (isTesterPresentCommand(
\r
587 &(protocolRow->DslProtocolRxBufferID->pduInfo))) {
\r
588 state = McuE_EnterCriticalSection();
\r
589 startS3SessionTimer( runtime, protocolRow ); /** @req DCM141 **/ /** @req DCM112 **//** @req DCM113 **/
\r
590 runtime->externalRxBufferStatus = NOT_IN_USE;
\r
591 McuE_ExitCriticalSection(state);
\r
593 if (runtime->protocolStarted == FALSE) {
\r
594 higherLayerResp = StartProtocolHelper(
\r
595 protocolRow->DslProtocolID);
\r
596 if (higherLayerResp == E_OK) {
\r
597 runtime->protocolStarted = TRUE;
\r
598 DcmDslRunTimeData.activeProtocol = protocolRow;
\r
601 if (runtime->protocolStarted == TRUE) {
\r
602 if (runtime->diagnosticActiveComM == FALSE) {
\r
603 ComM_DCM_ActivateDiagnostic(); /* @DCM163 */
\r
604 runtime->diagnosticActiveComM = TRUE;
\r
606 state = McuE_EnterCriticalSection();
\r
607 runtime->stateTimeoutCount =
\r
608 DCM_CONVERT_MS_TO_MAIN_CYCLES(timeParams->TimStrP2ServerMax); /* See 9.2.2. */
\r
609 runtime->externalRxBufferStatus = PROVIDED_TO_DSD;
\r
610 runtime->externalTxBufferStatus = PROVIDED_TO_DSD; // Used in main.
\r
611 timeParams = protocolRow->DslProtocolTimeLimit;
\r
612 runtime->stateTimeoutCount =
\r
613 DCM_CONVERT_MS_TO_MAIN_CYCLES(timeParams->TimStrP2ServerMax); /* Reinitiate timer, see 9.2.2. */
\r
614 McuE_ExitCriticalSection(state);
\r
615 runtime->diagnosticResponseFromDsd.SduDataPtr = protocolRow->DslProtocolTxBufferID->pduInfo.SduDataPtr;
\r
616 runtime->diagnosticResponseFromDsd.SduLength = protocolRow->DslProtocolTxBufferID->pduInfo.SduLength;
\r
617 _DsdDslDataIndication(
\r
618 //&protocolRow->DslProtocolRxBufferID->pduInfo,
\r
619 &(runtime->diagnosticRequestFromTester),
\r
620 protocolRow->DslProtocolSIDTable,
\r
621 protocolRx->DslProtocolAddrType,
\r
622 mainConnection->DslProtocolTx->PduR_DcmDslTxPduId,
\r
623 //&protocolRow->DslProtocolTxBufferID->pduInfo);
\r
624 &(runtime->diagnosticResponseFromDsd));
\r
629 // It is the local buffer that was provided to the PduR, that buffer
\r
630 // is only used for tester present reception in parallel to diagnostic
\r
632 state = McuE_EnterCriticalSection();
\r
633 if (runtime->localRxBuffer.status == PROVIDED_TO_PDUR) {
\r
634 if (isTesterPresentCommand(&(runtime->localRxBuffer.PduInfo))) {
\r
635 startS3SessionTimer( runtime, protocolRow ); /** @req DCM141 **/ /** @req DCM112 **//** @req DCM113 **/
\r
637 runtime->localRxBuffer.status = NOT_IN_USE;
\r
639 McuE_ExitCriticalSection(state);
\r
645 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
646 // Implements 'BufReq_ReturnType Dcm_ProvideTxBuffer(PduIdType dcmTxPduId,
\r
647 // PduInfoType **pduInfoPtr, PduLengthType length)'.
\r
648 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
649 // This TX-buffer request is likely triggered by the transport layer (i.e. CanTp)
\r
650 // after PduR_DcmTransmit() has been called (via PduR to CanTp) indicating that something
\r
651 // is to be sent. The PduR_DcmTransmit() call is done from the DSL main function when
\r
652 // it has detected that the pending request has been answered by DSD
\r
653 // (or any other module?).
\r
655 BufReq_ReturnType DslProvideTxBuffer(PduIdType dcmTxPduId,
\r
656 const PduInfoType **pduInfoPtr, PduLengthType length) {
\r
657 BufReq_ReturnType ret = BUFREQ_NOT_OK;
\r
658 const Dcm_DslProtocolRxType *protocolRx = NULL;
\r
659 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
660 const Dcm_DslConnectionType *connection = NULL;
\r
661 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
662 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
664 if (findParentConfigurationLeafs(dcmTxPduId, &protocolRx, &mainConnection,
\r
665 &connection, &protocolRow, &runtime)) {
\r
666 switch (runtime->externalTxBufferStatus) { // ### EXTERNAL TX BUFFER ###
\r
667 case DCM_TRANSMIT_SIGNALED: {
\r
668 *pduInfoPtr = &(protocolRow->DslProtocolTxBufferID->pduInfo);
\r
669 runtime->externalTxBufferStatus = PROVIDED_TO_PDUR;
\r
674 ret = BUFREQ_NOT_OK;
\r
677 if (ret == BUFREQ_NOT_OK) {
\r
678 switch (runtime->localTxBuffer.status) { // ### LOCAL TX BUFFER ###
\r
679 case DCM_TRANSMIT_SIGNALED: {
\r
680 runtime->localTxBuffer.PduInfo.SduDataPtr
\r
681 = runtime->localTxBuffer.buffer;
\r
682 runtime->localTxBuffer.PduInfo.SduLength
\r
683 = runtime->localTxBuffer.messageLenght;
\r
684 *pduInfoPtr = &runtime->localTxBuffer.PduInfo;
\r
685 runtime->localTxBuffer.status = PROVIDED_TO_PDUR; // Now the DSL should not touch this Tx-buffer anymore.
\r
690 ret = BUFREQ_NOT_OK;
\r
700 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
701 // Implements 'void Dcm_TxConfirmation(PduIdType dcmTxPduId, NotifResultType result))'.
\r
702 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
703 // This function is called by the PduR (which has been trigged by i.e. CanTp)
\r
704 // when a transmission has been successfully finished, have had errors or
\r
705 // is even stopped.
\r
707 void DslTxConfirmation(PduIdType dcmTxPduId, NotifResultType result) {
\r
708 const Dcm_DslProtocolRxType *protocolRx = NULL;
\r
709 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
710 const Dcm_DslConnectionType *connection = NULL;
\r
711 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
712 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
715 DEBUG( DEBUG_MEDIUM, "DslTxConfirmation called!\n");
\r
716 if (findParentConfigurationLeafs(dcmTxPduId, &protocolRx, &mainConnection,
\r
717 &connection, &protocolRow, &runtime)) {
\r
718 boolean externalBufferReleased = FALSE;
\r
720 // Free the buffer and free the Pdu runtime data buffer.
\r
721 state = McuE_EnterCriticalSection();
\r
722 switch (runtime->externalTxBufferStatus) { // ### EXTERNAL TX BUFFER ###
\r
723 case PROVIDED_TO_PDUR: {
\r
724 ComM_DCM_InactivateDiagnostic();
\r
725 startS3SessionTimer(runtime, protocolRow); // @DCM141
\r
726 releaseExternalRxTxBuffers(protocolRow, runtime);
\r
728 protocolRow->DslProtocolTxBufferID->externalBufferRuntimeData->status
\r
729 = BUFFER_AVAILABLE;
\r
730 protocolRow->DslProtocolRxBufferID->externalBufferRuntimeData->status
\r
731 = BUFFER_AVAILABLE;
\r
732 runtime->externalTxBufferStatus = IDLE;
\r
733 runtime->externalRxBufferStatus = IDLE;
\r
735 DEBUG( DEBUG_MEDIUM, "Released external buffer sucessfully!\n");
\r
736 externalBufferReleased = TRUE;
\r
737 DsdDataConfirmation(dcmTxPduId, result); /** @req DCM117 **//** @req DCM235 **/
\r
743 if ( externalBufferReleased == FALSE ) {
\r
744 switch (runtime->localTxBuffer.status) { // ### LOCAL TX BUFFER ###
\r
745 case PROVIDED_TO_PDUR:
\r
746 DEBUG( DEBUG_MEDIUM, "Released local buffer buffer!\n");
\r
747 runtime->localTxBuffer.status = IDLE;
\r
750 DEBUG( DEBUG_MEDIUM, "WARNING! DslTxConfirmation could not release any buffer!\n");
\r
754 McuE_ExitCriticalSection(state);
\r