Commit 0ef20763 authored by jehan's avatar jehan

implement mime parameter struture for sdp

parent f25a7246
......@@ -19,7 +19,7 @@
#ifndef BELLE_SDP_H_
#define BELLE_SDP_H_
#include "belle-sip.h"
#define BELLE_SDP_CAST(t) BELLE_SIP_CAST(t)
#define BELLE_SDP_CAST(obj,t) BELLE_SIP_CAST(obj,t)
/***************************************************************************************
* Attribute
......@@ -112,6 +112,28 @@ void belle_sdp_media_set_port_count(belle_sdp_media_t* media, int portCount);
void belle_sdp_media_set_protocol(belle_sdp_media_t* media, const char* protocole);
#define BELLE_SDP_MEDIA(t) BELLE_SDP_CAST(t,belle_sdp_media_t);
/***************************************************************************************
* mime_parameter
*
**************************************************************************************/
typedef struct _belle_sdp_mime_parameter belle_sdp_mime_parameter_t;
belle_sdp_mime_parameter_t* belle_sdp_mime_parameter_new();
int belle_sdp_mime_parameter_get_rate(const belle_sdp_mime_parameter_t* mime_parameter);
void belle_sdp_mime_parameter_set_rate(belle_sdp_mime_parameter_t* mime_parameter,int rate);
int belle_sdp_mime_parameter_get_channel_count(const belle_sdp_mime_parameter_t* mime_parameter);
void belle_sdp_mime_parameter_set_channel_count(belle_sdp_mime_parameter_t* mime_parameter,int count);
int belle_sdp_mime_parameter_get_ptime(const belle_sdp_mime_parameter_t* mime_parameter);
void belle_sdp_mime_parameter_set_ptime(belle_sdp_mime_parameter_t* mime_parameter,int ptime);
int belle_sdp_mime_parameter_get_max_ptime(const belle_sdp_mime_parameter_t* mime_parameter);
void belle_sdp_mime_parameter_set_max_ptime(belle_sdp_mime_parameter_t* mime_parameter,int max_ptime);
const char* belle_sdp_mime_parameter_get_type(const belle_sdp_mime_parameter_t* mime_parameter);
void belle_sdp_mime_parameter_set_type(belle_sdp_mime_parameter_t* mime_parameter,const char* type);
int belle_sdp_mime_parameter_get_media_format(const belle_sdp_mime_parameter_t* mime_parameter);
void belle_sdp_mime_parameter_set_media_format(belle_sdp_mime_parameter_t* mime_parameter,int format);
const char* belle_sdp_mime_parameter_get_parameters(const belle_sdp_mime_parameter_t* mime_parameter);
void belle_sdp_mime_parameter_set_parameters(belle_sdp_mime_parameter_t* mime_parameter,const char* parameters);
#define BELLE_SDP_MIME_PARAMETER(t) BELLE_SDP_CAST(t,belle_sdp_mime_parameter_t);
/***************************************************************************************
* Media Description
*
......@@ -128,8 +150,8 @@ belle_sdp_connection_t* belle_sdp_media_description_get_connection(const belle_s
belle_sdp_info_t* belle_sdp_media_description_get_info(const belle_sdp_media_description_t* media_description);
/*belle_sdp_key_t* belle_sdp_media_description_get_key(const belle_sdp_media_description_t* media_description);*/
belle_sdp_media_t* belle_sdp_media_description_get_media(const belle_sdp_media_description_t* media_description);
belle_sip_list_t* belle_sdp_media_description_get_mime_parameters(const belle_sdp_media_description_t* media_description);
belle_sip_list_t* belle_sdp_media_description_get_mime_types(const belle_sdp_media_description_t* media_description);
belle_sip_list_t* belle_sdp_media_description_build_mime_parameters(const belle_sdp_media_description_t* media_description);
/*belle_sip_list_t* belle_sdp_media_description_get_mime_types(const belle_sdp_media_description_t* media_description);*/
void belle_sdp_media_description_remove_attribute(belle_sdp_media_description_t* media_description,const char* attribute);
void belle_sdp_media_description_remove_bandwidth(belle_sdp_media_description_t* media_description,const char* bandwidth);
void belle_sdp_media_description_set_attribute(belle_sdp_media_description_t* media_description, const char* name, const char* value);
......@@ -142,19 +164,8 @@ void belle_sdp_media_description_set_connection(belle_sdp_media_description_t* m
void belle_sdp_media_description_set_info(belle_sdp_media_description_t* media_description,belle_sdp_info_t* i);
/*void belle_sdp_media_description_set_key(belle_sdp_media_description_t* media_description,belle_sdp_key_t* key);*/
void belle_sdp_media_description_set_media(belle_sdp_media_description_t* media_description, belle_sdp_media_t* media);
void belle_sdp_media_description_append_values_from_mime_parameter(belle_sdp_media_description_t* media_description, belle_sdp_mime_parameter_t* mime_parameter);
#define BELLE_SDP_MEDIA_DESCRIPTION(t) BELLE_SDP_CAST(t,belle_sdp_media_description_t);
/***************************************************************************************
* mime_parameter
*
**************************************************************************************/
typedef struct _belle_sdp_mime_parameter belle_sdp_mime_parameter_t;
belle_sdp_mime_parameter_t* belle_sdp_mime_parameter_new();
int belle_sdp_mime_get_rate(const belle_sdp_mime_parameter_t* mime_parameter);
int belle_sdp_mime_get_channnel_count(const belle_sdp_mime_parameter_t* mime_parameter);
int belle_sdp_mime_get_ptime(const belle_sdp_mime_parameter_t* mime_parameter);
int belle_sdp_mime_get_max_ptime(const belle_sdp_mime_parameter_t* mime_parameter);
belle_sip_list_t* belle_sdp_mime_get_parameters(const belle_sdp_mime_parameter_t* mime_parameter);
/***************************************************************************************
* Origin
......
......@@ -93,6 +93,7 @@ typedef enum belle_sip_type_id{
BELLE_SIP_TYPE_ID(belle_sdp_uri_t),
BELLE_SIP_TYPE_ID(belle_sdp_version_t),
BELLE_SIP_TYPE_ID(belle_sdp_base_description_t),
BELLE_SIP_TYPE_ID(belle_sdp_mime_parameter_t),
belle_sip_type_id_end
}belle_sip_type_id_t;
......
......@@ -16,7 +16,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
grammar belle_sdp;
options {
language = C;
......
......@@ -391,10 +391,163 @@ belle_sdp_info_t* belle_sdp_media_description_get_info(const belle_sdp_media_des
belle_sdp_media_t* belle_sdp_media_description_get_media(const belle_sdp_media_description_t* media_description) {
return media_description->media;
}
belle_sip_list_t* belle_sdp_media_description_get_mime_parameters(const belle_sdp_media_description_t* media_description) {
belle_sip_error("belle_sdp_media_description_get_mime_parameters: not implemented yet");
struct static_payload {
unsigned char number;
int channel_count;
const char* type;
int rate;
};
#define STATIC_PAYLOAD_LIST_LENTH 8
struct static_payload static_payload_list [STATIC_PAYLOAD_LIST_LENTH] ={
{0,1,"PCMU",8000},
{3,1,"GSM",8000},
{4,1,"G723",8000},
{5,1,"DVI4",8000},
{6,1,"DVI4",16000},
{8,1,"PCMA",8000},
{9,1,"G722",8000},
{34,-1,"H263",90000}
};
static int mime_parameter_fill_from_static(belle_sdp_mime_parameter_t *mime_parameter,int format) {
struct static_payload* iterator = static_payload_list;
int i;
for (i=0;i<STATIC_PAYLOAD_LIST_LENTH;i++) {
if (iterator->number == format) {
belle_sdp_mime_parameter_set_type(mime_parameter,iterator->type);
belle_sdp_mime_parameter_set_rate(mime_parameter,iterator->rate);
belle_sdp_mime_parameter_set_channel_count(mime_parameter,iterator->channel_count);
} else {
iterator++;
}
}
return 0;
}
static int mime_parameter_fill_from_rtpmap(belle_sdp_mime_parameter_t *mime_parameter, const char *rtpmap){
char *mime=belle_sip_strdup(rtpmap);
char *p=strchr(mime,'/');
if (p){
char *chans;
*p='\0';
p++;
chans=strchr(p,'/');
if (chans){
*chans='\0';
chans++;
belle_sdp_mime_parameter_set_channel_count(mime_parameter,atoi(chans));
}else belle_sdp_mime_parameter_set_channel_count(mime_parameter,1);
belle_sdp_mime_parameter_set_rate(mime_parameter,atoi(p));
}
belle_sdp_mime_parameter_set_type(mime_parameter,mime);
belle_sip_free(mime);
return 0;
}
/* return the value of attr "field" for payload pt at line pos (field=rtpmap,fmtp...)*/
static const char *belle_sdp_media_description_a_attr_value_get_with_pt(const belle_sdp_media_description_t* media_description,int pt,const char *field)
{
int tmppt=0,scanned=0;
const char *tmp;
belle_sdp_attribute_t *attr;
belle_sip_list_t* attribute_list;
for ( attribute_list =belle_sdp_media_description_get_attributes(media_description)
;attribute_list!=NULL
;attribute_list=attribute_list->next) {
attr = BELLE_SDP_ATTRIBUTE(attribute_list->data);
if (strcmp(field,belle_sdp_attribute_get_name(attr))==0 && belle_sdp_attribute_get_value(attr)!=NULL){
int nb = sscanf(belle_sdp_attribute_get_value(attr),"%i %n",&tmppt,&scanned);
/* the return value may depend on how %n is interpreted by the libc: see manpage*/
if (nb == 1 || nb==2 ){
if (pt==tmppt){
tmp=belle_sdp_attribute_get_value(attr)+scanned;
if (strlen(tmp)>0)
return tmp;
}
}else belle_sip_warning("sdp has a strange a= line (%s) nb=%i",belle_sdp_attribute_get_value(attr),nb);
}
}
return NULL;
}
belle_sip_list_t* belle_sdp_media_description_build_mime_parameters(const belle_sdp_media_description_t* media_description) {
/*First, get media type*/
belle_sdp_media_t* media = belle_sdp_media_description_get_media(media_description);
belle_sip_list_t* mime_parameter_list=NULL;
belle_sip_list_t* media_formats=NULL;
belle_sdp_mime_parameter_t* mime_parameter;
const char* rtpmap=NULL;
const char* fmtp=NULL;
const char* ptime=NULL;
const char* max_ptime=NULL;
int ptime_as_int=-1;
int max_ptime_as_int=-1;
if (!media) {
belle_sip_error("belle_sdp_media_description_build_mime_parameters: no media");
return NULL;
}
ptime = belle_sdp_media_description_get_attribute(media_description,"ptime");
ptime?ptime_as_int=atoi(ptime):-1;
max_ptime = belle_sdp_media_description_get_attribute(media_description,"maxptime");
max_ptime?max_ptime_as_int=atoi(max_ptime):-1;
for (media_formats = belle_sdp_media_get_media_formats(media);media_formats!=NULL;media_formats=media_formats->next) {
/*create mime parameters with format*/
mime_parameter = belle_sdp_mime_parameter_new();
belle_sdp_mime_parameter_set_ptime(mime_parameter,ptime_as_int);
belle_sdp_mime_parameter_set_max_ptime(mime_parameter,max_ptime_as_int);
belle_sdp_mime_parameter_set_media_format(mime_parameter,(int)(long)media_formats->data);
mime_parameter_fill_from_static(mime_parameter,belle_sdp_mime_parameter_get_media_format(mime_parameter));
/*get rtpmap*/
rtpmap = belle_sdp_media_description_a_attr_value_get_with_pt(media_description
,belle_sdp_mime_parameter_get_media_format(mime_parameter)
,"rtpmap");
if (rtpmap) {
mime_parameter_fill_from_rtpmap(mime_parameter,rtpmap);
}
fmtp = belle_sdp_media_description_a_attr_value_get_with_pt(media_description
,belle_sdp_mime_parameter_get_media_format(mime_parameter)
,"fmtp");
if (fmtp) {
belle_sdp_mime_parameter_set_parameters(mime_parameter,fmtp);
}
mime_parameter_list=belle_sip_list_append(mime_parameter_list,mime_parameter);
}
return mime_parameter_list;
}
#define MAX_FMTP_LENGH 64
void belle_sdp_media_description_append_values_from_mime_parameter(belle_sdp_media_description_t* media_description, belle_sdp_mime_parameter_t* mime_parameter) {
belle_sdp_media_t* media = belle_sdp_media_description_get_media(media_description);
char atribute_value [MAX_FMTP_LENGH];
belle_sdp_media_set_media_formats(media,belle_sip_list_append(belle_sdp_media_get_media_formats(media)
,(void*)(long)(belle_sdp_mime_parameter_get_media_format(mime_parameter))));
if (belle_sdp_mime_parameter_get_media_format(mime_parameter) > 34) {
/*dynamic payload*/
if (belle_sdp_mime_parameter_get_channel_count(mime_parameter)>1) {
snprintf(atribute_value,MAX_FMTP_LENGH,"%i %s/%i/%i"
,belle_sdp_mime_parameter_get_media_format(mime_parameter)
,belle_sdp_mime_parameter_get_type(mime_parameter)
,belle_sdp_mime_parameter_get_rate(mime_parameter)
,belle_sdp_mime_parameter_get_channel_count(mime_parameter));
} else {
snprintf(atribute_value,MAX_FMTP_LENGH,"%i %s/%i"
,belle_sdp_mime_parameter_get_media_format(mime_parameter)
,belle_sdp_mime_parameter_get_type(mime_parameter)
,belle_sdp_mime_parameter_get_rate(mime_parameter));
}
belle_sdp_media_description_set_attribute(media_description,"rtpmap",atribute_value);
if (belle_sdp_mime_parameter_get_parameters(mime_parameter)) {
snprintf(atribute_value,MAX_FMTP_LENGH,"%i %s"
,belle_sdp_mime_parameter_get_media_format(mime_parameter)
,belle_sdp_mime_parameter_get_parameters(mime_parameter));
belle_sdp_media_description_set_attribute(media_description,"fmtp",atribute_value);
}
}
}
belle_sip_list_t* belle_sdp_media_description_get_mime_types(const belle_sdp_media_description_t* media_description) {
belle_sip_error("belle_sdp_media_description_get_mime_types: not implemented yet");
return NULL;
......@@ -809,4 +962,39 @@ BELLE_SDP_NEW(version,belle_sip_object)
//BELLE_SDP_PARSE(version)
GET_SET_INT(belle_sdp_version,version,int);
/***************************************************************************************
* mime_parameter
*
**************************************************************************************/
struct _belle_sdp_mime_parameter {
belle_sip_object_t base;
int rate;
int channel_count;
int ptime;
int max_ptime;
int media_format;
const char* type;
const char* parameters;
};
static void belle_sdp_mime_parameter_destroy(belle_sdp_mime_parameter_t *mime_parameter) {
if (mime_parameter->type) belle_sip_free((void*)mime_parameter->type);
if (mime_parameter->parameters) belle_sip_free((void*)mime_parameter->parameters);
}
BELLE_SIP_INSTANCIATE_VPTR(belle_sdp_mime_parameter_t,belle_sip_object_t,belle_sdp_mime_parameter_destroy,NULL,NULL);
belle_sdp_mime_parameter_t* belle_sdp_mime_parameter_new() {
belle_sdp_mime_parameter_t* l_param = belle_sip_object_new(belle_sdp_mime_parameter_t);
l_param->ptime = -1;
l_param->max_ptime = -1;
return l_param;
}
GET_SET_INT(belle_sdp_mime_parameter,rate,int);
GET_SET_INT(belle_sdp_mime_parameter,channel_count,int);
GET_SET_INT(belle_sdp_mime_parameter,ptime,int);
GET_SET_INT(belle_sdp_mime_parameter,max_ptime,int);
GET_SET_INT(belle_sdp_mime_parameter,media_format,int);
GET_SET_STRING(belle_sdp_mime_parameter,type);
GET_SET_STRING(belle_sdp_mime_parameter,parameters);
......@@ -17,7 +17,7 @@
*/
grammar belle_sip_message;
options {
language = C;
......
......@@ -224,6 +224,90 @@ static void test_session_description(void) {
return;
}
static belle_sdp_mime_parameter_t* find_mime_parameter(belle_sip_list_t* list,const int format) {
for(;list!=NULL;list=list->next){
if (belle_sdp_mime_parameter_get_media_format((belle_sdp_mime_parameter_t*)list->data) == format) {
return (belle_sdp_mime_parameter_t*)list->data;
}
}
return NULL;
}
static void check_mime_param (belle_sdp_mime_parameter_t* mime_param
,int rate
,int channel_count
,int ptime
,int max_ptime
,int media_format
,const char* type
,const char* parameters) {
CU_ASSERT_PTR_NOT_NULL(mime_param);
CU_ASSERT_EQUAL(belle_sdp_mime_parameter_get_rate(mime_param),rate);
CU_ASSERT_EQUAL(belle_sdp_mime_parameter_get_channel_count(mime_param),channel_count);
CU_ASSERT_EQUAL(belle_sdp_mime_parameter_get_ptime(mime_param),ptime);
CU_ASSERT_EQUAL(belle_sdp_mime_parameter_get_max_ptime(mime_param),max_ptime);
CU_ASSERT_EQUAL(belle_sdp_mime_parameter_get_media_format(mime_param),media_format);
if (type) CU_ASSERT_STRING_EQUAL(belle_sdp_mime_parameter_get_type(mime_param),type);
if (parameters) CU_ASSERT_STRING_EQUAL(belle_sdp_mime_parameter_get_parameters(mime_param),parameters);
}
static void test_mime_parameter(void) {
const char* l_src = "m=audio 7078 RTP/AVP 111 110 0 8 9 3 101\r\n"\
"a=rtpmap:111 speex/16000\r\n"\
"a=fmtp:111 vbr=on\r\n"\
"a=rtpmap:110 speex/8000\r\n"\
"a=fmtp:110 vbr=on\r\n"\
"a=rtpmap:8 PCMA/8000\r\n"\
"a=rtpmap:101 telephone-event/8000\r\n"\
"a=fmtp:101 0-11\r\n"\
"a=ptime:40\r\n";
belle_sdp_media_description_t* l_media_description = belle_sdp_media_description_parse(l_src);
belle_sip_list_t* mime_parameter_list = belle_sdp_media_description_build_mime_parameters(l_media_description);
CU_ASSERT_PTR_NOT_NULL(mime_parameter_list);
belle_sip_object_unref(BELLE_SIP_OBJECT(l_media_description));
l_media_description = belle_sdp_media_description_new();
belle_sdp_media_description_set_media(l_media_description,belle_sdp_media_parse("m=audio 7078 RTP/AVP"));
for (;mime_parameter_list!=NULL;mime_parameter_list=mime_parameter_list->next) {
belle_sdp_media_description_append_values_from_mime_parameter(l_media_description,(belle_sdp_mime_parameter_t*)mime_parameter_list->data);
}
belle_sdp_media_description_set_attribute(l_media_description,"ptime","40");
mime_parameter_list = belle_sdp_media_description_build_mime_parameters(l_media_description);
belle_sdp_mime_parameter_t* l_param = find_mime_parameter(mime_parameter_list,111);
CU_ASSERT_PTR_NOT_NULL(l_param);
check_mime_param(l_param,16000,1,40,-1,111,"speex","vbr=on");
belle_sip_object_unref(BELLE_SIP_OBJECT(l_param));
l_param = find_mime_parameter(mime_parameter_list,110);
CU_ASSERT_PTR_NOT_NULL(l_param);
check_mime_param(l_param,8000,1,40,-1,110,"speex","vbr=on");
l_param = find_mime_parameter(mime_parameter_list,3);
CU_ASSERT_PTR_NOT_NULL(l_param);
check_mime_param(l_param,8000,1,40,-1,3,"GSM",NULL);
belle_sip_object_unref(BELLE_SIP_OBJECT(l_param));
l_param = find_mime_parameter(mime_parameter_list,0);
CU_ASSERT_PTR_NOT_NULL(l_param);
check_mime_param(l_param,8000,1,40,-1,0,"PCMU",NULL);
belle_sip_object_unref(BELLE_SIP_OBJECT(l_param));
l_param = find_mime_parameter(mime_parameter_list,8);
CU_ASSERT_PTR_NOT_NULL(l_param);
check_mime_param(l_param,8000,1,40,-1,8,"PCMA",NULL);
belle_sip_object_unref(BELLE_SIP_OBJECT(l_param));
l_param = find_mime_parameter(mime_parameter_list,9);
CU_ASSERT_PTR_NOT_NULL(l_param);
check_mime_param(l_param,8000,1,40,-1,9,"G722",NULL);
belle_sip_object_unref(BELLE_SIP_OBJECT(l_param));
l_param = find_mime_parameter(mime_parameter_list,101);
CU_ASSERT_PTR_NOT_NULL(l_param);
check_mime_param(l_param,8000,1,40,-1,101,"telephone-event","0-11");
belle_sip_object_unref(BELLE_SIP_OBJECT(l_param));
}
int belle_sdp_test_suite () {
CU_pSuite pSuite = NULL;
......@@ -253,6 +337,9 @@ int belle_sdp_test_suite () {
if (NULL == CU_add_test(pSuite, "media_description", test_media_description)) {
return CU_get_error();
}
if (NULL == CU_add_test(pSuite, "mime_parameter", test_mime_parameter)) {
return CU_get_error();
}
if (NULL == CU_add_test(pSuite, "session_description", test_session_description)) {
return CU_get_error();
} return 0;
......
......@@ -61,7 +61,7 @@ void test_complex_header_contact(void) {
CU_ASSERT_EQUAL(belle_sip_header_contact_get_expires(L_contact),3600);
float l_qvalue = belle_sip_header_contact_get_qvalue(L_contact);
CU_ASSERT_EQUAL(l_qvalue,0.7);
CU_ASSERT_EQUAL(l_qvalue,0.7f);
belle_sip_header_t* l_next = belle_sip_header_get_next(BELLE_SIP_HEADER(L_contact));
belle_sip_header_contact_t* L_next_contact = BELLE_SIP_HEADER_CONTACT(l_next);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment