📄 rasirr.c
字号:
/*
NOTICE:
This document contains information that is proprietary to RADVISION LTD..
No part of this publication may be reproduced in any form whatsoever without
written prior approval by RADVISION LTD..
RADVISION LTD. reserves the right to revise this publication and make changes
without obligation to notify any person of such revisions or changes.
*/
#include "rvinternal.h"
#include "cmutils.h"
#include "rasparams.h"
#include "rasutils.h"
#include "rasin.h"
#include "rasout.h"
#include "rasirr.h"
#ifdef __cplusplus
extern "C" {
#endif
/************************************************************************
*
* Private functions
*
************************************************************************/
/************************************************************************
* rasFindCallHandleForIrr
* purpose: Find the call handle for an IRR message with a single call
* information inside it. This function is used to determine if
* the IRR message is solicited or unsolicited
* input : ras - RAS module to use
* rootId - Node ID of the message to check
* srcAddress - Address of the sender
* output : none
* return : Call handle of a call matches the IRR
* NULL otherwise
************************************************************************/
HCALL rasFindCallHandleForIrr(
IN rasModule* ras,
IN int rootId,
IN cmRASTransport* srcAddress)
{
catStruct key;
int nodeId, tmpNodeId;
RVHCATCALL hCatCall;
/* We surely know the source address of the message */
key.flags = catRasSrcAddr;
memcpy(&key.rasSrcAddr, srcAddress, sizeof(cmRASTransport));
/* Find the call information... */
__pvtGetByFieldIds(nodeId, ras->hVal, rootId, {_anyField _q931(perCallInfo) _nul(1) LAST_TOKEN}, NULL, NULL, NULL);
/* RAS-CRV */
tmpNodeId = pvtGetChild(ras->hVal, nodeId, __q931(callReferenceValue), NULL);
if (tmpNodeId >= 0)
{
int crv;
if (pvtGet(ras->hVal, tmpNodeId, NULL, NULL, &crv, NULL) >= 0)
{
key.rasCRV = (RvUint32)(0x8000^crv);
key.flags |= catRasCRV;
}
}
/* CID */
tmpNodeId = pvtGetChild(ras->hVal, nodeId, __q931(conferenceID), NULL);
if (tmpNodeId >= 0)
if (pvtGetString(ras->hVal, tmpNodeId, sizeof(key.cid), (char*)key.cid) >= 0)
key.flags |= catCID;
/* CallId */
__pvtGetByFieldIds(tmpNodeId, ras->hVal, nodeId, {_q931(callIdentifier) _q931(guid) LAST_TOKEN}, NULL, NULL, NULL);
if (tmpNodeId >= 0)
if (pvtGetString(ras->hVal, tmpNodeId, sizeof(key.callID), (char*)key.callID) >= 0)
key.flags |= catCallId;
/* Find this call using CAT */
hCatCall = catFind(ras->hCat, &key);
if (hCatCall != NULL)
return catGetCallHandle(ras->hCat, hCatCall);
/* No such luck - no call found */
return NULL;
}
/************************************************************************
* rasFindIrqTxAndLock
* purpose: Find an IRQ transaction related to an incoming IRR and
* lock that transaction if found
* input : ras - RAS module to use
* requestSeqNum - Sequence number in decoded message after hook
* return : Solicited IRR transaction handle if found a possible IRQ matching
* NULL if 100% unsolicited IRR
************************************************************************/
rasOutTx* rasFindIrqTxAndLock(
IN rasModule* ras,
IN RvUint32 requestSeqNum)
{
rasOutTx* tx;
void* hashValue;
/* Check in the hash table */
RvLockGet(&ras->lockOutHash);
hashValue = hashGetElement(ras->outHash, hashFind(ras->outHash, &requestSeqNum));
if (hashValue != NULL)
tx = *((rasOutTx **)hashValue);
else
tx = NULL;
if (tx == NULL)
{
/* No outgoing transaction for this one - we can say for certain it's an unsolicited IRR */
RvLockRelease(&ras->lockOutHash);
return NULL;
}
/* Make sure the transaction's type matches an IRQ */
emaLock((EMAElement)tx);
RvLockRelease(&ras->lockOutHash);
if (tx->transactionType != cmRASInfo)
{
/* Not an IRQ - its certainly an unsolicited IRR */
emaUnlock((EMAElement)tx);
return NULL;
}
return tx;
}
/************************************************************************
* rasIsSolicited
* purpose: Determines if a message is a solicited or an unsolicited IRR
* input : ras - RAS module to use
* rootId - Node ID of the message to check
* srcAddress - Address of the sender
* requestSeqNum - Sequence number in decoded message after hook
* output : isSolicited - RV_TRUE if message is a solicited IRR
* RV_FALSE if message is an unsolicted IRR
* return : Non-negative value on success
* Negative value on failure
************************************************************************/
int rasIsSolicited(
IN rasModule* ras,
IN int rootId,
IN cmRASTransport* srcAddress,
IN RvUint32 requestSeqNum,
OUT RvBool* isSolicited)
{
rasOutTx* tx;
RvInt32 unsolicited, needResponse;
int status;
int tmpNodeId, calls;
HCALL hsCall;
/* Check if we're using Version 4: This message includes indication of this is a
solicited or an unsolicited IRR */
__pvtGetByFieldIds(status, ras->hVal, rootId, {_anyField _q931(unsolicited) LAST_TOKEN}, NULL, &unsolicited, NULL);
if (status >= 0)
{
*isSolicited = (unsolicited == RV_FALSE);
return 0;
}
/* No such luck - it's not Version 4. Check the amount of callInfo objects we've got.
Other than 1 means it's a solicited IRR */
__pvtGetByFieldIds(tmpNodeId, ras->hVal, rootId, {_anyField _q931(perCallInfo) LAST_TOKEN}, NULL, NULL, NULL);
if (tmpNodeId < 0)
{
/* no perCallInfo field - it's a solicited IRR */
*isSolicited = RV_TRUE;
return 0;
}
calls = pvtNumChilds(ras->hVal, tmpNodeId);
if (calls < 0) return calls; /* error */
if (calls != 1)
{
/* more than 1 call - it's a solicited IRR */
*isSolicited = RV_TRUE;
return 0;
}
/* We've got a single call - check if needResponse = RV_TRUE */
__pvtGetByFieldIds(status, ras->hVal, rootId, {_anyField _q931(needResponse) LAST_TOKEN}, NULL, &needResponse, NULL);
if ((status >= 0) && needResponse)
{
/* needResponse=RV_TRUE - it's unsolicited IRR */
*isSolicited = RV_FALSE;
return 0;
}
/* See if we can find a matching IRQ transaction for the IRR */
tx = rasFindIrqTxAndLock(ras, requestSeqNum);
if (tx == NULL)
{
*isSolicited = RV_FALSE;
return 0;
}
/* Seems like we have to find out if this call matches the one we've got */
hsCall = rasFindCallHandleForIrr(ras, rootId, srcAddress);
/* This is a solicited IRR if the call matches the one this IRQ is looking for, or if
the IRQ was not called on a specific call. */
*isSolicited = (tx->hsCall == NULL) || (hsCall == tx->hsCall);
emaUnlock((EMAElement)tx);
if (hsCall != NULL)
return 0;
else
{
RvLogError(&ras->log,
(&ras->log, "rasIsSolicited: No call matched the IRR message (root=%d)", rootId));
return RV_ERROR_UNKNOWN;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -