]> sjero.net Git - linphone/commitdiff
bugfix and improvements in chat support
authorSimon Morlat <simon.morlat@linphone.org>
Thu, 14 Oct 2010 17:24:15 +0000 (19:24 +0200)
committerSimon Morlat <simon.morlat@linphone.org>
Thu, 14 Oct 2010 17:24:15 +0000 (19:24 +0200)
coreapi/chat.c
coreapi/friend.c
coreapi/linphonecore.c
coreapi/presence.c
coreapi/private.h
coreapi/proxy.c
coreapi/sal_eXosip2.c
coreapi/sal_eXosip2.h
coreapi/sal_eXosip2_presence.c

index 35726796289ab46bd8df9fc4564a09104fa36b30..3a41b4c9fe4a5034ac1769ab994078232f2b0fac 100644 (file)
@@ -33,7 +33,6 @@
                cr->lc=lc;
                cr->peer=linphone_address_as_string(parsed_url);
                cr->peer_url=parsed_url;
-               cr->route=ms_strdup(linphone_core_get_route(lc));
                lc->chatrooms=ms_list_append(lc->chatrooms,(void *)cr);
                return cr;
        }
        lc->chatrooms=ms_list_remove(lc->chatrooms,(void *) cr);
        linphone_address_destroy(cr->peer_url);
        ms_free(cr->peer);
-       ms_free(cr->route);
+       if (cr->op)
+                sal_op_release(cr->op);
  }
  
 void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg){
-       const char *identity=linphone_core_get_identity(cr->lc);
+       const char *route=NULL;
+       const char *identity=linphone_core_find_best_identity(cr->lc,cr->peer_url,&route);
        SalOp *op;
        LinphoneCall *call;
        if((call = linphone_core_get_call_by_remote_address(cr->lc,cr->peer))!=NULL)
@@ -61,7 +62,12 @@ void linphone_chat_room_send_message(LinphoneChatRoom *cr, const char *msg){
        else
        {
                op = sal_op_new(cr->lc->sal);
-               sal_op_set_route(op,cr->route);
+               sal_op_set_route(op,route);
+               if (cr->op!=NULL){
+                       sal_op_release (cr->op);
+                       cr->op=NULL;
+               }
+               cr->op=op;
        }
        sal_text_send(op,identity,cr->peer,msg);
 }
index 1af7a4cb5c8e5276eb219bc0902114b6c44bea3e..1628d3e5f32a8e395689876ca4f62cccc4ea8f36 100644 (file)
@@ -128,6 +128,7 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
        char *friend=NULL;
        const char *route=NULL;
        const char *from=NULL;
+       const char *fixed_contact=NULL;
        LinphoneProxyConfig *cfg;
        
        friend=linphone_address_as_string(fr->uri);
@@ -135,6 +136,12 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
        if (cfg!=NULL){
                route=linphone_proxy_config_get_route(cfg);
                from=linphone_proxy_config_get_identity(cfg);
+               if (cfg->op){
+                       fixed_contact=sal_op_get_contact(cfg->op);
+                       if (fixed_contact) {
+                               ms_message("Contact for subscribe has been fixed using proxy to %s",fixed_contact);
+                       }
+               }
        }else from=linphone_core_get_primary_contact(fr->lc);
        if (fr->outsub==NULL){
                /* people for which we don't have yet an answer should appear as offline */
@@ -149,6 +156,7 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
        }
        fr->outsub=sal_op_new(fr->lc->sal);
        sal_op_set_route(fr->outsub,route);
+       sal_op_set_contact(fr->outsub,fixed_contact);
        sal_subscribe_presence(fr->outsub,from,friend);
        fr->subscribe_active=TRUE;
        ms_free(friend);
@@ -367,6 +375,7 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
        }
        ms_message("linphone_friend_apply() done.");
        lc->bl_refresh=TRUE;
+       fr->commit=FALSE;
 }
 
 void linphone_friend_edit(LinphoneFriend *fr){
@@ -391,7 +400,8 @@ void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf)
                return ;
        }
        lc->friends=ms_list_append(lc->friends,lf);
-       linphone_friend_apply(lf,lc);
+       if ( linphone_core_ready(lc)) linphone_friend_apply(lf,lc);
+       else lf->commit=TRUE;
        return ;
 }
 
@@ -404,6 +414,15 @@ void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){
        }
 }
 
+void linphone_core_send_initial_subscribes(LinphoneCore *lc){
+       const MSList *elem;
+       for(elem=lc->friends;elem!=NULL;elem=elem->next){
+               LinphoneFriend *f=(LinphoneFriend*)elem->data;
+               if (f->commit)
+                       linphone_friend_apply(f,lc);
+       }
+}
+
 void linphone_friend_set_ref_key(LinphoneFriend *lf, const char *key){
        if (lf->refkey!=NULL){
                ms_free(lf->refkey);
@@ -562,7 +581,7 @@ void linphone_core_write_friends_config(LinphoneCore* lc)
 {
        MSList *elem;
        int i;
-       if (!lc->ready) return; /*dont write config when reading it !*/
+       if (! linphone_core_ready(lc)) return; /*dont write config when reading it !*/
        for (elem=lc->friends,i=0; elem!=NULL; elem=ms_list_next(elem),i++){
                linphone_friend_write_to_config_file(lc->config,(LinphoneFriend*)elem->data,i);
        }
index 775d6712f75dbaae5fe9b3ca891e0633c9269199..b9e7fe518e9216cac538e6226d863c1b1b95a2d6 100644 (file)
@@ -38,7 +38,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 /*#define UNSTANDART_GSM_11K 1*/
 
 static const char *liblinphone_version=LIBLINPHONE_VERSION;
-static void set_network_reachable(LinphoneCore* lc,bool_t isReachable);
+static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime);
 
 #include "enum.h"
 
@@ -52,6 +52,7 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val);
 
 extern SalCallbacks linphone_sal_callbacks;
 
+
 void lc_callback_obj_init(LCCallbackObj *obj,LinphoneCoreCbFunc func,void* ud)
 {
   obj->_func=func;
@@ -103,7 +104,7 @@ static void call_logs_write_to_config_file(LinphoneCore *lc){
        char *tmp;
        LpConfig *cfg=lc->config;
 
-       if (!lc->ready) return;
+       if (linphone_core_get_global_state (lc)==LinphoneGlobalStartup) return;
        
        for(i=0,elem=lc->call_logs;elem!=NULL;elem=elem->next,++i){
                LinphoneCallLog *cl=(LinphoneCallLog*)elem->data;
@@ -996,10 +997,8 @@ static void linphone_core_init (LinphoneCore * lc, const LinphoneCoreVTable *vta
        ui_config_read(lc);
        if (lc->vtable.display_status)
                lc->vtable.display_status(lc,_("Ready"));
-       linphone_core_set_state(lc,LinphoneGlobalOn,"Ready");
        lc->auto_net_state_mon=lc->sip_conf.auto_net_state_mon;
-
-    lc->ready=TRUE;
+       linphone_core_set_state(lc,LinphoneGlobalOn,"Ready");
 }
 
 /**
@@ -1529,7 +1528,7 @@ static void monitor_network_state(LinphoneCore *lc, time_t curtime){
                        if (new_status){
                                ms_message("New local ip address is %s",result);
                        }
-                       set_network_reachable(lc,new_status);
+                       set_network_reachable(lc,new_status, curtime);
                        last_status=new_status;
                }
        }
@@ -1724,6 +1723,12 @@ void linphone_core_iterate(LinphoneCore *lc){
 
        linphone_core_do_plugin_tasks(lc);
 
+       if (lc->initial_subscribes_sent==FALSE && lc->netup_time!=0 &&
+           (curtime-lc->netup_time)>3){
+               linphone_core_send_initial_subscribes(lc);
+               lc->initial_subscribes_sent=TRUE;
+       }
+
        if (one_second_elapsed && lp_config_needs_commit(lc->config)){
                lp_config_sync(lc->config);
        }
@@ -1861,6 +1866,17 @@ LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const L
        return found_cfg;
 }
 
+const char *linphone_core_find_best_identity(LinphoneCore *lc, const LinphoneAddress *to, const char **route){
+       LinphoneProxyConfig *cfg=linphone_core_lookup_known_proxy(lc,to);
+       if (cfg==NULL)
+               linphone_core_get_default_proxy (lc,&cfg);
+       if (cfg!=NULL){
+               *route=linphone_proxy_config_get_route(cfg);
+               return linphone_proxy_config_get_identity (cfg);
+       }
+       return linphone_core_get_primary_contact (lc);
+}
+
 static char *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call , LinphoneProxyConfig *dest_proxy){
        LinphoneAddress *ctt;
        const char *localip=call->localip;
@@ -2669,7 +2685,7 @@ bool_t linphone_core_sound_device_can_playback(LinphoneCore *lc, const char *dev
 int linphone_core_set_ringer_device(LinphoneCore *lc, const char * devid){
        MSSndCard *card=get_card_from_string_id(devid,MS_SND_CARD_CAP_PLAYBACK);
        lc->sound_conf.ring_sndcard=card;
-       if (card && lc->ready)
+       if (card && linphone_core_ready(lc))
                lp_config_set_string(lc->config,"sound","ringer_dev_id",ms_snd_card_get_string_id(card));
        return 0;
 }
@@ -2683,7 +2699,7 @@ int linphone_core_set_ringer_device(LinphoneCore *lc, const char * devid){
 int linphone_core_set_playback_device(LinphoneCore *lc, const char * devid){
        MSSndCard *card=get_card_from_string_id(devid,MS_SND_CARD_CAP_PLAYBACK);
        lc->sound_conf.play_sndcard=card;
-       if (card && lc->ready)
+       if (card &&  linphone_core_ready(lc))
                lp_config_set_string(lc->config,"sound","playback_dev_id",ms_snd_card_get_string_id(card));
        return 0;
 }
@@ -2697,7 +2713,7 @@ int linphone_core_set_playback_device(LinphoneCore *lc, const char * devid){
 int linphone_core_set_capture_device(LinphoneCore *lc, const char * devid){
        MSSndCard *card=get_card_from_string_id(devid,MS_SND_CARD_CAP_CAPTURE);
        lc->sound_conf.capt_sndcard=card;
-       if (card && lc->ready)
+       if (card &&  linphone_core_ready(lc))
                lp_config_set_string(lc->config,"sound","capture_dev_id",ms_snd_card_get_string_id(card));
        return 0;
 }
@@ -2788,7 +2804,7 @@ void linphone_core_set_ring(LinphoneCore *lc,const char *path){
                ms_free(lc->sound_conf.local_ring);
        }
        lc->sound_conf.local_ring=ms_strdup(path);
-       if (lc->ready && lc->sound_conf.local_ring)
+       if ( linphone_core_ready(lc) && lc->sound_conf.local_ring)
                lp_config_set_string(lc->config,"sound","local_ring",lc->sound_conf.local_ring);
 }
 
@@ -2852,7 +2868,7 @@ const char * linphone_core_get_ringback(const LinphoneCore *lc){
 **/
 void linphone_core_enable_echo_cancellation(LinphoneCore *lc, bool_t val){
        lc->sound_conf.ec=val;
-       if (lc->ready)
+       if ( linphone_core_ready(lc))
                lp_config_set_int(lc->config,"sound","echocancellation",val);
 }
 
@@ -3162,7 +3178,7 @@ int linphone_core_set_video_device(LinphoneCore *lc, const char *id){
        if (olddev!=NULL && olddev!=lc->video_conf.device){
                toggle_video_preview(lc,FALSE);/*restart the video local preview*/
        }
-       if (lc->ready && lc->video_conf.device){
+       if ( linphone_core_ready(lc) && lc->video_conf.device){
                vd=ms_web_cam_get_string_id(lc->video_conf.device);
                if (vd && strstr(vd,"Static picture")!=NULL){
                        vd=NULL;
@@ -3381,7 +3397,7 @@ void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize)
                        toggle_video_preview(lc,FALSE);
                        toggle_video_preview(lc,TRUE);
                }
-               if (lc->ready)
+               if ( linphone_core_ready(lc))
                        lp_config_set_string(lc->config,"video","size",video_size_get_name(vsize));
        }
 }
@@ -3798,7 +3814,7 @@ static void linphone_core_uninit(LinphoneCore *lc)
        linphone_core_set_state(lc,LinphoneGlobalOff,"Off");
 }
 
-static void set_network_reachable(LinphoneCore* lc,bool_t isReachable){
+static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t curtime){
        ms_message("Network state is now [%s]",isReachable?"UP":"DOWN");
        // second get the list of available proxies
        const MSList *elem=linphone_core_get_proxy_config_list(lc);
@@ -3812,6 +3828,7 @@ static void set_network_reachable(LinphoneCore* lc,bool_t isReachable){
                        }
                }
        }
+       lc->netup_time=curtime;
        lc->network_reachable=isReachable;
 }
 
@@ -3821,7 +3838,7 @@ void linphone_core_set_network_reachable(LinphoneCore* lc,bool_t isReachable) {
                ms_message("Disabling automatic network state monitoring");
                lc->auto_net_state_mon=FALSE;
        }
-       set_network_reachable(lc,isReachable);
+       set_network_reachable(lc,isReachable, ms_time(NULL));
 }
 
 bool_t linphone_core_is_network_reachabled(LinphoneCore* lc) {
index 57e764c38e5ee0fa10191523766d12a165ae4728..500ce6d7e8e6e59a5d048e4c851a1dd8e210698f 100644 (file)
@@ -57,11 +57,24 @@ void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){
        LinphoneFriend *lf=NULL;
        char *tmp;
        LinphoneAddress *uri;
+       LinphoneProxyConfig *cfg;
+       const char *fixed_contact;
        
        uri=linphone_address_new(from);
        linphone_address_clean(uri);
        tmp=linphone_address_as_string(uri);
        ms_message("Receiving new subscription from %s.",from);
+
+       cfg=linphone_core_lookup_known_proxy(lc,uri);
+       if (cfg!=NULL){
+               if (cfg->op){
+                       fixed_contact=sal_op_get_contact(cfg->op);
+                       if (fixed_contact) {
+                               sal_op_set_contact (op,fixed_contact);
+                               ms_message("Contact for next subscribe answer has been fixed using proxy to %s",fixed_contact);
+                       }
+               }
+       }
        /* check if we answer to this subscription */
        if (linphone_find_friend(lc->friends,uri,&lf)!=NULL){
                lf->insub=op;
index c965bf4ac3b71a26dccf06024c052921db06b4b3..9bee983b6342bfaea2b62f3c5e478c3d2acce27a 100644 (file)
@@ -166,6 +166,7 @@ void linphone_core_update_allocated_audio_bandwidth(LinphoneCore *lc);
 void linphone_core_update_allocated_audio_bandwidth_in_call(LinphoneCore *lc, const PayloadType *pt);
 void linphone_core_run_stun_tests(LinphoneCore *lc, LinphoneCall *call);
 
+void linphone_core_send_initial_subscribes(LinphoneCore *lc);
 void linphone_core_write_friends_config(LinphoneCore* lc);
 void linphone_friend_write_to_config_file(struct _LpConfig *config, LinphoneFriend *lf, int index);
 LinphoneFriend * linphone_friend_new_from_config_file(struct _LinphoneCore *lc, int index);
@@ -173,6 +174,7 @@ LinphoneFriend * linphone_friend_new_from_config_file(struct _LinphoneCore *lc,
 void linphone_proxy_config_update(LinphoneProxyConfig *cfg);
 void linphone_proxy_config_get_contact(LinphoneProxyConfig *cfg, const char **ip, int *port);
 LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri);
+const char *linphone_core_find_best_identity(LinphoneCore *lc, const LinphoneAddress *to, const char **route);
 int linphone_core_get_local_ip_for(int type, const char *dest, char *result);
 
 LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(struct _LpConfig *config, int index);
@@ -238,8 +240,8 @@ struct _LinphoneAuthInfo
 struct _LinphoneChatRoom{
        struct _LinphoneCore *lc;
        char  *peer;
-       char *route;
        LinphoneAddress *peer_url;
+       SalOp *op;
        void * user_data;
 };
 
@@ -255,6 +257,7 @@ struct _LinphoneFriend{
        bool_t subscribe;
        bool_t subscribe_active;
        bool_t inc_subscribe_pending;
+       bool_t commit;
 };     
 
 
@@ -412,9 +415,10 @@ struct _LinphoneCore
        void *wait_ctx;
        unsigned long video_window_id;
        unsigned long preview_window_id;
+       time_t netup_time; /*time when network went reachable */
        bool_t use_files;
        bool_t apply_nat_settings;
-       bool_t ready;
+       bool_t initial_subscribes_sent;
        bool_t bl_refresh;
        bool_t preview_finished;
        bool_t auto_net_state_mon;
@@ -433,6 +437,8 @@ void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const
 SalMediaDescription *create_local_media_description(LinphoneCore *lc, 
                LinphoneCall *call, bool_t with_video, bool_t only_one_codec);
 
+#define linphone_core_ready(lc) ((lc)->state!=LinphoneGlobalStartup)
+
 #define HOLD_OFF       (0)
 #define HOLD_ON                (1)
 
index c946d988ee40421ebe6a75fd088fdead7c49365f..aa901cb8dc678c9828cf44e00b245ae3c8ba3137 100644 (file)
@@ -167,10 +167,16 @@ int linphone_proxy_config_set_route(LinphoneProxyConfig *obj, const char *route)
                obj->reg_route=NULL;
        }
        if (route!=NULL){
+               LinphoneAddress *addr;
                /*try to prepend 'sip:' */
                if (strstr(route,"sip:")==NULL){
                        obj->reg_route=ms_strdup_printf("sip:%s",route);
                }else obj->reg_route=ms_strdup(route);
+               addr=linphone_address_new(obj->reg_route);
+               if (addr==NULL){
+                       ms_free(obj->reg_route);
+                       obj->reg_route=NULL;
+               }else linphone_address_destroy(addr);
        }
        return 0;
 }
@@ -694,7 +700,7 @@ void linphone_proxy_config_update(LinphoneProxyConfig *cfg){
                if (cfg->type && cfg->ssctx==NULL){
                        linphone_proxy_config_activate_sip_setup(cfg);
                }
-               if (lc->sip_conf.register_only_when_network_is_up || lc->network_reachable)
+               if (!lc->sip_conf.register_only_when_network_is_up || lc->network_reachable)
                        linphone_proxy_config_register(cfg);
                if (cfg->publish && cfg->publish_op==NULL){
                        linphone_proxy_config_send_publish(cfg,lc->presence_mode);
index 0db619d0b4b1afaa728958d2f2b947791e112492..c61ec96abffa4514cbf449db2144fad85c562fc5 100644 (file)
@@ -26,7 +26,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
 static void text_received(Sal *sal, eXosip_event_t *ev);
 
-static void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
+void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
        void *data;
        while((data=osip_list_get(l,0))!=NULL){
                osip_list_remove(l,0);
@@ -102,7 +102,7 @@ static SalOp * sal_find_other(Sal *sal, osip_message_t *response){
        return NULL;
 }
 
-static void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
+void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
        osip_call_id_t *callid=osip_message_get_call_id(request);
        if (callid==NULL) {
                ms_error("There is no call id in the request !");
index 88afb1c21773aac2c3457107a4f20facde8a7ac0..bfb3d10f26cf781f278754bbb6f94be952780b67 100644 (file)
@@ -66,6 +66,7 @@ struct SalOp{
 
 void sal_remove_out_subscribe(Sal *sal, SalOp *op);
 void sal_remove_in_subscribe(Sal *sal, SalOp *op);
+void sal_add_other(Sal *sal, SalOp *op,  osip_message_t *request);
 
 void sal_exosip_subscription_recv(Sal *sal, eXosip_event_t *ev);
 void sal_exosip_subscription_answered(Sal *sal,eXosip_event_t *ev);
@@ -76,5 +77,6 @@ void sal_exosip_in_subscription_closed(Sal *sal, eXosip_event_t *ev);
 SalOp * sal_find_out_subscribe(Sal *sal, int sid);
 void sal_exosip_fix_route(SalOp *op);
 
+void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*));
 
 #endif
index bf94edcb3f562ecdd9755239ae2b02b494f7b96e..1e7409f19bfb74d22dd540e987517a1f438d5582 100644 (file)
@@ -83,9 +83,14 @@ int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){
                eXosip_lock();
                eXosip_message_build_request(&sip,"MESSAGE",sal_op_get_to(op),
                        sal_op_get_from(op),sal_op_get_route(op));
-               osip_message_set_content_type(sip,"text/plain");
-               osip_message_set_body(sip,msg,strlen(msg));
-               eXosip_message_send_request(sip);
+               if (sip!=NULL){
+                       osip_message_set_content_type(sip,"text/plain");
+                       osip_message_set_body(sip,msg,strlen(msg));
+                       sal_add_other(op->base.root,op,sip);
+                       eXosip_message_send_request(sip);
+               }else{
+                       ms_error("Could not build MESSAGE request !");
+               }
                eXosip_unlock();
        }
        else
@@ -93,22 +98,16 @@ int sal_text_send(SalOp *op, const char *from, const char *to, const char *msg){
                /* we are currently in communication with the destination */
                eXosip_lock();
                //First we generate an INFO message to get the current call_id and a good cseq
-               eXosip_call_build_info(op->did,&sip);
+               eXosip_call_build_request(op->did,"MESSAGE",&sip);
                if(sip == NULL)
                {
                        ms_warning("could not get a build info to send MESSAGE, maybe no previous call established ?");
-                       osip_message_free(sip);
                        eXosip_unlock();
                        return -1;
                }
-               //change the sip_message to be a MESSAGE ...
-               osip_free(osip_message_get_method(sip));
-               osip_message_set_method(sip,osip_strdup("MESSAGE"));
-               osip_free(osip_cseq_get_method(osip_message_get_cseq(sip)));
-               osip_cseq_set_method(osip_message_get_cseq(sip),osip_strdup("MESSAGE"));
                osip_message_set_content_type(sip,"text/plain");
                osip_message_set_body(sip,msg,strlen(msg));
-               eXosip_message_send_request(sip);
+               eXosip_call_send_request(op->did,sip);
                eXosip_unlock();
        }
        return 0;
@@ -125,6 +124,10 @@ int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
        eXosip_lock();
        eXosip_subscribe_build_initial_request(&msg,sal_op_get_to(op),sal_op_get_from(op),
                sal_op_get_route(op),"presence",600);
+       if (op->base.contact){
+               _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
+               osip_message_set_contact(msg,op->base.contact);
+       }
        op->sid=eXosip_subscribe_send_initial_request(msg);
        eXosip_unlock();
        if (op->sid==-1){
@@ -156,6 +159,10 @@ int sal_subscribe_accept(SalOp *op){
        osip_message_t *msg;
        eXosip_lock();
        eXosip_insubscription_build_answer(op->tid,202,&msg);
+       if (op->base.contact){
+               _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
+               osip_message_set_contact(msg,op->base.contact);
+       }
        eXosip_insubscription_send_answer(op->tid,202,msg);
        eXosip_unlock();
        return 0;