Commit d1f7e4d7 authored by Benjamin REIS's avatar Benjamin REIS

Add friends_map_uri to LinphoneFriendList

parent 97600a4b
......@@ -288,45 +288,65 @@ const LinphoneAddress * linphone_friend_get_address(const LinphoneFriend *lf) {
int linphone_friend_set_address(LinphoneFriend *lf, const LinphoneAddress *addr) {
LinphoneAddress *fr = linphone_address_clone(addr);
char *address;
LinphoneAddress *mAddr = linphone_friend_get_address(lf);
if(mAddr && lf->friend_list) {
char *mainAddress = linphone_address_as_string_uri_only(mAddr);
bctbx_iterator_t *it = bctbx_map_cchar_find_key(lf->friend_list->friends_map_uri, mainAddress);
if (!bctbx_iterator_cchar_equals(it, bctbx_map_cchar_end(lf->friend_list->friends_map_uri))){
linphone_friend_unref((LinphoneFriend*)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)));
bctbx_map_cchar_erase(lf->friend_list->friends_map_uri, it);
}
bctbx_iterator_cchar_delete(it);
}
linphone_address_clean(fr);
address = linphone_address_as_string_uri_only(fr);
if(lf->friend_list) {
bctbx_pair_t *pair = (bctbx_pair_t*) bctbx_pair_cchar_new(address, linphone_friend_ref(lf));
ms_message("inserting %s in map with friend [%p]", address, lf);
bctbx_map_cchar_insert_and_delete(lf->friend_list->friends_map_uri, pair);
}
if (linphone_core_vcard_supported()) {
char *address;
if (!lf->vcard) {
const char *dpname = linphone_address_get_display_name(fr) ? linphone_address_get_display_name(fr) : linphone_address_get_username(fr);
linphone_friend_create_vcard(lf, dpname);
}
address = linphone_address_as_string_uri_only(fr);
linphone_vcard_edit_main_sip_address(lf->vcard, address);
ms_free(address);
linphone_address_unref(fr);
} else {
if (lf->uri != NULL) linphone_address_unref(lf->uri);
lf->uri = fr;
}
ms_free(address);
return 0;
}
void linphone_friend_add_address(LinphoneFriend *lf, const LinphoneAddress *addr) {
LinphoneAddress *fr;
const char *uri;
if (!lf || !addr) return;
fr = linphone_address_clone(addr);
linphone_address_clean(fr);
uri = linphone_address_as_string_uri_only(fr);
if(lf->friend_list) {
bctbx_pair_t *pair = (bctbx_pair_t*) bctbx_pair_cchar_new(uri, linphone_friend_ref(lf));
ms_message("inserting %s in map with friend [%p]", uri, lf);
bctbx_map_cchar_insert_and_delete(lf->friend_list->friends_map_uri, pair);
}
if (linphone_core_vcard_supported()) {
if (lf->vcard) {
char *address = linphone_address_as_string_uri_only(fr);
linphone_vcard_add_sip_address(lf->vcard, address);
ms_free(address);
linphone_vcard_add_sip_address(lf->vcard, uri);
linphone_address_unref(fr);
}
} else {
if (lf->uri == NULL) lf->uri = fr;
else linphone_address_unref(fr);
}
ms_free(uri);
}
const bctbx_list_t* linphone_friend_get_addresses(const LinphoneFriend *lf) {
......@@ -342,18 +362,37 @@ const bctbx_list_t* linphone_friend_get_addresses(const LinphoneFriend *lf) {
}
void linphone_friend_remove_address(LinphoneFriend *lf, const LinphoneAddress *addr) {
char *address ;
if (!lf || !addr || !lf->vcard) return;
address = linphone_address_as_string_uri_only(addr);
if(lf->friend_list) {
bctbx_iterator_t *it = bctbx_map_cchar_find_key(lf->friend_list->friends_map_uri, address);
if (!bctbx_iterator_cchar_equals(it, bctbx_map_cchar_end(lf->friend_list->friends_map_uri))){
linphone_friend_unref((LinphoneFriend*)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)));
bctbx_map_cchar_erase(lf->friend_list->friends_map_uri, it);
}
bctbx_iterator_cchar_delete(it);
}
if (linphone_core_vcard_supported()) {
char *address = linphone_address_as_string_uri_only(addr);
linphone_vcard_remove_sip_address(lf->vcard, address);
ms_free(address);
}
ms_free(address);
}
void linphone_friend_add_phone_number(LinphoneFriend *lf, const char *phone) {
if (!lf || !phone) return;
if(lf->friend_list) {
const char *uri = linphone_friend_phone_number_to_sip_uri(lf, phone);
if(uri) {
bctbx_pair_t *pair = (bctbx_pair_t*) bctbx_pair_cchar_new(uri, linphone_friend_ref(lf));
bctbx_map_cchar_insert_and_delete(lf->friend_list->friends_map_uri, pair);
ms_free(uri);
}
}
if (linphone_core_vcard_supported()) {
if (!lf->vcard) {
linphone_friend_create_vcard(lf, phone);
......@@ -374,6 +413,19 @@ bctbx_list_t* linphone_friend_get_phone_numbers(LinphoneFriend *lf) {
void linphone_friend_remove_phone_number(LinphoneFriend *lf, const char *phone) {
if (!lf || !phone || !lf->vcard) return;
if(lf->friend_list) {
const char *uri = linphone_friend_phone_number_to_sip_uri(lf, phone);
if(uri) {
bctbx_iterator_t *it = bctbx_map_cchar_find_key(lf->friend_list->friends_map_uri, uri);
if (!bctbx_iterator_cchar_equals(it, bctbx_map_cchar_end(lf->friend_list->friends_map_uri))){
linphone_friend_unref((LinphoneFriend*)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)));
bctbx_map_cchar_erase(lf->friend_list->friends_map_uri, it);
}
bctbx_iterator_cchar_delete(it);
ms_free(uri);
}
}
if (linphone_core_vcard_supported()) {
linphone_vcard_remove_phone_number(lf->vcard, phone);
}
......@@ -1539,6 +1591,9 @@ bctbx_list_t* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFrie
sqlite3_free(buf);
for(elem = result; elem != NULL; elem = bctbx_list_next(elem)) {
bctbx_list_t *iterator;
bctbx_list_t *phone_numbers;
const bctbx_list_t *addresses;
LinphoneFriend *lf = (LinphoneFriend *)bctbx_list_get_data(elem);
lf->lc = lc;
lf->friend_list = list;
......@@ -1546,6 +1601,33 @@ bctbx_list_t* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFrie
bctbx_pair_t *pair = (bctbx_pair_t*) bctbx_pair_cchar_new(lf->refkey, linphone_friend_ref(lf));
bctbx_map_cchar_insert_and_delete(list->friends_map, pair);
}
phone_numbers = linphone_friend_get_phone_numbers(lf);
iterator = phone_numbers;
while (iterator) {
const char *number = (const char *)bctbx_list_get_data(iterator);
const char *uri = linphone_friend_phone_number_to_sip_uri(lf, number);
if(uri) {
bctbx_pair_t *pair = (bctbx_pair_t*) bctbx_pair_cchar_new(uri, linphone_friend_ref(lf));
bctbx_map_cchar_insert_and_delete(list->friends_map_uri, pair);
ms_free(uri);
}
iterator = bctbx_list_next(iterator);
}
addresses = linphone_friend_get_addresses(lf);
iterator = (bctbx_list_t *)addresses;
while (iterator) {
LinphoneAddress *lfaddr = (LinphoneAddress *)bctbx_list_get_data(iterator);
char *uri = linphone_address_as_string_uri_only(lfaddr);
if(uri) {
bctbx_pair_t *pair = (bctbx_pair_t*) bctbx_pair_cchar_new(uri, linphone_friend_ref(lf));
bctbx_map_cchar_insert_and_delete(list->friends_map_uri, pair);
ms_free(uri);
}
iterator = bctbx_list_next(iterator);
}
linphone_friend_save(lf, lc); /* required if we freshly created vcard but core was not set at this time */
}
linphone_vcard_context_set_user_data(lc->vcard_context, NULL);
......@@ -1702,7 +1784,7 @@ const char * linphone_friend_phone_number_to_sip_uri(LinphoneFriend *lf, const c
lfpnsu = (LinphoneFriendPhoneNumberSipUri *)bctbx_list_get_data(iterator);
if (strcmp(lfpnsu->number, phone_number) == 0) {
/*force sip uri computation because proxy config may have changed, specially, ccc could have been added since last computation*/
free_phone_number_sip_uri(lfpnsu);
//free_phone_number_sip_uri(lfpnsu);
if (lf->phone_number_sip_uri_map == iterator) {
/*change list head if head is removed*/
iterator = lf->phone_number_sip_uri_map = bctbx_list_erase_link(lf->phone_number_sip_uri_map, iterator);
......@@ -1720,6 +1802,25 @@ const char * linphone_friend_phone_number_to_sip_uri(LinphoneFriend *lf, const c
normalized_number = linphone_proxy_config_normalize_phone_number(proxy_config, phone_number);
if (!normalized_number) return NULL;
full_uri = ms_strdup_printf("sip:%s@%s;user=phone", normalized_number, linphone_proxy_config_get_domain(proxy_config));
if(strcmp(normalized_number, phone_number) != 0) {
char *old_uri = ms_strdup_printf("sip:%s@%s;user=phone", phone_number, linphone_proxy_config_get_domain(proxy_config));
if(linphone_friend_list_find_friend_by_uri(lf->friend_list, old_uri)) {
bctbx_iterator_t *it = bctbx_map_cchar_find_key(lf->friend_list->friends_map_uri, old_uri);
if (!bctbx_iterator_cchar_equals(it, bctbx_map_cchar_end(lf->friend_list->friends_map_uri))){
linphone_friend_unref((LinphoneFriend*)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)));
bctbx_map_cchar_erase(lf->friend_list->friends_map_uri, it);
}
bctbx_iterator_cchar_delete(it);
}
ms_free(old_uri);
}
if(!linphone_friend_list_find_friend_by_uri(lf->friend_list, full_uri)) {
bctbx_pair_t *pair = (bctbx_pair_t*) bctbx_pair_cchar_new(full_uri, linphone_friend_ref(lf));
bctbx_map_cchar_insert_and_delete(lf->friend_list->friends_map_uri, pair);
}
ms_free(normalized_number);
lfpnsu = ms_new0(LinphoneFriendPhoneNumberSipUri, 1);
lfpnsu->number = ms_strdup(phone_number);
......
......@@ -249,54 +249,48 @@ static void linphone_friend_list_parse_multipart_related_body(LinphoneFriendList
}
list->expected_notification_version = version + 1;
resource_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/rlmi:list/rlmi:resource");
resource_object = linphone_get_xml_xpath_object_for_node_list(xml_ctx, "/rlmi:list/rlmi:resource/rlmi:instance[@state=\"active\"]/..");
if ((resource_object != NULL) && (resource_object->nodesetval != NULL)) {
for (i = 1; i <= resource_object->nodesetval->nodeNr; i++) {
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);
else linphone_friend_set_presence_model_for_uri_or_tel(lf, uri, (LinphonePresenceModel *)presence);
if (full_state == FALSE) {
if (phone_number)
linphone_core_notify_notify_presence_received_for_uri_or_tel(list->lc, lf, phone_number, (LinphonePresenceModel *)presence);
else
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);
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);
else linphone_friend_set_presence_model_for_uri_or_tel(lf, uri, (LinphonePresenceModel *)presence);
if (full_state == FALSE) {
if (phone_number)
linphone_core_notify_notify_presence_received_for_uri_or_tel(list->lc, lf, phone_number, (LinphonePresenceModel *)presence);
else
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_content_unref(presence_part);
linphone_free_xml_text_content(uri);
}
linphone_content_unref(presence_part);
}
linphone_free_xml_text_content(cid);
}
linphone_free_xml_text_content(cid);
}
if (state != NULL) linphone_free_xml_text_content(state);
}
}
if (resource_object != NULL) xmlXPathFreeObject(resource_object);
......@@ -358,6 +352,7 @@ static LinphoneFriendList * linphone_friend_list_new(void) {
list->cbs = linphone_friend_list_cbs_new();
list->enable_subscriptions = TRUE;
list->friends_map = bctbx_mmap_cchar_new();
list->friends_map_uri = bctbx_mmap_cchar_new();
return list;
}
......@@ -376,6 +371,7 @@ static void linphone_friend_list_destroy(LinphoneFriendList *list) {
if (list->dirty_friends_to_update) list->dirty_friends_to_update = bctbx_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref);
if (list->friends) list->friends = bctbx_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release);
if (list->friends_map) bctbx_mmap_cchar_delete_with_data(list->friends_map, (void (*)(void *))linphone_friend_unref);
if (list->friends_map_uri) bctbx_mmap_cchar_delete_with_data(list->friends_map_uri, (void (*)(void *))linphone_friend_unref);
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriendList);
......@@ -528,6 +524,9 @@ LinphoneFriendListStatus linphone_friend_list_add_local_friend(LinphoneFriendLis
}
LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf, bool_t synchronize) {
bctbx_list_t *iterator;
bctbx_list_t *phone_numbers;
const bctbx_list_t *addresses;
if (lf->friend_list) {
if (lf->friend_list)
ms_error("linphone_friend_list_add_friend(): invalid friend, already in list");
......@@ -540,6 +539,35 @@ LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *
bctbx_pair_t *pair = (bctbx_pair_t*) bctbx_pair_cchar_new(lf->refkey, linphone_friend_ref(lf));
bctbx_map_cchar_insert_and_delete(list->friends_map, pair);
}
phone_numbers = linphone_friend_get_phone_numbers(lf);
iterator = phone_numbers;
while (iterator) {
const char *number = (const char *)bctbx_list_get_data(iterator);
const char *uri = linphone_friend_phone_number_to_sip_uri(lf, number);
if(uri) {
bctbx_pair_t *pair = (bctbx_pair_t*) bctbx_pair_cchar_new(uri, linphone_friend_ref(lf));
ms_message("inserting %s in map with friend [%p]", uri, lf);
bctbx_map_cchar_insert_and_delete(list->friends_map_uri, pair);
ms_free(uri);
}
iterator = bctbx_list_next(iterator);
}
addresses = linphone_friend_get_addresses(lf);
iterator = (bctbx_list_t *)addresses;
while (iterator) {
LinphoneAddress *lfaddr = (LinphoneAddress *)bctbx_list_get_data(iterator);
char *uri = linphone_address_as_string_uri_only(lfaddr);
if(uri) {
bctbx_pair_t *pair = (bctbx_pair_t*) bctbx_pair_cchar_new(uri, linphone_friend_ref(lf));
ms_message("inserting %s in map with friend [%p]", uri, lf);
bctbx_map_cchar_insert_and_delete(list->friends_map_uri, pair);
ms_free(uri);
}
iterator = bctbx_list_next(iterator);
}
if (synchronize) {
list->dirty_friends_to_update = bctbx_list_prepend(list->dirty_friends_to_update, linphone_friend_ref(lf));
}
......@@ -554,6 +582,9 @@ static void carddav_done(LinphoneCardDavContext *cdc, bool_t success, const char
}
static LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *lf, bool_t remove_from_server) {
bctbx_list_t *iterator;
bctbx_list_t *phone_numbers;
const bctbx_list_t *addresses;
bctbx_list_t *elem = bctbx_list_find(list->friends, lf);
if (elem == NULL) return LinphoneFriendListNonExistentFriend;
......@@ -587,6 +618,40 @@ static LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFrie
}
}
phone_numbers = linphone_friend_get_phone_numbers(lf);
iterator = phone_numbers;
while (iterator) {
const char *number = (const char *)bctbx_list_get_data(iterator);
const char *uri = linphone_friend_phone_number_to_sip_uri(lf, number);
if(uri) {
bctbx_iterator_t * it = bctbx_map_cchar_find_key(list->friends_map_uri, uri);
if (!bctbx_iterator_cchar_equals(it, bctbx_map_cchar_end(list->friends_map_uri))){
linphone_friend_unref((LinphoneFriend*)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)));
bctbx_map_cchar_erase(list->friends_map_uri, it);
}
bctbx_iterator_cchar_delete(it);
ms_free(uri);
}
iterator = bctbx_list_next(iterator);
}
addresses = linphone_friend_get_addresses(lf);
iterator = (bctbx_list_t *)addresses;
while (iterator) {
LinphoneAddress *lfaddr = (LinphoneAddress *)bctbx_list_get_data(iterator);
char *uri = linphone_address_as_string_uri_only(lfaddr);
if(uri) {
bctbx_iterator_t * it = bctbx_map_cchar_find_key(list->friends_map_uri, uri);
if (!bctbx_iterator_cchar_equals(it, bctbx_map_cchar_end(list->friends_map_uri))){
linphone_friend_unref((LinphoneFriend*)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)));
bctbx_map_cchar_erase(list->friends_map_uri, it);
}
bctbx_iterator_cchar_delete(it);
ms_free(uri);
}
iterator = bctbx_list_next(iterator);
}
lf->friend_list = NULL;
linphone_friend_unref(lf);
return LinphoneFriendListOK;
......@@ -679,44 +744,27 @@ void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *li
LinphoneFriend * linphone_friend_list_find_friend_by_address(const LinphoneFriendList *list, const LinphoneAddress *address) {
LinphoneFriend *result = NULL;
const bctbx_list_t *elem;
const char *param = linphone_address_get_uri_param(address, "user");
bool_t find_phone_number = (param && (strcmp(param, "phone") == 0));
char *uri = linphone_address_as_string_uri_only(address);
for (elem = list->friends; (elem != NULL) && (result == NULL); elem = bctbx_list_next(elem)) {
bctbx_list_t *iterator;
LinphoneFriend *lf = (LinphoneFriend *)bctbx_list_get_data(elem);
if (find_phone_number == TRUE) {
const char *phone_number = linphone_friend_sip_uri_to_phone_number(lf, uri);
bctbx_list_t *phone_numbers = linphone_friend_get_phone_numbers(lf);
iterator = phone_numbers;
if (!phone_number) continue;
while (iterator && (result == NULL)) {
const char *number = (const char *)bctbx_list_get_data(iterator);
if (strcmp(number, phone_number) == 0) result = lf;
iterator = bctbx_list_next(iterator);
}
} else {
const bctbx_list_t *addresses = linphone_friend_get_addresses(lf);
iterator = (bctbx_list_t *)addresses;
while (iterator && (result == NULL)) {
LinphoneAddress *lfaddr = (LinphoneAddress *)bctbx_list_get_data(iterator);
if (linphone_address_weak_equal(lfaddr, address)) result = lf;
iterator = bctbx_list_next(iterator);
}
}
if (result) break;
bctbx_iterator_t* it = bctbx_map_cchar_find_key(list->friends_map_uri, (void*)uri);
if (bctbx_iterator_cchar_equals(it, bctbx_map_cchar_end(list->friends_map_uri))) {
bctbx_iterator_cchar_delete(it);
ms_free(uri);
return NULL;
}
bctbx_pair_t *pair = bctbx_iterator_cchar_get_pair(it);
result = (LinphoneFriend *)bctbx_pair_cchar_get_second(pair);
bctbx_iterator_cchar_delete(it);
ms_free(uri);
return result;
}
LinphoneFriend * linphone_friend_list_find_friend_by_uri(const LinphoneFriendList *list, const char *uri) {
LinphoneAddress *address = linphone_address_new(uri);
LinphoneFriend *lf = address ? linphone_friend_list_find_friend_by_address(list, address) : NULL;
if (address) linphone_address_unref(address);
return lf;
LinphoneFriend *result = linphone_friend_list_find_friend_by_address(list, address);
linphone_address_destroy(address);
return result;
}
LinphoneFriend * linphone_friend_list_find_friend_by_ref_key(const LinphoneFriendList *list, const char *ref_key) {
......
......@@ -784,6 +784,7 @@ struct _LinphoneFriendList {
LinphoneAddress *rls_addr;
MSList *friends;
bctbx_map_t *friends_map;
bctbx_map_t *friends_map_uri;
unsigned char *content_digest;
int expected_notification_version;
unsigned int storage_id;
......
......@@ -246,6 +246,7 @@ static bool_t subscribe_to_callee_presence(LinphoneCoreManager* caller_mgr,Linph
}
/* BEWARE this test will fail if the machine it is run on is behind an active firewall not sending ICMP errors on incoming connections! */
/* It will create a leak of NOTIFY because during marie error after network switch off, Pauline will never received the acknowledgement of the notify ...*/
static void subscribe_failure_handle_by_app(void) {
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_tcp_rc");
......
......@@ -374,6 +374,159 @@ end:
unlink(friends_db);
bc_free(friends_db);
}
static void friends_sqlite_store_lot_of_friends(void) {
LinphoneCoreVTable *v_table = linphone_core_v_table_new();
LinphoneCore* lc = linphone_core_new(v_table, NULL, NULL, NULL);
sqlite3 *db;
int i;
char* errmsg = NULL;
char *key;
int ret;
char *buf;
ret = sqlite3_open(lc->friends_db_file, &db);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
ret = sqlite3_exec(db,"BEGIN",0,0,&errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
ret = sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS friends ("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"friend_list_id INTEGER,"
"sip_uri TEXT,"
"subscribe_policy INTEGER,"
"send_subscribe INTEGER,"
"ref_key TEXT,"
"vCard TEXT,"
"vCard_etag TEXT,"
"vCard_url TEXT,"
"presence_received INTEGER"
");", 0, 0, &errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
ret = sqlite3_exec(db,"END",0,0,&errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
ms_message("Départ :\n");
ret = sqlite3_exec(db,"BEGIN",0,0,&errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
for (i = 0; i < 20000; i++) {
buf = sqlite3_mprintf("INSERT INTO friends VALUES(NULL,%u,%Q,%i,%i,'key_%i',%Q,%Q,%Q,%i);",
i,
"dummy_addr",
0,
0,
i,
NULL,
NULL,
NULL,
0
);
ret = sqlite3_exec(db,buf,0,0,&errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
sqlite3_free(buf);
}
ret = sqlite3_exec(db,"END",0,0,&errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
ms_message("Fin :\n");
ret = sqlite3_exec(db,"BEGIN",0,0,&errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
ret = sqlite3_exec(db, "DELETE FROM friends;",0,0,&errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
ret = sqlite3_exec(db,"END",0,0,&errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
sqlite3_close(db);
linphone_core_destroy(lc);
linphone_core_v_table_destroy(v_table);
}
static void friends_sqlite_find_friend_in_lot_of_friends(void) {
LinphoneCoreVTable *v_table = linphone_core_v_table_new();
LinphoneCore* lc = linphone_core_new(v_table, NULL, NULL, NULL);
sqlite3 *db;
int i;
char* errmsg = NULL;
char *key;
int ret;
char *buf;
bctoolboxTimeSpec t1;
bctoolboxTimeSpec t2;
ret = sqlite3_open(lc->friends_db_file, &db);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
ret = sqlite3_exec(db,"BEGIN",0,0,&errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
ret = sqlite3_exec(db,
"CREATE TABLE IF NOT EXISTS friends ("
"id INTEGER PRIMARY KEY AUTOINCREMENT,"
"friend_list_id INTEGER,"
"sip_uri TEXT,"
"subscribe_policy INTEGER,"
"send_subscribe INTEGER,"
"ref_key TEXT,"
"vCard TEXT,"
"vCard_etag TEXT,"
"vCard_url TEXT,"
"presence_received INTEGER"
");", 0, 0, &errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
ret = sqlite3_exec(db,"END",0,0,&errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
ret = sqlite3_exec(db,"BEGIN",0,0,&errmsg);
BC_ASSERT_TRUE(ret ==SQLITE_OK);
for (i = 0; i < 20000; i++) {
buf = sqlite3_mprintf("INSERT INTO friends VALUES(NULL,%u,%Q,%i,%i,'key_%i',%Q,%Q,%Q,%i);",
i,
"dummy_addr",
0,
0,
i,
NULL,
NULL,