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

📄 rtcp.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.
***********************************************************************/

#include "rvstdio.h"
#include "rvlock.h"
#include "rvselect.h"
#include "rvsocket.h"
#include "rvmemory.h"
#include "rvclock.h"
#include "rvntptime.h"
#include "rvtime.h"
#include "rvtimer.h"
#include "rvhost.h"
#include "rvrtpbuffer.h"
#include "bitfield.h"

#include "rtputil.h"
#include "rvrtcp.h"

#ifdef __cplusplus
extern "C" {
#endif


#define MAXSDES                   255
#define MAXRTPSESSIONS            10
#define MAXRTPSESSIONMEMBERS      50
#define MAXRTCPPACKET             1470

#define MAXIPS                    20
#define MAX_DROPOUT               3000
#define MAX_MISORDER              100
#define MIN_SEQUENTIAL            2
#define RTP_SEQ_MOD               0x10000

#define ALIGNMENT                 0x10

/* RTCP header bit locations - see the standard */
#define HEADER_V                  30      /* version                       */
#define HEADER_P                  29      /* padding                       */
#define HEADER_RC                 24      /* reception report count        */
#define HEADER_PT                 16      /* packet type                   */
#define HEADER_len                0       /* packet length in 32-bit words */

/* RTCP header bit field lengths - see the standard */
#define HDR_LEN_V                 2       /* version                       */
#define HDR_LEN_P                 1       /* padding                       */
#define HDR_LEN_RC                5       /* reception report count        */
#define HDR_LEN_PT                8       /* packet type                   */
#define HDR_LEN_len               16      /* packet length in 32-bit words */


/* used to overcome byte-allignment issues */
#define SIZEOF_RTCPHEADER         (sizeof(RvUint32) * 2)
#define SIZEOF_SR                 (sizeof(RvUint32) * 5)
#define SIZEOF_RR                 (sizeof(RvUint32) * 6)

#define SIZEOF_SDES(sdes)         (((sdes).length + 6) & 0xfc)

/* initial bit field value for RTCP headers: V=2,P=0,RC=0,PT=0,len=0 */
#define RTCP_HEADER_INIT          0x80000000

typedef enum
{
   RTCP_SR   = 200,               /* sender report            */
   RTCP_RR   = 201,               /* receiver report          */
   RTCP_SDES = 202,               /* source description items */
   RTCP_BYE  = 203,               /* end of participation     */
   RTCP_APP  = 204                /* application specific     */
} rtcpType;

typedef enum
{
   RTCP_SDES_END   = 0,
   RTCP_SDES_CNAME = 1,
   RTCP_SDES_NAME  = 2,
   RTCP_SDES_EMAIL = 3,
   RTCP_SDES_PHONE = 4,
   RTCP_SDES_LOC   = 5,
   RTCP_SDES_TOOL  = 6,
   RTCP_SDES_NOTE  = 7,
   RTCP_SDES_PRIV  = 8
} rtcpSDesType;

typedef struct
{
   RvUint64     tNNTP;
   RvUint32     tRTP;

   RvUint32     nPackets;
   RvUint32     nBytes;
} rtcpSR;

typedef struct
{
   RvUint32 ssrc;
   RvUint32 bfLost;      /* 8Bit fraction lost and 24 bit cumulative lost */
   RvUint32 nExtMaxSeq;
   RvUint32 nJitter;
   RvUint32 tLSR;
   RvUint32 tDLSR;
} rtcpRR;

typedef struct
{
   RvUint16 max_seq;               /* highest seq. number seen */
   RvUint32 cycles;                /* shifted count of seq. number cycles */
   RvUint32 base_seq;              /* base seq number */
   RvUint32 bad_seq;               /* last 'bad' seq number + 1 */
   RvUint32 probation;             /* sequ. packets till source is valid */
   RvUint32 received;              /* packets received */
   RvUint32 expected_prior;        /* packet expected at last interval */
   RvUint32 received_prior;        /* packet received at last interval */
   RvUint32 transit;               /* relative trans time for prev pkt */
   RvUint32 jitter;                /* estimated jitter */
   /* ... */
} rtpSource;

typedef struct
{
   RvUint8  type;
   RvUint8  length;
   char     value[MAXSDES + 1];     /* leave a place for an asciiz */
} rtcpSDES;

typedef struct
{
   int        invalid;
   RvBool     active;
   rtpSource  src;

   RvUint32   ssrc;
   RvUint32   tLSRmyTime;
   rtcpSR     eSR;
   rtcpRR     eToRR;
   rtcpRR     eFromRR;
   rtcpSDES   eCName;
} rtcpInfo;

typedef struct
{
   RvUint32 bits;
   RvUint32 ssrc;
} rtcpHeader;


typedef struct
{
   RvBool    active;
   int       collision;
   RvUint32  ssrc;
   RvUint32  timestamp;
   rtcpSR    eSR;
   rtcpSDES  eCName;
} rtcpMyInfo;

typedef struct
{
   RvBool               isAllocated;
   RvSocket             socket;
   RvSelectFd           selectFd;
   rtcpMyInfo           myInfo;
   RvAddress            remoteAddress;
   RvBool               remoteAddressSet;
   RvTimer              timer; /* Timer of this RTCP session */
   RvBool               isTimerSet; /* RV_TRUE if we started a timer for this session */
   rtcpInfo*            participantsArray;
   int                  sessionMembers;
   int                  maxSessionMembers;
   LPRTCPEVENTHANDLER   rtcpRecvCallback;
   void*                haRtcp;
   RvLock               lock; /* Lock of this session. Used to protect the session members */
} rtcpSession;



#define RV_RTCP_MAXIPS RvUint32Const(20)



/* Internal RTCP instance used. There a single such object */
typedef struct
{
    RvSelectEngine*     selectEngine; /* select engine used for RTP/RTCP messages */

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

    RvTimerQueue*       timersQueue; /* Timers queue to use */

} RvRtcpInstance;



/* RTCP instance to use */
static RvRtcpInstance rvRtcpInstance;




#define reduceNNTP(a) (RvUint32)((a >> 16) && 0xffffffff)

#define W32Len(l)  ((l + 3) / 4)  /* length in 32-bit words */


/* local functions */
static RvUint64 getNNTPTime(void);
static RvBool rtcpTimerCallback(IN void* key);
static RvBool isMyIP(RvUint32 ip);
static void   setSDES(rtcpSDesType type, rtcpSDES* sdes, RvUint8 *data,
                      int length);
static void   init_seq  (rtpSource *s, RvUint16 seq);
static int    update_seq(rtpSource *s, RvUint16 seq, RvUint32 ts, RvUint32 arrival);

static RvUint32 getLost    (rtpSource *s);
static RvUint32 getJitter  (rtpSource *s);
static RvUint32 getSequence(rtpSource *s);
/*h.e 30.05.01*/
static RvUint32 getSSRCfrom(RvUint8 *);
/*===*/

static rtcpHeader makeHeader(RvUint32 ssrc, RvUint8 count, rtcpType type,
                             RvUint16 dataLen);

static rtcpInfo * findSSrc(rtcpSession *,RvUint32);

static rtcpInfo *insertNewSSRC(rtcpSession *s, RvUint32 ssrc);

static void rtcpEventCallback(
        IN RvSelectEngine*  selectEngine,
        IN RvSelectFd*      fd,
        IN RvSelectEvents   selectEvent,
        IN RvBool           error);



RVAPI
RvInt32 RVCALLCONV rtcpProcessCompoundRTCPPacket(
        IN      HRTCPSESSION  hRTCP,
        IN OUT  RvRtpBuffer*  buf,
        IN      RvUint64      myTime);


RVAPI
RvInt32 RVCALLCONV rtcpProcessRTCPPacket(
        IN  rtcpSession *  s,
        IN  RvUint8 *      data,
        IN  RvInt32        dataLen,
        IN  rtcpType       type,
        IN  RvInt32        reportCount,
        IN  RvUint64       myTime);




                      /* == Basic RTCP Functions == */


/*=========================================================================**
**  == rtcpInit() ==                                                       **
**                                                                         **
**  Initializes the RTCP module.                                           **
**                                                                         **
**  RETURNS:                                                               **
**      A non-negative value upon success, or a negative integer error     **
**      code.                                                              **
**                                                                         **
**=========================================================================*/

RVAPI
RvInt32 RVCALLCONV rtcpInit(void)
{
    RvStatus status;

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

    /* Construct a pool of timers to use */
    status = RvRtpInitTimerQueue(&rvRtcpInstance.timersQueue);
    if (status != RV_OK)
    {
        RvRtpEndSelectEngine();
        RvCBaseEnd();
        return ERR_RTCP_GENERALERROR;
    }

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

        rvRtcpInstance.localIp = 0;

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

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

    rvRtcpInstance.timesInitialized++;

    return RV_OK;
}


/*=========================================================================**
**  == rtcpInitEx() ==                                                     **
**                                                                         **
**  Initializes the RTCP module.                                           **
**  Parameter: ip - ip address to 'bind' RTCP session                      **
**                                                                         **
**  RETURNS:                                                               **
**      A non-negative value upon success, or a negative integer error     **
**      code.                                                              **
**                                                                         **
**=========================================================================*/

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

    if ((rc=rtcpInit()) >= 0)
    {
        rvRtcpInstance.localIp = ip;
    }

    return rc;
}

/*=========================================================================**
**  == rtcpEnd() ==                                                        **
**                                                                         **
**  Shuts down the RTCP module.                                            **
**                                                                         **
**  RETURNS:                                                               **
**      A non-negative value upon success, or a negative integer error     **

⌨️ 快捷键说明

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