diff --git a/coreapi/bellesip_sal/sal_op_events.c b/coreapi/bellesip_sal/sal_op_events.c index 3c328df00..8b439eb9b 100644 --- a/coreapi/bellesip_sal/sal_op_events.c +++ b/coreapi/bellesip_sal/sal_op_events.c @@ -226,10 +226,6 @@ int sal_unsubscribe(SalOp *op){ belle_sip_request_t *last_req=belle_sip_transaction_get_request(tr); sal_op_add_body(op,(belle_sip_message_t*)last_req,NULL); belle_sip_refresher_refresh(op->refresher,0); - if (op->dialog){ - belle_sip_dialog_set_application_data(op->dialog, NULL); - sal_op_unref(op); - } return 0; } return -1; diff --git a/coreapi/bellesip_sal/sal_op_presence.c b/coreapi/bellesip_sal/sal_op_presence.c index 94cf35c40..f1326d3ec 100644 --- a/coreapi/bellesip_sal/sal_op_presence.c +++ b/coreapi/bellesip_sal/sal_op_presence.c @@ -53,8 +53,12 @@ static void presence_process_io_error(void *user_ctx, const belle_sip_io_error_e static void presence_process_dialog_terminated(void *ctx, const belle_sip_dialog_terminated_event_t *event) { SalOp* op= (SalOp*)ctx; if (op->dialog) { - sal_op_unref(op); - op->dialog=NULL; + if (belle_sip_dialog_is_server(op->dialog)){ + /*in an incoming SUBSCRIBE*/ + ms_message("Presence unsubscribe received from [%s]",sal_op_get_from(op)); + op->base.root->callbacks.subscribe_presence_closed(op, sal_op_get_from(op)); + } + set_or_update_dialog(op, NULL); } } @@ -64,9 +68,7 @@ static void presence_refresher_listener(belle_sip_refresher_t* refresher, void* ms_message("The SUBSCRIBE dialog no longer works. Let's restart a new one."); belle_sip_refresher_stop(op->refresher); if (op->dialog) { /*delete previous dialog if any*/ - belle_sip_dialog_set_application_data(op->dialog,NULL); - belle_sip_object_unref(op->dialog); - op->dialog=NULL; + set_or_update_dialog(op, NULL); } if (sal_op_get_contact_address(op)) { @@ -223,9 +225,8 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques if (!op->dialog) { if (strcmp(method,"SUBSCRIBE")==0){ - op->dialog=belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(server_transaction)); - belle_sip_dialog_set_application_data(op->dialog,op); - sal_op_ref(op); + belle_sip_dialog_t *dialog = belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(server_transaction)); + set_or_update_dialog(op, dialog); ms_message("new incoming subscription from [%s] to [%s]",sal_op_get_from(op),sal_op_get_to(op)); }else{ /* this is a NOTIFY */ ms_message("Receiving out of dialog notify"); @@ -250,8 +251,7 @@ static void presence_process_request_event(void *op_base, const belle_sip_reques /*either a refresh or an unsubscribe*/ if (expires && belle_sip_header_expires_get_expires(expires)>0) { op->base.root->callbacks.subscribe_presence_received(op,sal_op_get_from(op)); - } else if(expires) { - ms_message("Unsubscribe received from [%s]",sal_op_get_from(op)); + }else{ resp=sal_op_create_response_from_request(op,req,200); belle_sip_server_transaction_send_response(server_transaction,resp); } @@ -330,8 +330,8 @@ static int sal_op_check_dialog_state(SalOp *op) { return -1; } else return 0; - } + int sal_notify_presence(SalOp *op, SalPresenceModel *presence){ belle_sip_request_t* notify=NULL; if (sal_op_check_dialog_state(op)) { diff --git a/coreapi/friend.c b/coreapi/friend.c index 819cdbdcf..250fdeed5 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -240,10 +240,14 @@ void linphone_friend_notify(LinphoneFriend *lf, LinphonePresenceModel *presence) } void linphone_friend_add_incoming_subscription(LinphoneFriend *lf, SalOp *op){ + /*ownership of the op is transfered from sal to the LinphoneFriend*/ lf->insubs = ms_list_append(lf->insubs, op); } void linphone_friend_remove_incoming_subscription(LinphoneFriend *lf, SalOp *op){ + if (ms_list_find(lf->insubs, op)){ + sal_op_release(op); + } lf->insubs = ms_list_remove(lf->insubs, op); } diff --git a/coreapi/presence.c b/coreapi/presence.c index f2f16806e..22164a746 100644 --- a/coreapi/presence.c +++ b/coreapi/presence.c @@ -1897,11 +1897,13 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa void linphone_subscription_closed(LinphoneCore *lc, SalOp *op){ LinphoneFriend *lf; lf=linphone_find_friend_by_inc_subscribe(lc->friends,op); - sal_op_release(op); + if (lf!=NULL){ + /*this will release the op*/ linphone_friend_remove_incoming_subscription(lf, op); }else{ - ms_warning("Receiving unsuscribe for unknown in-subscribtion from %s", sal_op_get_from(op)); + /*case of an op that we already released because the friend was destroyed*/ + ms_message("Receiving unsuscribe for unknown in-subscribtion from %s", sal_op_get_from(op)); } } diff --git a/tester/presence_tester.c b/tester/presence_tester.c index 0c5d5e700..37ebd2faf 100644 --- a/tester/presence_tester.c +++ b/tester/presence_tester.c @@ -162,6 +162,7 @@ static bool_t subscribe_to_callee_presence(LinphoneCoreManager* caller_mgr,Linph linphone_friend_done(friend); linphone_core_add_friend(caller_mgr->lc,friend); + linphone_friend_unref(friend); result=wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphonePresenceActivityOnline,initial_caller.number_of_LinphonePresenceActivityOnline+1); /*without proxy, callee cannot subscribe to caller @@ -184,7 +185,8 @@ static void subscribe_failure_handle_by_app(void) { LinphoneProxyConfig* config; LinphoneFriend* lf; char* lf_identity=linphone_address_as_string_uri_only(pauline->identity); - linphone_core_get_default_proxy(marie->lc,&config); + + linphone_core_get_default_proxy(marie->lc,&config); BC_ASSERT_TRUE(subscribe_to_callee_presence(marie,pauline)); wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_NewSubscriptionRequest,1); /*just to wait for unsubscription even if not notified*/ @@ -232,6 +234,7 @@ static void unsubscribe_while_subscribing(void) { linphone_friend_enable_subscribes(friend,TRUE); linphone_friend_done(friend); linphone_core_add_friend(marie->lc,friend); + linphone_friend_unref(friend); linphone_core_iterate(marie->lc); linphone_core_manager_destroy(marie); }