📄 rasin.c
字号:
if (tx->transactionType == cmRASInfo)
{
RvPvtNodeId irrNode = pvtAdd(ras->hVal, tx->txProperty, __q931(response), 0, NULL, NULL);
rasSetIrrFields(ras, (HRAS)tx, irrNode, tx->hsCall);
}
if (ras->evCallRequest != NULL)
{
/* Associate message context with transaction */
tx->hMsgContext = *hMsgContext;
*hMsgContext = NULL;
notifyApp = !ras->evCallRequest(ras->app,
(HRAS)tx,
tx->hsCall,
tx->transactionType,
srcAddress,
haCall,
ras->evAutoRas.cmEvAutoRASRequest);
}
}
else
{
if (ras->evEpRequest != NULL)
{
/* Associate message context with transaction */
tx->hMsgContext = *hMsgContext;
*hMsgContext = NULL;
notifyApp = !ras->evEpRequest(ras->app,
(HRAS)tx,
tx->transactionType,
srcAddress,
ras->evAutoRas.cmEvAutoRASRequest);
}
}
if (notifyApp)
{
if (ras->evApp.cmEvRASRequest != NULL)
{
/* Associate message context with transaction */
tx->hMsgContext = *hMsgContext;
*hMsgContext = NULL;
cmiCBEnter(ras->app, "cmEvRASRequest(hsRas=0x%p,hsCall=0x%p,trans=%d)", tx, tx->hsCall, tx->transactionType);
ras->evApp.cmEvRASRequest((HRAS)tx,
tx->hsCall,
&haRas,
tx->transactionType,
srcAddress,
haCall);
cmiCBExit(ras->app, "cmEvRASRequest(hsRas=0x%p,haRas=0x%p)", tx, haRas);
/* Update the application's handle */
emaSetApplicationHandle((EMAElement)tx, (void*)haRas);
}
else
{
/* Automatic RAS mode, and there's no callback for manual RAS messages.
We should kill this transaction. */
status = rasCloseInTx(ras, tx);
}
}
/* Release the transaction when we're done */
emaRelease((EMAElement)tx);
}
else
{
/* This is a retransmission - see if we have a reply for it */
emaLock((EMAElement)tx);
RvLockRelease(&ras->lockInHash);
switch (tx->state)
{
case rasTxStateReplySent:
/* Retransmit the reply to the sender */
status = rasRetransmit(ras, (HRAS)tx, tx->encodedMsg, &tx->destAddress, "response");
break;
case rasTxStateRipSent:
{
int timeLeft = (int)(Rv64Multiply((RvInt64)tx->ripStopTime, 1000) - Rv64Divide(RvTimestampGet(), RV_TIME64_NSECPERMSEC));
if (timeLeft > 0)
{
/* Let's send a RIP retransmission after calculating the delay */
status = rasSendRIP(ras, tx, timeLeft, RV_FALSE);
}
else
status = RV_ERROR_UNKNOWN;
break;
}
default:
/* Do nothing - retransmission of something that the application didn't
Reply to yet */
RvLogDebug(&ras->log,
(&ras->log, "rasHandleRequest: Retrasmission ignored for transaction 0x%d", tx));
}
emaUnlock((EMAElement)tx);
}
return status;
}
/************************************************************************
* rasSendConfirmMessage
* purpose: Sends a confirm response on an incoming RAS request
* input : ras - RAS module to use
* tx - Incoming transaction
* output : none
* return : If an error occurs, the function returns a negative value.
* If no error occurs, the function returns a non-negative value.
************************************************************************/
int rasSendConfirmMessage(
IN rasModule* ras,
IN rasInTx* tx)
{
int status = RV_ERROR_UNKNOWN;
/* Lock the transaction before dealing with it */
if(emaLock((EMAElement)tx))
{
status = rasSendResponse(ras, tx, cmRASTrStageConfirm, -1, RV_TRUE);
/* Unlock and release the transaction when we're done */
emaUnlock((EMAElement)tx);
}
return status;
}
/************************************************************************
* rasSendRejectMessage
* purpose: Sends a reject response on an incoming RAS request
* input : ras - RAS module to use
* tx - Incoming transaction
* reason - The reject reason to use
* output : none
* return : If an error occurs, the function returns a negative value.
* If no error occurs, the function returns a non-negative value.
************************************************************************/
int rasSendRejectMessage(
IN rasModule* ras,
IN rasInTx* tx,
IN cmRASReason reason)
{
int status = RV_ERROR_UNKNOWN;
/* Lock the transaction before dealing with it */
if(emaLock((EMAElement)tx))
{
if (reason == cmRASReasonUnknownMessageResponse)
{
RvPvtNodeId nodeId;
/* Create an XRS message */
__pvtBuildByFieldIds(nodeId, ras->hVal, tx->txProperty,
{_q931(response) _q931(unknownMessageResponse) LAST_TOKEN}, 0, NULL);
tx->responseSet = rasRejectSet;
}
else
{
/* Set the reject reason of this message */
status = rasSetParam(ras, (HRAS)tx, cmRASTrStageReject, cmRASParamRejectReason, 0, reason, NULL);
}
status = rasSendResponse(ras, tx, cmRASTrStageReject, -1, RV_TRUE);
/* Unlock and release the transaction when we're done */
emaUnlock((EMAElement)tx);
}
return status;
}
/************************************************************************
* rasSendRIP
* purpose: Sends a RIP response on an incoming RAS request
* input : ras - RAS module to use
* tx - Incoming transaction
* delay - Delay for RIP message in milliseconds
* updateStopTime - Indicate if we're updating the stop time
* and increasing the transaction's time or not
* output : none
* return : If an error occurs, the function returns a negative value.
* If no error occurs, the function returns a non-negative value.
************************************************************************/
int rasSendRIP(
IN rasModule* ras,
IN rasInTx* tx,
IN int delay,
IN RvBool updateStopTime)
{
int status, nodeId, progressNodeId;
/* Make sure delay is within range */
if ((delay < 1) || (delay > 65535))
{
RvLogError(&ras->log,
(&ras->log, "rasSendRIP: Delay %d out of range for tx=0x%p (1..65535)", delay, tx));
return RV_ERROR_UNKNOWN;
}
/* Build the RIP message */
nodeId = pvtAddRoot(ras->hVal, ras->synMessage, 0, NULL);
if (nodeId < 0) return nodeId;
__pvtBuildByFieldIds(status, ras->hVal, nodeId, {_q931(requestInProgress) _q931(delay) LAST_TOKEN}, delay, NULL);
if (status < 0)
{
pvtDelete(ras->hVal, nodeId);
return status;
}
/* Lock the transaction before dealing with it */
if(emaLock((EMAElement)tx))
{
/* Link the RIP message to the transaction's database */
progressNodeId = pvtAdd(ras->hVal, tx->txProperty, __q931(progress), 0, NULL, NULL);
status = pvtMoveTree(ras->hVal, progressNodeId, nodeId);
if (status < 0)
pvtDelete(ras->hVal, nodeId);
/* Send this message */
if (status >= 0)
status = rasSendResponse(ras, tx, cmRASTrStageConfirm, progressNodeId, RV_FALSE);
if (status >= 0)
{
tx->state = rasTxStateRipSent;
if (updateStopTime)
{
/* Recalculate the time this transaction will timeout */
tx->stopTime += delay;
tx->ripStopTime = (RvInt32)Rv64Divide(RvTimestampGet(), RV_TIME64_NSECPERSEC) +
((delay + 999) / 1000); /* Our timeouts for the RAS transactions are calculated in seconds and not milliseconds... */
}
}
/* Unlock and release the transaction when we're done */
emaUnlock((EMAElement)tx);
}
return status;
}
/************************************************************************
* rasCloseInTx
* purpose: Close an incoming transaction
* This won't actually free resources, only mark the transaction
* as a possibility for removal in the garbage collection.
* input : ras - RAS module to use
* tx - Incoming transaction to close
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int rasCloseInTx(
IN rasModule* ras,
IN rasInTx* tx)
{
int nodeId = -1;
void* hMsgContext = NULL;
RvLockGet(&ras->lockGarbage);
if(emaLock((EMAElement)tx))
{
/* Set garbage collection list to match the required order */
if (ras->lastTx != NULL) ras->lastTx->next = tx;
ras->lastTx = tx;
if (ras->firstTx == NULL) ras->firstTx = tx;
nodeId = tx->txProperty;
hMsgContext = tx->hMsgContext;
emaUnlock((EMAElement)tx);
}
RvLockRelease(&ras->lockGarbage);
/* Free some nodes in the PVT db */
if (nodeId >= 0)
pvtDelete(ras->hVal, nodeId);
/* Dispose of the message context for this transaction if we've got any */
if (hMsgContext != NULL)
ras->cmiEvRASReleaseMessageContext(hMsgContext);
return 0;
}
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -