📄 rvsdpenc.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 + -