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

📄 cmiras.c

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

/*

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 "stkutils.h"
#include "intutils.h"
#include "cmCrossReference.h"
#include "rvh323watchdog.h"
#include "rasdef.h"
#include "rasin.h"
#include "rasout.h"
#include "rasutils.h"
#include "rasdecoder.h"
#include "cmiras.h"

#ifdef __cplusplus
extern "C" {
#endif





/************************************************************************
 *
 *                          Private constants
 *
 ************************************************************************/

#define RAS_OID_VERSION H225_PROTOCOL_IDENTIFIER

#define RAS_RPOOL_BLOCK_SIZE (512)


/************************************************************************
 * rasMessageInfo
 * Static information about the messages. This information helps us
 * distinguish between incoming and outgoing messages and to find out
 * the transaction type for the messages.
 * The values are from the point of view of messages coming from the
 * network.
 * NOTES:
 * - IRR messages are handled separately
 * - XRS messages are discarded
 * - RIP messages are handled separately as outgoing transaction replies
 ************************************************************************/
const rasMessageInfoStruct rasMessageInfo[] =
{
    /* rasMsgGatekeeperRequest          */ {RAS_IN_TX,  rasTxMsgRequest, cmRASGatekeeper},
    /* rasMsgGatekeeperConfirm          */ {RAS_OUT_TX, rasTxMsgConfirm, cmRASGatekeeper},
    /* rasMsgGatekeeperReject           */ {RAS_OUT_TX, rasTxMsgReject,  cmRASGatekeeper},
    /* rasMsgRegistrationRequest        */ {RAS_IN_TX,  rasTxMsgRequest, cmRASRegistration},
    /* rasMsgRegistrationConfirm        */ {RAS_OUT_TX, rasTxMsgConfirm, cmRASRegistration},
    /* rasMsgRegistrationReject         */ {RAS_OUT_TX, rasTxMsgReject,  cmRASRegistration},
    /* rasMsgUnregistrationRequest      */ {RAS_IN_TX,  rasTxMsgRequest, cmRASUnregistration},
    /* rasMsgUnregistrationConfirm      */ {RAS_OUT_TX, rasTxMsgConfirm, cmRASUnregistration},
    /* rasMsgUnregistrationReject       */ {RAS_OUT_TX, rasTxMsgReject,  cmRASUnregistration},
    /* rasMsgAdmissionRequest           */ {RAS_IN_TX,  rasTxMsgRequest, cmRASAdmission},
    /* rasMsgAdmissionConfirm           */ {RAS_OUT_TX, rasTxMsgConfirm, cmRASAdmission},
    /* rasMsgAdmissionReject            */ {RAS_OUT_TX, rasTxMsgReject,  cmRASAdmission},
    /* rasMsgBandwidthRequest           */ {RAS_IN_TX,  rasTxMsgRequest, cmRASBandwidth},
    /* rasMsgBandwidthConfirm           */ {RAS_OUT_TX, rasTxMsgConfirm, cmRASBandwidth},
    /* rasMsgBandwidthReject            */ {RAS_OUT_TX, rasTxMsgReject,  cmRASBandwidth},
    /* rasMsgDisengageRequest           */ {RAS_IN_TX,  rasTxMsgRequest, cmRASDisengage},
    /* rasMsgDisengageConfirm           */ {RAS_OUT_TX, rasTxMsgConfirm, cmRASDisengage},
    /* rasMsgDisengageReject            */ {RAS_OUT_TX, rasTxMsgReject,  cmRASDisengage},
    /* rasMsgLocationRequest            */ {RAS_IN_TX,  rasTxMsgRequest, cmRASLocation},
    /* rasMsgLocationConfirm            */ {RAS_OUT_TX, rasTxMsgConfirm, cmRASLocation},
    /* rasMsgLocationReject             */ {RAS_OUT_TX, rasTxMsgReject,  cmRASLocation},
    /* rasMsgInfoRequest                */ {RAS_IN_TX,  rasTxMsgRequest, cmRASInfo},
    /* rasMsgInfoRequestResponse        */ {RAS_OUT_TX, rasTxMsgConfirm, cmRASInfo},
    /* rasMsgNonStandardMessage         */ {RAS_IN_TX,  rasTxMsgRequest, cmRASNonStandard},
    /* rasMsgUnknownMessageResponse     */ {RAS_OUT_TX, rasTxMsgReject,  (cmRASTransaction)0},
    /* rasMsgRequestInProgress          */ {RAS_OUT_TX, rasTxMsgOther,   (cmRASTransaction)0},
    /* rasMsgResourcesAvailableIndicate */ {RAS_IN_TX,  rasTxMsgRequest, cmRASResourceAvailability},
    /* rasMsgResourcesAvailableConfirm  */ {RAS_OUT_TX, rasTxMsgConfirm, cmRASResourceAvailability},
    /* rasMsgInfoRequestAck             */ {RAS_OUT_TX, rasTxMsgConfirm, cmRASUnsolicitedIRR},
    /* rasMsgInfoRequestNak             */ {RAS_OUT_TX, rasTxMsgReject,  cmRASUnsolicitedIRR},
    /* rasMsgServiceControlIndication   */ {RAS_IN_TX,  rasTxMsgRequest, cmRASServiceControl},
    /* rasMsgServiceControlResponse     */ {RAS_OUT_TX, rasTxMsgConfirm, cmRASServiceControl}
};





/************************************************************************
 *
 *                          Private functions
 *
 ************************************************************************/


/************************************************************************
 * rasWatchdogResourceCallback
 * purpose: Get a resource parameter from RAS for the watchdog
 * input  : context     - RAS context to use
 *          resource    - Resource to get
 *          type        - Type of resource
 * output : value       - Returned resource value
 * return : Non-negative value on success, other on failure
 ************************************************************************/
static int RVCALLCONV rasWatchdogResourceCallback(
    IN  void*                       context,
    IN  RvUint32                    resource,
    IN  RvH323WatchdogResourceType  type,
    OUT RvUint32*                   value)
{
    rasModule* ras = (rasModule *)context;

    if (resource == ras->rasTimersResourceVal)
    {
        RvRaStatistics statistics;
        if (RvH323TimerStatistics(ras->timers, &statistics) >= 0)
        {
            switch (type)
            {
            case RvH323WatchdogMaxVal: *value = statistics.max; return 0;
            case RvH323WatchdogMaxUsage: *value = statistics.maxUsage; return 0;
            case RvH323WatchdogCurrent: *value = statistics.cur; return 0;
            default:
                return RV_ERROR_UNKNOWN;
            }
        }
        return RV_ERROR_UNKNOWN;
    }

    return RV_ERROR_UNKNOWN;
}





/************************************************************************
 *
 *                          Public functions
 *
 ************************************************************************/


/************************************************************************
 * cmiRASInitialize
 * purpose: Initialize a RAS instance for use by the CM
 * input  : hApp            - Stack's instance handle
 *          hCat            - CAT instance handle
 *          hVal            - Value "forest" to use for ASN.1 messages
 *          rasConfNode     - RAS configuration node id
 *          maxIncomingTx   - Maximum number of incoming RAS transactions
 *          maxOutgoingTx   - Maximum number of outgoing RAS transactions
 *          maxBufSize      - Maximum buffer size for encoded messages
 *          isGatekeeper    - Indication if we should act as a GK
 * output : none
 * return : RAS module handle on success
 *          NULL on failure
 ************************************************************************/
HRASMGR RVCALLCONV cmiRASInitialize(
    IN  HAPP        hApp,
    IN  RVHCAT      hCat,
    IN  HPVT        hVal,
    IN  int         rasConfNode,
    IN  RvUint32    maxIncomingTx,
    IN  RvUint32    maxOutgoingTx,
    IN  RvUint32    maxBufSize,
    IN  RvBool      isGatekeeper)
{
    rasModule* ras;
    int numRpoolBlocks, bufSize;
    int status;
    int i, j;

    if (hApp == NULL) return NULL;

    /* Allocate the main RAS object */
    if(RvMemoryAlloc(NULL, (void**)&ras, sizeof(rasModule)) != RV_OK)
        return NULL;
    memset(ras, 0, sizeof(rasModule));

    ras->app = hApp;
    RvLogSourceConstruct(RvLogGet(), &ras->log, RV_LOG_LIBCODE_H323, "RAS", "RAS Transactions");
    RvLogSourceConstruct(RvLogGet(), &ras->logChan, RV_LOG_LIBCODE_H323, "UDPCHAN", "RAS Message Channels");

    /* Allocate outgoing transaction databases */
    if (maxOutgoingTx > 0)
    {
        ras->outRa =
            emaConstruct(sizeof(rasOutTx), (int)maxOutgoingTx, emaNormalLocks, "RAS OUT TX", RAS_OUT_TX, ras, hApp);
        ras->outHash =
            hashConstruct((int)(maxOutgoingTx*2), (int)maxOutgoingTx,
                          rasOutgoingHashFunc, hashDefaultCompare,
                          sizeof(RvUint32), sizeof(rasOutTx*), "RAS OUT HASH");

        emaAddWatchdogResource(ras->outRa, cmiGetWatchdogHandle(hApp), "OutgoingRasTx", "RAS", "Outgoing RAS transactions");
    }

    /* Allocate incoming transaction databases */
    if (maxIncomingTx > 0)
    {
        ras->inRa =
            emaConstruct(sizeof(rasInTx), (int)maxIncomingTx, emaNormalLocks, "RAS IN TX", RAS_IN_TX, ras, hApp);
        ras->inHash =
            hashConstruct((int)(maxIncomingTx*2), (int)maxIncomingTx,
                          rasIncomingHashFunc, rasIncomingHashCompare,
                          sizeof(rasInTxKey), sizeof(rasInTx*), "RAS IN HASH");

        emaAddWatchdogResource(ras->inRa, cmiGetWatchdogHandle(hApp), "IncomingRasTx", "RAS", "Incoming RAS transactions");
    }

    /* Allocate RPOOL for message retransmissions */
    if (maxBufSize > RAS_RPOOL_BLOCK_SIZE)
        bufSize = RAS_RPOOL_BLOCK_SIZE;
    else
        bufSize = maxBufSize;
    numRpoolBlocks = (maxIncomingTx + maxOutgoingTx) * (maxBufSize / RAS_RPOOL_BLOCK_SIZE);
    if (numRpoolBlocks > 0 && bufSize > 0)
        ras->messages = rpoolConstruct(bufSize, numRpoolBlocks, RV_FALSE, "RAS MESSAGES");

    /* Create the timers pool */
    if (maxOutgoingTx > 0)
    {
        ras->timers = RvH323TimerConstruct((int)maxOutgoingTx, NULL);
        RvWatchdogAddResource(cmiGetWatchdogHandle(hApp), "RasTimers", "RAS", "RAS timers",
            (RvWatchdogResourceCallback_T)rasWatchdogResourceCallback, ras, &ras->rasTimersResourceVal);
    }

    /* Make sure all allocations succeeded */
    if ((((ras->outRa == NULL) || (ras->outHash == NULL)) && (maxOutgoingTx > 0)) ||
        (((ras->inRa == NULL) || (ras->inHash == NULL)) && (maxIncomingTx > 0)) ||
        ((ras->messages == NULL) && (numRpoolBlocks > 0) && (bufSize > 0)) ||
        ((ras->timers == NULL) && (maxOutgoingTx > 0)))
    {
        if (ras->outRa != NULL) emaDestruct(ras->outRa);
        if (ras->outHash != NULL) hashDestruct(ras->outHash);
        if (ras->inRa != NULL) emaDestruct(ras->inRa);
        if (ras->inHash != NULL) hashDestruct(ras->inHash);
        if (ras->messages != NULL) rpoolDestruct(ras->messages);
        if (ras->timers != NULL) RvH323TimerDestruct(ras->timers);

        return NULL;
    }

    /* Make sure messages are empty */
    for (i = 0; i < cmRASMaxTransaction; i++)
        for (j = 0; j < 4; j++)
            ras->defaultMessages[i][j] = -1;

    /* Construct the syntax trees */
    ras->synMessage = pstConstruct(q931asn1GetSyntax(), (char *)"RasMessage");
    ras->synProperty = pstConstruct(q931asn1GetSyntax(), (char *)"RasApplicationMessage");

    /* Create mutexes */
    RvLockConstruct(&ras->lockInHash);
    RvLockConstruct(&ras->lockOutHash);
    RvLockConstruct(&ras->lockGarbage);

    /* Set the rest of the parameters */
    ras->confNode = rasConfNode;
    ras->hVal = hVal;
    ras->hCat = hCat;

    ras->termAliasesNode = RV_PVT_INVALID_NODEID;
    ras->gatekeeperCallSignalAddress = RV_PVT_INVALID_NODEID;
    ras->gatekeeperRASAddress = RV_PVT_INVALID_NODEID;
    ras->bufferSize = maxBufSize;
    ras->isGatekeeper = isGatekeeper;
    
    /* Set the fast-decoder for first 2 fields in messages */
    status = rasDecoderInit(ras);
    if (status < 0)
        return NULL;

    return (HRASMGR)ras;
}


/************************************************************************
 * cmiRASStart
 * purpose: Start a RAS instance for use by the CM
 *          Should be called after cmiRASInitialize() and before any
 *          other function.
 * input  : hRasMgr         - RAS instance handle
 *          rasAddressNode  - RAS listening address node id
 *          startingSeqNum  - Starting sequence number to use
 * output : none

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -