📄 rasout.c
字号:
/* Reroute the message to check it again... */
emaUnlock((EMAElement)tx);
return rasRouteMessage(ras, rasChanUnicast, srcAddress, messageBuf, messageLength, messageNodeId, newType, newSeqNum, hMsgContext);
}
}
if (status < 0)
{
/* Probably couldn't decode this message... */
if (messageNodeId >= 0)
pvtDelete(ras->hVal, messageNodeId);
emaUnlock((EMAElement)tx);
return status;
}
if (messageType == rasMsgRequestInProgress)
{
/* We've got a RIP - handle it differently */
status = rasHandleIncomingRIP(ras, tx, messageNodeId);
emaUnlock((EMAElement)tx);
return status;
}
/* We found the transaction - start handling it properly */
/* - No need to unlock the element - rasHandleTxResponse does that automatically */
return rasHandleTxResponse(ras, tx, messageNodeId, messageType, hMsgContext);
}
/************************************************************************
* rasHandleTxResponse
* purpose: Handle a reply of an outgoing request message, when we already
* know the exact transaction. This function is used internally
* by rasHandleReply() and when we've got an unsolicited IRR on
* a dummy request.
* This function doesn't lock the transaction when handling it.
* It assumes that the transaction is already locked from somewhere
* else. It will unlock the transaction when finished.
* input : ras - RAS module to use
* tx - Transaction we're dealing with
* messageNodeId - Node ID of message root. If negative, then
* message is decoded from given buffer and hook
* is called
* messageType - Message type of the reply
* output : hMsgContext - Incoming message context. Used mostly by security
* If the returned value is different than NULL,
* then the message context is not used by the
* transaction and should be released
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int rasHandleTxResponse(
IN rasModule* ras,
IN rasOutTx* tx,
IN int messageNodeId,
IN rasMessages messageType,
OUT void** hMsgContext)
{
HAPPRAS haRas;
int rootId;
int status;
cmRASTrStage stage;
if (rasMessageInfo[messageType].msgType == rasTxMsgConfirm)
stage = cmRASTrStageConfirm;
else
stage = cmRASTrStageReject;
/* Make sure to notify the application of an incoming RAS message */
if (ras->evMessages.cmEvRasMessageReceive != NULL)
{
/* An internal callback - no log for this one */
ras->evMessages.cmEvRasMessageReceive(messageNodeId, stage, (HRAS)tx, ras->evMessages.hAppRasMsg);
}
/* Add the decoded message to the transaction's DB */
rootId = pvtAdd(ras->hVal, tx->txProperty, __q931(response), 0, NULL, NULL);
status = pvtMoveTree(ras->hVal, rootId, messageNodeId);
messageNodeId = rootId;
/* Make sure timer is released */
RvH323TimerCancel(ras->timers, &tx->timer);
/* Update the transaction's state only if it's not multicast.
For multicast transactions we want to receive any incoming message */
if ((status >= 0) && (!tx->isMulticast))
tx->state = rasTxStateReplyReceived;
/* Mark the transaction before the callback and unlock it */
emaMark((EMAElement)tx);
emaUnlock((EMAElement)tx);
if (status >= 0)
{
haRas = (HAPPRAS)emaGetApplicationHandle((EMAElement)tx);
/* If we get GCF then save the GK RAS address*/
if (messageType == rasMsgGatekeeperConfirm)
{
int srcNodeId;
if (ras->gatekeeperRASAddress < 0)
ras->gatekeeperRASAddress = pvtAddRoot(ras->hVal, NULL, 0, NULL);
__pvtGetNodeIdByFieldIds(srcNodeId, ras->hVal, messageNodeId, {_anyField _q931(rasAddress) LAST_TOKEN});
pvtSetTree(ras->hVal, ras->gatekeeperRASAddress, ras->hVal, srcNodeId);
}
/* Make sure we update the registration information if we have to */
if (messageType == rasMsgRegistrationConfirm)
{
rasUpdateRegInfo(ras, messageNodeId);
/* Let's get the GK address - just in case... */
if (ras->gatekeeperRASAddress < 0)
ras->gatekeeperRASAddress = pvtAddRoot(ras->hVal, ((cmElem*)(ras->app))->hAddrSyn, 0, NULL);
cmTAToVt(ras->hVal, ras->gatekeeperRASAddress, &tx->destAddress);
}
if (messageType == rasMsgUnregistrationConfirm)
{
/* Get the original request */
int requestId = pvtGetChild(ras->hVal, tx->txProperty, __q931(request), NULL);
int nodeId;
/* now see if it was a partial unregistration */
__pvtGetNodeIdByFieldIds(nodeId, ras->hVal, requestId , {_q931(unregistrationRequest) _q931(endpointAlias) LAST_TOKEN});
if(nodeId<0)
/* it was a full unregistration */
rasUpdateRegInfo(ras, -1);
else
/* just remove these aliases */
rasUpdatePartUnreg(ras, requestId);
}
/* Check if we have an automatic RAS callback - if we do, this will
override any manual RAS callback... */
/* Automatic RAS callback */
if (tx->evResponse != NULL)
{
/* We should overide the manual RAS callbacks - the automatic RAS should decide
if it should be called */
/* Associate message context with transaction */
tx->hMsgContext = *hMsgContext;
*hMsgContext = NULL;
/* Callback... */
if ((rasMessageInfo[messageType].msgType == rasTxMsgConfirm) && (ras->evAutoRas.cmEvAutoRASConfirm != NULL))
{
cmiCBEnter(ras->app, "cmEvAutoRASConfirm(hsRas=0x%p)", tx);
ras->evAutoRas.cmEvAutoRASConfirm((HRAS)tx);
cmiCBExit(ras->app, "cmEvAutoRASConfirm(hsRas=0x%p)", tx);
}
else if ((rasMessageInfo[messageType].msgType == rasTxMsgReject) && (ras->evAutoRas.cmEvAutoRASReject != NULL))
{
/* Find out the reject reason and then set the callback */
RvInt32 reason;
if (messageType == rasMsgUnknownMessageResponse)
reason = cmRASReasonUnknownMessageResponse; /* Reason is XRS */
else
{
/* Get the reason field from the reject message */
status = rasGetParam(ras, (HRAS)tx, cmRASTrStageReject, cmRASParamRejectReason, 0, &reason, NULL);
}
cmiCBEnter(ras->app, "cmEvAutoRasReject(hsRas=0x%p)", tx);
ras->evAutoRas.cmEvAutoRASReject((HRAS)tx, (cmRASReason)reason);
cmiCBExit(ras->app, "cmEvAutoRasReject(hsRas=0x%p)", tx);
}
if (!emaWasDeleted((EMAElement)tx))
tx->evResponse(haRas, (HRAS)tx, stage);
}
else
{
/* Manual RAS callbacks */
/* Start with the callbacks */
if ((rasMessageInfo[messageType].msgType == rasTxMsgConfirm) && (ras->evApp.cmEvRASConfirm != NULL))
{
/* Associate message context with transaction */
tx->hMsgContext = *hMsgContext;
*hMsgContext = NULL;
/* xCF message */
cmiCBEnter(ras->app, "cmEvRASConfirm(haRas=0x%p,hsRas=0x%p)", haRas, tx);
ras->evApp.cmEvRASConfirm(haRas, (HRAS)tx);
cmiCBExit(ras->app, "cmEvRASConfirm(haRas=0x%p,hsRas=0x%p)", haRas, tx);
}
else if ((rasMessageInfo[messageType].msgType == rasTxMsgReject) && (ras->evApp.cmEvRASReject != NULL))
{
/* xRJ message */
/* Find out the reject reason and then set the callback */
RvInt32 reason;
if (messageType == rasMsgUnknownMessageResponse)
reason = cmRASReasonUnknownMessageResponse; /* Reason is XRS */
else
{
/* Get the reason field from the reject message */
status = rasGetParam(ras, (HRAS)tx, cmRASTrStageReject, cmRASParamRejectReason, 0, &reason, NULL);
}
/* Associate message context with transaction */
tx->hMsgContext = *hMsgContext;
*hMsgContext = NULL;
/* Make sure we notify the application with a callback... */
cmiCBEnter(ras->app, "cmEvRasReject(haRas=0x%p,hsRas=0x%p)", haRas, tx);
ras->evApp.cmEvRASReject(haRas, (HRAS)tx, (cmRASReason)reason);
cmiCBExit(ras->app, "cmEvRasReject(haRas=0x%p,hsRas=0x%p)", haRas, tx);
}
}
}
/* Release the transaction and we're done */
emaRelease((EMAElement)tx);
return status;
}
/************************************************************************
* rasCloseOutTx
* purpose: Close an outgoing transaction
* input : ras - RAS module to use
* tx - Outgoing transaction to close
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int rasCloseOutTx(
IN rasModule* ras,
IN rasOutTx* tx)
{
int nodeId;
void* hMsgContext;
/* Lock the hash table first */
RvLockGet(&ras->lockOutHash);
/* Lock the transaction itself and mark it - we'll delete it before unlocking it... */
if(emaLock((EMAElement)tx))
{
/* Delete the hash entry */
if (tx->hashValue != NULL)
hashDelete(ras->outHash, tx->hashValue);
/* Unlock the hash table before killing the transaction */
RvLockRelease(&ras->lockOutHash);
/* Get all the handle we need to remove after unlocking */
nodeId = tx->txProperty;
hMsgContext = tx->hMsgContext;
/* Kill the timer if there is one - before unlocking... */
RvH323TimerCancel(ras->timers, &tx->timer);
/* Remove RPOOL element */
if (tx->encodedMsg != NULL)
rpoolFree(ras->messages, tx->encodedMsg);
/* Delete, Unlock and Release */
emaDelete((EMAElement)tx);
emaUnlock((EMAElement)tx);
/* Free some nodes in the PVT db */
pvtDelete(ras->hVal, nodeId);
/* Dispose the message context for this transaction if we've got one */
if (hMsgContext != NULL)
ras->cmiEvRASReleaseMessageContext(hMsgContext);
}
return 0;
}
#ifdef __cplusplus
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -