📄 rasout.c
字号:
/* Take it from configuration - the gatekeeper's address */
srcNodeId = ras->gatekeeperRASAddress;
if (ras->gatekeeperRASAddress < 0)
__pvtGetNodeIdByFieldIds(srcNodeId, ras->hVal, ras->confNode, {_q931(manualDiscovery) _q931(defaultGatekeeper) LAST_TOKEN});
/* Save the GK RAS address*/
if ((ras->gatekeeperRASAddress < 0) && (srcNodeId >= 0))
{
ras->gatekeeperRASAddress = pvtAddRoot(ras->hVal, NULL, 0, NULL);
pvtSetTree(ras->hVal,ras->gatekeeperRASAddress,ras->hVal,srcNodeId);
}
status=0;
if (srcNodeId>=0)
status = cmVtToTA(ras->hVal, srcNodeId, &tx->destAddress);
else
memset(&(tx->destAddress),0,sizeof(cmTransportAddress));
}
else if (destAddress != NULL)
{
/* Get the address the user gave us */
tx->destAddress = *destAddress;
}
/* Build the default request message */
if (status >= 0)
{
requestNode = pvtAdd(ras->hVal, tx->txProperty, __q931(request), 0, NULL, NULL);
status = pvtSetTree(ras->hVal, requestNode, ras->hVal, ras->defaultMessages[transaction][cmRASTrStageRequest]);
}
/* Calculate the number of retries for this transaction */
tx->retryCount = rasCfgGetRetries(ras);
if (status < 0)
{
pvtDelete(ras->hVal, tx->txProperty);
emaDelete(tx);
return NULL;
}
return tx;
}
/************************************************************************
* rasSendRequestMessage
* purpose: Send an outgoing request message
* input : ras - RAS module to use
* tx - Outgoing transaction to send
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int rasSendRequestMessage(
IN rasModule* ras,
IN rasOutTx* tx)
{
RvUint32 reqSeqNum;
int nodeId, reqNodeId;
int status = 0;
/* Set the sequence number of the transaction */
RvLockGet(&ras->lockOutHash);
if (ras->requestSeqNum == 65535)
ras->requestSeqNum = 2;
else
ras->requestSeqNum++;
reqSeqNum = ras->requestSeqNum;
/* Update the outgoing hash table with this transaction */
if (tx->hashValue != NULL)
hashDelete(ras->outHash, tx->hashValue);
tx->hashValue = hashAdd(ras->outHash, &reqSeqNum, &tx, RV_TRUE);
if (tx->hashValue == NULL)
{
RvLogError(&ras->log,
(&ras->log, "rasSendRequestMessage: Cannot insert to hash 0x%p (requestSeqNum=%d)",
tx, reqSeqNum));
status = RV_ERROR_UNKNOWN;
}
/* Lock the transaction and then unlock the hash */
if (status >= 0)
if(!emaLock((EMAElement)tx))
status = RV_ERROR_UNKNOWN;
RvLockRelease(&ras->lockOutHash);
if (status < 0)
return status;
/* Make sure timer is released */
RvH323TimerCancel(ras->timers, &tx->timer);
/* Get the request message */
reqNodeId = pvtGetChild(ras->hVal, tx->txProperty, __q931(request), NULL);
if (reqNodeId < 0) status = reqNodeId;
/* Set the sequence number inside the outgoing request message */
__pvtBuildByFieldIds(nodeId, ras->hVal, reqNodeId, {_anyField _q931(requestSeqNum) LAST_TOKEN}, (RvInt32)reqSeqNum, NULL);
/* Mark transaction before using any of the callbacks */
if (status >= 0)
status = rasEncodeAndSend(ras, (HRAS)tx, cmRASTrStageRequest, reqNodeId, tx->isMulticast, &tx->destAddress, RV_TRUE, &tx->encodedMsg);
if (status >= 0)
{
/* No one closed this transaction - set the timer and finish with it */
switch (tx->transactionType)
{
case cmRASNonStandard:
/* Non-associated transaction */
tx->state = rasTxStateIdle;
tx->retryCount = 0;
break;
case cmRASUnsolicitedIRR:
{
/* Check if this IRR is waiting for a reply of some kind */
RvInt32 needResponse;
__pvtGetByFieldIds(nodeId, ras->hVal, reqNodeId, {_anyField _q931(needResponse) LAST_TOKEN}, NULL, &needResponse, NULL);
if (!needResponse)
{
/* We're not looking for a response - change state and end switch */
tx->state = rasTxStateIdle;
tx->retryCount = 0;
break;
}
/* If we got here, then we should wait for the
response as the rest of the messages: */
}
default:
{
RvInt timeout;
/* We'll be waiting for a reply... */
tx->state = rasTxStateRequestSent;
if(tx->transactionType == cmRASAdmission)
timeout = 2* 1000;
else
/* Set the timer for retries */
timeout = rasCfgGetTimeout(ras) * 1000;
tx->timer = RvH323TimerStartPeriodic(ras->timers, rasTimeoutEvent, tx, timeout);
}
}
}
emaUnlock((EMAElement)tx);
return status;
}
/************************************************************************
* rasDummyRequest
* purpose: Handle incoming unsolicited IRRs as responses
* input : ras - RAS module to use
* tx - Outgoing transaction to send
* output : none
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int rasDummyRequest(
IN rasModule* ras,
IN rasOutTx* tx)
{
/* We only act as if a message was sent so we'll be waiting for responses */
/* Make sure it's an unsolicited IRR transaction */
if ((tx->transactionType != cmRASUnsolicitedIRR) || (tx->hsCall == NULL))
{
RvLogError(&ras->log,
(&ras->log, "rasDummyRequest: Not an unsolicited IRR transaction (tx=0x%p)", tx));
return RV_ERROR_UNKNOWN;
}
if(emaLock((EMAElement)tx))
{
tx->state = rasTxStateRequestSent;
emaUnlock((EMAElement)tx);
}
/* Make sure we've got this handle in the CAT */
return catSetUnsolicitedIRR(ras->hCat, cmiGetCatForCall(tx->hsCall), (HRAS)tx);
}
/************************************************************************
* rasHandleReply
* purpose: Handle a reply of an outgoing request message
* input : ras - RAS module to use
* srcAddress - Address of the sender
* messageBuf - The message buffer to send
* messageLength - The length of the message in bytes
* 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
* seqNum - requestSeqNum field value of the message
* 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 rasHandleReply(
IN rasModule* ras,
IN cmRASTransport* srcAddress,
IN RvUint8* messageBuf,
IN RvUint32 messageLength,
IN int messageNodeId,
IN rasMessages messageType,
IN RvUint32 seqNum,
OUT void** hMsgContext)
{
rasOutTx* tx;
void* hashValue;
int status = 0;
/* Lock hash to find the transaction */
RvLockGet(&ras->lockOutHash);
/* Look for this transaction */
hashValue = hashGetElement(ras->outHash, hashFind(ras->outHash, &seqNum));
if (hashValue != NULL)
tx = *((rasOutTx **)hashValue);
else
tx = NULL;
if (tx == NULL)
{
RvLogWarning(&ras->log,
(&ras->log, "rasHandleReply: Transaction not found for seqNum=%d", seqNum));
if (messageNodeId >= 0)
pvtDelete(ras->hVal, messageNodeId);
RvLockRelease(&ras->lockOutHash);
return RV_ERROR_UNKNOWN;
}
/* Lock the transaction and unlock the hash table */
emaLock((EMAElement)tx);
RvLockRelease(&ras->lockOutHash);
/* Make sure we're still waiting for a reply of some kind */
if (!((tx->state == rasTxStateRequestSent) || (tx->state == rasTxStateRipReceived) ||
((tx->isMulticast == RV_TRUE) && (tx->state == rasTxStateReplyReceived))))
{
RvLogWarning(&ras->log,
(&ras->log, "rasHandleReply: Transaction 0x%p not waiting for replies. Reply is discarded", tx));
if (messageNodeId >= 0)
pvtDelete(ras->hVal, messageNodeId);
status = RV_ERROR_UNKNOWN;
}
/* Make sure this message belongs to the transaction */
if ((status >= 0) && (tx->transactionType != rasMessageInfo[messageType].transaction))
{
switch (messageType)
{
case rasMsgUnknownMessageResponse:
case rasMsgRequestInProgress:
/* We're fine - let these messages continue */
break;
default:
RvLogWarning(&ras->log,
(&ras->log, "rasHandleReply: Reply (%d) doesn't match this transaction type (%d)", messageType, tx->transactionType));
status = RV_ERROR_UNKNOWN;
}
}
if ((messageNodeId < 0) && (status >= 0))
{
/* We're in business - decode the whole message if we have to */
rasMessages newType;
RvUint32 newSeqNum;
status =
rasDecodeAndRecv(ras, messageBuf, messageLength, RV_FALSE, srcAddress,
&messageNodeId, &newType, &newSeqNum, hMsgContext);
/* Make sure the application didn't change the sequence number or type of message */
if ((status >= 0) && ((newSeqNum != seqNum) || (messageType != newType)))
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -