diff --git a/coreapi/carddav.c b/coreapi/carddav.c index 40dcca759..ceb782d4a 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -120,6 +120,7 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * cdc->contact_created_cb(cdc, lf); } } + linphone_friend_unref(lf); } vCards = ms_list_next(vCards); } diff --git a/coreapi/friend.c b/coreapi/friend.c index fe015a10b..bfb7d0457 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -535,19 +535,15 @@ void linphone_friend_edit(LinphoneFriend *fr) { } void linphone_friend_done(LinphoneFriend *fr) { - const char *previous_md5 = NULL; - ms_return_if_fail(fr); if (!fr->lc || !fr->friend_list) return; linphone_friend_apply(fr, fr->lc); linphone_friend_save(fr, fr->lc); if (fr && fr->vcard) { - previous_md5 = linphone_vcard_get_md5_hash(fr->vcard); - linphone_vcard_compute_md5_hash(fr->vcard); - if (previous_md5 && strcmp(previous_md5, linphone_vcard_get_md5_hash(fr->vcard)) != 0) { + 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 = ms_list_append(fr->friend_list->dirty_friends_to_update, fr); + fr->friend_list->dirty_friends_to_update = ms_list_append(fr->friend_list->dirty_friends_to_update, linphone_friend_ref(fr)); } } } @@ -561,7 +557,7 @@ LinphoneFriend * linphone_core_create_friend_with_address(LinphoneCore *lc, cons } void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) { - if ((lc->friends_lists == NULL) || (linphone_friend_list_add_friend(linphone_core_get_default_friend_list(lc), lf) != LinphoneFriendListOK)) return; + if (linphone_friend_list_add_friend(linphone_core_get_default_friend_list(lc), lf) != LinphoneFriendListOK) return; if (ms_list_find(lc->subscribers, lf)) { /*if this friend was in the pending subscriber list, now remove it from this list*/ lc->subscribers = ms_list_remove(lc->subscribers, lf); @@ -901,8 +897,6 @@ LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard) { fr->pol = LinphoneSPDeny; fr->subscribe = FALSE; - linphone_friend_set_vcard(fr, vcard); - if (sipAddresses) { const char *sipAddress = (const char *)sipAddresses->data; linphone_address = linphone_address_new(sipAddress); @@ -914,6 +908,7 @@ LinphoneFriend *linphone_friend_new_from_vcard(LinphoneVCard *vcard) { if (name) { linphone_friend_set_name(fr, name); } + fr->vcard = vcard; return fr; } @@ -1053,10 +1048,15 @@ void linphone_core_friends_storage_init(LinphoneCore *lc) { lc->friends_db = db; friends_lists = linphone_core_fetch_friends_lists_from_db(lc); - while (friends_lists) { - LinphoneFriendList *list = (LinphoneFriendList *)friends_lists->data; - linphone_core_add_friend_list(lc, list); - friends_lists = ms_list_next(friends_lists); + if (friends_lists) { + lc->friends_lists = ms_list_free_with_data(lc->friends_lists, (void (*)(void*))linphone_friend_list_unref); + lc->friends_lists = NULL; + + while (friends_lists) { + LinphoneFriendList *list = (LinphoneFriendList *)friends_lists->data; + linphone_core_add_friend_list(lc, list); + friends_lists = ms_list_next(friends_lists); + } } } diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index 3ce918215..8ea3877cd 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -316,8 +316,12 @@ void _linphone_friend_list_release(LinphoneFriendList *list){ linphone_friend_list_cbs_unref(list->cbs); list->cbs = NULL; } - list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); - list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release); + if (list->dirty_friends_to_update) { + list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); + } + if (list->friends) { + list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release); + } linphone_friend_list_unref(list); } @@ -465,6 +469,7 @@ static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { LinphoneFriendList *lfl = cdc->friend_list; MSList *elem = ms_list_find(lfl->friends, lf); if (elem) { + linphone_friend_unref(lf); lfl->friends = ms_list_remove_link(lfl->friends, elem); } if (cdc->friend_list->cbs->contact_deleted_cb) { diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index d27384655..ccadf9465 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1687,8 +1687,6 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab const char *remote_provisioning_uri = NULL; LinphoneCoreVTable* local_vtable= linphone_core_v_table_new(); LinphoneCoreVTable *internal_vtable = linphone_core_v_table_new(); - LinphoneFriendList *list = NULL; - const char *rls_uri = NULL; ms_message("Initializing LinphoneCore %s", linphone_core_get_version()); @@ -1696,13 +1694,7 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab lc->data=userdata; lc->ringstream_autorelease=TRUE; - list = linphone_core_create_friend_list(lc); - rls_uri = lp_config_get_string(lc->config, "sip", "rls_uri", NULL); - if (rls_uri && lp_config_get_int(lc->config, "sip", "use_rls_presence", 0)) { - linphone_friend_list_set_rls_uri(list, rls_uri); - } - linphone_core_add_friend_list(lc, list); - linphone_friend_list_unref(list); + linphone_core_add_friend_list(lc, NULL); linphone_task_list_init(&lc->hooks); @@ -1941,9 +1933,12 @@ bool_t linphone_core_generic_confort_noise_enabled(const LinphoneCore *lc){ } const MSList* linphone_core_get_friend_list(const LinphoneCore *lc) { - if (lc->friends_lists && lc->friends_lists->data) { - LinphoneFriendList *list = (LinphoneFriendList *)lc->friends_lists->data; - return list->friends; + MSList *lists = lc->friends_lists; + if (lists) { + LinphoneFriendList *list = (LinphoneFriendList *)lists->data; + if (list) { + return list->friends; + } } return NULL; } @@ -1953,12 +1948,10 @@ const MSList* linphone_core_get_friends_lists(const LinphoneCore *lc) { } LinphoneFriendList* linphone_core_get_default_friend_list(const LinphoneCore *lc) { - LinphoneFriendList *list = NULL; - if (!lc->friends_lists) { - return NULL; + if (lc && lc->friends_lists) { + return (LinphoneFriendList *)lc->friends_lists->data; } - list = (LinphoneFriendList *)lc->friends_lists->data; - return list; + return NULL; } void linphone_core_remove_friend_list(LinphoneCore *lc, LinphoneFriendList *list) { @@ -1979,8 +1972,17 @@ void linphone_core_add_friend_list(LinphoneCore *lc, LinphoneFriendList *list) { } lc->friends_lists = ms_list_append(lc->friends_lists, linphone_friend_list_ref(list)); #ifdef FRIENDS_SQL_STORAGE_ENABLED - linphone_core_store_friends_list_in_db(lc, list); + linphone_core_store_friends_list_in_db(lc, list); #endif + } else { + const char *rls_uri = lp_config_get_string(lc->config, "sip", "rls_uri", NULL); + list = linphone_core_create_friend_list(lc); + linphone_friend_list_set_display_name(list, "_default"); + if (rls_uri && lp_config_get_int(lc->config, "sip", "use_rls_presence", 0)) { + linphone_friend_list_set_rls_uri(list, rls_uri); + } + lc->friends_lists = ms_list_append(lc->friends_lists, linphone_friend_list_ref(list)); + linphone_friend_list_unref(list); } } @@ -6391,13 +6393,8 @@ static void codecs_config_uninit(LinphoneCore *lc) void ui_config_uninit(LinphoneCore* lc) { - MSList *elem = NULL; ms_message("Destroying friends."); - for (elem = lc->friends_lists; elem != NULL; elem = ms_list_next(elem)) { - LinphoneFriendList *list = (LinphoneFriendList *)elem->data; - _linphone_friend_list_release(list); - } - lc->friends_lists = NULL; + lc->friends_lists = ms_list_free_with_data(lc->friends_lists, (void (*)(void*))_linphone_friend_list_release); if (lc->subscribers) { lc->subscribers = ms_list_free_with_data(lc->subscribers, (void (*)(void *))_linphone_friend_release); } diff --git a/coreapi/linphonefriend.h b/coreapi/linphonefriend.h index 7b11ec253..86c4a641a 100644 --- a/coreapi/linphonefriend.h +++ b/coreapi/linphonefriend.h @@ -357,9 +357,9 @@ LINPHONE_PUBLIC void linphone_core_interpret_friend_uri(LinphoneCore *lc, const LINPHONE_PUBLIC void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *fr); /** - * remove a friend from the buddy list + * Removes a friend from the buddy list * @param lc #LinphoneCore object - * @param fr #LinphoneFriend to add + * @param fr #LinphoneFriend to remove */ LINPHONE_PUBLIC void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend *fr); diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index 77d136642..6b2c4fcd9 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -21,12 +21,13 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "belcard/belcard.hpp" #include "belcard/belcard_parser.hpp" #include "sal/sal.h" +#include struct _LinphoneVCard { shared_ptr belCard; char *etag; char *url; - char *md5; + unsigned char *md5; }; #ifdef __cplusplus @@ -225,20 +226,33 @@ const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { } void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard) { + unsigned char digest[16]; + const char *text = NULL; if (!vCard) { return; } - if (vCard->md5) { - ms_free(vCard->md5); - } - //TODO: compute md5 hash + text = linphone_vcard_as_vcard4_string(vCard); + md5((unsigned char *)text, strlen(text), digest); + vCard->md5 = (unsigned char *)ms_malloc(sizeof(digest)); + memcpy(vCard->md5, digest, sizeof(digest)); } -const char *linphone_vcard_get_md5_hash(LinphoneVCard *vCard) { - if (!vCard) { - return NULL; +bool_t linphone_vcard_compare_md5_hash(LinphoneVCard *vCard) { + unsigned char *previous_md5 = vCard->md5; + unsigned char *new_md5 = NULL; + int result = -1; + + if (!previous_md5) { + return result; } - return vCard->md5; + + linphone_vcard_compute_md5_hash(vCard); + new_md5 = vCard->md5; + result = memcmp(new_md5, previous_md5, sizeof(previous_md5)); + + ms_free(previous_md5); + ms_free(new_md5); + return result; } #ifdef __cplusplus diff --git a/coreapi/vcard.h b/coreapi/vcard.h index 70f61b41c..e1d035fb3 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -176,11 +176,11 @@ const char* linphone_vcard_get_url(const LinphoneVCard *vCard); void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard); /** - * Computes the md5 hash for the vCard + * Compares the previously computed md5 hash (using linphone_vcard_compute_md5_hash) with the current one * @param[in] vCard the LinphoneVCard - * @return the last md5 hash computed for the vCard, or NULL if it wasn't computed yet + * @return 0 if the md5 hasn't changed, 1 otherwise */ -const char *linphone_vcard_get_md5_hash(LinphoneVCard *vCard); +bool_t linphone_vcard_compare_md5_hash(LinphoneVCard *vCard); /** * @} diff --git a/coreapi/vcard_stubs.c b/coreapi/vcard_stubs.c index 4f12c0415..500119f20 100644 --- a/coreapi/vcard_stubs.c +++ b/coreapi/vcard_stubs.c @@ -103,6 +103,6 @@ void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard) { } -const char *linphone_vcard_get_md5_hash(LinphoneVCard *vCard) { - return NULL; +bool_t linphone_vcard_compare_md5_hash(LinphoneVCard *vCard) { + return FALSE; } \ No newline at end of file diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 3a09bf890..029ed7fcc 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -126,7 +126,7 @@ static void friends_sqlite_storage(void) { LinphoneCoreManager* manager = linphone_core_manager_new2("empty_rc", FALSE); LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); LinphoneVCard *lvc = linphone_vcard_new(); - LinphoneFriend *lf = linphone_friend_new(); + LinphoneFriend *lf = NULL; LinphoneFriend *lf2 = NULL; LinphoneAddress *addr = linphone_address_new("sip:sylvain@sip.linphone.org"); const MSList *friends = linphone_core_get_friend_list(manager->lc); @@ -138,20 +138,18 @@ static void friends_sqlite_storage(void) { unlink(friends_db); linphone_core_set_friends_database_path(manager->lc, friends_db); friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, linphone_core_get_default_friend_list(manager->lc)); - BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); - friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); - BC_ASSERT_EQUAL(ms_list_size(friends), 0, int, "%d"); + BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 0, int, "%d"); linphone_vcard_set_etag(lvc, "\"123-456789\""); linphone_vcard_set_url(lvc, "http://dav.somewhere.fr/addressbook/me/someone.vcf"); - linphone_friend_set_vcard(lf, lvc); + lf = linphone_friend_new_from_vcard(lvc); linphone_friend_set_address(lf, addr); linphone_friend_set_name(lf, "Sylvain"); linphone_core_add_friend_list(manager->lc, lfl); - + linphone_friend_list_unref(lfl); linphone_friend_list_set_display_name(lfl, "Test"); - linphone_friend_list_add_friend(lfl, lf); + BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%i"); linphone_friend_unref(lf); BC_ASSERT_EQUAL(lfl->storage_id, 1, int, "%d"); BC_ASSERT_EQUAL(lf->storage_id, 1, int, "%d"); @@ -161,6 +159,7 @@ static void friends_sqlite_storage(void) { friends_lists_from_db = linphone_core_fetch_friends_lists_from_db(manager->lc); BC_ASSERT_EQUAL(ms_list_size(friends_lists_from_db), 1, int, "%d"); + friends_lists_from_db = ms_list_free_with_data(friends_lists_from_db, (void (*)(void *))linphone_friend_list_unref); friends_from_db = linphone_core_fetch_friends_from_db(manager->lc, lfl); BC_ASSERT_EQUAL(ms_list_size(friends_from_db), 1, int, "%d"); @@ -197,7 +196,6 @@ end: unlink(friends_db); ms_free(friends_db); linphone_address_unref(addr); - friends_from_db = ms_list_free_with_data(friends_from_db, (void (*)(void *))linphone_friend_unref); linphone_core_manager_destroy(manager); } #endif @@ -242,6 +240,7 @@ static void carddav_sync(void) { linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_unref(lfl); c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); @@ -258,7 +257,6 @@ static void carddav_sync(void) { BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); ms_free(stats); - linphone_friend_list_unref(lfl); linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } @@ -273,12 +271,13 @@ static void carddav_sync_2(void) { linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_unref(lfl); c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); unlink(friends_db); linphone_core_set_friends_database_path(manager->lc, friends_db); - linphone_friend_list_add_friend(lfl, lf); + BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); linphone_friend_unref(lf); linphone_carddav_set_user_data(c, stats); @@ -299,7 +298,6 @@ static void carddav_sync_2(void) { ms_free(stats); unlink(friends_db); ms_free(friends_db); - linphone_friend_list_unref(lfl); linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } @@ -315,12 +313,13 @@ static void carddav_sync_3(void) { linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_unref(lfl); c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); unlink(friends_db); linphone_core_set_friends_database_path(manager->lc, friends_db); - linphone_friend_list_add_friend(lfl, lf); + BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); linphone_friend_unref(lf); linphone_carddav_set_user_data(c, stats); @@ -339,7 +338,6 @@ static void carddav_sync_3(void) { ms_free(stats); unlink(friends_db); ms_free(friends_db); - linphone_friend_list_unref(lfl); linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } @@ -354,6 +352,7 @@ static void carddav_sync_4(void) { linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); linphone_core_add_friend_list(manager->lc, lfl); + linphone_friend_list_unref(lfl); c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); @@ -377,7 +376,6 @@ static void carddav_sync_4(void) { linphone_friend_unref(lf); ms_free(stats); - linphone_friend_list_unref(lfl); linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } @@ -410,15 +408,17 @@ static void carddav_integration(void) { BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); BC_ASSERT_TRUE(linphone_vcard_generate_unique_id(lvc)); BC_ASSERT_PTR_NOT_NULL(linphone_vcard_get_uid(lvc)); - linphone_friend_list_add_friend(lfl, lf); + BC_ASSERT_EQUAL_FATAL(linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); wait_for_until(manager->lc, NULL, NULL, 1, 2000); linphone_friend_list_remove_friend(lfl, lf); wait_for_until(manager->lc, NULL, NULL, 1, 2000); linphone_friend_unref(lf); + lf = NULL; lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Ghislain Mary\r\nIMPP;TYPE=work:sip:ghislain@sip.linphone.org\r\nEND:VCARD\r\n"); lf = linphone_friend_new_from_vcard(lvc); - _linphone_friend_list_add_friend(lfl, lf); + BC_ASSERT_EQUAL_FATAL(_linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d"); + linphone_friend_unref(lf); BC_ASSERT_EQUAL(lfl->revision, 0, int, "%i"); linphone_friend_list_synchronize_friends_from_server(lfl); @@ -428,8 +428,19 @@ static void carddav_integration(void) { BC_ASSERT_EQUAL(stats->removed_contact_count, 1, int, "%i"); BC_ASSERT_NOT_EQUAL(lfl->revision, 0, int, "%i"); + BC_ASSERT_EQUAL_FATAL(ms_list_size(lfl->friends), 1, int, "%i"); + lf = (LinphoneFriend *)lfl->friends->data; + linphone_friend_edit(lf); + linphone_friend_done(lf); + BC_ASSERT_EQUAL(ms_list_size(lf->friend_list->dirty_friends_to_update), 0, int, "%i"); + + linphone_core_set_network_reachable(manager->lc, FALSE); //To prevent the CardDAV update + linphone_friend_edit(lf); + linphone_friend_set_name(lf, "François Grisez"); + linphone_friend_done(lf); + BC_ASSERT_EQUAL(ms_list_size(lf->friend_list->dirty_friends_to_update), 1, int, "%i"); + ms_free(stats); - linphone_friend_unref(lf); linphone_friend_list_unref(lfl); linphone_core_manager_destroy(manager); }