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

📄 rasout.c

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

/*

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 "cmdebprn.h"
#include "rasutils.h"
#include "rasparams.h"
#include "rasout.h"

#ifdef __cplusplus
extern "C" {
#endif

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


/************************************************************************
 * rasTimeoutEvent
 * purpose: Callback function that is called when the timeout expires
 *          on an outgoing transaction message, making sure that a
 *          retransmission on this transaction will occur if necessary.
 * input  : context - Context to use
 *                    This is the outgoing transaction object
 * output : none
 * return : none
 ************************************************************************/
RvBool rasTimeoutEvent(IN void* context)
{
    rasModule*          ras;
    rasOutTx*           tx = (rasOutTx *)context;
    HRPOOLELEM          message;
    int                 retryCount;
    RvTimer*            timer = NULL;
    RvBool              cont = RV_TRUE;

    /* Lock the transaction so no one will close it */
	
    /* 2004.09.07. added to avoid exception. */
    if (tx == NULL)
    {
        printf("rasTimeoutEvent(): tx == NULL, return\n");
        return cont;
    }
    
    if (emaLock((EMAElement)tx))
    {
        /* This element exists... */
        ras = (rasModule *)emaGetUserData((EMAElement)tx);

	/* 2004.09.07. added to avoid exception. */
        if (ras == NULL || ras->app == NULL)
        {
            printf("rasTimeoutEvent(): ras == NULL || ras->app == NULL, return\n");
	     emaUnlock((EMAElement)tx);
            return cont;
        }

        cmCallPreCallBack((HAPP)ras->app);

        RvLogDebug(&ras->log,
            (&ras->log, "rasTimeoutEvent: On outTx=0x%p, retries=%d", tx, tx->retryCount));

        /* Decrease the retry count */
        tx->retryCount--;
        if (tx->retryCount == 0)
        {
            tx->state = rasTxStateTimedOut;
            timer = tx->timer;
            tx->timer = NULL;
        }

        /* Make sure we've got all the necessary parameters */
        retryCount = tx->retryCount;
        message = tx->encodedMsg;

        if (retryCount == 0)
        {
            /* Transaction has timed out */
            cmiEvRASResponseT   evResponse;

            /* Stop the timer - we don't need it anymore */
            RvH323TimerClear(ras->timers, &timer);
            cont = RV_FALSE;

            evResponse = tx->evResponse;

            /* Unlock it before we're done */
            emaMark((EMAElement)tx);
            emaUnlock((EMAElement)tx);

            /* See which of the response callbacks we have to call */
            if (evResponse != NULL)
            {
                if (ras->evAutoRas.cmEvAutoRASTimeout != NULL)
                {
                    cmiCBEnter(ras->app, "cmEvAutoRASTimeout(hsRas=0x%p)", tx);
                    ras->evAutoRas.cmEvAutoRASTimeout((HRAS)tx);
                    cmiCBExit(ras->app, "cmEvAutoRASTimeout(hsRas=0x%p)", tx);
                }

                if (!emaWasDeleted((EMAElement)tx))
                    evResponse((HAPPRAS)emaGetApplicationHandle((EMAElement)tx), (HRAS)tx, cmRASTrStageTimeout);
            }
            else if (ras->evApp.cmEvRASTimeout != NULL)
            {
                HAPPRAS haRas = (HAPPRAS)emaGetApplicationHandle((EMAElement)tx);
                cmiCBEnter(ras->app, "cmEvRASTimeout(haRas=0x%p,hsRas=0x%p)", haRas, tx);
                ras->evApp.cmEvRASTimeout(haRas, (HRAS)tx);
                cmiCBExit(ras->app, "cmEvRASTimeout(haRas=0x%p,hsRas=0x%p)", haRas, tx);
            }

            emaRelease((EMAElement)tx);
        }
        else if (message != NULL)
        {
            /* Retransmit */

            if (tx->state == rasTxStateRipReceived)
            {
                RvInt32 timeout;

                /* Reset the timer for regular intervals after RIP */
                RvH323TimerClear(ras->timers, &tx->timer);
                cont = RV_FALSE;
                timeout = rasCfgGetTimeout(ras) * 1000;
                tx->timer = RvH323TimerStart(ras->timers, rasTimeoutEvent, tx, timeout);
            }

            /* Send the message */
            rasRetransmit(ras, (HRAS)tx, message, &tx->destAddress, "request");

            /* Unlock it before we're done */
            emaUnlock((EMAElement)tx);
        }
	else
	{
		emaUnlock((EMAElement)tx);
	}
    }
    return cont;
}


/************************************************************************
 * rasHandleIncomingRIP
 * purpose: Handle an incoming RIP on an outgoing request
 * input  : ras             - RAS module to use
 *          tx              - Outgoing transaction we're dealing with
 *          messageNodeId   - Node ID of the RIP message
 * output : none
 * return : Non-negative value on success
 *          Negative value on failure
 ************************************************************************/
int rasHandleIncomingRIP(
    IN rasModule*   ras,
    IN rasOutTx*    tx,
    IN int          messageNodeId)
{
    int nodeId;
    RvInt32 delay; /* in ms */

    /* Make sure we're not in a multicast transaction */
    if (!tx->isMulticast)
    {
        /* Find the timeout */
        __pvtGetByFieldIds(nodeId, ras->hVal, messageNodeId, {_anyField _q931(delay) LAST_TOKEN}, NULL, &delay, NULL);

        /* Set the timeout to its new value */
        RvH323TimerCancel(ras->timers, &tx->timer);
        tx->timer = RvH323TimerStart(ras->timers, rasTimeoutEvent, tx, delay);
        tx->state = rasTxStateRipReceived;
    }
    else
    {
        RvLogWarning(&ras->log,
            (&ras->log, "rasHandleIncomingRIP: outTx=0x%p is multicast. Ignoring RIP message"));
    }

    /* Delete the message and return */
    pvtDelete(ras->hVal, messageNodeId);
    return 0;
}






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


/************************************************************************
 * rasOutgoingHashFunc
 * purpose: Outgoing transactions hash function
 *          This function returns as the hash key the actual sequence
 *          number of the transaction without fooling around with it
 * input  : param       - Parameter we're going to hash
 *                        This time it's a RvUint32 of the sequence number
 *          paramSize   - Size of the parameter (4 here)
 *          hashSize    - Size of the hash table itself
 * output : none
 * return : Hash value to use
 ************************************************************************/
RvUint32 rasOutgoingHashFunc(
    IN void *param,
    IN int paramSize,
    IN int hashSize)
{
    if (paramSize);
    return ((*(RvUint32*)param) % hashSize);
}





/************************************************************************
 * rasCreateOutTx
 * purpose: Create an outgoing transaction and return its pointer
 * input  : ras         - RAS module to use
 *          haRas       - Application's handle for the RAS transaction
 *          transaction - The transaction type we want to start
 *          destAddress - Address of the destination.
 *                        If set to NULL, then it's for the gatekeeper
 * output : none
 * return : Pointer to an outgoing RAS transaction on success
 *          NULL on failure
 ************************************************************************/
rasOutTx* rasCreateOutTx(
    IN rasModule*       ras,
    IN HAPPRAS          haRas,
    IN cmRASTransaction transaction,
    IN cmRASTransport*  destAddress)
{
    rasOutTx*   tx;
    int         srcNodeId, requestNode;
    int         status; /* = 0 if no errors occured */

    /* Make sure we're working with outgoing transactions */
    if (ras->outRa == NULL)
        return NULL;

    /* Create the RAS transaction */
    tx = (rasOutTx *)emaAdd(ras->outRa, (void*)haRas);
    if (tx == NULL)
        return NULL;
    memset(tx, 0, sizeof(rasOutTx));

    /* Grab a node as root for the property db */
    tx->txProperty = pvtAddRoot(ras->hVal, ras->synProperty, 0, NULL);
    if (!RV_PVT_NODEID_IS_VALID(tx->txProperty))
    {
        emaDelete(tx);
        return NULL;
    }

    /* Set some of the transaction's values */
    tx->isMulticast     = RV_FALSE;
    tx->transactionType = transaction;
    tx->state           = rasTxStateIdle;
    tx->timer           = NULL;

    /* Set the destination address for the transaction */
    status = pvtAdd(ras->hVal, tx->txProperty, __q931(address), 0, NULL, NULL);
    if ((destAddress == NULL) && (status >= 0))
    {

⌨️ 快捷键说明

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