diff --git a/coreapi/friend.c b/coreapi/friend.c index 83d4c7b8f..387997115 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -264,16 +264,9 @@ void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char const LinphoneAddress * linphone_friend_get_address(const LinphoneFriend *lf) { if (linphone_core_vcard_supported()) { if (lf->vcard) { - bctbx_list_t *sip_addresses = linphone_vcard_get_sip_addresses(lf->vcard); + const bctbx_list_t *sip_addresses = linphone_vcard_get_sip_addresses(lf->vcard); if (sip_addresses) { - const char *uri = (const char *)bctbx_list_nth_data(sip_addresses, 0); - LinphoneAddress *addr = NULL; - if (uri) addr = linphone_address_new(uri); - bctbx_list_free(sip_addresses); - if (lf->uri){ - linphone_address_unref(lf->uri); - } - ((LinphoneFriend*)lf)->uri = addr; + LinphoneAddress *addr = (LinphoneAddress *)bctbx_list_nth_data(sip_addresses, 0); return addr; } } @@ -327,27 +320,20 @@ void linphone_friend_add_address(LinphoneFriend *lf, const LinphoneAddress *addr } bctbx_list_t* linphone_friend_get_addresses(const LinphoneFriend *lf) { - bctbx_list_t *sip_addresses = NULL; - bctbx_list_t *addresses = NULL; - bctbx_list_t *iterator = NULL; - if (!lf) return NULL; if (linphone_core_vcard_supported()) { - sip_addresses = linphone_vcard_get_sip_addresses(lf->vcard); - iterator = sip_addresses; - while (iterator) { - const char *sip_address = (const char *)bctbx_list_get_data(iterator); - LinphoneAddress *addr = linphone_address_new(sip_address); - if (addr) { - addresses = bctbx_list_append(addresses, addr); - } - iterator = bctbx_list_next(iterator); + bctbx_list_t *result = NULL; + const bctbx_list_t * addresses = linphone_vcard_get_sip_addresses(lf->vcard); + while (addresses) { + LinphoneAddress *addr = (LinphoneAddress *)addresses->data; + result = bctbx_list_append(result, linphone_address_clone(addr)); + addresses = bctbx_list_next(addresses); } - if (sip_addresses) bctbx_list_free(sip_addresses); - return addresses; + return result; } else { - return lf->uri ? bctbx_list_append(addresses, linphone_address_clone(lf->uri)) : NULL; + bctbx_list_t *addresses = NULL; + return lf->uri ? bctbx_list_append(addresses, lf->uri) : NULL; } } @@ -771,14 +757,17 @@ void linphone_friend_edit(LinphoneFriend *fr) { void linphone_friend_done(LinphoneFriend *fr) { ms_return_if_fail(fr); - if (!fr->lc || !fr->friend_list) return; + if (!fr->lc) return; linphone_friend_apply(fr, fr->lc); linphone_friend_save(fr, fr->lc); if (fr && linphone_core_vcard_supported() && fr->vcard) { if (linphone_vcard_compare_md5_hash(fr->vcard) != 0) { - ms_debug("vCard's md5 has changed, mark friend as dirty"); - fr->friend_list->dirty_friends_to_update = bctbx_list_append(fr->friend_list->dirty_friends_to_update, linphone_friend_ref(fr)); + ms_debug("vCard's md5 has changed, mark friend as dirty and clear sip addresses list cache"); + linphone_vcard_clean_cache(fr->vcard); + if (fr->friend_list) { + fr->friend_list->dirty_friends_to_update = bctbx_list_append(fr->friend_list->dirty_friends_to_update, linphone_friend_ref(fr)); + } } } } diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 04fc99a6a..9d99efa78 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -37,6 +37,7 @@ struct _LinphoneVcard { char *etag; char *url; unsigned char md5[VCARD_MD5_HASH_SIZE]; + bctbx_list_t *sip_addresses_cache; }; #ifdef __cplusplus @@ -82,6 +83,7 @@ void linphone_vcard_free(LinphoneVcard *vCard) { if (!vCard) return; if (vCard->etag) ms_free(vCard->etag); if (vCard->url) ms_free(vCard->url); + linphone_vcard_clean_cache(vCard); vCard->belCard.reset(); ms_free(vCard); } @@ -238,17 +240,17 @@ void linphone_vcard_edit_main_sip_address(LinphoneVcard *vCard, const char *sip_ } } -bctbx_list_t* linphone_vcard_get_sip_addresses(const LinphoneVcard *vCard) { - bctbx_list_t *result = NULL; +const bctbx_list_t* linphone_vcard_get_sip_addresses(LinphoneVcard *vCard) { if (!vCard) return NULL; - - for (auto it = vCard->belCard->getImpp().begin(); it != vCard->belCard->getImpp().end(); ++it) { - const char *value = (*it)->getValue().c_str(); - if (strncmp(value, "sip:", 4) == 0) { - result = bctbx_list_append(result, (char *)value); + if (!vCard->sip_addresses_cache) { + for (auto it = vCard->belCard->getImpp().begin(); it != vCard->belCard->getImpp().end(); ++it) { + LinphoneAddress* addr = linphone_address_new((*it)->getValue().c_str()); + if (addr) { + vCard->sip_addresses_cache = bctbx_list_append(vCard->sip_addresses_cache, addr); + } } } - return result; + return vCard->sip_addresses_cache; } void linphone_vcard_add_phone_number(LinphoneVcard *vCard, const char *phone) { @@ -390,6 +392,11 @@ bool_t linphone_core_vcard_supported(void) { return TRUE; } +void linphone_vcard_clean_cache(LinphoneVcard *vCard) { + if (vCard->sip_addresses_cache) bctbx_list_free_with_data(vCard->sip_addresses_cache, (void (*)(void*))linphone_address_unref); + vCard->sip_addresses_cache = NULL; +} + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/coreapi/vcard.h b/coreapi/vcard.h index 84ca83b3b..7e72b5347 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -179,11 +179,11 @@ void linphone_vcard_remove_sip_address(LinphoneVcard *vCard, const char *sip_add void linphone_vcard_edit_main_sip_address(LinphoneVcard *vCard, const char *sip_address); /** - * Returns the list of SIP addresses (as string) in the vCard (all the IMPP attributes that has an URI value starting by "sip:") or NULL + * Returns the list of SIP addresses (as LinphoneAddress) in the vCard (all the IMPP attributes that has an URI value starting by "sip:") or NULL * @param[in] vCard the LinphoneVcard - * @return \mslist{const char *} + * @return const \mslist{LinphoneAddress *} */ -LINPHONE_PUBLIC bctbx_list_t* linphone_vcard_get_sip_addresses(const LinphoneVcard *vCard); +LINPHONE_PUBLIC const bctbx_list_t* linphone_vcard_get_sip_addresses(LinphoneVcard *vCard); /** * Adds a phone number in the vCard, using the TEL property @@ -283,6 +283,8 @@ void linphone_vcard_compute_md5_hash(LinphoneVcard *vCard); */ bool_t linphone_vcard_compare_md5_hash(LinphoneVcard *vCard); +void linphone_vcard_clean_cache(LinphoneVcard *vCard); + /** * @} */ diff --git a/coreapi/vcard_stubs.c b/coreapi/vcard_stubs.c index 878d51a66..9f4618a61 100644 --- a/coreapi/vcard_stubs.c +++ b/coreapi/vcard_stubs.c @@ -158,3 +158,6 @@ bool_t linphone_vcard_compare_md5_hash(LinphoneVcard *vCard) { bool_t linphone_core_vcard_supported(void) { return FALSE; } + +void linphone_vcard_clean_cache(LinphoneVcard *vCard) { +} diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 9754acccf..ef37989bd 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -157,6 +157,7 @@ static void linphone_vcard_phone_numbers_and_sip_addresses(void) { lvc = linphone_vcard_context_get_vcard_from_buffer(manager->lc->vcard_context, "BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nTEL;TYPE=work:0952636505\r\nTEL:0476010203\r\nEND:VCARD\r\n"); lf = linphone_friend_new_from_vcard(lvc); + lf->lc = manager->lc; sip_addresses = linphone_friend_get_addresses(lf); phone_numbers = linphone_friend_get_phone_numbers(lf); @@ -167,7 +168,6 @@ static void linphone_vcard_phone_numbers_and_sip_addresses(void) { addr = linphone_address_new("sip:sylvain@sip.linphone.org"); linphone_friend_add_address(lf, addr); - linphone_address_unref(addr); sip_addresses = linphone_friend_get_addresses(lf); BC_ASSERT_EQUAL((unsigned int)bctbx_list_size(sip_addresses), 1, unsigned int, "%u"); if (sip_addresses) bctbx_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref); @@ -182,9 +182,9 @@ static void linphone_vcard_phone_numbers_and_sip_addresses(void) { BC_ASSERT_EQUAL((unsigned int)bctbx_list_size(phone_numbers), 0, unsigned int, "%u"); if (phone_numbers) bctbx_list_free(phone_numbers); - addr = linphone_address_new("sip:sylvain@sip.linphone.org"); + linphone_friend_edit(lf); linphone_friend_remove_address(lf, addr); - linphone_address_unref(addr); + linphone_friend_done(lf); sip_addresses = linphone_friend_get_addresses(lf); BC_ASSERT_EQUAL((unsigned int)bctbx_list_size(sip_addresses), 0, unsigned int, "%u"); if (sip_addresses) bctbx_list_free_with_data(sip_addresses, (void (*)(void *))linphone_address_unref); @@ -194,6 +194,7 @@ static void linphone_vcard_phone_numbers_and_sip_addresses(void) { BC_ASSERT_EQUAL((unsigned int)bctbx_list_size(phone_numbers), 1, unsigned int, "%u"); if (phone_numbers) bctbx_list_free(phone_numbers); + linphone_address_unref(addr); linphone_friend_unref(lf); lf = NULL; lvc = NULL;