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

📄 rtp.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 3 页
字号:
/***********************************************************************
        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.
***********************************************************************/


#include "rvstdio.h"
#include "rvmemory.h"
#include "rvtimestamp.h"
#include "rvrandomgenerator.h"
#include "rvhost.h"
#include "rvsocket.h"
#include "rvselect.h"
#include "rvcbase.h"

#include "bitfield.h"
#include "rtputil.h"

#include "rvrtp.h"
#include "rvrtcp.h"



#ifdef __cplusplus
extern "C" {
#endif


#define BUILD_VER_NUM(_max, _min, _dot1, _dot2) \
    ((RvUint32)((_max << 24) + (_min << 16) + (_dot1 << 8) + _dot2))

#define VERSION_STR    "4.1.0.0"
#define VERSION_NUM    BUILD_VER_NUM(4, 1, 0, 0)


#define RV_RTP_MAXIPS RvUint32Const(20)


/* Internal RTP instance used. There a single such object */
typedef struct
{
    RvSelectEngine*     selectEngine; /* Select engine used */

    RvUint32            localIp; /* IP to bind to */
    RvUint32            hostIPs[RV_RTP_MAXIPS]; /* Local host IPs */
    RvUint32            timesInitialized; /* Times the RTP was initialized */

    RvRandomGenerator   randomGenerator; /* Random numbers generator to use */

} RvRtpInstance;



/* RTP instance to use */
static RvRtpInstance rvRtpInstance;



#if 1
typedef struct
{
    RvBool              isAllocated; /* RV_TRUE if the RTP package allocated this struct internally */
    RvSocket            socket; /* UDP socket used for this session */
    RvSelectFd          selectFd; /* fd object to use for non-blocking mode */
    RvUint32            sSrc;
    RvUint32            sSrcMask;
    RvUint32            sSrcPattern;
    LPRTPEVENTHANDLER   eventHandler;
    void *              context;
    RvUint16            sequenceNumber;
    RvAddress           remoteAddress; /* Remote address of this session */
    RvBool              remoteAddressSet; /* RV_TRUE if we already set the remote address */
    RvBool              useSequenceNumber;
    HRTCPSESSION        hRTCP; /* Associate RTCP session if available */
} rtpSession;       /* HRTPSESSION */
#endif



/* local functions */
static RvBool isMyIP(RvUint32 ip);
static void rtpEvent(
        IN RvSelectEngine*  selectEngine,
        IN RvSelectFd*      fd,
        IN RvSelectEvents   selectEvent,
        IN RvBool           error);



                       /* == Basic RTP Functions == */


RVAPI
RvInt32 RVCALLCONV rtpInit(void)
{
    RvStatus status;
    
    status = RvCBaseInit();
    if (status != RV_OK)
        return status;

    if (rvRtpInstance.timesInitialized == 0)
    {
        RvAddress addresses[RV_RTP_MAXIPS];
        RvUint32 numAddrs = RV_RTP_MAXIPS;
        RvUint32 i;

        /* Find the list of host addresses we have */
        status = RvHostLocalGetAddress(&numAddrs, addresses);
        if (status != RV_OK)
        {
            RvCBaseEnd();
            return status;
        }

        for (i = 0; i < numAddrs; i++)
            rvRtpInstance.hostIPs[i] = RvAddressIpv4GetIp(RvAddressGetIpv4(addresses + i));

        while (i > 0)
        {
            i--;
            RvAddressDestruct(addresses+i);
        }

        if (status != RV_OK)
        {
            RvCBaseEnd();
            return status;
        }

        /* Create a random generator */
        RvRandomGeneratorConstruct(&rvRtpInstance.randomGenerator,
            (RvRandom)(RvTimestampGet()>>8));
    }

    status = RvRtpInitSelectEngine(&rvRtpInstance.selectEngine);
    if (status != RV_OK)
    {
        RvCBaseEnd();
        return status;
    }

    rvRtpInstance.timesInitialized++;

    return RV_OK;
}


RVAPI
RvInt32 RVCALLCONV rtpInitEx(RvUint32 ip)
{
    RvInt32 rc;

    if ((rc=rtpInit()) != RV_ERROR_UNKNOWN)
        rvRtpInstance.localIp = ip;

    return rc;
}


/************************************************************************************
 * rtpSetLocalAddress
 * description: Set the local address to use for calls to rtpOpenXXX functions.
 *              This parameter overrides the value given in rtpInitEx() for all
 *              subsequent calls.
 * input: ip    - Local IP address to use
 * output: none.
 * return value: Non-negative value on success
 *               Negative value on failure
 ***********************************************************************************/
RVAPI
int RVCALLCONV rtpSetLocalAddress(IN RvUint32 ip)
{
    rvRtpInstance.localIp = ip;
    return RV_OK;
}


RVAPI
void RVCALLCONV rtpEnd(void)
{
    rvRtpInstance.timesInitialized--;

    if (rvRtpInstance.timesInitialized == 0)
    {
        RvRandomGeneratorDestruct(&rvRtpInstance.randomGenerator);
    }

    RvRtpEndSelectEngine();
    RvCBaseEnd();
}


RVAPI
int RVCALLCONV rtpGetAllocationSize(void)
{
    return sizeof(rtpSession);
}



/************************************************************************************
 * rtpOpenFrom
 * description: Opens an RTP session in the memory that the application allocated.
 * input: port        - The UDP port number to be used for the RTP session.
 *        ssrcPattern - Synchronization source Pattern value for the RTP session.
 *        ssrcMask    - Synchronization source Mask value for the RTP session.
 *        buffer      - Application allocated buffer with a value no less than the
 *                      value returned by the function rtpGetAllocationSize().
 *        bufferSize  - size of the buffer.
 * output: none.
 * return value: If no error occurs, the function returns the handle for the opened RTP
 *               session. Otherwise, it returns NULL.
 ***********************************************************************************/
RVAPI
HRTPSESSION RVCALLCONV rtpOpenFrom(
        IN  RvUint16    port,
        IN  RvUint32    ssrcPattern,
        IN  RvUint32    ssrcMask,
        IN  void*       buffer,
        IN  int         bufferSize)
{
    rtpSession *s = (rtpSession *)buffer;
    RvAddress localAddress;
    RvRandom randomValue;
    RvStatus res;

    if (bufferSize < rtpGetAllocationSize())
        return NULL;

    memset(buffer, 0 , (RvSize_t)rtpGetAllocationSize());

    /* Get a random value for the beginning sequence number */
    RvRandomGeneratorGetValue(&rvRtpInstance.randomGenerator, &randomValue);

    s->isAllocated    = RV_FALSE;
    s->sSrcPattern    = ssrcPattern;
    s->sSrcMask       = ssrcMask;
    s->sequenceNumber = (RvUint16)randomValue;

    RvAddressConstructIpv4(&localAddress, rvRtpInstance.localIp, port);

    /* Open and bind the socket */
    res = RvSocketConstruct(&s->socket, RV_ADDRESS_TYPE_IPV4, RvSocketProtocolUdp);
    if (res == RV_OK)
    {
        res = RvSocketSetBuffers(&s->socket, 8192, 8192);
        if (res == RV_OK)
            res = RvSocketSetBroadcast(&s->socket, RV_TRUE);
        if (res == RV_OK)
            res = RvSocketSetBlocking(&s->socket, RV_TRUE);
        if (res == RV_OK)
            res = RvSocketBind(&s->socket, &localAddress, NULL);

        if (res != RV_OK)
            RvSocketDestruct(&s->socket, RV_FALSE, NULL);
    }

    RvAddressDestruct(&localAddress);

    if (res == RV_OK)
    {
        rtpRegenSSRC((HRTPSESSION)s);
        return (HRTPSESSION)s;
    }
    else
    {
        return (HRTPSESSION)NULL;
    }
}


/************************************************************************************
 * rtpOpen
 * description: Opens an RTP session. The RTP Stack allocates an object and the
 *              memory needed for the RTP session. It also opens a socket and waits
 *              for packets. rtpOpen() also returns the handle of this session to
 *              the application.
 * input: port        - The UDP port number to be used for the RTP session.
 *        ssrcPattern - Synchronization source Pattern value for the RTP session.
 *        ssrcMask    - Synchronization source Mask value for the RTP session.
 * output: none.
 * return value: If no error occurs, the function returns the handle for the opened RTP
 *               session. Otherwise, it returns NULL.
 ***********************************************************************************/
RVAPI
HRTPSESSION RVCALLCONV rtpOpen(
        IN  RvUint16    port,
        IN  RvUint32    ssrcPattern,
        IN  RvUint32    ssrcMask)
{
    return rtpOpenEx(port, ssrcPattern, ssrcMask, NULL);
}

/************************************************************************************
 * rtpOpenEx
 * description: Opens an RTP session and an associated RTCP session.
 * input: port        - The UDP port number to be used for the RTP session.
 *        ssrcPattern - Synchronization source Pattern value for the RTP session.
 *        ssrcMask    - Synchronization source Mask value for the RTP session.
 *        cname       - The unique name representing the source of the RTP data.
 * output: none.
 * return value: If no error occurs, the function returns the handle for the open
 *               RTP session. Otherwise, the function returns NULL.
 ***********************************************************************************/
RVAPI
HRTPSESSION RVCALLCONV rtpOpenEx(
        IN  RvUint16    port,
        IN  RvUint32    ssrcPattern,
        IN  RvUint32    ssrcMask,
        IN  char *      cname)
{
    /* allocate rtp session.*/
    rtpSession* s;
    RvStatus res;

    res = RvMemoryAlloc(NULL, (void**)&s, (RvSize_t)rtpGetAllocationSize());
    if (res != RV_OK)
        return NULL;

    if ((rtpSession *)rtpOpenFrom(port, ssrcPattern, ssrcMask, (void*)s, rtpGetAllocationSize())==NULL)
    {
        RvMemoryFree(s);
        return NULL;
    }
    s->isAllocated=RV_TRUE;
    if (cname)
    {
        /* Open a new rtcp session.The port for an RTCP session is always
           (RTP port + 1).*/
        s->hRTCP = rtcpOpen(s->sSrc, (RvUint16)((port)?port+1:port), cname);
        if (s->hRTCP == NULL)
        {
            /* Bad RTCP - let's just kill the RTP and be done with it */
            rtpClose((HRTPSESSION)s);
            s = NULL;
        }
    }

    return (HRTPSESSION)s;
}

/************************************************************************************
 * rtpClose
 * description: Close RTP session.
 * input: hRTP - Handle of the RTP session.
 * output: none.
 * return value: If an error occurs, the function returns a negative value.
 *               If no error occurs, the function returns a non-negative value.
 ***********************************************************************************/
RVAPI
RvUint32 RVCALLCONV rtpClose(
        IN  HRTPSESSION  hRTP)
{
    rtpSession *s = (rtpSession *)hRTP;

    if (s)
    {
        if (s->hRTCP)
            rtcpClose(s->hRTCP);

        /* Send udp data through specified socket to the local host */
        rtpResume(hRTP);

        if (s->eventHandler != NULL)
        {
            /* We're probably also in non-blocking mode */
            RvSelectRemove(RvRtpGetSelectEngine(rvRtpInstance.selectEngine), &s->selectFd);
            RvFdDestruct(&s->selectFd);
        }

        /* This function closes the specified IP socket and all the socket's connections.*/

⌨️ 快捷键说明

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