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

📄 rtp.c

📁 h.248协议源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef __cplusplus
extern "C" {
#endif



/*

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.

*/ 


/****************************************************************************
  
  rtp.c  --  RTP implementation.

  This Comment:   16-Mar-1997
  Module Authors: Sasha Ruditsky, Oz Solomonovich

  Abstract:       The main RTP module file.  

  Platforms:      All.
  
  Known Bugs:     None.

****************************************************************************/

#include <stdlib.h>
#include <string.h>
#include "rvcore.h"
#include "rvmem.h"
#include "rvtime.h"
#include "rvdefalloc.h"
#include "rvinet.h"
#include "rvhost.h"
#include "rvsocket.h"
#include "rvsocketaddr.h"

#ifdef _ATM_
#include "rvatm.h"
#endif

#include "bitfield.h"
#ifdef _ATM_
#include "liatm.h"
#endif

#include "rtpstd.h"
#include "rtputil.h"
#include "rtp.h"
#include "rtcp.h"
#ifdef _ATM_
#include "rtpatm.h"
#endif


#define BUILD_VER_NUM(major, minor, dot1, dot2) \
    ((RvUint32)((major << 24) + (minor << 16) + (dot1 << 8) + dot2))

#define VERSION_STR    "2.2.0.3"
#define VERSION_NUM    BUILD_VER_NUM(2, 2, 0, 3)

static rtpEngine* rtpDefaultEngine = NULL;
static RvHost host;
#ifdef _MTS_
static unsigned int seed;
#endif

static RvBool isMyIP(RvSocketAddr* addr)
{
    size_t i;

    for (i=0; i < rvHostGetNumOfAddrs(&host); i++)
    {
        if (rvIpv4AddrToUint32(rvSocketAddrGetIpv4Addr(addr)) == 
			rvIpv4AddrToUint32(rvHostGetIpv4Addr(&host, i)))
            return rvTrue;
    }

    return rvFalse;
}

                       /* == Basic RTP Functions == */

RVVXDAPI
RvInt32 VXDCALLCONV rtpInit(void)
{
	RvTimespec t;

	rvCoreInit();
	rvTimeGetEpochTime(&t);
    rvHostConstructLocal(&host);

#ifdef _MTS_
    seed = (unsigned)(rvTimespecSecs(&t) * rvTimespecNsecs(&t)) * rvIpv4AddrToUint32(rvHostGetIpv4Addr(&host, 0));
#else
	srand((unsigned)(rvTimespecSecs(&t) * rvTimespecNsecs(&t)) * rvIpv4AddrToUint32(rvHostGetIpv4Addr(&host, 0)));
#endif

    return 0;
}

RVVXDAPI
RvInt32 VXDCALLCONV rtpInitEx(RvUint32 ip)
{
	RvTimespec t;

	rvCoreInit();
	rvTimeGetEpochTime(&t);
	rvHostConstructIpv4(&host, (RvIpv4Addr*)&ip);

#ifdef _MTS_
    seed = (unsigned)(rvTimespecSecs(&t) * (rvTimespecNsecs(&t) + 1)) * rvIpv4AddrToUint32(rvHostGetIpv4Addr(&host, 0));
#else
	srand((unsigned)(rvTimespecSecs(&t) * (rvTimespecNsecs(&t) + 1)) * rvIpv4AddrToUint32(rvHostGetIpv4Addr(&host, 0)));
#endif

    return 0;
}

RVVXDAPI
void VXDCALLCONV rtpEnd(void)
{
	rvHostDestruct(&host);
	rvCoreEnd();
}

static void rtpReceive_(RvSocketSelect* ss, RvSocketListener* sl, void* data) {
	rtpSession* s = (rtpSession*)data;
	rvMutexLock(&s->mutex);
	if (s->eventHandler)
		s->eventHandler((HRTPSESSION)s, s->context);
	rvMutexUnlock(&s->mutex);
}

RVVXDAPI
rtpEngine* VXDCALLCONV rtpEngineConstruct(rtpEngine* engine, RvPriority priority)
{
	rvSocketEngineConstruct(engine, rvPriorityGetValue(&priority), &rvDefaultAlloc);
	rtpDefaultEngine = engine;
	rvSocketEngineStart(engine);
	return engine;
}

RVVXDAPI
void VXDCALLCONV rtpEngineDestruct(rtpEngine* engine) {
	rvSocketEngineDestruct(engine);
}

RVVXDAPI
int VXDCALLCONV rtpGetAllocationSize(void)
{
    return sizeof(rtpSession);
}

RVVXDAPI
HRTPSESSION VXDCALLCONV rtpOpenFrom(
        IN  RvUint16  port,
        IN  RvUint32  ssrcPattern,
        IN  RvUint32  ssrcMask,
	IN  void*   buffer,
	IN  int	    bufferSize)
{
    rtpSession *s = (rtpSession *)buffer;

    if (bufferSize < rtpGetAllocationSize())
		return NULL;
    
    memset(buffer, 0 , rtpGetAllocationSize());

    s->isAllocated		= rvFalse;
    s->sSrcPattern		= ssrcPattern;
    s->sSrcMask			= ssrcMask;
    s->sequenceNumber	= (RvUint16)0;
	s->eventHandler		= NULL;
	s->engine			= NULL;

#ifdef _MTS_
      rand_r(&seed);
#else
      rand();
#endif
	rvMutexConstruct(&s->mutex);

	/* If only one local interface bind to it, otherwise bind to "any" */
	if (rvHostGetNumOfAddrs(&host) == 1) {
		RvSocketAddr sa;
		rvSocketAddrConstructInet(&sa, &host, 0, port);
		rvSocketConstructUdpEx(&s->socket, &sa);
	} else {
		if(port == 0) {
			rvSocketConstructUdpAnyPort(&s->socket); /* assign a port now */
		} else rvSocketConstructUdp(&s->socket, port);
	}
	
    rtpRegenSSRC((HRTPSESSION)s); 

	rvSocketListenerConstruct(&s->listener, &s->socket, rtpReceive_, s);

    return (HRTPSESSION)s;
}

RVVXDAPI
HRTPSESSION VXDCALLCONV rtpOpen(
        IN  RvUint16  port,
        IN  RvUint32  ssrcPattern,
        IN  RvUint32  ssrcMask)
{
    return rtpOpenEx(port, ssrcPattern, ssrcMask, NULL);
}


RVVXDAPI
HRTPSESSION VXDCALLCONV rtpOpenEx(
        IN  RvUint16  port,
        IN  RvUint32  ssrcPattern,
        IN  RvUint32  ssrcMask,
        IN  char *  cname)
{
    rtpSession *s = (rtpSession*)rvMemAlloc(rtpGetAllocationSize());

    if (s==NULL) return NULL;
	memset(s, 0, rtpGetAllocationSize());

    if ((rtpSession *)rtpOpenFrom(port, ssrcPattern, ssrcMask, (void*)s, rtpGetAllocationSize())==NULL) 
    {
	rvMemFree(s);
	return NULL;
    }
    s->isAllocated=rvTrue;
    if (cname)
    {   
        s->hRTCP = rtcpOpen(s->sSrc, (RvUint16)((port)?port+1:port), cname);
    }

    return (HRTPSESSION)s;
}

RVVXDAPI
RvUint32 VXDCALLCONV rtpClose(
        IN  HRTPSESSION  hRTP)
{
    rtpSession *s = (rtpSession *)hRTP;

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

	if (s->engine)
		rvSocketEngineUnregisterListener(s->engine, &s->listener);
	rvSocketListenerDestruct(&s->listener);

#if 0
	{
		RvHost h;
		RvSocketAddr toAddr;
		rvHostConstruct(&h, "127.0.0.1");
		rvSocketAddrConstructInet(&toAddr, &h, 0, rvSocketGetPort(&s->socket));
		rvSocketSendTo(&s->socket, (RvUint8*)"", 1, &toAddr);
	}
#endif
    
	rvSocketDestruct(&s->socket);
	rvMutexDestruct(&s->mutex);

	if (s->isAllocated)
		rvMemFree(s);

    return 0;
}


RVVXDAPI
RvUint32 VXDCALLCONV rtpGetSSRC(
        IN  HRTPSESSION  hRTP)
{
    rtpSession *s = (rtpSession *)hRTP;

    return s->sSrc;
}

RVVXDAPI
void VXDCALLCONV rtpSetEventHandlerEx(
        IN  HRTPSESSION			hRTP,
		IN	rtpEngine*			engine, 
        IN  LPRTPEVENTHANDLER	eventHandler,
        IN  void*				context)
{
    rtpSession *s = (rtpSession *)hRTP;

    if (s)
    {
		rvMutexLock(&s->mutex);
        s->eventHandler = eventHandler;
        s->context      = context;
		if (engine != NULL) {
			s->engine = engine;
			rvSocketEngineRegisterListener(s->engine, &s->listener);
		}
		rvMutexUnlock(&s->mutex);
    }
}

RVVXDAPI
void VXDCALLCONV rtpSetEventHandler(
        IN  HRTPSESSION			hRTP,
        IN  LPRTPEVENTHANDLER	eventHandler,
        IN  void*				context)
{
	rtpSetEventHandlerEx(hRTP, rtpDefaultEngine, eventHandler, context);
}

RVVXDAPI
void VXDCALLCONV rtpSetRemoteAddress(
        IN HRTPSESSION  hRTP,	/* RTP Session Opaque Handle */
        IN RvUint32       ip,
        IN RvUint16       port)
{
    rtpSession *s = (rtpSession *)hRTP;

	rvMutexLock(&s->mutex);
    s->ip   = ip;
    s->port = port;
	rvMutexUnlock(&s->mutex);
}


RVVXDAPI
RvInt32 VXDCALLCONV rtpWrite(
        IN  HRTPSESSION  hRTP,
        IN  void *       buf,
        IN  RvInt32        len,
        IN  rtpParam *   p)
{
    int retVal;
	RvIpv4Addr ipv4;
	RvSocketAddr toAddr;
    rtpSession *s = (rtpSession *)hRTP;
    RvUint32 *header=(RvUint32*)((char*)buf+p->sByte-12);

	rvMutexLock(&s->mutex);
	rvIpv4AddrConstruct(&ipv4, s->ip);
	rvSocketAddrConstructIpv4(&toAddr, &ipv4, s->port);

    if (s->useSequenceNumber)
        s->sequenceNumber=p->sequenceNumber;
    p->sequenceNumber=s->sequenceNumber;

    header[0]=0;
    header[0]=bitfieldSet(header[0],2,30,2);	
    header[0]=bitfieldSet(header[0],p->marker,23,1);	
    header[0]=bitfieldSet(header[0],p->payload,16,7);	
    header[0]=bitfieldSet(header[0],s->sequenceNumber++,0,16);	
    header[1]=p->timestamp;
    header[2]=s->sSrc;
    p->len=len-p->sByte;
	       
	ConvertToNetwork(header,0,3);
	retVal = rvSocketSendTo(&s->socket, (RvUint8*)header, 
                       len-((char*)header-(char*)buf), &toAddr);

    if (s->hRTCP  &&  retVal)
    {
        rtcpRTPPacketSent(s->hRTCP, p->len, p->timestamp);
    }

	rvMutexUnlock(&s->mutex);
    return retVal;
}


RVVXDAPI
RvInt32 VXDCALLCONV rtpRead(
        IN  HRTPSESSION  hRTP,
        IN  void *buf,
        IN  RvInt32 len,
        OUT rtpParam* p)
{
    rtpSession *s = (rtpSession *)hRTP;
	RvSocketAddr fromAddr;
    RvUint32 *header=(RvUint32*)buf;
        
	p->len=rvSocketRecvFrom(&s->socket,(unsigned char*)buf,len,&fromAddr);
	if (p->len <= 0)
		return p->len;
	rvMutexLock(&s->mutex);
    ConvertFromNetwork(buf,0,3);
    if((isMyIP(&fromAddr) && s->sSrc==((RvUint32*)buf)[2]) || p->len == -1 || p->len < 12)
	{ 
		rvMutexUnlock(&s->mutex); 
		return (-1); 
	}
    
    ConvertFromNetwork(buf,3,bitfieldGet(header[0],24,4));
    p->timestamp=header[1];
    p->sequenceNumber=(RvUint16)bitfieldGet(header[0],0,16);
    p->sSrc=header[2];
    p->marker=bitfieldGet(header[0],23,1);
    p->payload=(unsigned char)bitfieldGet(header[0],16,7);
    
    p->sByte=12+bitfieldGet(header[0],24,4)*sizeof(RvUint32);
    if (bitfieldGet(header[0],28,1))/*Extension Bit Set*/
    {
        int xStart=p->sByte/sizeof(RvUint32);
        ConvertFromNetwork(buf,xStart,1);
        ConvertFromNetwork(buf,xStart+1,bitfieldGet(header[xStart],0,16));
        p->sByte+=bitfieldGet(header[xStart],0,16)*sizeof(RvUint32);
    }
	if (bitfieldGet(header[0],29,1))/*Padding Bit Set*/
    {
		p->len-=((char*)buf)[p->len-1];
    }
	rvMutexUnlock(&s->mutex);
    return 0;
}

RVVXDAPI
RvInt32 VXDCALLCONV rtpReadEx(
        IN  HRTPSESSION  hRTP,
        IN  void *       buf,
        IN  RvInt32        len,
        IN  RvUint32       timestamp,
        OUT rtpParam *   p)
{
    rtpSession *s = (rtpSession *)hRTP;
    int retVal;
	rvMutexLock(&s->mutex);

    retVal = rtpRead(hRTP, buf, len, p);

    if (s->hRTCP  &&  retVal >= 0)
    {
        rtcpRTPPacketRecv(s->hRTCP, p->sSrc, timestamp,  p->timestamp, p->sequenceNumber);
    }

	rvMutexUnlock(&s->mutex);
    return retVal;
}



RVVXDAPI
RvUint16 VXDCALLCONV rtpGetPort(
        IN HRTPSESSION  hRTP)	/* RTP Session Opaque Handle */
{
	RvUint16 port;
    rtpSession *s = (rtpSession *)hRTP;
	rvMutexLock(&s->mutex);
	port = rvSocketGetPort(&s->socket);
	rvMutexUnlock(&s->mutex);
	return port;
}

RVVXDAPI
char * VXDCALLCONV rtpGetVersion(void)
{
    return (char*)VERSION_STR;
}

RVVXDAPI
RvUint32 VXDCALLCONV rtpGetVersionNum(void)
{
    return VERSION_NUM;
}


                    /* == ENDS: Basic RTP Functions == */



                     /* == Accessory RTP Functions == */


RVVXDAPI
HRTCPSESSION VXDCALLCONV rtpGetRTCPSession(

⌨️ 快捷键说明

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