diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index c362db72ea5ef6efe73974de098939d6b06f851d..27a88c50a865e5f9946598e13a94af8f36f380fa 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2477,7 +2477,7 @@ static void linphone_core_internal_subscribe_received(LinphoneCore *lc, Linphone static void _linphone_core_conference_subscription_state_changed (LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) { #ifdef HAVE_ADVANCED_IM if (!linphone_core_conference_server_enabled(lc)) { - CoreListener *parent = static_cast<CoreListener *>(linphone_event_get_user_data(lev)); + ObjectPrivate *parent = static_cast<ObjectPrivate *>(linphone_event_get_user_data(lev)); RemoteConferenceEventHandlerPrivate *thiz = dynamic_cast<RemoteConferenceEventHandlerPrivate *>(parent); if (thiz && (state == LinphoneSubscriptionError || state == LinphoneSubscriptionTerminated)) { thiz->invalidateSubscription(); diff --git a/src/sal/event-op.cpp b/src/sal/event-op.cpp index ceef260f29ccfbca3c3f4daea30c3995669d8227..0c9728e2a6dfeac5836b3309bd58449078cae4eb 100644 --- a/src/sal/event-op.cpp +++ b/src/sal/event-op.cpp @@ -203,8 +203,9 @@ void SalSubscribeOp::subscribeProcessDialogTerminatedCb (void *userCtx, const be auto op = static_cast<SalSubscribeOp *>(userCtx); if (!op->mDialog) return; - - if (belle_sip_dialog_terminated_event_is_expired(event)) { + if (op->mState == SalOp::State::Terminated) { + lInfo() << "Op [" << op << "] is terminated, nothing to do with this dialog terminated"; + } else if (belle_sip_dialog_terminated_event_is_expired(event)) { auto dialog = belle_sip_dialog_terminated_event_get_dialog(event); if (belle_sip_dialog_is_server(dialog)) { op->mRoot->mCallbacks.incoming_subscribe_closed(op); diff --git a/tester/eventapi_tester.c b/tester/eventapi_tester.c index b24bdd01038c9b713a87aa650d6d94ea9b31cdea..021b0ef6540ca0e0060d6328012ba4d3e6ed987d 100644 --- a/tester/eventapi_tester.c +++ b/tester/eventapi_tester.c @@ -291,6 +291,67 @@ static void subscribe_loosing_dialog(void) { bctbx_list_free(lcs); } +/* This test has LeaksMemory attribute due to the brutal disconnection of pauline, followed by core destruction. + * TODO: fix it. + */ +static void subscribe_loosing_dialog_2(void) { +#ifdef WIN32 + /*Unfortunately this test doesn't work on windows due to the way closed TCP ports behave. + * Unlike linux and macOS, released TCP port don't send an ICMP error (or maybe at least for a period of time. + * This prevents this test from working, see comments below*/ + ms_warning("subscribe_loosing_dialog() skipped on windows."); +#else + LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); + LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); + LinphoneContent* content; + LinphoneEvent *lev; + int expires= 4; + bctbx_list_t* lcs=bctbx_list_append(NULL,marie->lc); + + lcs=bctbx_list_append(lcs,pauline->lc); + + content = linphone_core_create_content(marie->lc); + linphone_content_set_type(content,"application"); + linphone_content_set_subtype(content,"somexml"); + linphone_content_set_buffer(content,(const uint8_t *)subscribe_content,strlen(subscribe_content)); + + lev=linphone_core_create_subscribe(marie->lc,pauline->identity,"dodo",expires); + linphone_event_add_custom_header(lev,"My-Header","pouet"); + linphone_event_add_custom_header(lev,"My-Header2","pimpon"); + linphone_event_send_subscribe(lev,content); + + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionOutgoingProgress,1,1000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionIncomingReceived,1,3000)); + + + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneSubscriptionActive,1,5000)); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionActive,1,5000)); + + /*make sure marie receives first notification before terminating*/ + BC_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_NotifyReceived,1,5000)); + + + /* now marie looses internet connection and reboots */ + linphone_core_set_network_reachable(marie->lc, FALSE); + lcs = bctbx_list_remove(lcs, marie->lc); + linphone_core_manager_destroy(marie); + marie = linphone_core_manager_new( "pauline_tcp_rc"); + lcs = bctbx_list_append(lcs, marie->lc); + + BC_ASSERT_TRUE(wait_for_list(lcs,NULL,0,2000)); + //now try a terminate the dialog + linphone_event_terminate(pauline->lev); + BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneSubscriptionTerminated,1,5000)); + /*let expire the incoming subscribe received by pauline */ + BC_ASSERT_TRUE(wait_for_list(lcs,NULL,0,3000)); + + linphone_content_unref(content); + linphone_core_manager_destroy(marie); + linphone_core_manager_destroy(pauline); + bctbx_list_free(lcs); +#endif +} + static void subscribe_with_io_error(void) { LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_tcp_rc"); @@ -484,6 +545,7 @@ test_t event_tests[] = { TEST_ONE_TAG("Subscribe with custom headers", subscribe_test_with_custom_header, "presence"), TEST_ONE_TAG("Subscribe refreshed", subscribe_test_refreshed, "presence"), TEST_TWO_TAGS("Subscribe loosing dialog", subscribe_loosing_dialog, "presence", "LeaksMemory"), + TEST_ONE_TAG("Server try to terminate a lost dialog", subscribe_loosing_dialog_2, "presence"), TEST_ONE_TAG("Subscribe with io error", subscribe_with_io_error, "presence"), TEST_ONE_TAG("Subscribe manually refreshed", subscribe_test_manually_refreshed, "presence"), TEST_ONE_TAG("Subscribe terminated by notifier", subscribe_test_terminated_by_notifier, "presence"), @@ -492,6 +554,7 @@ test_t event_tests[] = { TEST_ONE_TAG("Publish without expires", publish_without_expires, "presence"), TEST_ONE_TAG("Publish without automatic refresh",publish_no_auto_test, "presence"), TEST_ONE_TAG("Out of dialog notify", out_of_dialog_notify, "presence") + }; test_suite_t event_test_suite = {"Event", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,