⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rasirr.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 2 页
字号:

/*

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 + -