Commit f92de282 authored by Sylvain Berfini's avatar Sylvain Berfini 🎩
Browse files

Improved performances of presence server list notify

parent 2eb63047
......@@ -116,9 +116,7 @@ static bctbx_list_t * uri_list(const LinphoneFriendList *list) {
if (addr) {
char *uri = linphone_address_as_string_uri_only(addr);
if (uri) {
if (bctbx_list_find_custom(uri_list, (bctbx_compare_func)strcmp, uri) == NULL) {
uri_list = bctbx_list_insert_sorted(uri_list, uri, (bctbx_compare_func)strcasecmp);
}
uri_list = bctbx_list_prepend(uri_list, uri);
}
}
iterator = bctbx_list_next(iterator);
......@@ -128,9 +126,7 @@ static bctbx_list_t * uri_list(const LinphoneFriendList *list) {
const char *number = (const char *)bctbx_list_get_data(iterator);
const char *uri = linphone_friend_phone_number_to_sip_uri(lf, number);
if (uri) {
if (bctbx_list_find_custom(uri_list, (bctbx_compare_func)strcmp, uri) == NULL) {
uri_list = bctbx_list_insert_sorted(uri_list, ms_strdup(uri), (bctbx_compare_func)strcasecmp);
}
uri_list = bctbx_list_prepend(uri_list, ms_strdup(uri));
}
iterator = bctbx_list_next(iterator);
}
......@@ -256,30 +252,31 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
resource_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/rlmi:list/rlmi:resource");
if ((resource_object != NULL) && (resource_object->nodesetval != NULL)) {
for (i = 1; i <= resource_object->nodesetval->nodeNr; i++) {
LinphoneAddress* addr;
snprintf(xpath_str, sizeof(xpath_str), "/rlmi:list/rlmi:resource[%i]/@uri", i);
uri = linphone_get_xml_text_content(xml_ctx, xpath_str);
if (uri == NULL) continue;
addr = linphone_address_new(uri);
if (!addr) continue;
lf = linphone_friend_list_find_friend_by_address(list, addr);
linphone_address_unref(addr);
if (lf != NULL) {
const char *state = NULL;
snprintf(xpath_str, sizeof(xpath_str),"/rlmi:list/rlmi:resource[%i]/rlmi:instance/@state", i);
state = linphone_get_xml_text_content(xml_ctx, xpath_str);
if ((state != NULL) && (strcmp(state, "active") == 0)) {
const char *cid = NULL;
snprintf(xpath_str, sizeof(xpath_str),"/rlmi:list/rlmi:resource[%i]/rlmi:instance/@cid", i);
cid = linphone_get_xml_text_content(xml_ctx, xpath_str);
if (cid != NULL) {
presence_part = linphone_content_find_part_by_header(body, "Content-Id", cid);
if (presence_part == NULL) {
ms_warning("rlmi+xml: Cannot find part with Content-Id: %s", cid);
} else {
SalPresenceModel *presence = NULL;
linphone_notify_parse_presence(linphone_content_get_type(presence_part), linphone_content_get_subtype(presence_part), linphone_content_get_string_buffer(presence_part), &presence);
if (presence != NULL) {
const char *state = NULL;
snprintf(xpath_str, sizeof(xpath_str),"/rlmi:list/rlmi:resource[%i]/rlmi:instance/@state", i);
state = linphone_get_xml_text_content(xml_ctx, xpath_str);
if ((state != NULL) && (strcmp(state, "active") == 0)) {
const char *cid = NULL;
snprintf(xpath_str, sizeof(xpath_str),"/rlmi:list/rlmi:resource[%i]/rlmi:instance/@cid", i);
cid = linphone_get_xml_text_content(xml_ctx, xpath_str);
if (cid != NULL) {
presence_part = linphone_content_find_part_by_header(body, "Content-Id", cid);
if (presence_part == NULL) {
ms_warning("rlmi+xml: Cannot find part with Content-Id: %s", cid);
} else {
SalPresenceModel *presence = NULL;
linphone_notify_parse_presence(linphone_content_get_type(presence_part), linphone_content_get_subtype(presence_part), linphone_content_get_string_buffer(presence_part), &presence);
if (presence != NULL) {
// Try to reduce CPU cost of linphone_address_new and find_friend_by_address by only doing it when we know for sure we have a presence to notify
LinphoneAddress* addr;
snprintf(xpath_str, sizeof(xpath_str), "/rlmi:list/rlmi:resource[%i]/@uri", i);
uri = linphone_get_xml_text_content(xml_ctx, xpath_str);
if (uri == NULL) continue;
addr = linphone_address_new(uri);
if (!addr) continue;
lf = linphone_friend_list_find_friend_by_address(list, addr);
linphone_address_unref(addr);
if (lf) {
const char *phone_number = linphone_friend_sip_uri_to_phone_number(lf, uri);
lf->presence_received = TRUE;
if (phone_number) linphone_friend_set_presence_model_for_uri_or_tel(lf, phone_number, (LinphonePresenceModel *)presence);
......@@ -291,16 +288,15 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
linphone_core_notify_notify_presence_received_for_uri_or_tel(list->lc, lf, uri, (LinphonePresenceModel *)presence);
linphone_core_notify_notify_presence_received(list->lc, lf);
}
linphone_free_xml_text_content(uri);
}
linphone_content_unref(presence_part);
}
}
if (cid != NULL) linphone_free_xml_text_content(cid);
linphone_free_xml_text_content(cid);
}
if (state != NULL) linphone_free_xml_text_content(state);
lf->subscribe_active = TRUE;
}
linphone_free_xml_text_content(uri);
if (state != NULL) linphone_free_xml_text_content(state);
}
}
if (resource_object != NULL) xmlXPathFreeObject(resource_object);
......@@ -768,6 +764,7 @@ static void linphone_friend_list_send_list_subscription(LinphoneFriendList *list
linphone_event_refresh_subscribe(list->event);
} else {
LinphoneContent *content;
bctbx_list_t * elem = NULL;
int expires = lp_config_get_int(list->lc->config, "sip", "rls_presence_expires", 3600);
list->expected_notification_version = 0;
if (list->content_digest != NULL) ms_free(list->content_digest);
......@@ -792,6 +789,10 @@ static void linphone_friend_list_send_list_subscription(LinphoneFriendList *list
linphone_content_set_encoding(content, "deflate");
linphone_event_add_custom_header(list->event, "Accept-Encoding", "deflate");
}
for (elem = list->friends; elem != NULL; elem = bctbx_list_next(elem)) {
LinphoneFriend *lf = (LinphoneFriend *)elem->data;
lf->subscribe_active = TRUE;
}
linphone_event_send_subscribe(list->event, content);
linphone_content_unref(content);
linphone_event_set_user_data(list->event, list);
......
......@@ -393,15 +393,12 @@ static void test_presence_list_base(bool_t enable_compression) {
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), marie_identity);
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusBusy, int, "%d");
if (!BC_ASSERT_TRUE(lf->presence_received)) goto end;
if (!BC_ASSERT_TRUE(lf->subscribe_active)) goto end;
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity);
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusVacation, int, "%d");
if (!BC_ASSERT_TRUE(lf->presence_received)) goto end;
if (!BC_ASSERT_TRUE(lf->subscribe_active)) goto end;
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), "sip:michelle@sip.inexistentdomain.com");
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
BC_ASSERT_FALSE(lf->presence_received);
if (!BC_ASSERT_TRUE(lf->subscribe_active)) goto end;
lfl = linphone_core_create_friend_list(marie->lc);
linphone_friend_list_set_rls_uri(lfl, rls_uri);
......@@ -419,7 +416,6 @@ static void test_presence_list_base(bool_t enable_compression) {
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(marie->lc), laure_identity);
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOnline, int, "%d");
if (!BC_ASSERT_TRUE(lf->presence_received)) goto end;
if (!BC_ASSERT_TRUE(lf->subscribe_active)) goto end;
lfl = linphone_core_create_friend_list(pauline->lc);
linphone_friend_list_set_rls_uri(lfl, rls_uri);
......@@ -437,7 +433,6 @@ static void test_presence_list_base(bool_t enable_compression) {
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(pauline->lc), marie_identity);
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusBusy, int, "%d");
if (!BC_ASSERT_TRUE(lf->presence_received)) goto end;
if (!BC_ASSERT_TRUE(lf->subscribe_active)) goto end;
linphone_core_set_presence_model(marie->lc, linphone_core_create_presence_model_with_activity(marie->lc, LinphonePresenceActivityOnThePhone, NULL));
......@@ -547,11 +542,9 @@ static void test_presence_list_subscribe_before_publish(void) {
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity);
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusVacation, int, "%d");
BC_ASSERT_TRUE(lf->presence_received);
BC_ASSERT_TRUE(lf->subscribe_active);
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), "sip:michelle@sip.inexistentdomain.com");
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
BC_ASSERT_FALSE(lf->presence_received);
BC_ASSERT_TRUE(lf->subscribe_active);
enable_publish(laure, FALSE);
enable_publish(pauline, FALSE);
......@@ -625,11 +618,9 @@ static void test_presence_list_subscribe_with_error(bool_t io_error) {
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), pauline_identity);
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusVacation, int, "%d");
BC_ASSERT_TRUE(lf->presence_received);
BC_ASSERT_TRUE(lf->subscribe_active);
lf = linphone_friend_list_find_friend_by_uri(linphone_core_get_default_friend_list(laure->lc), "sip:michelle@sip.inexistentdomain.com");
BC_ASSERT_EQUAL(linphone_friend_get_status(lf), LinphoneStatusOffline, int, "%d");
BC_ASSERT_FALSE(lf->presence_received);
BC_ASSERT_TRUE(lf->subscribe_active);
BC_ASSERT_TRUE(wait_for_until(laure->lc, pauline->lc, &laure->stat.number_of_LinphonePresenceActivityVacation, 2, 6000));
if (io_error) {
......@@ -996,6 +987,28 @@ static void long_term_presence_with_crossed_references(void) {
}else ms_warning("Test skipped, no vcard support");
}
static void long_term_presence_list_for_many_friends(void) {
if (linphone_core_vcard_supported()) {
LinphoneFriendList *friends;
char *import_filepath = bc_tester_res("vcards/presence.vcf");
LinphoneCoreManager *pauline;
pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
friends = linphone_core_create_friend_list(pauline->lc);
linphone_friend_list_set_rls_uri(friends, "sip:rls@sip.example.org");
linphone_friend_list_import_friends_from_vcard4_file(friends, import_filepath);
linphone_core_remove_friend_list(pauline->lc, linphone_core_get_default_friend_list(pauline->lc));
linphone_core_add_friend_list(pauline->lc, friends);
linphone_core_refresh_registers(pauline->lc);
linphone_friend_list_unref(friends);
BC_ASSERT_TRUE(wait_for(pauline->lc,NULL,&pauline->stat.number_of_NotifyPresenceReceived,1));
linphone_core_manager_destroy(pauline);
} else ms_warning("Test skipped, no vcard support");
}
test_t presence_server_tests[] = {
TEST_NO_TAG("Simple", simple),
TEST_NO_TAG("Fast activity change", fast_activity_change),
......@@ -1010,6 +1023,7 @@ test_t presence_server_tests[] = {
TEST_ONE_TAG("Long term presence phone alias",long_term_presence_phone_alias, "longterm"),
TEST_ONE_TAG("Long term presence phone alias 2",long_term_presence_phone_alias2, "longterm"),
TEST_ONE_TAG("Long term presence list",long_term_presence_list, "longterm"),
TEST_ONE_TAG("Long term presence list for many friends",long_term_presence_list_for_many_friends, "longterm"),
TEST_ONE_TAG("Long term presence with +164 phone, without sip",long_term_presence_with_e164_phone_without_sip, "longterm"),
TEST_ONE_TAG("Long term presence with phone, without sip",long_term_presence_with_phone_without_sip, "longterm"),
TEST_ONE_TAG("Long term presence with cross references", long_term_presence_with_crossed_references,"longtern"),
......
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