diff --git a/coreapi/carddav.c b/coreapi/carddav.c index f24a3463f..4f4c904de 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -302,16 +302,32 @@ static void process_response_from_carddav_request(void *data, const belle_http_r { belle_sip_header_t *header = belle_sip_message_get_header((belle_sip_message_t *)event->response, "ETag"); LinphoneFriend *lf = (LinphoneFriend *)query->user_data; - if (lf) { - LinphoneVCard *lvc = linphone_friend_get_vcard(lf); - if (header && lvc && !linphone_vcard_get_etag(lvc)) { + LinphoneVCard *lvc = linphone_friend_get_vcard(lf); + if (lf && lvc) { + if (header) { const char *etag = belle_sip_header_get_unparsed_value(header); - ms_debug("eTag for newly created vCard is: %s", etag); + if (!linphone_vcard_get_etag(lvc)) { + ms_debug("eTag for newly created vCard is: %s", etag); + } else { + ms_debug("eTag for updated vCard is: %s", etag); + } linphone_vcard_set_etag(lvc, etag); + + linphone_carddav_sync_done(query->context, TRUE, ""); + linphone_friend_unref(lf); + } else { + // For some reason, server didn't return the eTag of the updated/created vCard + // We need to do a GET on the vCard to get the correct one + MSList *vcard = NULL; + LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)ms_new0(LinphoneCardDavResponse, 1); + response->url = linphone_vcard_get_url(lvc); + response->context = query->context; + vcard = ms_list_append(vcard, response); + linphone_carddav_pull_vcards(query->context, vcard); + ms_list_free(vcard); } - linphone_carddav_sync_done(query->context, TRUE, ""); - linphone_friend_unref(lf); - } else { + } + else { linphone_carddav_sync_done(query->context, FALSE, "No LinphoneFriend found in user_date field of query"); } } diff --git a/coreapi/friend.c b/coreapi/friend.c index 99d652cb9..4bb0e7448 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -777,10 +777,17 @@ void linphone_friend_destroy(LinphoneFriend *lf) { } LinphoneVCard* linphone_friend_get_vcard(LinphoneFriend *fr) { - return fr->vcard; + if (fr) { + return fr->vcard; + } + return NULL; } void linphone_friend_set_vcard(LinphoneFriend *fr, LinphoneVCard *vcard) { + if (!fr) { + return; + } + if (fr->vcard) { linphone_vcard_free(fr->vcard); } diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 774aec654..1cda3a1f7 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -206,6 +206,7 @@ static void carddav_sync_done(LinphoneCardDavContext *c, bool_t success, const c static void carddav_new_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(lf); + linphone_core_add_friend(c->lc, lf); linphone_friend_unref(lf); stats->new_contact_count++; } @@ -230,6 +231,8 @@ static void carddav_sync(void) { LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + const MSList *friends = NULL; + LinphoneFriend *lf = NULL; BC_ASSERT_PTR_NOT_NULL_FATAL(c); BC_ASSERT_PTR_NOT_NULL(c->server_url); @@ -248,6 +251,16 @@ static void carddav_sync(void) { wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + friends = linphone_core_get_friend_list(manager->lc); + BC_ASSERT_PTR_NOT_NULL_FATAL(friends); + lf = (LinphoneFriend *)friends->data; + linphone_carddav_put_vcard(c, lf); + + wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 2000); + BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i"); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); + ms_free(stats); linphone_carddav_destroy(c); linphone_core_manager_destroy(manager);