diff --git a/coreapi/address.c b/coreapi/address.c index 4d4b1d2d6..7475ab596 100644 --- a/coreapi/address.c +++ b/coreapi/address.c @@ -129,6 +129,29 @@ char *linphone_address_as_string_uri_only(const LinphoneAddress *u){ return sal_address_as_string_uri_only(u); } +static bool_t strings_equals(const char *s1, const char *s2){ + if (s1==NULL && s2==NULL) return TRUE; + if (s1!=NULL && s2!=NULL && strcmp(s1,s2)==0) return TRUE; + return FALSE; +} + +/** + * Compare two LinphoneAddress ignoring tags and headers, basically just domain, username, and port. + * Returns TRUE if they are equal. +**/ +bool_t linphone_address_weak_compare(const LinphoneAddress *a1, const LinphoneAddress *a2){ + const char *u1,*u2; + const char *h1,*h2; + int p1,p2; + u1=linphone_address_get_username(a1); + u2=linphone_address_get_username(a2); + p1=linphone_address_get_port_int(a1); + p2=linphone_address_get_port_int(a2); + h1=linphone_address_get_domain(a1); + h2=linphone_address_get_domain(a2); + return strings_equals(u1,u2) && strings_equals(h1,h2) && p1==p2; +} + /** * Destroys a LinphoneAddress object. **/ @@ -139,6 +162,7 @@ void linphone_address_destroy(LinphoneAddress *u){ int linphone_address_get_port_int(const LinphoneAddress *u) { return sal_address_get_port_int(u); } + const char* linphone_address_get_port(const LinphoneAddress *u) { return sal_address_get_port(u); } diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 7f5060809..53382eb27 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -35,6 +35,18 @@ static void linphone_connect_incoming(LinphoneCore *lc, LinphoneCall *call){ linphone_call_start_media_streams(call); } +static bool_t is_duplicate_call(LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to){ + MSList *elem; + for(elem=lc->calls;elem!=NULL;elem=elem->next){ + LinphoneCall *call=(LinphoneCall*)elem->data; + if (linphone_address_weak_compare(call->log->from,from) && + linphone_address_weak_compare(call->log->to, to)){ + return TRUE; + } + } + return FALSE; +} + static void call_received(SalOp *h){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(h)); char *barmesg; @@ -42,6 +54,7 @@ static void call_received(SalOp *h){ const char *from,*to; char *tmp; LinphoneAddress *from_parsed; + LinphoneAddress *from_addr, *to_addr; const char * early_media=linphone_core_get_remote_ringback_tone (lc); /* first check if we can answer successfully to this invite */ @@ -67,9 +80,18 @@ static void call_received(SalOp *h){ } from=sal_op_get_from(h); to=sal_op_get_to(h); + from_addr=linphone_address_new(from); + to_addr=linphone_address_new(to); + + if (is_duplicate_call(lc,from_addr,to_addr)){ + ms_warning("Receiving duplicated call, refusing this one."); + sal_call_decline(h,SalReasonBusy,NULL); + linphone_address_destroy(from_addr); + linphone_address_destroy(to_addr); + return; + } - call=linphone_call_new_incoming(lc,linphone_address_new(from),linphone_address_new(to),h); - + call=linphone_call_new_incoming(lc,from_addr,to_addr,h); sal_call_set_local_media_description(h,call->localdesc); call->resultdesc=sal_call_get_final_media_description(h); if (call->resultdesc) @@ -79,14 +101,11 @@ static void call_received(SalOp *h){ linphone_call_unref(call); return; } + + /* the call is acceptable so we can now add it to our list */ - if(linphone_core_add_call(lc,call)!= 0) - { - ms_warning("we cannot handle anymore call\n"); - sal_call_decline(h,SalReasonMedia,NULL); - linphone_call_unref(call); - return; - } + linphone_core_add_call(lc,call); + from_parsed=linphone_address_new(sal_op_get_from(h)); linphone_address_clean(from_parsed); tmp=linphone_address_as_string(from_parsed); @@ -322,6 +341,8 @@ static void call_updating(SalOp *op){ static void call_terminated(SalOp *op, const char *from){ LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op)); LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op); + + if (call==NULL) return; if (linphone_call_get_state(call)==LinphoneCallEnd || linphone_call_get_state(call)==LinphoneCallError){ ms_warning("call_terminated: ignoring."); diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 179002c36..f536bdd71 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -93,6 +93,7 @@ void linphone_address_set_port_int(LinphoneAddress *uri, int port); void linphone_address_clean(LinphoneAddress *uri); char *linphone_address_as_string(const LinphoneAddress *u); char *linphone_address_as_string_uri_only(const LinphoneAddress *u); +bool_t linphone_address_weak_compare(const LinphoneAddress *a1, const LinphoneAddress *a2); void linphone_address_destroy(LinphoneAddress *u); struct _SipSetupContext;