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
17 * General requirements
\r
24 #include "Dcm_Internal.h"
\r
26 #if defined(USE_COMM)
\r
27 #include "ComM_Dcm.h"
\r
29 #include "PduR_Dcm.h"
\r
30 #include "ComStack_Types.h"
\r
32 //#define USE_DEBUG_PRINTF
\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
39 #if (DCM_PAGEDBUFFER_ENABLED)
\r
40 #error "DCM_PAGEDBUFFER_ENABLED is set to STD_ON, this is not supported by the code."
\r
46 // #define MAX_PARALLEL_PROTOCOLS_ALLOWED 1
\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
56 static DcmDsl_RunTimeDataType DcmDslRunTimeData = {
\r
58 .activeProtocol = NULL
\r
59 // .preemptedProtocol = NULL,
\r
60 // .protocolList = {}
\r
63 // ################# HELPER FUNCTIONS START #################
\r
66 // This function reset/stars the session (S3) timer. See requirement
\r
67 // DCM141 when that action should be taken.
\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
75 // - - - - - - - - - - -
\r
78 // This function reset/stars the session (S3) timer. See requirement
\r
79 // DCM141 when that action should be taken.
\r
81 static inline void stopS3SessionTimer(Dcm_DslRunTimeProtocolParametersType *runtime) {
\r
82 runtime->S3ServerTimeoutCount = 0;
\r
85 // - - - - - - - - - - -
\r
88 // This function implements the requirement DCM139 when
\r
89 // transition from one session to another.
\r
91 static void changeDiagnosticSession(Dcm_DslRunTimeProtocolParametersType *runtime, Dcm_SesCtrlType newSession) {
\r
95 switch (runtime->sessionControl) {
\r
96 case DCM_DEFAULT_SESSION: // "default".
\r
97 /* to set the dsp buffer to default*/
\r
101 case DCM_PROGRAMMING_SESSION:
\r
102 case DCM_EXTENDED_DIAGNOSTIC_SESSION:
\r
103 case DCM_SAFTEY_SYSTEM_DIAGNOSTIC_SESSION:
\r
104 case DCM_ALL_SESSION_LEVEL:
\r
105 runtime->securityLevel = DCM_SEC_LEV_LOCKED; // "0x00".
\r
109 DET_REPORTERROR(MODULE_ID_DCM, 0, DCM_CHANGE_DIAGNOSTIC_SESSION_ID, DCM_E_PARAM);
\r
110 //DEBUG(DEBUG_MEDIUM, "Old session invalid");
\r
114 switch (newSession) {
\r
115 case DCM_DEFAULT_SESSION: // "default".
\r
116 case DCM_PROGRAMMING_SESSION:
\r
117 case DCM_EXTENDED_DIAGNOSTIC_SESSION:
\r
118 case DCM_SAFTEY_SYSTEM_DIAGNOSTIC_SESSION:
\r
119 case DCM_ALL_SESSION_LEVEL:
\r
120 runtime->sessionControl = newSession;
\r
124 DET_REPORTERROR(MODULE_ID_DCM, 0, DCM_CHANGE_DIAGNOSTIC_SESSION_ID, DCM_E_PARAM);
\r
125 //DEBUG(DEBUG_MEDIUM, "New session invalid");
\r
130 // - - - - - - - - - - -
\r
132 void DslResetSessionTimeoutTimer(void) {
\r
133 const Dcm_DslProtocolRowType *activeProtocol;
\r
134 Dcm_DslRunTimeProtocolParametersType *runtime;
\r
136 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
137 runtime = activeProtocol->DslRunTimeProtocolParameters;
\r
138 startS3SessionTimer(runtime, activeProtocol); /** @req DCM141 */
\r
141 // - - - - - - - - - - -
\r
143 void DslGetCurrentServiceTable(const Dcm_DsdServiceTableType **currentServiceTable) { /** @req DCM195 */
\r
144 const Dcm_DslProtocolRowType *activeProtocol;
\r
146 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
147 if (activeProtocol != NULL) {
\r
148 *currentServiceTable = activeProtocol->DslProtocolSIDTable;
\r
152 // - - - - - - - - - - -
\r
154 Std_ReturnType DslGetActiveProtocol(Dcm_ProtocolType *protocolId) { /** @req DCM340 */
\r
155 Std_ReturnType ret = E_NOT_OK;
\r
156 const Dcm_DslProtocolRowType *activeProtocol;
\r
158 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
159 if (activeProtocol != NULL) {
\r
160 *protocolId = activeProtocol->DslProtocolID;
\r
166 // - - - - - - - - - - -
\r
168 void DslSetSecurityLevel(Dcm_SecLevelType secLevel) { /** @req DCM020 */
\r
169 const Dcm_DslProtocolRowType *activeProtocol;
\r
170 Dcm_DslRunTimeProtocolParametersType *runtime;
\r
172 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
173 runtime = activeProtocol->DslRunTimeProtocolParameters;
\r
174 runtime->securityLevel = secLevel;
\r
177 // - - - - - - - - - - -
\r
179 Std_ReturnType DslGetSecurityLevel(Dcm_SecLevelType *secLevel) { /** @req DCM020 *//** @req DCM338 */
\r
180 Std_ReturnType ret = E_NOT_OK;
\r
181 const Dcm_DslProtocolRowType *activeProtocol;
\r
182 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
184 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
185 if (activeProtocol != NULL) {
\r
186 runtime = activeProtocol->DslRunTimeProtocolParameters;
\r
187 *secLevel = runtime->securityLevel;
\r
193 // - - - - - - - - - - -
\r
195 void DslSetSesCtrlType(Dcm_SesCtrlType sesCtrl) { /** @req DCM022 */
\r
196 const Dcm_DslProtocolRowType *activeProtocol;
\r
197 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
199 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
200 if (activeProtocol != NULL) {
\r
201 runtime = activeProtocol->DslRunTimeProtocolParameters;
\r
202 if (runtime->sessionControl != sesCtrl) {
\r
203 changeDiagnosticSession(runtime, sesCtrl);
\r
204 DslResetSessionTimeoutTimer();
\r
209 // - - - - - - - - - - -
\r
211 Std_ReturnType DslGetSesCtrlType(Dcm_SesCtrlType *sesCtrlType) { /** @req DCM022 *//** @req DCM339 */
\r
212 Std_ReturnType ret = E_NOT_OK;
\r
213 const Dcm_DslProtocolRowType *activeProtocol;
\r
214 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
216 activeProtocol = DcmDslRunTimeData.activeProtocol;
\r
217 if (activeProtocol != NULL) {
\r
218 runtime = activeProtocol->DslRunTimeProtocolParameters;
\r
219 *sesCtrlType = runtime->sessionControl;
\r
225 // - - - - - - - - - - -
\r
227 static boolean findRxPduIdParentConfigurationLeafs(PduIdType dcmRxPduId,
\r
228 const Dcm_DslProtocolRxType **protocolRx,
\r
229 const Dcm_DslMainConnectionType **mainConnection,
\r
230 const Dcm_DslConnectionType **connection,
\r
231 const Dcm_DslProtocolRowType **protocolRow,
\r
232 Dcm_DslRunTimeProtocolParametersType **runtime) {
\r
234 boolean ret = FALSE;
\r
235 if (dcmRxPduId < DCM_DSL_RX_PDU_ID_LIST_LENGTH) {
\r
236 *protocolRx = &DCM_Config.Dsl->DslProtocol->DslProtocolRxGlobalList[dcmRxPduId];
\r
237 *mainConnection = (*protocolRx)->DslMainConnectionParent;
\r
238 *connection = (*mainConnection)->DslConnectionParent;
\r
239 *protocolRow = (*connection)->DslProtocolRow;
\r
240 *runtime = (*protocolRow)->DslRunTimeProtocolParameters;
\r
246 // - - - - - - - - - - -
\r
248 static boolean findTxPduIdParentConfigurationLeafs(PduIdType dcmTxPduId,
\r
249 const Dcm_DslProtocolTxType **protocolTx,
\r
250 const Dcm_DslMainConnectionType **mainConnection,
\r
251 const Dcm_DslConnectionType **connection,
\r
252 const Dcm_DslProtocolRowType **protocolRow,
\r
253 Dcm_DslRunTimeProtocolParametersType **runtime) {
\r
255 boolean ret = FALSE;
\r
256 if (dcmTxPduId < DCM_DSL_TX_PDU_ID_LIST_LENGTH) {
\r
257 *protocolTx = &DCM_Config.Dsl->DslProtocol->DslProtocolTxGlobalList[dcmTxPduId];
\r
258 *mainConnection = (*protocolTx)->DslMainConnectionParent;
\r
259 *connection = (*mainConnection)->DslConnectionParent;
\r
260 *protocolRow = (*connection)->DslProtocolRow;
\r
261 *runtime = (*protocolRow)->DslRunTimeProtocolParameters;
\r
267 // - - - - - - - - - - -
\r
269 static inline void releaseExternalRxTxBuffers(const Dcm_DslProtocolRowType *protocolRow,
\r
270 Dcm_DslRunTimeProtocolParametersType *runtime) {
\r
272 protocolRow->DslProtocolTxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;
\r
273 protocolRow->DslProtocolRxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;
\r
274 runtime->externalTxBufferStatus = NOT_IN_USE; // We are waiting for DSD to return the buffer. qqq.
\r
275 runtime->externalRxBufferStatus = NOT_IN_USE; // We are waiting for DSD to return the buffer. qqq.
\r
278 // - - - - - - - - - - -
\r
281 static inline void releaseExternalRxTxBuffersHelper(PduIdType rxPduIdRef) {
\r
282 const Dcm_DslProtocolRxType *protocolRx = NULL;
\r
283 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
284 const Dcm_DslConnectionType *connection = NULL;
\r
285 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
286 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
288 if (findRxPduIdParentConfigurationLeafs(rxPduIdRef, &protocolRx, &mainConnection, &connection, &protocolRow, &runtime)) {
\r
289 releaseExternalRxTxBuffers(protocolRow, runtime);
\r
293 // - - - - - - - - - - -
\r
296 * This function is called from the DSD module to the DSL when
\r
297 * a response to a diagnostic request has been copied into the
\r
298 * given TX-buffer and is ready for transmission.
\r
300 void DslDsdProcessingDone(PduIdType rxPduIdRef, DsdProcessingDoneResultType responseResult) {
\r
301 const Dcm_DslProtocolRxType *protocolRx = NULL;
\r
302 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
303 const Dcm_DslConnectionType *connection = NULL;
\r
304 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
305 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
307 // DEBUG( DEBUG_MEDIUM, "DslDsdProcessingDone rxPduIdRef=%d\n", rxPduIdRef);
\r
309 if (findRxPduIdParentConfigurationLeafs(rxPduIdRef, &protocolRx, &mainConnection, &connection, &protocolRow, &runtime)) {
\r
312 switch (responseResult) {
\r
313 case DSD_TX_RESPONSE_READY:
\r
314 runtime->externalTxBufferStatus = DSD_PENDING_RESPONSE_SIGNALED; /** @req DCM114 */
\r
316 case DSD_TX_RESPONSE_SUPPRESSED: /** @req DCM238 */
\r
317 //DEBUG( DEBUG_MEDIUM, "DslDsdProcessingDone called with DSD_TX_RESPONSE_SUPPRESSED.\n");
\r
318 releaseExternalRxTxBuffersHelper(rxPduIdRef);
\r
321 //DEBUG( DEBUG_MEDIUM, "Unknown response result from DslDsdProcessingDone!\n");
\r
324 Irq_Restore(state);
\r
328 // - - - - - - - - - - -
\r
331 * This function preparing transmission of response
\r
332 * pending message to tester.
\r
334 static void sendResponse(const Dcm_DslProtocolRowType *protocol,
\r
335 Dcm_NegativeResponseCodeType responseCode) {
\r
336 //Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
337 const Dcm_DslProtocolRxType *protocolRx = NULL;
\r
338 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
339 const Dcm_DslConnectionType *connection = NULL;
\r
340 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
341 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
342 Std_ReturnType transmitResult;
\r
347 if (findRxPduIdParentConfigurationLeafs(protocol->DslRunTimeProtocolParameters->diagReqestRxPduId, &protocolRx, &mainConnection, &connection, &protocolRow, &runtime)) {
\r
348 if (runtime->localTxBuffer.status == NOT_IN_USE) {
\r
349 runtime->localTxBuffer.status = PROVIDED_TO_DSD;
\r
350 runtime->localTxBuffer.buffer[0] = SID_NEGATIVE_RESPONSE;
\r
351 runtime->localTxBuffer.buffer[1] = protocol->DslProtocolRxBufferID->pduInfo.SduDataPtr[2];
\r
352 runtime->localTxBuffer.buffer[2] = responseCode;
\r
353 runtime->localTxBuffer.PduInfo.SduDataPtr = 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 interested in sending.
\r
356 transmitResult = PduR_DcmTransmit(mainConnection->DslProtocolTx->DcmDslProtocolTxPduId, &(runtime->localTxBuffer.PduInfo));/** @req DCM115.Partially */ /* The P2ServerMin has not been implemented. */
\r
357 if (transmitResult != E_OK) {
\r
358 // TODO: What to do here?
\r
362 Irq_Restore(state);
\r
365 // - - - - - - - - - - -
\r
367 static Std_ReturnType StartProtocolHelper(Dcm_ProtocolType protocolId) {
\r
368 Std_ReturnType ret = E_NOT_OK;
\r
371 for (i = 0; !DCM_Config.Dsl->DslCallbackDCMRequestService[i].Arc_EOL; i++) {
\r
372 if (DCM_Config.Dsl->DslCallbackDCMRequestService[i].StartProtocol != NULL) {
\r
373 ret = DCM_Config.Dsl->DslCallbackDCMRequestService[i]. StartProtocol(protocolId);
\r
382 // - - - - - - - - - - -
\r
384 static boolean isTesterPresentCommand(const PduInfoType *rxPdu) {
\r
385 boolean ret = FALSE;
\r
386 if ((rxPdu->SduDataPtr[0] == SID_TESTER_PRESENT) && (rxPdu->SduDataPtr[1] & SUPPRESS_POS_RESP_BIT)) {
\r
392 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
393 // Implements 'void Dcm_Init(void)' for DSL.
\r
394 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
395 void DslInit(void) {
\r
396 const Dcm_DslProtocolRowType *listEntry;
\r
397 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
399 listEntry = DCM_Config.Dsl->DslProtocol->DslProtocolRowList;
\r
400 while (listEntry->Arc_EOL == FALSE) {
\r
401 runtime = listEntry->DslRunTimeProtocolParameters;
\r
402 runtime->externalRxBufferStatus = DCM_IDLE;
\r
403 runtime->externalTxBufferStatus = DCM_IDLE;
\r
404 runtime->localRxBuffer.status = DCM_IDLE;
\r
405 runtime->localTxBuffer.status = DCM_IDLE;
\r
406 runtime->securityLevel = DCM_SEC_LEV_LOCKED; /** @req DCM033 */
\r
407 runtime->sessionControl = DCM_DEFAULT_SESSION; /** @req DCM034 */
\r
408 listEntry->DslProtocolRxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;
\r
409 listEntry->DslProtocolRxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;
\r
412 //DcmDslRunTimeData.diagnosticRequestPending = FALSE;
\r
413 DcmDslRunTimeData.initRun = TRUE;
\r
416 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
417 // Implements 'void DslInternal_ResponseOnOneDataByPeriodicId(uint8 PericodID)' for simulator a periodic did data.
\r
418 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
420 Std_ReturnType DslInternal_ResponseOnOneDataByPeriodicId(uint8 PericodID)
\r
422 Std_ReturnType ret = E_NOT_OK;
\r
423 const Dcm_DslProtocolRowType *protocolRowEntry;
\r
424 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
425 PduInfoType *pPeriodData;
\r
426 protocolRowEntry = DCM_Config.Dsl->DslProtocol->DslProtocolRowList;
\r
427 while (protocolRowEntry->Arc_EOL == FALSE)
\r
429 runtime = protocolRowEntry->DslRunTimeProtocolParameters;
\r
430 if(runtime != NULL) // find the runtime
\r
432 if( BUFREQ_OK == DslProvideRxBufferToPdur(runtime->diagReqestRxPduId, 3, (const PduInfoType **)&pPeriodData)){
\r
433 pPeriodData->SduDataPtr[0] = 0x2a;
\r
434 pPeriodData->SduDataPtr[1] = 0;
\r
435 pPeriodData->SduDataPtr[2] = PericodID;
\r
436 pPeriodData->SduLength = 3;
\r
437 DslRxIndicationFromPduR(0, NTFRSLT_OK);
\r
446 protocolRowEntry++;
\r
453 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
454 // Implements 'void Dcm_MainFunction(void)' for DSL.
\r
455 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
456 void DslMain(void) {
\r
457 const Dcm_DslProtocolRowType *protocolRowEntry;
\r
458 const Dcm_DslProtocolTimingRowType *timeParams = NULL;
\r
459 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
461 protocolRowEntry = DCM_Config.Dsl->DslProtocol->DslProtocolRowList;
\r
462 while (protocolRowEntry->Arc_EOL == FALSE) {
\r
463 runtime = protocolRowEntry->DslRunTimeProtocolParameters;
\r
464 if (runtime != NULL) {
\r
465 // #### HANDLE THE TESTER PRESENT PRESENCE ####
\r
466 if (runtime->sessionControl != DCM_DEFAULT_SESSION) { // Timeout if tester present is lost.
\r
467 DECREMENT(runtime->S3ServerTimeoutCount);
\r
468 if (runtime->S3ServerTimeoutCount == 0) {
\r
469 changeDiagnosticSession(runtime, DCM_DEFAULT_SESSION); /** @req DCM140 */
\r
472 switch (runtime->externalTxBufferStatus) { // #### TX buffer state. ####
\r
474 //DEBUG( DEBUG_MEDIUM, "state NOT_IN_USE!\n");
\r
476 case PROVIDED_TO_DSD: {
\r
477 DECREMENT(runtime->stateTimeoutCount);
\r
478 if (runtime->stateTimeoutCount == 0) {
\r
479 timeParams = protocolRowEntry->DslProtocolTimeLimit;
\r
480 runtime->stateTimeoutCount = DCM_CONVERT_MS_TO_MAIN_CYCLES(timeParams->TimStrP2ServerMax); /* Reinitiate timer, see 9.2.2. */
\r
481 if (DCM_Config.Dsl->DslDiagResp != NULL) {
\r
482 if (DCM_Config.Dsl->DslDiagResp->DslDiagRespForceRespPendEn == TRUE) {
\r
483 if (runtime->responsePendingCount != 0) {
\r
484 sendResponse(protocolRowEntry, DCM_E_RESPONSEPENDING); /** @req DCM024 */
\r
485 DECREMENT( runtime->responsePendingCount );
\r
487 sendResponse(protocolRowEntry, DCM_E_GENERALREJECT); /** @req DCM120 */
\r
488 releaseExternalRxTxBuffers(protocolRowEntry, runtime);
\r
491 // DEBUG( DEBUG_MEDIUM, "Not configured to send response pending, now sending general reject!\n");
\r
492 sendResponse(protocolRowEntry, DCM_E_GENERALREJECT);
\r
493 releaseExternalRxTxBuffers(protocolRowEntry, runtime);
\r
499 case DSD_PENDING_RESPONSE_SIGNALED:
\r
500 // The DSD has signaled to DSL that the diagnostic response is available in the Tx buffer.
\r
501 // Make sure that response pending or general reject have not been issued,
\r
502 // if so we can not transmit to PduR because we would not know from where
\r
503 // the Tx confirmation resides later.
\r
504 // DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n");
\r
505 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
506 const Dcm_DslProtocolRxType *protocolRx = NULL;
\r
507 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
508 const Dcm_DslConnectionType *connection = NULL;
\r
509 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
510 Std_ReturnType transmitResult;
\r
512 if (findRxPduIdParentConfigurationLeafs(runtime->diagReqestRxPduId, &protocolRx, &mainConnection, &connection, &protocolRow, &runtime)) {
\r
513 const PduIdType txPduId = mainConnection->DslProtocolTx->DcmDslProtocolTxPduId;
\r
514 // DEBUG( DEBUG_MEDIUM, "runtime->externalTxBufferStatus enter state DCM_TRANSMIT_SIGNALED.\n" );
\r
515 runtime->externalTxBufferStatus = DCM_TRANSMIT_SIGNALED;
\r
516 transmitResult = PduR_DcmTransmit(txPduId, &runtime->diagnosticResponseFromDsd); /** @req DCM237 *//* Will trigger PduR (CanTP) to call DslProvideTxBuffer(). */
\r
517 if (transmitResult != E_OK) {
\r
518 // TODO: What to do here?
\r
521 // DEBUG( DEBUG_MEDIUM, "***** WARNING, THIS IS UNEXPECTED !!! ********.\n" );
\r
522 const PduIdType txPduId = protocolRowEntry->DslConnection->DslMainConnection->DslProtocolTx->DcmDslProtocolTxPduId;
\r
523 // DEBUG( DEBUG_MEDIUM, "runtime->externalTxBufferStatus enter state DSD_PENDING_RESPONSE_SIGNALED.\n", txPduId);
\r
524 runtime->externalTxBufferStatus = DCM_TRANSMIT_SIGNALED;
\r
525 // DEBUG( DEBUG_MEDIUM, "Calling PduR_DcmTransmit with txPduId = %d from DslMain\n", txPduId);
\r
526 transmitResult = PduR_DcmTransmit(txPduId, &runtime->diagnosticResponseFromDsd); /** @req DCM237 *//* Will trigger PduR (CanTP) to call DslProvideTxBuffer(). */
\r
527 if (transmitResult != E_OK) {
\r
528 // TODO: What to do here?
\r
533 case DCM_TRANSMIT_SIGNALED:
\r
534 //DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n");
\r
536 case PROVIDED_TO_PDUR: // The valid data is being transmitted by TP-layer.
\r
537 //DEBUG( DEBUG_MEDIUM, "state DSD_PENDING_RESPONSE_SIGNALED!\n");
\r
543 protocolRowEntry++;
\r
547 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
548 // Implements 'BufReq_ReturnType Dcm_ProvideRxBuffer(PduIdType dcmRxPduId,
\r
549 // PduLengthType tpSduLength, PduInfoType **pduInfoPtr)'.
\r
550 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
551 // This function is called called by the PduR typically when CanTp has
\r
552 // received a FF or a single frame and needs to obtain a buffer from the
\r
553 // receiver so that received data can be forwarded.
\r
555 BufReq_ReturnType DslProvideRxBufferToPdur(PduIdType dcmRxPduId, PduLengthType tpSduLength, const PduInfoType **pduInfoPtr) {
\r
556 BufReq_ReturnType ret = BUFREQ_NOT_OK;
\r
557 const Dcm_DslProtocolRxType *protocolRx = NULL;
\r
558 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
559 const Dcm_DslConnectionType *connection = NULL;
\r
560 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
561 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
563 // DEBUG( DEBUG_MEDIUM, "DslProvideRxBufferToPdur(dcmRxPduId=%d) called!\n", dcmRxPduId);
\r
565 if (findRxPduIdParentConfigurationLeafs(dcmRxPduId, &protocolRx, &mainConnection, &connection, &protocolRow, &runtime)) {
\r
566 const Dcm_DslBufferType *externalRxBuffer = protocolRow->DslProtocolRxBufferID;
\r
567 if (externalRxBuffer->pduInfo.SduLength >= tpSduLength) { /** @req DCM443 */
\r
568 if ((runtime->externalRxBufferStatus == NOT_IN_USE) && (externalRxBuffer->externalBufferRuntimeData->status == BUFFER_AVAILABLE)) {
\r
569 // DEBUG( DEBUG_MEDIUM, "External buffer available!\n");
\r
570 // ### EXTERNAL BUFFER IS AVAILABLE; GRAB IT AND REMEBER THAT WE OWN IT! ###
\r
571 externalRxBuffer->externalBufferRuntimeData->status = BUFFER_BUSY;
\r
572 runtime->diagnosticRequestFromTester.SduDataPtr = externalRxBuffer->pduInfo.SduDataPtr;
\r
573 runtime->diagnosticRequestFromTester.SduLength = tpSduLength;
\r
574 *pduInfoPtr = &(runtime->diagnosticRequestFromTester);
\r
575 runtime->externalRxBufferStatus = PROVIDED_TO_PDUR; /** @req DCM342 */
\r
578 if (runtime->externalRxBufferStatus == PROVIDED_TO_DSD) {
\r
579 // ### EXTERNAL BUFFER IS IN USE BY THE DSD, TRY TO USE LOCAL BUFFER! ###
\r
580 if (runtime->localRxBuffer.status == NOT_IN_USE) {
\r
581 if (tpSduLength < DCM_DSL_LOCAL_BUFFER_LENGTH) {
\r
582 runtime->localRxBuffer.status = PROVIDED_TO_PDUR;
\r
583 runtime->localRxBuffer.PduInfo.SduDataPtr = runtime->localRxBuffer.buffer;
\r
584 runtime->localRxBuffer.PduInfo.SduLength = tpSduLength;
\r
585 *pduInfoPtr = &(runtime->localRxBuffer.PduInfo);
\r
592 // The buffer is in use by the PduR, we can not help this because then
\r
593 // we would have two different Rx-indications with same PduId but we
\r
594 // will not know which buffer the indication should free.
\r
595 ret = BUFREQ_BUSY; /** @req DCM445 */
\r
599 ret = BUFREQ_OVFL; /** @req DCM444 */
\r
601 if (ret == BUFREQ_OK) {
\r
602 stopS3SessionTimer(runtime); /** @req DCM141 */
\r
605 Irq_Restore(state);
\r
609 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
610 // Implements 'void Dcm_RxIndication(PduIdType dcmRxPduId, NotifResultType result)'.
\r
611 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
612 // This function is called called by the PduR typically when CanTp has
\r
613 // received the diagnostic request, copied it to the provided buffer and need to indicate
\r
614 // this to the DCM (DSL) module via proprietary API.
\r
616 void DslRxIndicationFromPduR(PduIdType dcmRxPduId, NotifResultType result) {
\r
617 const Dcm_DslProtocolRxType *protocolRx = NULL;
\r
618 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
619 const Dcm_DslConnectionType *connection = NULL;
\r
620 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
621 const Dcm_DslProtocolTimingRowType *timeParams = NULL;
\r
622 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
623 Std_ReturnType higherLayerResp;
\r
626 /** @req DCM345, this needs to be verified when connection to CanIf works. */
\r
628 if (findRxPduIdParentConfigurationLeafs(dcmRxPduId, &protocolRx, &mainConnection, &connection, &protocolRow, &runtime)) {
\r
629 timeParams = protocolRow->DslProtocolTimeLimit;
\r
630 // We need to find out in what buffer we can find our Rx data (it can
\r
631 // be either in the normal RX-buffer or the 'extra' buffer for implementing
\r
632 // the Concurrent "Test Present" functionality.
\r
634 if (runtime->externalRxBufferStatus == PROVIDED_TO_PDUR) {
\r
635 if ( result == NTFRSLT_OK ) { /** @req DCM111 */
\r
636 if (isTesterPresentCommand(&(protocolRow->DslProtocolRxBufferID->pduInfo))) {
\r
637 startS3SessionTimer(runtime, protocolRow); /** @req DCM141 *//** @req DCM112 *//** @req DCM113 */
\r
638 runtime->externalRxBufferStatus = NOT_IN_USE;
\r
639 protocolRow->DslProtocolRxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;
\r
641 if (runtime->protocolStarted == FALSE) {
\r
642 higherLayerResp = StartProtocolHelper(protocolRow->DslProtocolID); /** @req DCM036 */
\r
643 if (higherLayerResp == E_OK) {
\r
644 runtime->protocolStarted = TRUE;
\r
645 DcmDslRunTimeData.activeProtocol = protocolRow;
\r
648 if (runtime->protocolStarted == TRUE) {
\r
649 if (runtime->diagnosticActiveComM == FALSE) {
\r
650 #if defined(USE_COMM)
\r
651 ComM_DCM_ActiveDiagnostic(); /** @req DCM163 */
\r
653 runtime->diagnosticActiveComM = TRUE;
\r
655 timeParams = protocolRow->DslProtocolTimeLimit;
\r
656 runtime->stateTimeoutCount = DCM_CONVERT_MS_TO_MAIN_CYCLES(timeParams->TimStrP2ServerMax); /* See 9.2.2. */
\r
657 runtime->externalRxBufferStatus = PROVIDED_TO_DSD; /** @req DCM241 */
\r
658 if (runtime->externalTxBufferStatus == NOT_IN_USE) {
\r
659 // DEBUG( DEBUG_MEDIUM, "External Tx buffer available, we can pass it to DSD.\n");
\r
661 //DEBUG( DEBUG_MEDIUM, "External buffer not available, a response is being transmitted?\n");
\r
663 runtime->externalTxBufferStatus = PROVIDED_TO_DSD; /** @req DCM241 */
\r
664 runtime->responsePendingCount = DCM_Config.Dsl->DslDiagResp->DslDiagRespMaxNumRespPend;
\r
665 runtime->diagnosticResponseFromDsd.SduDataPtr = protocolRow->DslProtocolTxBufferID->pduInfo.SduDataPtr;
\r
666 runtime->diagnosticResponseFromDsd.SduLength = protocolRow->DslProtocolTxBufferID->pduInfo.SduLength;
\r
667 // DEBUG( DEBUG_MEDIUM, "DsdDslDataIndication(DcmDslProtocolTxPduId=%d, dcmRxPduId=%d)\n", mainConnection->DslProtocolTx->DcmDslProtocolTxPduId, dcmRxPduId);
\r
668 runtime->diagReqestRxPduId = dcmRxPduId;
\r
669 // DEBUG(DEBUG_MEDIUM,"\n\n runtime->diagnosticRequestFromTester.SduDataPtr[2] %x\n\n ",runtime->diagnosticRequestFromTester.SduDataPtr[2]);
\r
670 DsdDslDataIndication( // qqq: We are inside a critical section.
\r
671 &(runtime->diagnosticRequestFromTester),
\r
672 protocolRow->DslProtocolSIDTable, /** @req DCM035 */
\r
673 protocolRx->DslProtocolAddrType,
\r
674 mainConnection->DslProtocolTx->DcmDslProtocolTxPduId,
\r
675 &(runtime->diagnosticResponseFromDsd),
\r
679 } else { /** @req DCM344 */
\r
680 // The indication was not equal to NTFRSLT_OK, release the resources and no forward to DSD.
\r
681 runtime->externalRxBufferStatus = NOT_IN_USE;
\r
682 protocolRow->DslProtocolRxBufferID->externalBufferRuntimeData->status = BUFFER_AVAILABLE;
\r
685 // It is the local buffer that was provided to the PduR, that buffer
\r
686 // is only used for tester present reception in parallel to diagnostic
\r
688 if (runtime->localRxBuffer.status == PROVIDED_TO_PDUR) {
\r
689 if ( result == NTFRSLT_OK ) { // Make sure that the data in buffer is valid.
\r
690 if (isTesterPresentCommand(&(runtime->localRxBuffer.PduInfo))) {
\r
691 startS3SessionTimer(runtime, protocolRow); /** @req DCM141 *//** @req DCM112 *//** @req DCM113 */
\r
694 runtime->localRxBuffer.status = NOT_IN_USE;
\r
697 Irq_Restore(state);
\r
701 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
702 // Implements 'BufReq_ReturnType Dcm_ProvideTxBuffer(PduIdType dcmTxPduId,
\r
703 // PduInfoType **pduInfoPtr, PduLengthType length)'.
\r
704 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
705 // This TX-buffer request is likely triggered by the transport layer (i.e. CanTp)
\r
706 // after PduR_DcmTransmit() has been called (via PduR to CanTp) indicating that something
\r
707 // is to be sent. The PduR_DcmTransmit() call is done from the DSL main function when
\r
708 // it has detected that the pending request has been answered by DSD
\r
709 // (or any other module?).
\r
711 BufReq_ReturnType DslProvideTxBuffer(PduIdType dcmTxPduId, const PduInfoType **pduInfoPtr, PduLengthType length) {
\r
712 BufReq_ReturnType ret = BUFREQ_NOT_OK;
\r
713 const Dcm_DslProtocolTxType *protocolTx = NULL;
\r
714 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
715 const Dcm_DslConnectionType *connection = NULL;
\r
716 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
717 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
719 (void)length; // Currently not used, this is only to remove compilation warnings
\r
720 // DEBUG( DEBUG_MEDIUM, "DslProvideTxBuffer=%d\n", dcmTxPduId);
\r
721 if (findTxPduIdParentConfigurationLeafs(dcmTxPduId, &protocolTx, &mainConnection, &connection, &protocolRow, &runtime)) {
\r
722 switch (runtime->externalTxBufferStatus) { // ### EXTERNAL TX BUFFER ###
\r
723 case DCM_TRANSMIT_SIGNALED: {
\r
724 /** @req DCM346 */ /* Length verification is already done if this state is reached. */
\r
725 *pduInfoPtr = &(protocolRow->DslProtocolTxBufferID->pduInfo);
\r
726 runtime->externalTxBufferStatus = PROVIDED_TO_PDUR; /** @req DCM349 */
\r
731 //DEBUG( DEBUG_MEDIUM, "DCM_TRANSMIT_SIGNALED was not signaled in the external buffer\n");
\r
732 ret = BUFREQ_NOT_OK;
\r
735 if (ret == BUFREQ_NOT_OK) {
\r
736 switch (runtime->localTxBuffer.status) { // ### LOCAL TX BUFFER ###
\r
737 case DCM_TRANSMIT_SIGNALED: {
\r
738 runtime->localTxBuffer.PduInfo.SduDataPtr = runtime->localTxBuffer.buffer;
\r
739 runtime->localTxBuffer.PduInfo.SduLength = runtime->localTxBuffer.messageLenght;
\r
740 *pduInfoPtr = &runtime->localTxBuffer.PduInfo;
\r
741 runtime->localTxBuffer.status = PROVIDED_TO_PDUR; // Now the DSL should not touch this Tx-buffer anymore.
\r
746 //DEBUG( DEBUG_MEDIUM, "DCM_TRANSMIT_SIGNALED was not signaled for the local buffer either\n");
\r
747 ret = BUFREQ_NOT_OK;
\r
755 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
756 // Implements 'void Dcm_TxConfirmation(PduIdType dcmTxPduId, NotifResultType result))'.
\r
757 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
\r
758 // This function is called by the PduR (which has been trigged by i.e. CanTp)
\r
759 // when a transmission has been successfully finished, have had errors or
\r
760 // is even stopped.
\r
762 void DslTxConfirmation(PduIdType dcmTxPduId, NotifResultType result) {
\r
763 const Dcm_DslProtocolTxType *protocolTx = NULL;
\r
764 const Dcm_DslMainConnectionType *mainConnection = NULL;
\r
765 const Dcm_DslConnectionType *connection = NULL;
\r
766 const Dcm_DslProtocolRowType *protocolRow = NULL;
\r
767 Dcm_DslRunTimeProtocolParametersType *runtime = NULL;
\r
770 // DEBUG( DEBUG_MEDIUM, "DslTxConfirmation=%d, result=%d\n", dcmTxPduId, result);
\r
771 if (findTxPduIdParentConfigurationLeafs(dcmTxPduId, &protocolTx, &mainConnection, &connection, &protocolRow, &runtime)) {
\r
772 boolean externalBufferReleased = FALSE;
\r
774 // Free the buffer and free the Pdu runtime data buffer.
\r
776 switch (runtime->externalTxBufferStatus) { // ### EXTERNAL TX BUFFER ###
\r
777 case PROVIDED_TO_PDUR: {
\r
778 #if defined(USE_COMM)
\r
779 ComM_DCM_InactiveDiagnostic(); /** @req DCM164 */
\r
781 startS3SessionTimer(runtime, protocolRow); /** @req DCM141 */
\r
782 releaseExternalRxTxBuffers(protocolRow, runtime); /** @req DCM118 *//** @req DCM352 *//** @req DCM353 *//** @req DCM354 */
\r
783 externalBufferReleased = TRUE;
\r
784 // DEBUG( DEBUG_MEDIUM, "Released external buffer OK!\n");
\r
785 DsdDataConfirmation(mainConnection->DslProtocolTx->DcmDslProtocolTxPduId, result); /** @req DCM117 *//** @req DCM235 */
\r
791 if (!externalBufferReleased) {
\r
792 switch (runtime->localTxBuffer.status) { // ### LOCAL TX BUFFER ###
\r
793 case PROVIDED_TO_PDUR:
\r
794 // DEBUG( DEBUG_MEDIUM, "Released local buffer buffer OK!\n");
\r
795 runtime->localTxBuffer.status = DCM_IDLE;
\r
798 // DEBUG( DEBUG_MEDIUM, "WARNING! DslTxConfirmation could not release external or local buffer!\n");
\r
802 Irq_Restore(state);
\r