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

📄 transport.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 5 页
字号:
/***********************************************************************
        Copyright (c) 2002 RADVISION Ltd.
************************************************************************
NOTICE:
This document contains information that is confidential and proprietary
to RADVISION Ltd.. No part of this document may be reproduced in any
form whatsoever without written prior approval by RADVISION Ltd..

RADVISION Ltd. reserve the right to revise this publication and make
changes without obligation to notify any person of such revisions or
changes.
***********************************************************************/


/*************************************************************************************
 * Transport module
 * ----------------
 *
 * This is the module that interacts with the network on one hand, while on the other
 * it communicates with the other protocol modules, such as Q.931, H.245, H.450 etc.
 *
 * The lower level can handle TPKT, Annex E types of communications in a transparent
 * way to th eupper layers.
 *
 * The upper level exports and imports (by means of APIs and callbacks) messages to the
 * different modules: Mainly Q.931, H.245 (including tunneled messages) and the
 * rest of the tunneled protocols (Annex M, Annex L).
 *
 **************************************************************************************/
#include "rvinternal.h"
#include "transport.h"
#include "transportint.h"
#include "transnet.h"
#include "transStates.h"
#include "transutil.h"
#include "cmutils.h"
#include "ema.h"
#include "hash.h"
#include "tpkt.h"
#include "annexe.h"

#include "q931asn1.h"
#include "h245.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus*/

#define justLocal           1
#define justRemote          2



/*---------------------------------------------------------------------------------------
 * dummyControlSession :
 *
 * defines if the control session is dummy
 *
 * Input:  hsTranSession   - An handle to the created session element
 * Output: none
 * Return: 1 - if control session is DUMMY.
 *         0 - otherwise
 *---------------------------------------------------------------------------------------*/
RvBool dummyControlSession(HSTRANSSESSION hsTransSession)
{
    cmTransSession  *session    = (cmTransSession *)hsTransSession;
    int result=(RvBool)0; /* init the result as NOT dummy */

    if ((session->tunnelingState == tunnNo) ||
        (session->tunnelingState == tunnRejected))
    {
        if ((session->H245Connection) && (session->H245Connection->dummyHost))
        {
            /* We have a reported existing host (i.e. no tunneling)
            which has no TPKT object,
            i.e. it's a dummy control session that is not connnected to
            the network and thus not allowed to send messages */
            result=(RvBool)1;
        }
    }
    return result;
}


/*---------------------------------------------------------------------------------------
 * transWatchdogResourceCallback :
 *
 * this function sets the resources of transport module  at the watchdog internal table
 *
 * Input:  context - the watchdog handle of the ss instnace.
 *         resource   - the requested resource's enumeration
 *         type       - the typ eof info requested;
 *
 * Output: value - The actual resource value
 * Return: non negative value -  if success.
 *         negative value     -  if failed
 *
 *---------------------------------------------------------------------------------------*/
static int RVCALLCONV transWatchdogResourceCallback(
    IN  void*                       context,
    IN  RvUint32                    resource,
    IN  RvH323WatchdogResourceType  type,
    OUT RvUint32*                   value)
{
    cmTransGlobals* app=(cmTransGlobals*)context;
    int res = RV_ERROR_UNKNOWN;

    if (resource == app->rpoolResourceVal)
    {
        RvInt32 size, allocated, usage;
        res = rpoolStatistics(app->messagesRPool, &size, &usage, &allocated);
        if (res >= 0)
        {
            switch (type)
            {
            case RvH323WatchdogMaxVal: *value = size; break;
            case RvH323WatchdogMaxUsage: *value = usage; break;
            case RvH323WatchdogCurrent: *value = allocated; break;
            default:
                res = RV_ERROR_UNKNOWN;
            }
        }
    }
    else if (resource == app->timersResourceVal)
    {
        RvRaStatistics statistics;
        if (RvH323TimerStatistics(app->hTimers, &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;
            }
        }
    }
    else
         res = RV_ERROR_UNKNOWN;

    return res;
}


/**************************************************************************************
 * cmTransInit
 *
 * Purpose: To initialize the entire transport module
 *
 * Input:   hAppATrans              - The application handle to the entire transport module
 *          hPvt                    - The handle to the stack's PVT.
 *          selEngine               - select engine to use
 *          numOfSessions           - The maximal amount of session elemnts to allocate.
 *          numOfHostConnections    - The maximal amount of host elemnts to allocate.
 *          poolSizeInKB            - maximum amount of storage for messages before send
 *          maxMessageSize          - Maximal size of encoded message.
 *          annexESupported         - Do we support annex E.
 *          portRange               - Port range to use
 *
 * Output:  None.
 *
 * Returned value: A handle to the entire transport module
 *
 **************************************************************************************/
HAPPTRANS cmTransInit(IN HAPPATRANS      hAppATrans,
                      IN HPVT            hPvt,
                      IN RvSelectEngine* selEngine,
                      IN int             numOfSessions,
                      IN int             numOfHostConnections,
                      IN int             poolSizeInKB,
                      IN int             maxMessageSize,
                      IN RvBool          annexESupported,
                      IN RvPortRange*    portRange)
{
    annexEStatus eStat;
    int status;
    cmTransGlobals * transGlobals;

    /* Allocate global element of the module */
    if(RvMemoryAlloc(NULL, (void**)&transGlobals, sizeof(cmTransGlobals)) != RV_OK)
        return NULL;
    memset(transGlobals, 0, sizeof(cmTransGlobals));

    /* set the application handle to the module's instance */
    transGlobals->hAppATrans = hAppATrans;

    /* Allocate the global locks */
    RvMutexConstruct(&transGlobals->lockSessionsList);
    RvLockConstruct(&transGlobals->lockHash);

    /* Start the log */
    RvLogSourceConstruct(RvLogGet(), &transGlobals->hLog, RV_LOG_LIBCODE_H323, "Transport", "Transport Layer");
    RvLogSourceConstruct(RvLogGet(), &transGlobals->hTPKTCHAN, RV_LOG_LIBCODE_H323, "TPKTCHAN", "Transport message print");

    /* save pvt and io channel handles */
    transGlobals->hPvt = hPvt;

    RvLogInfo(&transGlobals->hLog,
        (&transGlobals->hLog, "Transport layer initializing with: hAppATrans=%p, hPvt=%p, numOfSessions=%d, numOfHostConnections=%d, poolSizeInKB=%d, maxMessageSize=%d",
              hAppATrans, hPvt, numOfSessions, numOfHostConnections, poolSizeInKB, maxMessageSize));

    /* Allocate reservoir of sessions */
    transGlobals->hEmaSessions =  emaConstruct( sizeof(cmTransSession),
                                                numOfSessions,
                                                emaNormalLocks,
                                                "TRANSPORT Sessions",
                                                0,
                                                transGlobals,
                                                NULL);
    if (transGlobals->hEmaSessions == NULL)
    {
        RvLogError(&transGlobals->hLog,
            (&transGlobals->hLog, "Transport layer can't allocate sessions pool."));

        /* release all */
        cmTransEnd( (HAPPTRANS)transGlobals );

        return NULL;
    }

    /* Calculate the host quantity in the case user did not provide us with one*/
    if (numOfHostConnections<0)
    {
        if (annexESupported)
            numOfHostConnections = numOfSessions * 3 + 1;
        else
            numOfHostConnections = numOfSessions * 2 + 1;
    }

    /* Allocate reservoir of hosts    */
    transGlobals->hEmaHosts = emaConstruct(sizeof(cmTransHost),
                                            numOfHostConnections,
                                            emaNormalLocks,
                                            "TRANSPORT Hosts",
                                            0,
                                            transGlobals,
                                            NULL);
    if (transGlobals->hEmaHosts == NULL)
    {
        RvLogError(&transGlobals->hLog,
            (&transGlobals->hLog, "Transport layer can't allocate hosts pool."));

        /* release all */
        cmTransEnd( (HAPPTRANS)transGlobals );

        return NULL;
    }

    status = emaAddWatchdogResource(transGlobals->hEmaSessions, cmiGetWatchdogHandle((HAPP)hAppATrans), "TransportSessions", "Transport", "Session elements");
    if (status < 0) return NULL;

    status = emaAddWatchdogResource(transGlobals->hEmaHosts, cmiGetWatchdogHandle((HAPP)hAppATrans), "TransportHosts", "Transport", "Host elements");
    if (status < 0) return NULL;


    /* build the hash table for the host by remoteAddress + type */
    transGlobals->hHashHosts = hashConstruct(   numOfHostConnections*2 + 1,
                                                numOfHostConnections,
                                                hashstr,
                                                hashDefaultCompare,
                                                sizeof_hostKey,
                                                sizeof(HSTRANSHOST),
                                                "Transport Hosts hash");

    if (transGlobals->hHashHosts == NULL)
    {
        RvLogError(&transGlobals->hLog,
            (&transGlobals->hLog, "Transport layer can't build hosts hash table."));

        /* release all */
        cmTransEnd( (HAPPTRANS)transGlobals );

        return NULL;
    }


    /* build the hash table for the sessions by CRV + host */
    transGlobals->hHashSessions = hashConstruct(numOfSessions*2 + 1,
                                                numOfSessions,
                                                hashstr,
                                                hashDefaultCompare,
                                                sizeof_sessionKey,
                                                sizeof(HSTRANSSESSION),
                                                "Transport Sessions hash");

    if (transGlobals->hHashSessions == NULL)
    {
        RvLogError(&transGlobals->hLog,
            (&transGlobals->hLog, "Transport layer can't build sessions hash table."));

        /* release all */
        cmTransEnd( (HAPPTRANS)transGlobals );

        return NULL;
    }

    /* build the rpool reservoir for outgoing messages */
    transGlobals->curUsedNumOfMessagesInRpool = 0;
    transGlobals->maxUsedNumOfMessagesInRpool = 0;

    transGlobals->messagesRPool = rpoolConstruct( TRANS_RPOOL_CHUNK_SIZE,
                                                  (poolSizeInKB * 1024)/TRANS_RPOOL_CHUNK_SIZE,
                                                  RV_TRUE,
                                                  "rPool of outgoing/tunneled messages");

    status = RvWatchdogAddResource(cmiGetWatchdogHandle((HAPP)hAppATrans), "MessagesPool", "Transport", "Transport messages pool",
        (RvWatchdogResourceCallback_T)transWatchdogResourceCallback,(void*)transGlobals, &transGlobals->rpoolResourceVal);
    if (status < 0) return NULL;

    if ((transGlobals->messagesRPool == NULL) || (status < 0))
    {
        RvLogError(&transGlobals->hLog,
            (&transGlobals->hLog, "Transport layer can't build rPool of messages."));

        /* release all */
        cmTransEnd( (HAPPTRANS)transGlobals );

        return NULL;
    }

    /* allocate the encoding buffer (the extra bytes are for TPKT header and pointer
       to next message */
    {
        RvUint8 *buffer;

        transGlobals->codingBufferSize = maxMessageSize+MSG_HEADER_SIZE+TPKT_HEADER_SIZE;
        getEncodeDecodeBuffer(transGlobals->codingBufferSize, &buffer);

        if (buffer == NULL)
        {
            RvLogError(&transGlobals->hLog,
                (&transGlobals->hLog, "Transport layer can't allocate coding buffer."));

            /* release all */
            cmTransEnd( (HAPPTRANS)transGlobals );

            return NULL;
        }
    }

⌨️ 快捷键说明

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