Commit 16180e24 authored by Simon Morlat's avatar Simon Morlat

change the way payload type numbers are assigned, so that an application can...

change the way payload type numbers are assigned, so that an application can support more payload type than the RTP profile table allows to contain.
Compliance with RFC3264 (offer answer model) is improved, by reusing numbers in case of reINVITEs.
Fix memory leaks
Move offer/answer related tests into a new test suite.
parent 317504a3
......@@ -18,7 +18,8 @@ common_SRC_FILES := \
transport_tester.c \
player_tester.c \
dtmf_tester.c \
accountmanager.c
accountmanager.c \
offeranswer_tester.c
common_C_INCLUDES += \
$(LOCAL_PATH) \
......
......@@ -235,7 +235,10 @@ int sal_ping(SalOp *op, const char *from, const char *to){
void sal_op_set_remote_ua(SalOp*op,belle_sip_message_t* message) {
belle_sip_header_user_agent_t* user_agent=belle_sip_message_get_header_by_type(message,belle_sip_header_user_agent_t);
char user_agent_string[256];
if(user_agent && belle_sip_header_user_agent_get_products_as_string(user_agent,user_agent_string,sizeof(user_agent_string))>0) {
if (user_agent && belle_sip_header_user_agent_get_products_as_string(user_agent,user_agent_string,sizeof(user_agent_string))>0) {
if (op->base.remote_ua!=NULL){
ms_free(op->base.remote_ua);
}
op->base.remote_ua=ms_strdup(user_agent_string);
}
}
......
......@@ -96,7 +96,23 @@ static void prepare_early_media_forking(LinphoneCall *call){
if (call->videostream){
rtp_session_set_symmetric_rtp(call->videostream->ms.sessions.rtp_session,FALSE);
}
}
void linphone_call_update_frozen_payloads(LinphoneCall *call, SalMediaDescription *result_desc){
SalMediaDescription *local=call->localdesc;
int i;
for(i=0;i<result_desc->nb_streams;++i){
MSList *elem;
for (elem=result_desc->streams[i].payloads;elem!=NULL;elem=elem->next){
PayloadType *pt=(PayloadType*)elem->data;
if (is_payload_type_number_available(local->streams[i].already_assigned_payloads, payload_type_get_number(pt), NULL)){
/*new codec, needs to be added to the list*/
local->streams[i].already_assigned_payloads=ms_list_append(local->streams[i].already_assigned_payloads, payload_type_clone(pt));
ms_message("LinphoneCall[%p] : payload type %i %s/%i fmtp=%s added to frozen list.",
call, payload_type_get_number(pt), pt->mime_type, pt->clock_rate, pt->recv_fmtp ? pt->recv_fmtp : NULL);
}
}
}
}
void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMediaDescription *new_md){
......@@ -181,6 +197,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
if (call->state==LinphoneCallPausing && call->paused_by_app && ms_list_size(lc->calls)==1){
linphone_core_play_named_tone(lc,LinphoneToneCallOnHold);
}
linphone_call_update_frozen_payloads(call, new_md);
end:
if (oldmd)
sal_media_description_unref(oldmd);
......
......@@ -228,35 +228,154 @@ void linphone_call_set_authentication_token_verified(LinphoneCall *call, bool_t
propagate_encryption_changed(call);
}
static MSList *make_codec_list(LinphoneCore *lc, const MSList *codecs, int bandwidth_limit,int* max_sample_rate, int nb_codecs_limit){
MSList *l=NULL;
static int get_max_codec_sample_rate(const MSList *codecs){
int max_sample_rate=0;
const MSList *it;
int nb = 0;
if (max_sample_rate) *max_sample_rate=0;
for(it=codecs;it!=NULL;it=it->next){
PayloadType *pt=(PayloadType*)it->data;
if (pt->flags & PAYLOAD_TYPE_ENABLED){
int sample_rate = payload_type_get_rate(pt);
int sample_rate;
if( strcasecmp("G722",pt->mime_type) == 0 ){
/* G722 spec says 8000 but the codec actually requires 16000 */
sample_rate = 16000;
}else sample_rate=pt->clock_rate;
if (sample_rate>max_sample_rate) max_sample_rate=sample_rate;
}
return max_sample_rate;
}
if( strcasecmp("G722",pt->mime_type) == 0 ){
/* G722 spec says 8000 but the codec actually requires 16000 */
ms_debug("Correcting sample rate for G722");
sample_rate = 16000;
static int find_payload_type_number(const MSList *assigned, const PayloadType *pt){
const MSList *elem;
const PayloadType *candidate=NULL;
for(elem=assigned;elem!=NULL;elem=elem->next){
const PayloadType *it=(const PayloadType*)elem->data;
if ((strcasecmp(pt->mime_type, payload_type_get_mime(it)) == 0)
&& (it->clock_rate==pt->clock_rate)
&& (it->channels==pt->channels || pt->channels<=0)) {
candidate=it;
if ((it->recv_fmtp!=NULL && pt->recv_fmtp!=NULL && strcasecmp(it->recv_fmtp, pt->recv_fmtp)==0)
|| (it->recv_fmtp==NULL && pt->recv_fmtp==NULL)){
break;/*exact match*/
}
}
}
return candidate ? payload_type_get_number(candidate) : -1;
}
if (bandwidth_limit>0 && !linphone_core_is_payload_type_usable_for_bandwidth(lc,pt,bandwidth_limit)){
ms_message("Codec %s/%i eliminated because of audio bandwidth constraint of %i kbit/s",
pt->mime_type,pt->clock_rate,bandwidth_limit);
continue;
bool_t is_payload_type_number_available(const MSList *l, int number, const PayloadType *ignore){
const MSList *elem;
for (elem=l; elem!=NULL; elem=elem->next){
const PayloadType *pt=(PayloadType*)elem->data;
if (pt!=ignore && payload_type_get_number(pt)==number) return FALSE;
}
return TRUE;
}
static void linphone_core_assign_payload_type_numbers(LinphoneCore *lc, MSList *codecs){
MSList *elem;
int dyn_number=lc->codecs_conf.dyn_pt;
for (elem=codecs; elem!=NULL; elem=elem->next){
PayloadType *pt=(PayloadType*)elem->data;
int number=payload_type_get_number(pt);
/*check if number is duplicated: it could be the case if the remote forced us to use a mapping with a previous offer*/
if (number!=-1 && !(pt->flags & PAYLOAD_TYPE_FROZEN_NUMBER)){
if (!is_payload_type_number_available(codecs, number, pt)){
ms_message("Reassigning payload type %i %s/%i because already offered.", number, pt->mime_type, pt->clock_rate);
number=-1; /*need to be re-assigned*/
}
}
if (number==-1){
while(dyn_number<127){
if (is_payload_type_number_available(codecs, dyn_number, NULL)){
payload_type_set_number(pt, dyn_number);
dyn_number++;
break;
}
dyn_number++;
}
if (linphone_core_check_payload_type_usability(lc,pt)){
l=ms_list_append(l,payload_type_clone(pt));
nb++;
if (max_sample_rate && sample_rate>*max_sample_rate) *max_sample_rate=sample_rate;
if (dyn_number==127){
ms_error("Too many payload types configured ! codec %s/%i is disabled.", pt->mime_type, pt->clock_rate);
payload_type_set_enable(pt, FALSE);
}
}
}
}
static bool_t has_telephone_event_at_rate(const MSList *tev, int rate){
const MSList *it;
for(it=tev;it!=NULL;it=it->next){
const PayloadType *pt=(PayloadType*)it->data;
if (pt->clock_rate==rate) return TRUE;
}
return FALSE;
}
static MSList * create_telephone_events(LinphoneCore *lc, const MSList *codecs){
const MSList *it;
MSList *ret=NULL;
for(it=codecs;it!=NULL;it=it->next){
const PayloadType *pt=(PayloadType*)it->data;
if (!has_telephone_event_at_rate(ret,pt->clock_rate)){
PayloadType *tev=payload_type_clone(&payload_type_telephone_event);
tev->clock_rate=pt->clock_rate;
/*let it choose the number dynamically as for normal codecs*/
payload_type_set_number(tev, -1);
if (ret==NULL){
/*But for first telephone-event, prefer the number that was configured in the core*/
if (is_payload_type_number_available(codecs, lc->codecs_conf.telephone_event_pt, NULL)){
payload_type_set_number(tev, lc->codecs_conf.telephone_event_pt);
}
}
ret=ms_list_append(ret,tev);
}
if ((nb_codecs_limit > 0) && (nb >= nb_codecs_limit)) break;
}
return ret;
}
typedef struct _CodecConstraints{
int bandwidth_limit;
int max_codecs;
MSList *previously_used;
}CodecConstraints;
static MSList *make_codec_list(LinphoneCore *lc, CodecConstraints * hints, const MSList *codecs){
MSList *l=NULL;
MSList *tevs=NULL;
const MSList *it;
int nb = 0;
for(it=codecs;it!=NULL;it=it->next){
PayloadType *pt=(PayloadType*)it->data;
int num;
if (!(pt->flags & PAYLOAD_TYPE_ENABLED))
continue;
if (hints->bandwidth_limit>0 && !linphone_core_is_payload_type_usable_for_bandwidth(lc,pt,hints->bandwidth_limit)){
ms_message("Codec %s/%i eliminated because of audio bandwidth constraint of %i kbit/s",
pt->mime_type,pt->clock_rate,hints->bandwidth_limit);
continue;
}
if (!linphone_core_check_payload_type_usability(lc,pt)){
continue;
}
pt=payload_type_clone(pt);
/*look for a previously assigned number for this codec*/
num=find_payload_type_number(hints->previously_used, pt);
if (num!=-1){
payload_type_set_number(pt,num);
payload_type_set_flag(pt, PAYLOAD_TYPE_FROZEN_NUMBER);
}
l=ms_list_append(l, pt);
nb++;
if ((hints->max_codecs > 0) && (nb >= hints->max_codecs)) break;
}
tevs=create_telephone_events(lc,l);
l=ms_list_concat(l,tevs);
linphone_core_assign_payload_type_numbers(lc, l);
return l;
}
......@@ -395,9 +514,16 @@ void linphone_call_update_local_media_description_from_ice_or_upnp(LinphoneCall
#endif //BUILD_UPNP
}
static void transfer_already_assigned_payload_types(SalMediaDescription *old, SalMediaDescription *md){
int i;
for(i=0;i<old->nb_streams;++i){
md->streams[i].already_assigned_payloads=old->streams[i].already_assigned_payloads;
old->streams[i].already_assigned_payloads=NULL;
}
}
void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *call){
MSList *l;
PayloadType *pt;
SalMediaDescription *old_md=call->localdesc;
int i;
int nb_active_streams = 0;
......@@ -406,6 +532,7 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
LinphoneAddress *addr;
char* local_ip=call->localip;
const char *subject=linphone_call_params_get_session_name(call->params);
CodecConstraints codec_hints={0};
linphone_core_adapt_to_network(lc,call->ping_time,call->params);
......@@ -439,9 +566,11 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
md->streams[0].ptime=call->params->down_ptime;
else
md->streams[0].ptime=linphone_core_get_download_ptime(lc);
l=make_codec_list(lc,lc->codecs_conf.audio_codecs,call->params->audio_bw,&md->streams[0].max_rate,-1);
pt=payload_type_clone(rtp_profile_get_payload_from_mime(lc->default_profile,"telephone-event"));
l=ms_list_append(l,pt);
codec_hints.bandwidth_limit=call->params->audio_bw;
codec_hints.max_codecs=-1;
codec_hints.previously_used=old_md ? old_md->streams[0].already_assigned_payloads : NULL;
l=make_codec_list(lc, &codec_hints, lc->codecs_conf.audio_codecs);
md->streams[0].max_rate=get_max_codec_sample_rate(l);
md->streams[0].payloads=l;
nb_active_streams++;
......@@ -453,7 +582,10 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
md->streams[1].rtcp_port=call->media_ports[1].rtcp_port;
md->streams[1].proto=md->streams[0].proto;
md->streams[1].type=SalVideo;
l=make_codec_list(lc,lc->codecs_conf.video_codecs,0,NULL,-1);
codec_hints.bandwidth_limit=0;
codec_hints.max_codecs=-1;
codec_hints.previously_used=old_md ? old_md->streams[1].already_assigned_payloads : NULL;
l=make_codec_list(lc, &codec_hints, lc->codecs_conf.video_codecs);
md->streams[1].payloads=l;
nb_active_streams++;
}
......@@ -468,7 +600,10 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
md->streams[i].proto = call->biggestdesc->streams[i].proto;
md->streams[i].type = call->biggestdesc->streams[i].type;
md->streams[i].dir = SalStreamInactive;
l = make_codec_list(lc, lc->codecs_conf.video_codecs, 0, NULL, 1);
codec_hints.bandwidth_limit=0;
codec_hints.max_codecs=1;
codec_hints.previously_used=NULL;
l = make_codec_list(lc, &codec_hints, lc->codecs_conf.video_codecs);
md->streams[i].payloads = l;
}
......@@ -481,6 +616,7 @@ void linphone_call_make_local_media_description(LinphoneCore *lc, LinphoneCall *
linphone_call_update_local_media_description_from_ice_or_upnp(call);
linphone_address_destroy(addr);
if (old_md){
transfer_already_assigned_payload_types(old_md,md);
call->localdesc_changed=sal_media_description_equals(md,old_md);
sal_media_description_unref(old_md);
}
......
This diff is collapsed.
......@@ -2345,8 +2345,19 @@ LINPHONE_PUBLIC int linphone_core_enable_payload_type(LinphoneCore *lc, Linphone
*/
LINPHONE_PUBLIC LinphonePayloadType* linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) ;
/**
* @ingroup media_parameters
* Returns the payload type number assigned for this codec.
**/
LINPHONE_PUBLIC int linphone_core_get_payload_type_number(LinphoneCore *lc, const PayloadType *pt);
/**
* @ingroup media_parameters
* Force a number for a payload type. The LinphoneCore does payload type number assignment automatically. THis function is to be used mainly for tests, in order
* to override the automatic assignment mechanism.
**/
LINPHONE_PUBLIC void linphone_core_set_payload_type_number(LinphoneCore *lc, PayloadType *pt, int number);
LINPHONE_PUBLIC const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt);
LINPHONE_PUBLIC bool_t linphone_core_check_payload_type_usability(LinphoneCore *lc, const PayloadType *pt);
......
......@@ -59,15 +59,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define RTP_HDR_SZ 12
#define IP4_HDR_SZ 20 /*20 is the minimum, but there may be some options*/
static void payload_type_set_enable(PayloadType *pt,int value)
{
if ((value)!=0) payload_type_set_flag(pt,PAYLOAD_TYPE_ENABLED); \
else payload_type_unset_flag(pt,PAYLOAD_TYPE_ENABLED);
}
static bool_t payload_type_enabled(const PayloadType *pt) {
return (((pt)->flags & PAYLOAD_TYPE_ENABLED)!=0);
}
bool_t linphone_core_payload_type_enabled(LinphoneCore *lc, const LinphonePayloadType *pt){
if (ms_list_find(lc->codecs_conf.audio_codecs, (PayloadType*) pt) || ms_list_find(lc->codecs_conf.video_codecs, (PayloadType*)pt)){
......@@ -97,6 +88,10 @@ int linphone_core_get_payload_type_number(LinphoneCore *lc, const PayloadType *p
return payload_type_get_number(pt);
}
void linphone_core_set_payload_type_number(LinphoneCore *lc, PayloadType *pt, int number){
payload_type_set_number(pt,number);
}
const char *linphone_core_get_payload_type_description(LinphoneCore *lc, PayloadType *pt){
if (ms_filter_codec_supported(pt->mime_type)){
MSFilterDesc *desc=ms_filter_get_encoder(pt->mime_type);
......
......@@ -110,6 +110,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
res=ms_list_append(res,newp);
/* we should use the remote numbering even when parsing a response */
payload_type_set_number(newp,remote_number);
payload_type_set_flag(newp, PAYLOAD_TYPE_FROZEN_NUMBER);
if (reading_response && remote_number!=local_number){
ms_warning("For payload type %s, proposed number was %i but the remote phone answered %i",
newp->mime_type, local_number, remote_number);
......@@ -120,6 +121,7 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
*/
newp=payload_type_clone(newp);
payload_type_set_number(newp,local_number);
payload_type_set_flag(newp, PAYLOAD_TYPE_FROZEN_NUMBER);
res=ms_list_append(res,newp);
}
}else{
......@@ -143,7 +145,8 @@ static MSList *match_payloads(const MSList *local, const MSList *remote, bool_t
if (!found){
ms_message("Adding %s/%i for compatibility, just in case.",p1->mime_type,p1->clock_rate);
p1=payload_type_clone(p1);
p1->flags|=PAYLOAD_TYPE_FLAG_CAN_RECV;
payload_type_set_flag(p1, PAYLOAD_TYPE_FLAG_CAN_RECV);
payload_type_set_flag(p1, PAYLOAD_TYPE_FROZEN_NUMBER);
res=ms_list_append(res,p1);
}
}
......
......@@ -365,6 +365,7 @@ static MS2_INLINE void set_string(char **dest, const char *src){
#define PAYLOAD_TYPE_ENABLED PAYLOAD_TYPE_USER_FLAG_0
#define PAYLOAD_TYPE_BITRATE_OVERRIDE PAYLOAD_TYPE_USER_FLAG_3
#define PAYLOAD_TYPE_FROZEN_NUMBER PAYLOAD_TYPE_USER_FLAG_4
void linphone_process_authentication(LinphoneCore* lc, SalOp *op);
void linphone_authentication_ok(LinphoneCore *lc, SalOp *op);
......@@ -643,7 +644,9 @@ typedef struct sound_config
typedef struct codecs_config
{
MSList *audio_codecs; /* list of audio codecs in order of preference*/
MSList *video_codecs; /* for later use*/
MSList *video_codecs;
int dyn_pt;
int telephone_event_pt;
}codecs_config_t;
typedef struct video_config{
......@@ -710,7 +713,8 @@ struct _LinphoneCore
Sal *sal;
LinphoneGlobalState state;
struct _LpConfig *config;
RtpProfile *default_profile;
MSList *default_audio_codecs;
MSList *default_video_codecs;
net_config_t net_conf;
sip_config_t sip_conf;
rtp_config_t rtp_conf;
......@@ -719,8 +723,6 @@ struct _LinphoneCore
codecs_config_t codecs_conf;
ui_config_t ui_conf;
autoreplier_config_t autoreplier_conf;
MSList *payload_types;
int dyn_pt;
LinphoneProxyConfig *default_proxy;
MSList *friends;
MSList *auth_info;
......@@ -1014,6 +1016,18 @@ static MS2_INLINE const LinphoneErrorInfo *linphone_error_info_from_sal_op(const
return (const LinphoneErrorInfo*)sal_op_get_error_info(op);
}
static MS2_INLINE void payload_type_set_enable(PayloadType *pt,int value)
{
if ((value)!=0) payload_type_set_flag(pt,PAYLOAD_TYPE_ENABLED); \
else payload_type_unset_flag(pt,PAYLOAD_TYPE_ENABLED);
}
static MS2_INLINE bool_t payload_type_enabled(const PayloadType *pt) {
return (((pt)->flags & PAYLOAD_TYPE_ENABLED)!=0);
}
bool_t is_payload_type_number_available(const MSList *l, int number, const PayloadType *ignore);
const MSCryptoSuite * linphone_core_get_srtp_crypto_suites(LinphoneCore *lc);
/** Belle Sip-based objects need unique ids
......
......@@ -332,6 +332,7 @@ static int send_report(LinphoneCall* call, reporting_session_report_t * report,
}
linphone_content_set_buffer(content, buffer, strlen(buffer));
ms_free(buffer);
if (call->log->reporting.on_report_sent != NULL){
call->log->reporting.on_report_sent(
......
......@@ -62,9 +62,10 @@ SalMediaDescription *sal_media_description_new(){
static void sal_media_description_destroy(SalMediaDescription *md){
int i;
for(i=0;i<SAL_MEDIA_DESCRIPTION_MAX_STREAMS;i++){
ms_list_for_each(md->streams[i].payloads,(void (*)(void *))payload_type_destroy);
ms_list_free(md->streams[i].payloads);
ms_list_free_with_data(md->streams[i].payloads,(void (*)(void *))payload_type_destroy);
ms_list_free_with_data(md->streams[i].already_assigned_payloads,(void (*)(void *))payload_type_destroy);
md->streams[i].payloads=NULL;
md->streams[i].already_assigned_payloads=NULL;
}
ms_free(md);
}
......
......@@ -196,7 +196,8 @@ typedef struct SalStreamDescription{
char rtcp_addr[64];
int rtp_port;
int rtcp_port;
MSList *payloads; //<list of PayloadType
MSList *payloads; /*<list of PayloadType */
MSList *already_assigned_payloads; /*<list of PayloadType offered in the past, used for correct allocation of payload type numbers*/
int bandwidth;
int ptime;
SalStreamDir dir;
......
mediastreamer2 @ 7d2a3021
Subproject commit 5662b24bc9ddd186daae74555b05b42bfedd763d
Subproject commit 7d2a30214b8010224eed26bc1f239907618b9674
oRTP @ e5470e27
Subproject commit 0ad89f5e106d9f9a4a1d0608101d26b9a10be8b7
Subproject commit e5470e271d5be74f425db9221cd35a60ce4cf52e
......@@ -26,7 +26,8 @@ liblinphonetester_la_SOURCES = tester.c \
transport_tester.c \
player_tester.c \
dtmf_tester.c \
accountmanager.c
accountmanager.c \
offeranswer_tester.c
liblinphonetester_la_LDFLAGS= -no-undefined
liblinphonetester_la_LIBADD= ../coreapi/liblinphone.la $(CUNIT_LIBS)
......
......@@ -77,6 +77,7 @@ void account_manager_destroy(void){
ms_free(the_am);
}
the_am=NULL;
ms_message("Test account manager destroyed.");
}
Account *account_manager_get_account(AccountManager *m, const LinphoneAddress *identity){
......@@ -211,10 +212,6 @@ void linphone_core_manager_check_accounts(LinphoneCoreManager *m){
for(it=linphone_core_get_proxy_config_list(m->lc);it!=NULL;it=it->next){
LinphoneProxyConfig *cfg=(LinphoneProxyConfig *)it->data;
LinphoneAddress *modified_identity=account_manager_check_account(am,cfg);
if (m->identity){
linphone_address_unref(m->identity);
}
m->identity=linphone_address_ref(modified_identity);
account_manager_check_account(am,cfg);
}
}
......@@ -34,7 +34,6 @@
static void srtp_call(void);
static void call_base(LinphoneMediaEncryption mode, bool_t enable_video,bool_t enable_relay,LinphoneFirewallPolicy policy);
static void disable_all_audio_codecs_except_one(LinphoneCore *lc, const char *mime, int rate);
static char *create_filepath(const char *dir, const char *filename, const char *ext);
// prototype definition for call_recording()
......@@ -727,7 +726,7 @@ static void cancelled_call(void) {
linphone_core_manager_destroy(pauline);
}
static void disable_all_audio_codecs_except_one(LinphoneCore *lc, const char *mime, int rate){
void disable_all_audio_codecs_except_one(LinphoneCore *lc, const char *mime, int rate){
const MSList *elem=linphone_core_get_audio_codecs(lc);
PayloadType *pt;
......@@ -754,40 +753,6 @@ static void disable_all_video_codecs_except_one(LinphoneCore *lc, const char *mi
}
#endif
static void call_failed_because_of_codecs(void) {
int begin,leaked_objects;
belle_sip_object_enable_leak_detector(TRUE);
begin=belle_sip_object_get_object_count();
{
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
LinphoneCall* out_call;
disable_all_audio_codecs_except_one(marie->lc,"pcmu",-1);
disable_all_audio_codecs_except_one(pauline->lc,"pcma",-1);
out_call = linphone_core_invite_address(pauline->lc,marie->identity);
linphone_call_ref(out_call);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallOutgoingInit,1));
/*flexisip will retain the 488 until the "urgent reply" timeout (I.E 5s) arrives.*/
CU_ASSERT_TRUE(wait_for_until(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallError,1,7000));
CU_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonNotAcceptable);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallIncomingReceived,0);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallReleased,0);
linphone_call_unref(out_call);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
leaked_objects=belle_sip_object_get_object_count()-begin;
CU_ASSERT_TRUE(leaked_objects==0);
if (leaked_objects>0){
belle_sip_object_dump_active_objects();
}
}
static void call_with_dns_time_out(void) {
LinphoneCoreManager* marie = linphone_core_manager_new2( "empty_rc", FALSE);
LCSipTransports transport = {9773,0,0,0};
......@@ -3036,115 +3001,6 @@ static void multiple_early_media(void) {
}
#endif
static void profile_call(bool_t avpf1, bool_t srtp1, bool_t avpf2, bool_t srtp2, const char *expected_profile) {
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_rc");
LinphoneProxyConfig *lpc;
const LinphoneCallParams *params;
if (avpf1) {
linphone_core_get_default_proxy(marie->lc, &lpc);
linphone_proxy_config_enable_avpf(lpc, TRUE);
linphone_proxy_config_set_avpf_rr_interval(lpc, 3);
}
if (avpf2) {
linphone_core_get_default_proxy(pauline->lc, &lpc);
linphone_proxy_config_enable_avpf(lpc, TRUE);
linphone_proxy_config_set_avpf_rr_interval(lpc, 3);
}
if (srtp1) {
if (linphone_core_media_encryption_supported(marie->lc, LinphoneMediaEncryptionSRTP)) {
linphone_core_set_media_encryption(marie->lc, LinphoneMediaEncryptionSRTP);
}
}
if (srtp2) {
if (linphone_core_media_encryption_supported(pauline->lc, LinphoneMediaEncryptionSRTP)) {
linphone_core_set_media_encryption(pauline->lc, LinphoneMediaEncryptionSRTP);
}
}
CU_ASSERT_TRUE(call(marie, pauline));
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1));
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1));
params = linphone_call_get_current_params(linphone_core_get_current_call(marie->lc));
CU_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
params = linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc));
CU_ASSERT_STRING_EQUAL(linphone_call_params_get_rtp_profile(params), expected_profile);
linphone_core_terminate_all_calls(marie->lc);
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
CU_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallConnected, 1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallConnected, 1);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
}
static void avp_to_avp_call(void) {
profile_call(FALSE, FALSE, FALSE, FALSE, "RTP/AVP");
}
static void avp_to_avpf_call(void) {
profile_call(FALSE, FALSE, TRUE, FALSE, "RTP/AVP");
}
static void avp_to_savp_call(void) {
profile_call(FALSE, FALSE, FALSE, TRUE, "RTP/AVP");
}
static void avp_to_savpf_call(void) {
profile_call(FALSE, FALSE, TRUE, TRUE, "RTP/AVP");
}
static void avpf_to_avp_call(void) {
profile_call(TRUE, FALSE, FALSE, FALSE, "RTP/AVPF");
}
static void avpf_to_avpf_call(void) {
profile_call(TRUE, FALSE, TRUE, FALSE, "RTP/AVPF");
}
static void avpf_to_savp_call(void) {
profile_call(TRUE, FALSE, FALSE, TRUE, "RTP/AVPF");
}
static void avpf_to_savpf_call(void) {
profile_call(TRUE, FALSE, TRUE, TRUE, "RTP/AVPF");
}
static void savp_to_avp_call(void) {
profile_call(FALSE, TRUE, FALSE, FALSE, "RTP/SAVP");
}
static void savp_to_avpf_call(void) {
profile_call(FALSE, TRUE, TRUE, FALSE, "RTP/SAVP");
}
static void savp_to_savp_call(void) {
profile_call(FALSE, TRUE, FALSE, TRUE, "RTP/SAVP");
}
static void savp_to_savpf_call(void) {
profile_call(FALSE, TRUE, TRUE, TRUE, "RTP/SAVP");
}
static void savpf_to_avp_call(void) {
profile_call(TRUE, TRUE, FALSE, FALSE, "RTP/SAVPF");
}
static void savpf_to_avpf_call(void) {
profile_call(TRUE, TRUE, TRUE, FALSE, "RTP/SAVPF");
}
static void savpf_to_savp_call(void) {
profile_call(TRUE, TRUE, FALSE, TRUE, "RTP/SAVPF");
}
static void savpf_to_savpf_call(void) {
profile_call(TRUE, TRUE, TRUE, TRUE, "RTP/SAVPF");
}
static char *create_filepath(const char *dir, const char *filename, const char *ext) {
return ms_strdup_printf("%s/%s.%s",dir,filename,ext);
}
......@@ -3530,7 +3386,6 @@ test_t call_tests[] = {
{ "Early cancelled call", early_cancelled_call},
{ "Call with DNS timeout", call_with_dns_time_out },
{ "Cancelled ringing call", cancelled_ringing_call },
{ "Call failed because of codecs", call_failed_because_of_codecs },
{ "Simple call", simple_call },
{ "Call with timeouted bye", call_with_timeouted_bye },
{ "Direct call over IPv6", direct_call_over_ipv6},
......@@ -3607,22 +3462,6 @@ test_t call_tests[] = {
{ "Call established with rejected RE-INVITE in error", call_established_with_rejected_reinvite_with_error},
{ "Call redirected by callee", call_redirect},
{ "Call with specified codec bitrate", call_with_specified_codec_bitrate},
{ "AVP to AVP call", avp_to_avp_call },
{ "AVP to AVPF call", avp_to_avpf_call },
{ "AVP to SAVP call", avp_to_savp_call },
{ "AVP to SAVPF call", avp_to_savpf_call },
{ "AVPF to AVP call", avpf_to_avp_call },
{ "AVPF to AVPF call", avpf_to_avpf_call },
{ "AVPF to SAVP call", avpf_to_savp_call },
{ "AVPF to SAVPF call", avpf_to_savpf_call },
{ "SAVP to AVP call", savp_to_avp_call },
{ "SAVP to AVPF call", savp_to_avpf_call },
{ "SAVP to SAVP call", savp_to_savp_call },
{ "SAVP to SAVPF call", savp_to_savpf_call },
{ "SAVPF to AVP call", savpf_to_avp_call },
{ "SAVPF to AVPF call", savpf_to_avpf_call },
{ "SAVPF to SAVP call", savpf_to_savp_call },
{ "SAVPF to SAVPF call", savpf_to_savpf_call },
{ "Call with in-dialog UPDATE request", call_with_in_dialog_update },
{ "Call with in-dialog codec change", call_with_in_dialog_codec_change },
{ "Call with in-dialog codec change no sdp", call_with_in_dialog_codec_change_no_sdp },
......
......@@ -62,6 +62,7 @@ extern test_suite_t log_collection_test_suite;
extern test_suite_t transport_test_suite;
extern test_suite_t player_test_suite;
extern test_suite_t dtmf_test_suite;
extern test_suite_t offeranswer_test_suite;