Commit 1f3a8bc9 authored by Ghislain MARY's avatar Ghislain MARY

Implement parsing of rtcp-fb SDP attribute.

parent aee05e63
......@@ -49,6 +49,35 @@ BELLESIP_EXPORT belle_sdp_raw_attribute_t* belle_sdp_raw_attribute_parse(const c
BELLESIP_EXPORT belle_sdp_raw_attribute_t* belle_sdp_raw_attribute_create(const char* name, const char* value);
BELLESIP_EXPORT void belle_sdp_raw_attribute_set_value(belle_sdp_raw_attribute_t* attribute, const char* value);
#define BELLE_SDP_RAW_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_raw_attribute_t)
/***************************************************************************************
* RTCP-FB Attribute
*
**************************************************************************************/
typedef enum _belle_sdp_rtcp_fb_val_type {
BELLE_SDP_RTCP_FB_ACK,
BELLE_SDP_RTCP_FB_NACK,
BELLE_SDP_RTCP_FB_TRR_INT
} belle_sdp_rtcp_fb_val_type_t;
typedef enum _belle_sdp_rtcp_fb_val_param {
BELLE_SDP_RTCP_FB_NONE,
BELLE_SDP_RTCP_FB_PLI,
BELLE_SDP_RTCP_FB_SLI,
BELLE_SDP_RTCP_FB_RPSI,
BELLE_SDP_RTCP_FB_APP
} belle_sdp_rtcp_fb_val_param_t;
typedef struct _belle_sdp_rtcp_fb_attribute belle_sdp_rtcp_fb_attribute_t;
BELLESIP_EXPORT belle_sdp_rtcp_fb_attribute_t* belle_sdp_rtcp_fb_attribute_new();
BELLESIP_EXPORT belle_sdp_rtcp_fb_attribute_t* belle_sdp_rtcp_fb_attribute_parse(const char* attribute);
BELLESIP_EXPORT belle_sdp_rtcp_fb_attribute_t* belle_sdp_rtcp_fb_attribute_create();
BELLESIP_EXPORT int8_t belle_sdp_rtcp_fb_attribute_get_id(const belle_sdp_rtcp_fb_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_id(belle_sdp_rtcp_fb_attribute_t* attribute, int8_t id);
BELLESIP_EXPORT belle_sdp_rtcp_fb_val_type_t belle_sdp_rtcp_fb_attribute_get_type(const belle_sdp_rtcp_fb_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_type(belle_sdp_rtcp_fb_attribute_t* attribute, belle_sdp_rtcp_fb_val_type_t type);
BELLESIP_EXPORT belle_sdp_rtcp_fb_val_param_t belle_sdp_rtcp_fb_attribute_get_param(const belle_sdp_rtcp_fb_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_param(belle_sdp_rtcp_fb_attribute_t* attribute, belle_sdp_rtcp_fb_val_param_t param);
BELLESIP_EXPORT uint8_t belle_sdp_rtcp_fb_attribute_get_trr_int(const belle_sdp_rtcp_fb_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_trr_int(belle_sdp_rtcp_fb_attribute_t* attribute, uint8_t seconds);
#define BELLE_SDP_RTCP_FB_ATTRIBUTE(t) BELLE_SDP_CAST(t,belle_sdp_rtcp_fb_attribute_t)
/***************************************************************************************
* RTCP-XR Attribute
*
......
......@@ -91,6 +91,7 @@ BELLE_SIP_DECLARE_TYPES_BEGIN(belle_sip,1)
BELLE_SIP_TYPE_ID(belle_sdp_phone_t),
BELLE_SIP_TYPE_ID(belle_sdp_raw_attribute_t),
BELLE_SIP_TYPE_ID(belle_sdp_repeate_time_t),
BELLE_SIP_TYPE_ID(belle_sdp_rtcp_fb_attribute_t),
BELLE_SIP_TYPE_ID(belle_sdp_rtcp_xr_attribute_t),
BELLE_SIP_TYPE_ID(belle_sdp_session_description_t),
BELLE_SIP_TYPE_ID(belle_sdp_session_name_t),
......
......@@ -43,6 +43,7 @@ struct attribute_name_func_pair {
attribute_parse_func func;
};
static struct attribute_name_func_pair attribute_table[] = {
{ "rtcp-fb", (attribute_parse_func)belle_sdp_rtcp_fb_attribute_parse },
{ "rtcp-xr", (attribute_parse_func)belle_sdp_rtcp_xr_attribute_parse }
};
struct _belle_sdp_attribute {
......@@ -142,6 +143,101 @@ void belle_sdp_raw_attribute_set_value(belle_sdp_raw_attribute_t* attribute, con
attribute->value = belle_sip_strdup(value);
} else attribute->value = NULL;
}
/***************************************************************************************
* RTCP-FB Attribute
*
**************************************************************************************/
struct _belle_sdp_rtcp_fb_attribute {
belle_sdp_attribute_t base;
belle_sdp_rtcp_fb_val_type_t type;
belle_sdp_rtcp_fb_val_param_t param;
uint8_t trr_int;
int8_t id;
};
BELLESIP_EXPORT unsigned int belle_sdp_rtcp_fb_attribute_has_pli(const belle_sdp_rtcp_fb_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_pli(belle_sdp_rtcp_fb_attribute_t* attribute, unsigned int enable);
BELLESIP_EXPORT unsigned int belle_sdp_rtcp_fb_attribute_has_sli(const belle_sdp_rtcp_fb_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_sli(belle_sdp_rtcp_fb_attribute_t* attribute, unsigned int enable);
BELLESIP_EXPORT unsigned int belle_sdp_rtcp_fb_attribute_has_rpsi(const belle_sdp_rtcp_fb_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_rpsi(belle_sdp_rtcp_fb_attribute_t* attribute, unsigned int enable);
BELLESIP_EXPORT unsigned int belle_sdp_rtcp_fb_attribute_has_app(const belle_sdp_rtcp_fb_attribute_t* attribute);
BELLESIP_EXPORT void belle_sdp_rtcp_fb_attribute_set_app(belle_sdp_rtcp_fb_attribute_t* attribute, unsigned int enable);
void belle_sdp_rtcp_fb_attribute_destroy(belle_sdp_rtcp_fb_attribute_t* attribute) {
}
void belle_sdp_rtcp_fb_attribute_clone(belle_sdp_rtcp_fb_attribute_t* attribute, const belle_sdp_rtcp_fb_attribute_t *orig) {
attribute->type = orig->type;
attribute->param = orig->param;
attribute->trr_int = orig->trr_int;
attribute->id = orig->id;
}
belle_sip_error_code belle_sdp_rtcp_fb_attribute_marshal(belle_sdp_rtcp_fb_attribute_t* attribute, char * buff, size_t buff_size, size_t *offset) {
int8_t id = belle_sdp_rtcp_fb_attribute_get_id(attribute);
belle_sdp_rtcp_fb_val_type_t type = belle_sdp_rtcp_fb_attribute_get_type(attribute);
belle_sdp_rtcp_fb_val_param_t param = belle_sdp_rtcp_fb_attribute_get_param(attribute);
belle_sip_error_code error = belle_sdp_attribute_marshal(BELLE_SDP_ATTRIBUTE(attribute), buff, buff_size, offset);
if (error != BELLE_SIP_OK) return error;
if (id < 0) {
error = belle_sip_snprintf(buff, buff_size, offset, ":* ");
} else {
error = belle_sip_snprintf(buff, buff_size, offset, ":%u ", id);
}
if (error != BELLE_SIP_OK) return error;
switch (type) {
case BELLE_SDP_RTCP_FB_ACK:
error = belle_sip_snprintf(buff, buff_size, offset, "ack");
if (error != BELLE_SIP_OK) return error;
switch (param) {
default:
case BELLE_SDP_RTCP_FB_NONE:
break;
case BELLE_SDP_RTCP_FB_RPSI:
error = belle_sip_snprintf(buff, buff_size, offset, " rpsi");
break;
case BELLE_SDP_RTCP_FB_APP:
error = belle_sip_snprintf(buff, buff_size, offset, " app");
break;
}
break;
case BELLE_SDP_RTCP_FB_NACK:
error = belle_sip_snprintf(buff, buff_size, offset, "nack");
if (error != BELLE_SIP_OK) return error;
switch (param) {
default:
case BELLE_SDP_RTCP_FB_NONE:
break;
case BELLE_SDP_RTCP_FB_PLI:
error = belle_sip_snprintf(buff, buff_size, offset, " pli");
break;
case BELLE_SDP_RTCP_FB_SLI:
error = belle_sip_snprintf(buff, buff_size, offset, " sli");
break;
case BELLE_SDP_RTCP_FB_RPSI:
error = belle_sip_snprintf(buff, buff_size, offset, " rpsi");
break;
case BELLE_SDP_RTCP_FB_APP:
error = belle_sip_snprintf(buff, buff_size, offset, " app");
break;
}
break;
case BELLE_SDP_RTCP_FB_TRR_INT:
error = belle_sip_snprintf(buff, buff_size, offset, "trr-int %u", belle_sdp_rtcp_fb_attribute_get_trr_int(attribute));
break;
}
return error;
}
static void belle_sdp_rtcp_fb_attribute_init(belle_sdp_rtcp_fb_attribute_t* attribute) {
belle_sdp_attribute_set_name(BELLE_SDP_ATTRIBUTE(attribute), "rtcp-fb");
attribute->id = -1;
attribute->type = BELLE_SDP_RTCP_FB_TRR_INT;
attribute->param = BELLE_SDP_RTCP_FB_NONE;
attribute->trr_int = 0;
}
BELLE_SDP_NEW_WITH_CTR(rtcp_fb_attribute,belle_sdp_attribute)
BELLE_SDP_PARSE(rtcp_fb_attribute)
GET_SET_INT(belle_sdp_rtcp_fb_attribute,id,int8_t)
GET_SET_INT(belle_sdp_rtcp_fb_attribute,type,belle_sdp_rtcp_fb_val_type_t)
GET_SET_INT(belle_sdp_rtcp_fb_attribute,param,belle_sdp_rtcp_fb_val_param_t)
GET_SET_INT(belle_sdp_rtcp_fb_attribute,trr_int,uint8_t)
/***************************************************************************************
* RTCP-XR Attribute
*
......
......@@ -171,6 +171,7 @@ BELLE_SIP_DECLARE_VPTR(belle_sdp_origin_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_phone_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_raw_attribute_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_repeate_time_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_rtcp_fb_attribute_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_rtcp_xr_attribute_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_session_description_t);
BELLE_SIP_DECLARE_VPTR(belle_sdp_session_name_t);
......
......@@ -76,6 +76,7 @@ options {
#pragma GCC diagnostic ignored "-Wunused-function"
#endif
}
/*
@rulecatch
{
if (HASEXCEPTION())
......@@ -87,6 +88,7 @@ options {
EXCEPTION->type = ANTLR3_RECOGNITION_EXCEPTION;
}
}
*/
@includes {
#include "belle-sip/defs.h"
......@@ -246,7 +248,7 @@ catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
belle_sip_message("[\%s] reason [\%s]",(const char*)EXCEPTION->name,(const char*)EXCEPTION->message);
belle_sip_object_unref($ret);
$ret=NULL;
}
}
rtcp_xr_attribute_value :
(pkt_loss_rle)=> pkt_loss_rle
| (pkt_dup_rle)=> pkt_dup_rle
......@@ -287,6 +289,87 @@ rtcp_xr_stat_summary_flag :
rtcp_xr_max_size : DIGIT+;
rtcp_fb_attribute returns [belle_sdp_rtcp_fb_attribute_t* ret]
scope { belle_sdp_rtcp_fb_attribute_t* current; }
@init { $rtcp_fb_attribute::current = belle_sdp_rtcp_fb_attribute_new();$ret = $rtcp_fb_attribute::current;}
: {IS_TOKEN(a)}?alpha_num EQUAL {IS_TOKEN(rtcp-fb)}? attribute_name /*'rtcp-fb'*/ COLON rtcp_fb_pt SPACE rtcp_fb_val;
catch [ANTLR3_MISMATCHED_TOKEN_EXCEPTION]
{
belle_sip_message("[\%s] reason [\%s]",(const char*)EXCEPTION->name,(const char*)EXCEPTION->message);
belle_sip_object_unref($ret);
$ret=NULL;
}
rtcp_fb_pt: STAR {
belle_sdp_rtcp_fb_attribute_set_id($rtcp_fb_attribute::current,-1);
} | integer {
belle_sdp_rtcp_fb_attribute_set_id($rtcp_fb_attribute::current,atoi((const char*)$integer.text->chars));
};
rtcp_fb_val :
(rtcp_fb_ack_val)=>rtcp_fb_ack_val
| (rtcp_fb_nack_val)=>rtcp_fb_nack_val
| (rtcp_fb_trr_int_val)=>rtcp_fb_trr_int_val
| (rtcp_fb_id_val)=>rtcp_fb_id_val;
rtcp_fb_ack_val:
{IS_TOKEN(ack)}? rtcp_fb_attribute_name /*'ack'*/ (SPACE rtcp_fb_ack_param)? {
belle_sdp_rtcp_fb_attribute_set_type($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_ACK);
};
rtcp_fb_nack_val:
{IS_TOKEN(nack)}? rtcp_fb_attribute_name /*'nack'*/ (SPACE rtcp_fb_nack_param)? {
belle_sdp_rtcp_fb_attribute_set_type($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_NACK);
};
rtcp_fb_trr_int_val:
{IS_TOKEN(trr-int)}? rtcp_fb_attribute_name /*'trr-int'*/ SPACE integer {
belle_sdp_rtcp_fb_attribute_set_type($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_TRR_INT);
belle_sdp_rtcp_fb_attribute_set_trr_int($rtcp_fb_attribute::current,(uint8_t)atoi((const char*)$integer.text->chars));
};
rtcp_fb_id_val:
rtcp_fb_attribute_name (SPACE rtcp_fb_param)?;
rtcp_fb_param:
(rtcp_fb_app_param)=>rtcp_fb_app_param
| (rtcp_fb_token_param)=>rtcp_fb_token_param;
rtcp_fb_ack_param:
(rtcp_fb_rpsi_param)=>rtcp_fb_rpsi_param
| (rtcp_fb_app_param)=>rtcp_fb_app_param
| (rtcp_fb_token_param)=>rtcp_fb_token_param;
rtcp_fb_nack_param:
(rtcp_fb_pli_param)=>rtcp_fb_pli_param
| (rtcp_fb_sli_param)=>rtcp_fb_sli_param
| (rtcp_fb_rpsi_param)=>rtcp_fb_rpsi_param
| (rtcp_fb_app_param)=>rtcp_fb_app_param
| (rtcp_fb_token_param)=>rtcp_fb_token_param;
rtcp_fb_pli_param:
{IS_TOKEN(pli)}? rtcp_fb_attribute_name /*'pli'*/ {
belle_sdp_rtcp_fb_attribute_set_param($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_PLI);
};
rtcp_fb_sli_param:
{IS_TOKEN(sli)}? rtcp_fb_attribute_name /*'sli'*/ {
belle_sdp_rtcp_fb_attribute_set_param($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_SLI);
};
rtcp_fb_rpsi_param:
{IS_TOKEN(rpsi)}? rtcp_fb_attribute_name /*'rpsi'*/ {
belle_sdp_rtcp_fb_attribute_set_param($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_RPSI);
};
rtcp_fb_app_param:
{IS_TOKEN(app)}? rtcp_fb_attribute_name /*'app'*/ (SPACE byte_string) {
belle_sdp_rtcp_fb_attribute_set_param($rtcp_fb_attribute::current,BELLE_SDP_RTCP_FB_APP);
};
rtcp_fb_token_param:
rtcp_fb_attribute_name (SPACE byte_string)?;
media_description returns [belle_sdp_media_description_t* ret]
scope { belle_sdp_media_description_t* current; }
@init {$media_description::current = belle_sdp_media_description_new(); $ret=$media_description::current; }
......@@ -347,6 +430,8 @@ rtcp_xr_rcvr_rtt_mode: word;
rtcp_xr_stat_summary_flag_value: word;
rtcp_fb_attribute_name: word;
sess_id: DIGIT+;
// ;should be unique for this originating username/host
......@@ -473,4 +558,5 @@ COLON: ':';
SLASH: '/';
DASH: '-';
COMMA: ',';
STAR: '*';
OCTET : .;
......@@ -70,6 +70,31 @@ static void test_attribute_2(void) {
belle_sip_object_unref(BELLE_SIP_OBJECT(lAttribute));
}
static void test_rtcp_fb_attribute(void) {
belle_sdp_rtcp_fb_attribute_t* lAttribute;
lAttribute = BELLE_SDP_RTCP_FB_ATTRIBUTE(attribute_parse_marshall_parse_clone("a=rtcp-fb:* ack"));
CU_ASSERT_STRING_EQUAL(belle_sdp_attribute_get_name(BELLE_SDP_ATTRIBUTE(lAttribute)), "rtcp-fb");
CU_ASSERT_EQUAL(belle_sdp_rtcp_fb_attribute_get_id(lAttribute), -1);
CU_ASSERT_EQUAL(belle_sdp_rtcp_fb_attribute_get_type(lAttribute), BELLE_SDP_RTCP_FB_ACK);
CU_ASSERT_EQUAL(belle_sdp_rtcp_fb_attribute_get_param(lAttribute), BELLE_SDP_RTCP_FB_NONE);
belle_sip_object_unref(BELLE_SIP_OBJECT(lAttribute));
lAttribute = BELLE_SDP_RTCP_FB_ATTRIBUTE(attribute_parse_marshall_parse_clone("a=rtcp-fb:98 nack rpsi"));
CU_ASSERT_STRING_EQUAL(belle_sdp_attribute_get_name(BELLE_SDP_ATTRIBUTE(lAttribute)), "rtcp-fb");
CU_ASSERT_EQUAL(belle_sdp_rtcp_fb_attribute_get_id(lAttribute), 98);
CU_ASSERT_EQUAL(belle_sdp_rtcp_fb_attribute_get_type(lAttribute), BELLE_SDP_RTCP_FB_NACK);
CU_ASSERT_EQUAL(belle_sdp_rtcp_fb_attribute_get_param(lAttribute), BELLE_SDP_RTCP_FB_RPSI);
belle_sip_object_unref(BELLE_SIP_OBJECT(lAttribute));
lAttribute = BELLE_SDP_RTCP_FB_ATTRIBUTE(attribute_parse_marshall_parse_clone("a=rtcp-fb:* trr-int 3"));
CU_ASSERT_STRING_EQUAL(belle_sdp_attribute_get_name(BELLE_SDP_ATTRIBUTE(lAttribute)), "rtcp-fb");
CU_ASSERT_EQUAL(belle_sdp_rtcp_fb_attribute_get_id(lAttribute), -1);
CU_ASSERT_EQUAL(belle_sdp_rtcp_fb_attribute_get_type(lAttribute), BELLE_SDP_RTCP_FB_TRR_INT);
CU_ASSERT_EQUAL(belle_sdp_rtcp_fb_attribute_get_trr_int(lAttribute), 3);
belle_sip_object_unref(BELLE_SIP_OBJECT(lAttribute));
}
static void test_rtcp_xr_attribute(void) {
belle_sdp_rtcp_xr_attribute_t* lAttribute;
......@@ -594,6 +619,7 @@ static void test_mime_parameter(void) {
test_t sdp_tests[] = {
{ "a= (attribute)", test_attribute },
{ "a= (attribute) 2", test_attribute_2 },
{ "a=rtcp-fb", test_rtcp_fb_attribute },
{ "a=rtcp-xr", test_rtcp_xr_attribute },
{ "b= (bandwidth)", test_bandwidth },
{ "o= (IPv4 origin)", test_origin },
......
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