📄 rvsdpprsaux.c
字号:
/******************************************************************************
Filename :rvsdpprsaux.c
Description :SDP parser auxiliary (reduction) functions
******************************************************************************
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:7/18/99$
$Author:Dan Elbert$
******************************************************************************/
#include <stdio.h>
#include <ctype.h>
#include "rvsdpprsaux.h"
#include "rvlog.h"
#include "rvsdpprs.h"
/* Perform a case-insensitive comparison */
/* Return 0 if strings are equal,one otherwise */
/* Stop after n characters or when first string ends */
static RvBool StrIEqualN(const char *str1, const char *str2,int s2len) {
while (s2len && *str1) {
if (toupper(*str1) != toupper(*str2) )
return rvFalse;
str1++;
str2++;
s2len--;
}
if (*str1 == 0 && s2len==0 )
return rvTrue;
return rvFalse;
}
/* Internal prototypes */
void rvSdpParserStateConstruct(RvSdpParserState_ * state,char * buf,RvSdpMsg * sdp, RvAlloc *a);
void rvSdpParseAuxAddSessionTime(RvSdpParserState_ * state,RvUint32 start,RvUint32 stop) {
state->cur_session_time = rvSdpMsgAddSessionTime(state->cur_sdp,start,stop);
}
void rvSdpParseAuxAddSessionRepeatField(RvSdpParserState_ * state,RvSdpTypedTime time) {
state->cur_typed_time.time = time.time;
state->cur_typed_time.type = time.type;
}
void rvSdpParseAuxSetRepeatActiveDuration(RvSdpParserState_ * state,RvSdpTypedTime time) {
state->cur_repeat = rvSdpSessionTimeAddRepeatInterval(state->cur_session_time,
state->cur_typed_time.time,state->cur_typed_time.type,
time.time,time.type);
}
void rvSdpParseAuxAddRepeatOffset(RvSdpParserState_ * state,RvSdpTypedTime time){
rvSdpRepeatIntervalAddOffset(state->cur_repeat,time.time,time.type);
}
void rvSdpParseAuxAddZoneAdjustment(RvSdpParserState_ * state,RvUint32 time,RvInt32 offset_time,RvSdpTimeUnit offset_units) {
rvSdpMsgTimeAddZoneAdjustment(state->cur_sdp,time,offset_time,offset_units);
}
static RvSdpMediaType GetMediaType(const char * media,int len) {
if(StrIEqualN("audio",media,len)) return RV_SDPMEDIATYPE_AUDIO;
if(StrIEqualN("video",media,len)) return RV_SDPMEDIATYPE_VIDEO;
if(StrIEqualN("application",media,len)) return RV_SDPMEDIATYPE_APP;
if(StrIEqualN("data",media,len)) return RV_SDPMEDIATYPE_DATA;
if(StrIEqualN("image",media,len)) return RV_SDPMEDIATYPE_IMAGE;
if(StrIEqualN("control",media,len)) return RV_SDPMEDIATYPE_CONTROL;
return RV_SDPMEDIATYPE_UNKNOWN;
}
static RvSdpProtocol GetProtocolType(const char * proto,int len) {
if(StrIEqualN("RTP/AVP",proto,len)) return RV_SDPPROTOCOL_RTP;
if(StrIEqualN("LOCAL",proto,len)) return RV_SDPPROTOCOL_LOCAL;
if(StrIEqualN("ATM/AVP",proto,len)) return RV_SDPPROTOCOL_ATM;
if(StrIEqualN("UDP",proto,len)) return RV_SDPPROTOCOL_UDP;
if(StrIEqualN("udp t38",proto,len)) return RV_SDPPROTOCOL_UDP_T38;
/* Transport */
if(StrIEqualN("AAL1/ATMF",proto,len)) return RV_SDPPROTOCOL_AAL1ATMF;
if(StrIEqualN("AAL1/ITU",proto,len)) return RV_SDPPROTOCOL_AAL1ITU;
if(StrIEqualN("AAL1/custom",proto,len)) return RV_SDPPROTOCOL_AAL1CUSTOM;
if(StrIEqualN("AAL2/ATMF",proto,len)) return RV_SDPPROTOCOL_AAL2ATMF;
if(StrIEqualN("AAL2/ITU",proto,len)) return RV_SDPPROTOCOL_AAL2ITU;
if(StrIEqualN("AAL2/custom",proto,len)) return RV_SDPPROTOCOL_AAL2CUSTOM;
if(StrIEqualN("AAL5/ATMF",proto,len)) return RV_SDPPROTOCOL_AAL5ATMF;
if(StrIEqualN("AAL5/ITU",proto,len)) return RV_SDPPROTOCOL_AAL5ITU;
if(StrIEqualN("AAL5/custom",proto,len)) return RV_SDPPROTOCOL_AAL5CUSTOM;
if(StrIEqualN("H323c",proto,len)) return RV_SDPPROTOCOL_H323C;
return RV_SDPPROTOCOL_UNKNOWN;
}
static void rvSdpParseAuxAddSdpMedia_(RvSdpParserState_ * state,RvSdpMediaType media_type,int port,int subport,RvSdpProtocol protocol) {
state->cur_media_descr = rvSdpMsgAddMediaDescr(state->cur_sdp,media_type,(int)port,protocol);
state->cur_sdp_fields = &state->cur_media_descr->fields;
rvSdpMediaDescrSetNumOfPorts(state->cur_media_descr,subport);
}
void rvSdpParseAuxAddSdpMedia(RvSdpParserState_ * state,RvpStrPtrN media,int port,int subport,RvpStrPtrN proto) {
RvSdpProtocol protocol = GetProtocolType(proto.buf,proto.len);
RvSdpMediaType media_type = GetMediaType(media.buf,media.len);
rvSdpParseAuxAddSdpMedia_(state,media_type,port,subport,protocol);
if(media_type==RV_SDPMEDIATYPE_UNKNOWN)
rvSdpMediaDescrSetMediaTypeStrN(state->cur_media_descr,media.buf,media.len);
if(protocol==RV_SDPPROTOCOL_UNKNOWN)
rvSdpMediaDescrSetProtocolStrN(state->cur_media_descr,proto.buf,proto.len);
/* ATM */
rvSdpParserAuxSetVcIdN(state);
}
void rvSdpParseAuxAddSdpMediaNAS(RvSdpParserState_ * state,int port,int subport,char * access_method,size_t len) {
rvSdpParseAuxAddSdpMedia_(state,RV_SDPMEDIATYPE_NAS,(int)port,subport,(RvSdpProtocol)RV_SDPFIELD_NOTSET);
rvSdpParserAuxSetDescrCtrlMethodN(state,access_method,len);
}
void rvSdpParserAuxSetDescrCtrlMethodN(RvSdpParserState_ * state,const char* cm,size_t len) {
rvSdpMediaDescrSetCtrlMethodN(state->cur_media_descr,cm,len);
}
void rvSdpParseAuxAddMediaDescrFormatN(RvSdpParserState_ * state,const char* fmt,size_t len){
rvSdpMediaDescrAddFormatN(state->cur_media_descr,fmt,len);
}
static RvSdpNetType GetNetType(const char * nettype,size_t nlen) {
if(StrIEqualN("IN",nettype,nlen)) return RV_SDPNETTYPE_IN;
if(StrIEqualN("LOCAL",nettype,nlen)) return RV_SDPNETTYPE_LOCAL;
if(StrIEqualN("ATM",nettype,nlen)) return RV_SDPNETTYPE_ATM;
if(StrIEqualN("OTHER",nettype,nlen)) return RV_SDPNETTYPE_OTHER;
if(StrIEqualN("TN",nettype,nlen)) return RV_SDPNETTYPE_TN;
if(StrIEqualN("$",nettype,nlen)) return RV_SDPNETTYPE_ANY;
if(StrIEqualN("-",nettype,nlen)) return RV_SDPNETTYPE_IGNORE;
return RV_SDPNETTYPE_UNKNOWN;
}
static RvSdpAddrType GetAddrType(const char * addrtype,size_t alen) {
if(StrIEqualN("IP4",addrtype,alen)) return RV_SDPADDRTYPE_IP4;
if(StrIEqualN("IP6",addrtype,alen)) return RV_SDPADDRTYPE_IP6;
if(StrIEqualN("EPN",addrtype,alen)) return RV_SDPADDRTYPE_ENDPOINT;
if(StrIEqualN("NSAP",addrtype,alen)) return RV_SDPADDRTYPE_NSAP;
if(StrIEqualN("E164",addrtype,alen)) return RV_SDPADDRTYPE_E164;
if(StrIEqualN("GWID",addrtype,alen)) return RV_SDPADDRTYPE_GWID;
if(StrIEqualN("ALIAS",addrtype,alen)) return RV_SDPADDRTYPE_ALIAS;
if(StrIEqualN("RFC2543",addrtype,alen)) return RV_SDPADDRTYPE_RFC2543;
if(StrIEqualN("$", addrtype,alen)) return RV_SDPADDRTYPE_ANY;
if(StrIEqualN("-", addrtype,alen)) return RV_SDPADDRTYPE_IGNORE;
return RV_SDPADDRTYPE_UNKNOWN;
}
void rvSdpParserAuxSetConnectionN(RvSdpParserState_ * state) {
const char* nettype = state->cur_nettype.buf;
const char* addrtype = state->cur_addrtype.buf;
const char* connaddr = state->cur_addr.buf;
size_t nlen = state->cur_nettype.len;
size_t alen = state->cur_addrtype.len;
size_t calen = state->cur_addr.len;
RvSdpNetType n = GetNetType(nettype,nlen);
RvSdpAddrType a = GetAddrType(addrtype,alen);
rvSdpCommonFieldsSetConnectionN(state->cur_sdp_fields,(RvSdpNetType)n,(RvSdpAddrType)a,connaddr,calen,state->cur_sdp->alloc);
#ifdef RV_SDPSYMB_USESTRING
if(n==RV_SDPNETTYPE_UNKNOWN)
rvSdpConnectionSetNetTypeStrN(state->cur_sdp_fields->connection,nettype,nlen);
if(a==RV_SDPADDRTYPE_UNKNOWN)
rvSdpConnectionSetAddrTypeStrN(state->cur_sdp_fields->connection,addrtype,alen);
#endif
rvSdpConnectionSetAddressTTL(state->cur_sdp_fields->connection,state->ttl);
rvSdpConnectionSetAddressNum(state->cur_sdp_fields->connection,state->num_addr);
}
void rvSdpParserAuxSaveAddr(RvSdpParserState_ * state,const char * nettype,size_t nlen,
const char * addrtype,size_t alen,const char * connaddr,size_t calen) {
state->cur_nettype.buf = (char *)nettype;
state->cur_nettype.len = nlen;
state->cur_addrtype.buf = (char *)addrtype;
state->cur_addrtype.len = alen;
state->cur_addr.buf = (char *)connaddr;
state->cur_addr.len = calen;
}
void rvSdpParserAuxSetOriginN(RvSdpParserState_ * state,RvSdpMsg * sdp,const char * username,size_t ulen,
const char * sess_id,size_t slen,const char * version,size_t vlen) {
const char* nettype = state->cur_nettype.buf;
const char* addrtype = state->cur_addrtype.buf;
const char* connaddr = state->cur_addr.buf;
size_t nlen = state->cur_nettype.len;
size_t atlen = state->cur_addrtype.len;
size_t alen = state->cur_addr.len;
RvSdpNetType n = GetNetType(nettype,nlen);
RvSdpAddrType at = GetAddrType(addrtype,atlen);
rvSdpMsgSetOriginN(sdp,username,ulen,sess_id,slen,version,vlen,n,at,connaddr,alen);
#ifdef RV_SDPSYMB_USESTRING
if(n==RV_SDPNETTYPE_UNKNOWN)
rvSdpOriginSetNetTypeStrN(sdp->origin,nettype,nlen);
if(at==RV_SDPADDRTYPE_UNKNOWN)
rvSdpOriginSetAddressTypeStrN(sdp->origin,addrtype,atlen);
#endif
}
static RvSdpEncrMethod GetKeyType(const char * type,size_t len) {
if(StrIEqualN("prompt",type,len)) return RV_SDPENCRMTHD_PROMPT;
if(StrIEqualN("clear",type,len)) return RV_SDPENCRMTHD_CLEAR;
if(StrIEqualN("base64",type,len)) return RV_SDPENCRMTHD_BASE64;
if(StrIEqualN("uri",type,len)) return RV_SDPENCRMTHD_URI;
return RV_SDPENCRMTHD_UNKNOWN;
}
void rvSdpParserAuxSetKeyN(RvSdpParserState_ * state,RvpStrPtrN key_type,const char * data,int data_len) {
RvSdpEncrMethod type = GetKeyType(key_type.buf,key_type.len);
rvSdpCommonFieldsSetKeyN(state->cur_sdp_fields,type,data,data_len,state->cur_sdp->alloc);
#ifdef RV_SDPSYMB_USESTRING
if(type==RV_SDPENCRMTHD_UNKNOWN)
rvSdpKeySetTypeStrN(state->cur_sdp_fields->key,key_type.buf,key_type.len);
#endif
}
/* Construct auxiliary parser state */
void rvSdpParserStateConstruct(RvSdpParserState_ * state,char * buf,RvSdpMsg * sdp, RvAlloc *a) {
state->stat = RV_SDPPARSER_PARSING;
state->cur_line = buf;
state->cur_token = buf;
state->cur_sdp = sdp;
state->cur_sdp_fields = &sdp->fields;
state->ttl = RV_SDPTTL_NOTSET;
state->num_addr = 1;
rvStringListConstructA(&state->vcid_value, a);
}
/* Parser Error Handlers */
static void rvSdpParseErrLog(rvSdpParser_pcb_type * pcb) {
char err_buf[256] = {0};
char * buf = err_buf;
/*const char * cur_line = pcb->sdp_prs_state.cur_line;*/
/* buf+=sprintf(buf,"\n------------------------------------\n"); */
buf+=sprintf(buf,"SDP Parser Error : %d \n",pcb->sdp_prs_state.stat);
buf+=sprintf(buf,"%s, line %d, column %d\n",
pcb->error_message,pcb->line,pcb->column);
/* Log the error using user-provided function */
rvLogError(&rvLog,err_buf);
}
void rvSdpParseSetSyntaxErr(void * pcb_) {
rvSdpParser_pcb_type * pcb = (rvSdpParser_pcb_type*)pcb_;
if( pcb->sdp_prs_state.stat == RV_SDPPARSER_PARSING )
pcb->sdp_prs_state.stat = RV_SDPPARSER_STOP_ERROR;
rvSdpParseErrLog(pcb);
}
void rvSdpParseSetSemErr(void * pcb_,const char * msg) {
rvSdpParser_pcb_type * pcb = (rvSdpParser_pcb_type *)pcb_;
char err_buf[256] = {0};
char * buf = err_buf;
/* Causes the parser to stop */
pcb->exit_flag = AG_SEMANTIC_ERROR_CODE;
/* Set msg error code */
if( pcb->sdp_prs_state.stat == RV_SDPPARSER_PARSING ) {
pcb->sdp_prs_state.stat = RV_SDPPARSER_STOP_ERROR;
/* buf+=sprintf(buf,"\n------------------------------------\n"); */
buf+=sprintf(buf,"SDP Parser Error : \n");
buf+=sprintf(buf,"%s: line %d, column %d\n",msg,pcb->line,pcb->column);
/* Log the error using user-provided function */
rvLogError(&rvLog,err_buf);
}
}
void rvSdpParserAuxValidateFieldLength(void * pcb_,int length,int max) {
if(length > max)
rvSdpParseSetSemErr(pcb_,"Field too long");
}
/* Function used by parser or construct parse */
RvSdpMsg * rvSdpMsgConstructParseA(RvSdpMsg * sdp,char * msg,int * len,RvSdpParseStatus * stat,RvAlloc * a) {
rvSdpParser_pcb_type pcb; /* Parser control block */
/* Init parser */
pcb.sdp_msg = sdp;
pcb.pointer = (unsigned char*)(msg);
sdp->sdp_msg = msg;
/* Construct message and auxiliary state */
rvSdpParserStateConstruct(&pcb.sdp_prs_state,(char*)pcb.pointer,sdp,a);
rvSdpMsgConstructA(sdp,a);
/* Call parser function */
rvSdpParser(&pcb);
/* Return values */
*len = (char*)pcb.pointer - (char*)msg;
*stat = pcb.sdp_prs_state.stat;
if(*stat==RV_SDPPARSER_STOP_ERROR) {
rvSdpMsgDestruct(sdp);
return NULL;
}
return sdp;
}
/* Function used by parser or construct parse with the default allocator */
RvSdpMsg * rvSdpMsgConstructParse(RvSdpMsg * sdp,char * msg,int * len,RvSdpParseStatus * stat) {
return rvSdpMsgConstructParseA(sdp,msg,len,stat,&rvDefaultAlloc);
}
/*------ VcId -------*/
void rvSdpParserAuxSaveVcId(RvSdpParserState_ * state,int type, const char *value, int len)
{
size_t index;
rvStringListAddN(&state->vcid_value, value, len);
index = rvStringListGetSize(&state->vcid_value) - 1;
state->vcid_type[index] = type;
state->vcid_len[index] = len;
}
void rvSdpParserAuxSetVcIdN(RvSdpParserState_ * state) {
size_t i;
if (rvStringListGetSize(&state->vcid_value)>0) {
for (i=0;i<rvStringListGetSize(&state->vcid_value);i++) {
rvSdpMediaDescrAddVcIdN(state->cur_media_descr,
state->vcid_type[i],
rvStringListGetElem(&state->vcid_value, i),
state->vcid_len[i]);
}
}
rvStringListClear(&state->vcid_value);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -