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

📄 rvsdpenc.c

📁 h.248协议源码
💻 C
字号:
/******************************************************************************
Filename    :rvsdpenc.c
Description : SDP encoder
******************************************************************************
                Copyright (c) 1999 RADVision Inc.
************************************************************************
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.
******************************************************************************
$Revision:1.0$
$Date:12/20/99$
$Author:Dan Elbert$
******************************************************************************/

#include "rvsdpmsg.h"
#include "rvsdpenc.h"
#include "rvstrstream.h"



static void PrintIntSP(RvStrStream * o_str,int integer) {
	rvStrStreamWriteUInt(o_str,integer);
	rvStrStreamPut(o_str,' ');
}

static void PrintIntEOL(RvStrStream * o_str,int integer) {
	rvStrStreamWriteUInt(o_str,integer);
	rvStrStreamEndl(o_str);
}

/* Print one character into a string, returns 1 */
static void PutSDPArgument(RvStrStream * o_str,char c) {
	char arg[] = "c=";
	arg[0]=c;
	rvStrStreamWriteStrN(o_str,arg,2);
}

static void PrintStringSP(RvStrStream * o_str,const char *s) {
	rvStrStreamWriteStr(o_str,s);
	rvStrStreamPut(o_str,' ');
}

static void PrintStringEOL(RvStrStream * o_str,const char *s) {
	rvStrStreamWriteStr(o_str,s);
	rvStrStreamEndl(o_str);
}

static void EncodeSdpOrigin(RvStrStream * o_str,RvSdpMsg* sdp) {
	RvSdpOrigin * origin;
	RvStatus stat;

	/* Check if field is set */
	if( (origin=rvSdpMsgGetOrigin(sdp))==NULL )
		return;

	PutSDPArgument(o_str,'o');
	PrintStringSP(o_str,rvSdpOriginGetUsername(origin));
	PrintStringSP(o_str,rvSdpOriginGetSessionId(origin));
	PrintStringSP(o_str,rvSdpOriginGetVersion(origin));

	if(rvSdpOriginGetNetType(origin)==RV_SDPNETTYPE_UNKNOWN)
		PrintStringSP(o_str,rvSdpOriginGetNetTypeStr(origin));
	else
		PrintStringSP(o_str,rvSdpSymbolGetString(rvSdpOriginGetNetType(origin),&stat));

	if(rvSdpOriginGetAddressType(origin)==RV_SDPADDRTYPE_UNKNOWN)
		PrintStringSP(o_str,rvSdpOriginGetAddressTypeStr(origin));
	else
		PrintStringSP(o_str,rvSdpSymbolGetString(rvSdpOriginGetAddressType(origin),&stat));
	PrintStringEOL(o_str,rvSdpOriginGetAddress(origin));
	return;
}

static void EncodeSdpSessionName(RvStrStream * o_str,RvSdpMsg* sdp) {

	if( *rvSdpMsgGetSessionName(sdp)!='\0' ) {
		PutSDPArgument(o_str,'s');
		PrintStringEOL(o_str,rvSdpMsgGetSessionName(sdp));
	}
	return;
}

static void EncodeSdpInfo(RvStrStream * o_str,const char * info) {
	if( *info!='\0' ) {
		PutSDPArgument(o_str,'i');
		PrintStringEOL(o_str,info);
	}
	return;
}

static void EncodeSdpURI(RvStrStream * o_str,RvSdpMsg* sdp) {
	if( *rvSdpMsgGetURI(sdp)!='\0' ) {
		PutSDPArgument(o_str,'u');
		PrintStringEOL(o_str,rvSdpMsgGetURI(sdp));
	}
	return;
}

static void EncodeSdpEmail(RvStrStream * o_str,RvSdpMsg* sdp) {
	RvSdpEmail * email;
	const char * text;
	size_t i;

	for(i=0;i<rvSdpMsgGetNumOfEmail(sdp);i++) {
		email = rvSdpMsgGetEmail(sdp,i);
		PutSDPArgument(o_str,'e');
		rvStrStreamWriteStr(o_str,rvSdpEmailGetAddress(email));

		/* Encode free text */
		text = rvSdpEmailGetText(email);
		if(text[0]!='\0') {
			rvStrStreamPut(o_str,'(');
			rvStrStreamWriteStr(o_str,text);
			rvStrStreamPut(o_str,')');
		}
		rvStrStreamEndl(o_str);
	}
	return;
}

static void EncodeSdpPhone(RvStrStream * o_str,RvSdpMsg* sdp) {
	RvSdpPhone * phone;
	const char * text;
	size_t i;

	for(i=0;i<rvSdpMsgGetNumOfPhones(sdp);i++) {
		phone = rvSdpMsgGetPhone(sdp,i);
		PutSDPArgument(o_str,'p');
		rvStrStreamWriteStr(o_str,rvSdpPhoneGetNumber(phone));

		/* Encode free text */
		text = rvSdpPhoneGetText(phone);
		if(text[0]!='\0') {
			rvStrStreamPut(o_str,'(');
			rvStrStreamWriteStr(o_str,text);
			rvStrStreamPut(o_str,')');
		}
		rvStrStreamEndl(o_str);
	}
	return;
}

static void EncodeSdpConnection(RvStrStream * o_str,RvSdpConnection* c,RvStatus * stat) {

	if(c==NULL)
		return;
	PutSDPArgument(o_str,'c');
	if(rvSdpConnectionGetNetType(c)==RV_SDPNETTYPE_UNKNOWN)
		PrintStringSP(o_str,rvSdpConnectionGetNetTypeStr(c));
	else
		PrintStringSP(o_str,rvSdpSymbolGetString(rvSdpConnectionGetNetType(c),stat));
	if(rvSdpConnectionGetAddrType(c)==RV_SDPADDRTYPE_UNKNOWN)
		PrintStringSP(o_str,rvSdpConnectionGetAddrTypeStr(c));
	else
		PrintStringSP(o_str,rvSdpSymbolGetString(rvSdpConnectionGetAddrType(c),stat));
	rvStrStreamWriteStr(o_str,rvSdpConnectionGetAddress(c));
	if(rvSdpConnectionGetAddressTTL(c)!=RV_SDPTTL_NOTSET) {
		unsigned int num = rvSdpConnectionGetAddressNum(c);
		rvStrStreamPut(o_str,'/');
		rvStrStreamWriteUInt(o_str,rvSdpConnectionGetAddressTTL(c));
		if(num!=1) { /* Don't encode the default */
			rvStrStreamPut(o_str,'/');
			rvStrStreamWriteUInt(o_str,num);
		}
	}	
	rvStrStreamEndl(o_str);
	return;
}

static void EncodeSdpBandwidth(RvStrStream * o_str,RvSdpBandwidth* b,RvStatus * stat) {
	if(b==NULL)
		return;

	PutSDPArgument(o_str,'b');
	rvStrStreamWriteStr(o_str,rvSdpBandwidthGetType(b));
	rvStrStreamPut(o_str,':');
	PrintIntEOL(o_str,rvSdpBandwidthGetValue(b));

	return;
}

static void  EncodeSdpKey(RvStrStream * o_str,RvSdpKey* k,RvStatus * stat) {
	const char * data;

	if(k==NULL)
		return;

	PutSDPArgument(o_str,'k');
	if(rvSdpKeyGetType(k)==RV_SDPENCRMTHD_UNKNOWN)
		rvStrStreamWriteStr(o_str,rvSdpKeyGetTypeStr(k));
	else
		rvStrStreamWriteStr(o_str,rvSdpSymbolGetString(rvSdpKeyGetType(k),stat));
	data = rvSdpKeyGetData(k);
	if( data[0]!='\0' ) {
		rvStrStreamPut(o_str,':');
		rvStrStreamWriteStr(o_str,data);
	}
	rvStrStreamEndl(o_str);
	return;
}

#ifdef RV_SDPTIME_FULL
static void EncodeTypedTime(RvStrStream * o_str,RvSdpTimeUnit unit,RvUint32 time,RvStatus * stat) {
	rvStrStreamWriteUInt(o_str,time);
	if(unit!=RV_SDPTIMETYPE_SECOND)
		rvStrStreamWriteStr(o_str,rvSdpSymbolGetString(unit,stat));

	return;
}
#endif

#ifdef RV_SDPTIME_FULL
static void EncodeRepeatInterval(RvStrStream * o_str,RvSdpRepeatInterval * repeat,RvStatus * stat) {
	size_t i;

	PutSDPArgument(o_str,'r');

	/* Encode repeat interval */
	EncodeTypedTime(o_str,rvSdpRepeatIntervalGetIntervalUnits(repeat),
						  rvSdpRepeatIntervalGetIntervalTime(repeat),stat);

	rvStrStreamPut(o_str,' ');

	/* Encode duration */
	EncodeTypedTime(o_str,rvSdpRepeatIntervalGetDurationUnits(repeat),
						  rvSdpRepeatIntervalGetDurationTime(repeat),stat);

	rvStrStreamPut(o_str,' ');

	/* Encode list of offsets */
	for(i=0;i<rvSdpRepeatIntervalGetNumOfOffset(repeat);i++) {
		EncodeTypedTime(o_str,rvSdpRepeatIntervalGetOffsetUnits(repeat,i),
							  rvSdpRepeatIntervalGetOffsetTime(repeat,i),stat);
		rvStrStreamPut(o_str,' ');
	}
	/* Remove last white space */
	rvStrStreamSeekOffCur(o_str,-1);

	rvStrStreamEndl(o_str);
	return;
}
#endif

static void  EncodeSessionTime(RvStrStream * o_str,RvSdpSessionTime * time,RvStatus * stat) {
#ifdef RV_SDPTIME_FULL
	size_t i = 0;
#endif

	PutSDPArgument(o_str,'t');
	PrintIntSP(o_str,rvSdpSessionTimeGetStart(time));
	PrintIntEOL(o_str,rvSdpSessionTimeGetEnd(time));
#ifdef RV_SDPTIME_FULL
	for(i=0;i<rvSdpSessionTimeGetNumOfRepeatInterval(time);i++) 
		EncodeRepeatInterval(o_str,rvSdpSessionTimeGetRepeatInterval(time,i),stat);
#endif
	return;
}

static void  EncodeZoneAdjustment(RvStrStream * o_str,RvSdpMsg * sdp,RvStatus * stat) {
#ifdef RV_SDPTIME_FULL
	int offset;
	size_t num_adj = rvSdpMsgGetNumOfZoneAdjustments(sdp);
	RvSdpTimeZoneAdjust * adjust;
	size_t i;

	if(num_adj>0)
		PutSDPArgument(o_str,'z');
	else
		return;

	for(i=0;i<num_adj;i++) {
		adjust = rvSdpMsgGetZoneAdjustment(sdp,i);
		PrintIntSP(o_str,rvSdpTimeZoneAdjustGetTime(adjust));
		offset=rvSdpTimeZoneAdjustGetOffsetTime(adjust);
		if(offset<0) {
			rvStrStreamPut(o_str,'-');
			offset*=-1;
		}
		rvStrStreamWriteUInt(o_str,(unsigned int)offset);
		if(rvSdpTimeZoneAdjustGetOffsetUnits(adjust)!=RV_SDPTIMETYPE_SECOND)
			rvStrStreamWriteStr(o_str,rvSdpSymbolGetString(rvSdpTimeZoneAdjustGetOffsetUnits(adjust),stat));
		rvStrStreamPut(o_str,' ');
	}
	/* Delete last space */
	if(num_adj>0)
		rvStrStreamSeekOffCur(o_str,-1);

	rvStrStreamEndl(o_str);
#endif
	return;
}


static void  EncodeSdpAttr(RvStrStream * o_str,RvSdpAttribute * attr) {
	const char * attr_value;

	PutSDPArgument(o_str,'a');
	rvStrStreamWriteStr(o_str,rvSdpAttributeGetName(attr));

	attr_value = rvSdpAttributeGetValue(attr);
	if( attr_value[0]!='\0' ) {
		rvStrStreamPut(o_str,':');
		rvStrStreamWriteStr(o_str,rvSdpAttributeGetValue(attr));
	}
	rvStrStreamEndl(o_str);
	return;
}


static void  EncodeSdpRtpMap(RvStrStream * o_str,RvSdpRtpMap * rtpmap) {
	/*int channels = rvSdpRtpMapGetChannels(rtpmap);*/
	const char * enc_params = rvSdpRtpMapGetEncodingParameters(rtpmap);

	PutSDPArgument(o_str,'a');
	rvStrStreamWriteStrN(o_str,"rtpmap:",7);
	PrintIntSP(o_str,rvSdpRtpMapGetPayload(rtpmap));
	rvStrStreamWriteStr(o_str,rvSdpRtpMapGetEncodingName(rtpmap));
	rvStrStreamPut(o_str,'/');
	rvStrStreamWriteUInt(o_str,rvSdpRtpMapGetClockRate(rtpmap));

	if(strlen(enc_params)!=0) {
		rvStrStreamPut(o_str,'/');
		rvStrStreamWriteStr(o_str,enc_params);
	}

	rvStrStreamEndl(o_str);
	return;
}

static void  EncodeSdpConnectionMode(RvStrStream * o_str,RvSdpConnectionMode mode,RvStatus* stat) {
	if(mode==RV_SDPCONNECTMODE_NOTSET)
		return;

	PutSDPArgument(o_str,'a');
	PrintStringEOL(o_str,rvSdpSymbolGetString(mode,stat));
	return;
}

static void EncodeSdpMedia(RvStrStream * o_str,RvSdpMediaDescr * descr,RvStatus * stat) {
	unsigned int j=0;
	RvSdpMediaType media_type;
	size_t pos1,pos2,i;
	int port;

	pos1 = pos2 = rvStrStreamTellPos(o_str);

	/* Print media field */
	PutSDPArgument(o_str,'m');

	media_type = rvSdpMediaDescrGetMediaType(descr);

	/* Special MGCP case */
	if( media_type==RV_SDPMEDIATYPE_NAS) {
		rvStrStreamWriteStrN(o_str,"nas/",4);
		if( *rvSdpMediaDescrGetNASCtrlMethod(descr)!=0 )
			PrintStringEOL(o_str,rvSdpMediaDescrGetNASCtrlMethod(descr));
		else
			PrintStringEOL(o_str,"none");
		return;
	}

	/* Normal case,all parameters exist */
	if( media_type==RV_SDPMEDIATYPE_UNKNOWN ) {
		PrintStringSP(o_str,rvSdpMediaDescrGetMediaTypeStr(descr));
	}
	else
		PrintStringSP(o_str,rvSdpSymbolGetString(media_type,stat));
	port = rvSdpMediaDescrGetPort(descr);
	if( port!=RV_SDPPORT_NOTSET ) {
		if(port==RV_SDPPORT_ANY) /* Use for MEGACO */
			rvStrStreamPut(o_str,'$');		
		else if (port==RV_SDPPORT_IGNORE)
			rvStrStreamPut(o_str,'-');
		else if ( port == RV_SDPPORT_ATM ) {		/* ATM */
			if (rvSdpMediaDescrGetVcIdNum(descr) > 0) {
				for (i=0;i<rvSdpMediaDescrGetVcIdNum(descr);i++) {
					rvStrStreamWriteStr(o_str, 
						rvSdpSymbolGetString(rvSdpMediaDescrGetVcIdType(descr, i), stat));
					rvStrStreamPut(o_str, '-');
					rvStrStreamWriteStr(o_str, rvSdpMediaDescrGetVcIdValue(descr, i));
					rvStrStreamPut(o_str, '/');
				}
				rvStrStreamSeekOffCur(o_str,-1);
			}
		}
		else
			rvStrStreamWriteUInt(o_str,port);
		
		if( rvSdpMediaDescrGetNumOfPorts(descr)!=RV_SDPFIELD_NOTSET ) {
			rvStrStreamPut(o_str,'/');
			rvStrStreamWriteUInt(o_str,rvSdpMediaDescrGetNumOfPorts(descr));
		}
		rvStrStreamPut(o_str,' ');

		/* Encode protocol */
		if(rvSdpMediaDescrGetProtocol(descr)==RV_SDPPROTOCOL_UNKNOWN)
			PrintStringSP(o_str,rvSdpMediaDescrGetProtocolStr(descr));
		else
			PrintStringSP(o_str,rvSdpSymbolGetString(rvSdpMediaDescrGetProtocol(descr),stat));
	}

	/* print formats */
	pos2 = rvStrStreamTellPos(o_str);

	for(j=0;j<rvSdpMediaDescrGetNumOfFormats(descr);j++)
		PrintStringSP(o_str,rvSdpMediaDescrGetFormat(descr,j));

	if(rvStrStreamTellPos(o_str)>pos2 || rvStrStreamTellPos(o_str)==pos2)
		rvStrStreamSeekOffCur(o_str,-1); /* Unput last space */

	rvStrStreamEndl(o_str);

	return;
}


static void EncodeSdpMediaDescr(RvStrStream * o_str,RvSdpMediaDescr * descr,RvStatus * stat) {
	size_t i;

	/* Encode media field */
	EncodeSdpMedia(o_str,descr,stat);

	/* Encode additional fields */
	EncodeSdpInfo(o_str,rvSdpMediaDescrGetInformation(descr));
	EncodeSdpConnection(o_str,rvSdpMediaDescrGetConnection(descr),stat);
	EncodeSdpBandwidth(o_str,rvSdpMediaDescrGetBandwidth(descr),stat);
	EncodeSdpKey(o_str,rvSdpMediaDescrGetKey(descr),stat);

	for(i=0;i<rvSdpMediaDescrGetNumOfAttr(descr);i++)
		EncodeSdpAttr(o_str,rvSdpMediaDescrGetAttribute(descr,i));

	for(i=0;i<rvSdpMediaDescrGetNumOfRtpMap(descr);i++)
		EncodeSdpRtpMap(o_str,rvSdpMediaDescrGetRtpMap(descr,i));

	EncodeSdpConnectionMode(o_str,rvSdpMediaDescrGetConnectionMode(descr),stat);

	return;
}

RvBool rvSdpMsgEncode(RvSdpMsg * sdp,RvStrStream * o_str) {
	size_t i;
	RvStatus stat;

	/* Print version - always present */
	PutSDPArgument(o_str,'v');
	PrintStringEOL(o_str,rvSdpMsgGetVersion(sdp));

	EncodeSdpOrigin(o_str,sdp);
	EncodeSdpSessionName(o_str,sdp);
	EncodeSdpInfo(o_str,rvSdpMsgGetSessionInformation(sdp));
	EncodeSdpURI(o_str,sdp);
	EncodeSdpEmail(o_str,sdp);
	EncodeSdpPhone(o_str,sdp);
	EncodeSdpConnection(o_str,rvSdpMsgGetConnection(sdp),&stat);
	EncodeSdpBandwidth(o_str,rvSdpMsgGetBandwidth(sdp),&stat);

	/* Time fields*/
	for(i=0;i<rvSdpMsgGetNumOfSessionTime(sdp);i++)
		EncodeSessionTime(o_str,rvSdpMsgGetSessionTime(sdp,i),&stat);

	EncodeZoneAdjustment(o_str,sdp,&stat);

	EncodeSdpKey(o_str,rvSdpMsgGetKey(sdp),&stat);

	for(i=0;i<rvSdpMsgGetNumOfAttr(sdp);i++)
		EncodeSdpAttr(o_str,rvSdpMsgGetAttribute(sdp,i));

	for(i=0;i<rvSdpMsgGetNumOfRtpMap(sdp);i++)
		EncodeSdpRtpMap(o_str,rvSdpMsgGetRtpMap(sdp,i));

	EncodeSdpConnectionMode(o_str,rvSdpMsgGetConnectionMode(sdp),&stat);

	for(i=0;i<rvSdpMsgGetNumOfMediaDescr(sdp);i++)
		EncodeSdpMediaDescr(o_str,rvSdpMsgGetMediaDescr(sdp,i),&stat);

	/* Zero-terminate the message, but don't change the size */
	rvStrStreamEnds(o_str);
	rvStrStreamSeekOffCur(o_str,-1);

	/* return values */
	return (rvStrStreamGetStatus(o_str)==rvOk)?rvTrue:rvFalse; 
}

char * rvSdpMsgEncodeToBuf(RvSdpMsg * sdp,char * buf,int len,RvStatus * stat) {
	RvStrStream o_str;
	char * buf_ = buf;

	rvStrStreamConstructBuf(&o_str,len,buf);

	/* Encode the message */
	rvSdpMsgEncode(sdp,&o_str);

	/* Get status and encoding length */
	*stat = rvStrStreamGetStatus(&o_str);
	buf_+=rvStrStreamGetSize(&o_str);

	rvStrStreamDestruct(&o_str);

	/* Return pointer at the end of the encoding */
	return buf_;
}

⌨️ 快捷键说明

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