Commit 17b93580 authored by jehan's avatar jehan
Browse files

Disable automatic retry of subscriptions when core is in state Shutdown.

It fix a crash linked to GC of chatroom on a restarted core
parent 156896a4
......@@ -681,6 +681,7 @@ static void info_received(SalOp *op, SalBodyHandler *body_handler) {
static void subscribe_response(SalOp *op, SalSubscribeStatus status, int will_retry){
LinphoneEvent *lev=(LinphoneEvent*)op->getUserPointer();
LinphoneCore *lc=(LinphoneCore *)op->getSal()->getUserPointer();
if (lev==NULL) return;
......@@ -689,7 +690,7 @@ static void subscribe_response(SalOp *op, SalSubscribeStatus status, int will_re
}else if (status==SalSubscribePending){
linphone_event_set_state(lev,LinphoneSubscriptionPending);
}else{
if (will_retry){
if (will_retry && linphone_core_get_global_state(lc) != LinphoneGlobalShutdown ){
linphone_event_set_state(lev,LinphoneSubscriptionOutgoingProgress);
}
else linphone_event_set_state(lev,LinphoneSubscriptionError);
......
......@@ -221,6 +221,7 @@ LINPHONE_PUBLIC int sal_enable_pending_trans_checking(Sal *sal, bool_t value);
LINPHONE_PUBLIC void sal_enable_unconditional_answer(Sal *sal, bool_t value);
LINPHONE_PUBLIC void sal_set_dns_timeout(Sal* sal,int timeout);
LINPHONE_PUBLIC void sal_set_dns_user_hosts_file(Sal *sal, const char *hosts_file);
LINPHONE_PUBLIC const char* sal_get_dns_user_hosts_file (const Sal *sal);
LINPHONE_PUBLIC void *sal_get_stack_impl(Sal *sal);
LINPHONE_PUBLIC void sal_set_refresher_retry_after(Sal *sal,int value);
LINPHONE_PUBLIC int sal_get_refresher_retry_after(const Sal *sal);
......
......@@ -962,6 +962,10 @@ LINPHONE_PUBLIC void sal_set_dns_user_hosts_file (Sal *sal, const char *hostsFil
sal->setDnsUserHostsFile(hostsFile);
}
LINPHONE_PUBLIC const char* sal_get_dns_user_hosts_file (const Sal *sal) {
return sal->getDnsUserHostsFile().c_str();
}
LINPHONE_PUBLIC void *sal_get_stack_impl (Sal *sal) {
return sal->getStackImpl();
}
......
......@@ -5488,6 +5488,71 @@ static void one_to_one_chat_room_send_forward_message (void) {
group_chat_room_unique_one_to_one_chat_room_with_forward_message_recreated_from_message_base(TRUE,TRUE);
}
static void core_stop_start_with_chat_room_ref (void) {
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline1 = linphone_core_manager_create("pauline_rc");
LinphoneChatRoom *marie1Cr = NULL, *pauline1Cr = NULL, *newPauline1Cr = NULL;
const LinphoneAddress *confAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie1);
coresManagerList = bctbx_list_append(coresManagerList, pauline1);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline1->lc)));
stats initialMarie1Stats = marie1->stat;
stats initialPauline1Stats = pauline1->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marie1Cr = create_chat_room_client_side(coresList, marie1, &initialMarie1Stats, participantsAddresses, initialSubject, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marie1Cr)) goto end;
participantsAddresses = NULL;
confAddr = linphone_chat_room_get_conference_address(marie1Cr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
// Check that the chat room is correctly created on Pauline1
pauline1Cr = check_creation_chat_room_client_side(coresList, pauline1, &initialPauline1Stats, confAddr, initialSubject, 1, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(pauline1Cr)) goto end;
//Pauline leaving but keeping a ref like a Java GC can do, this is the key part of this test.
linphone_chat_room_ref(pauline1Cr);
linphone_core_stop(pauline1->lc);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline1->stat.number_of_LinphoneGlobalShutdown, initialPauline1Stats.number_of_LinphoneGlobalShutdown + 1, 3000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline1->stat.number_of_LinphoneGlobalOff, initialPauline1Stats.number_of_LinphoneGlobalOff + 1, 3000));
linphone_core_start(pauline1->lc);
//now GC is cleaning old chatroom
if (pauline1Cr) linphone_chat_room_unref(pauline1Cr);
coresList = bctbx_list_remove(coresList, pauline1->lc);
linphone_core_manager_reinit(pauline1);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, pauline1);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(pauline1, TRUE);
// Check that the chat room has correctly created on Laure's side and that the participants are added
newPauline1Cr = check_has_chat_room_client_side(coresList, pauline1, &initialPauline1Stats, confAddr, initialSubject, 1, FALSE);
wait_for_list(coresList, NULL, 0, 1000);
end:
// Clean db from chat room
if (marie1Cr) linphone_core_manager_delete_chat_room(marie1, marie1Cr, coresList);
if (newPauline1Cr) linphone_core_manager_delete_chat_room(pauline1, newPauline1Cr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
bctbx_list_free_with_data(participantsAddresses,(bctbx_list_free_func)linphone_address_unref);
linphone_core_manager_destroy(marie1);
linphone_core_manager_destroy(pauline1);
}
test_t group_chat_tests[] = {
TEST_NO_TAG("Chat room params", group_chat_room_params),
TEST_NO_TAG("Chat room with forced local identity", group_chat_room_creation_with_given_identity),
......@@ -5551,7 +5616,8 @@ test_t group_chat_tests[] = {
TEST_ONE_TAG("Participant removed then added", participant_removed_then_added, "LeaksMemory" /*due to core restart*/),
TEST_ONE_TAG("Check if participant device are removed", group_chat_room_join_one_to_one_chat_room_with_a_new_device_not_notified, "LeaksMemory" /*due to core restart*/),
TEST_ONE_TAG("Subscribe successfull after set chat database path", subscribe_test_after_set_chat_database_path, "LeaksMemory" /*due to core restart*/),
TEST_ONE_TAG("Send forward message", one_to_one_chat_room_send_forward_message, "LeaksMemory" /*due to core restart*/)
TEST_ONE_TAG("Send forward message", one_to_one_chat_room_send_forward_message, "LeaksMemory" /*due to core restart*/),
TEST_ONE_TAG("Linphone core stop/start and chatroom ref", core_stop_start_with_chat_room_ref, "LeaksMemory" /*due to core restart*/)
};
test_suite_t group_chat_test_suite = {
......
......@@ -321,6 +321,14 @@ typedef struct _stats {
int number_of_ManInTheMiddleDetected;
int number_of_snapshot_taken;
int number_of_LinphoneGlobalOn;
int number_of_LinphoneGlobalReady;
int number_of_LinphoneGlobalOff;
int number_of_LinphoneGlobalShutdown;
int number_of_LinphoneGlobalStartup;
int number_of_LinphoneGlobalConfiguring;
}stats;
......@@ -402,7 +410,8 @@ void linphone_configuration_status(LinphoneCore *lc, LinphoneConfiguringState st
void linphone_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t on, const char *authentication_token);
void dtmf_received(LinphoneCore *lc, LinphoneCall *call, int dtmf);
void call_stats_updated(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *stats);
void global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message);
LinphoneAddress * create_linphone_address(const char * domain);
LinphoneAddress * create_linphone_address_for_algo(const char * domain, const char * username);
bool_t wait_for(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value);
......
......@@ -462,6 +462,7 @@ void linphone_core_manager_init(LinphoneCoreManager *mgr, const char* rc_file, c
linphone_core_cbs_set_network_reachable(mgr->cbs, network_reachable);
linphone_core_cbs_set_dtmf_received(mgr->cbs, dtmf_received);
linphone_core_cbs_set_call_stats_updated(mgr->cbs, call_stats_updated);
linphone_core_cbs_set_global_state_changed(mgr->cbs, global_state_changed);
mgr->phone_alias = phone_alias ? ms_strdup(phone_alias) : NULL;
......@@ -1620,6 +1621,29 @@ void file_transfer_received(LinphoneChatMessage *msg, const LinphoneContent* con
bc_free(receive_file);
}
void global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message) {
stats *counters = get_stats(lc);
switch (gstate) {
case LinphoneGlobalOn:
counters->number_of_LinphoneGlobalOn++;
break;
case LinphoneGlobalReady:
counters->number_of_LinphoneGlobalReady++;
break;
case LinphoneGlobalOff:
counters->number_of_LinphoneGlobalOff++;
break;
case LinphoneGlobalStartup:
counters->number_of_LinphoneGlobalStartup++;
break;
case LinphoneGlobalShutdown:
counters->number_of_LinphoneGlobalShutdown++;
break;
case LinphoneGlobalConfiguring:
counters->number_of_LinphoneGlobalConfiguring++;
break;
}
}
void setup_sdp_handling(const LinphoneCallTestParams* params, LinphoneCoreManager* mgr ){
if( params->sdp_removal ){
sal_default_set_sdp_handling(linphone_core_get_sal(mgr->lc), SalOpSDPSimulateRemove);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment