Commit 43619c53 authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Added contact updated callback in friendlist when using CardDAV

parent 49047285
......@@ -110,6 +110,12 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList *
if (local_friend) {
LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data;
lf->storage_id = lf2->storage_id;
lf->pol = lf2->pol;
lf->subscribe = lf2->subscribe;
lf->refkey = ms_strdup(lf2->refkey);
lf->presence_received = lf2->presence_received;
if (cdc->contact_updated_cb) {
ms_debug("Contact updated: %s", linphone_friend_get_name(lf));
cdc->contact_updated_cb(cdc, lf, lf2);
......@@ -169,41 +175,33 @@ end:
}
static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend *lf) {
LinphoneVCard *lvc1 = linphone_vcard_new_from_vcard4_buffer(response->vcard);
LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf);
const char *uid1 = NULL, *uid2 = NULL;
if (!lvc1 || !lvc2) {
if (lvc1) linphone_vcard_free(lvc1);
return 1;
}
uid1 = linphone_vcard_get_uid(lvc1);
uid2 = linphone_vcard_get_uid(lvc2);
linphone_vcard_free(lvc1);
if (!uid1 || !uid2) {
if (!response->url || !lf || !lf->vcard || !linphone_vcard_get_url(lf->vcard)) {
return 1;
}
return strcmp(uid1, uid2);
return strcmp(response->url, linphone_vcard_get_url(lf->vcard));
}
static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) {
if (vCards != NULL && ms_list_size(vCards) > 0) {
MSList *friends = cdc->friend_list->friends;
MSList *friends_to_remove = NULL;
MSList *temp_list = NULL;
while (friends) {
LinphoneFriend *lf = (LinphoneFriend *)friends->data;
if (lf) {
MSList *vCard = ms_list_find_custom(vCards, (int (*)(const void*, const void*))find_matching_vcard, lf);
if (!vCard) {
ms_error("Local friend %s isn't in the remote vCard list, delete it", linphone_friend_get_name(lf));
friends_to_remove = ms_list_append(friends_to_remove, lf);
ms_debug("Local friend %s isn't in the remote vCard list, delete it", linphone_friend_get_name(lf));
temp_list = ms_list_append(temp_list, linphone_friend_ref(lf));
} else {
LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)vCard->data;
ms_debug("Local friend %s is in the remote vCard list, check eTag", linphone_friend_get_name(lf));
if (response) {
LinphoneVCard *lvc = linphone_friend_get_vcard(lf);
ms_debug("Local friend eTag is %s, remote vCard eTag is %s", linphone_vcard_get_etag(lvc), response->etag);
if (lvc && strcmp(linphone_vcard_get_etag(lvc), response->etag) == 0) {
const char *etag = linphone_vcard_get_etag(lvc);
ms_debug("Local friend eTag is %s, remote vCard eTag is %s", etag, response->etag);
if (lvc && etag && strcmp(etag, response->etag) == 0) {
ms_list_remove(vCards, vCard);
ms_free(response);
}
......@@ -212,17 +210,18 @@ static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList
}
friends = ms_list_next(friends);
}
friends_to_remove = temp_list;
while(friends_to_remove) {
LinphoneFriend *lf = (LinphoneFriend *)friends_to_remove->data;
if (lf) {
if (cdc->contact_removed_cb) {
ms_error("Contact removed: %s", linphone_friend_get_name(lf));
ms_debug("Contact removed: %s", linphone_friend_get_name(lf));
cdc->contact_removed_cb(cdc, lf);
}
}
friends_to_remove = ms_list_next(friends_to_remove);
}
friends_to_remove = ms_list_free(friends_to_remove);
temp_list = ms_list_free_with_data(temp_list, (void (*)(void *))linphone_friend_unref);
linphone_carddav_pull_vcards(cdc, vCards);
}
......
......@@ -72,6 +72,14 @@ void linphone_friend_list_cbs_set_contact_deleted(LinphoneFriendListCbs *cbs, Li
cbs->contact_deleted_cb = cb;
}
LinphoneFriendListContactUpdatedCb linphone_friend_list_cbs_get_contact_updated(const LinphoneFriendListCbs *cbs) {
return cbs->contact_updated_cb;
}
void linphone_friend_list_cbs_set_contact_updated(LinphoneFriendListCbs *cbs, LinphoneFriendListContactUpdatedCb cb) {
cbs->contact_updated_cb = cb;
}
static char * create_resource_list_xml(const LinphoneFriendList *list) {
char *xml_content = NULL;
MSList *elem;
......@@ -423,6 +431,16 @@ static void carddav_done(LinphoneCardDavContext *cdc, bool_t success, const char
linphone_carddav_context_destroy(cdc);
}
LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFriendList *list, MSList *elem, LinphoneFriend *lf) {
if (!elem) {
return LinphoneFriendListNonExistentFriend;
}
lf->friend_list = NULL;
linphone_friend_unref(lf);
list->friends = ms_list_remove_link(list->friends, elem);
return LinphoneFriendListOK;
}
LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *lf) {
MSList *elem = ms_list_find(list->friends, lf);
LinphoneCardDavContext *cdc = linphone_carddav_context_new(list);
......@@ -436,10 +454,7 @@ LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *
linphone_carddav_delete_vcard(cdc, lf);
}
lf->friend_list = NULL;
linphone_friend_unref(lf);
list->friends = ms_list_remove_link(list->friends, elem);
return LinphoneFriendListOK;
return _linphone_friend_list_remove_friend(list, elem, lf);
}
void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list) {
......@@ -472,11 +487,7 @@ static void carddav_created(LinphoneCardDavContext *cdc, LinphoneFriend *lf) {
static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) {
if (cdc) {
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);
}
linphone_friend_list_remove_friend(lfl, lf);
if (cdc->friend_list->cbs->contact_deleted_cb) {
cdc->friend_list->cbs->contact_deleted_cb(lfl, lf);
}
......@@ -484,7 +495,17 @@ static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) {
}
static void carddav_updated(LinphoneCardDavContext *cdc, LinphoneFriend *lf_new, LinphoneFriend *lf_old) {
//TODO
if (cdc) {
LinphoneFriendList *lfl = cdc->friend_list;
MSList *elem = ms_list_find(lfl->friends, lf_old);
if (elem) {
_linphone_friend_list_remove_friend(lfl, elem, lf_old);
}
_linphone_friend_list_add_friend(lfl, lf_new);
if (cdc->friend_list->cbs->contact_updated_cb) {
cdc->friend_list->cbs->contact_updated_cb(lfl, lf_new, lf_old);
}
}
}
void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *list) {
......
......@@ -160,6 +160,7 @@ LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *li
* @return LinphoneFriendListOK if removed successfully, LinphoneFriendListNonExistentFriend if the friend is not in the list.
**/
LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *afriend);
LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFriendList *list, MSList *elem, LinphoneFriend *lf);
/**
* Find a friend in the friend list using a LinphoneAddress.
......@@ -232,6 +233,11 @@ typedef void (*LinphoneFriendListContactCreatedCb)(LinphoneFriendList *list, Lin
**/
typedef void (*LinphoneFriendListContactDeletedCb)(LinphoneFriendList *list, LinphoneFriend *lf);
/**
* Callback used to notify a contact has been updated on the CardDAV server
**/
typedef void (*LinphoneFriendListContactUpdatedCb)(LinphoneFriendList *list, LinphoneFriend *new_friend, LinphoneFriend *old_friend);
/**
* Get the LinphoneFriendListCbs object associated with a LinphoneFriendList.
* @param[in] request LinphoneXmlRpcRequest object
......@@ -294,6 +300,20 @@ LINPHONE_PUBLIC LinphoneFriendListContactDeletedCb linphone_friend_list_cbs_get_
**/
LINPHONE_PUBLIC void linphone_friend_list_cbs_set_contact_deleted(LinphoneFriendListCbs *cbs, LinphoneFriendListContactDeletedCb cb);
/**
* Get the contact updated callback.
* @param[in] cbs LinphoneFriendListCbs object.
* @return The current contact updated callback.
**/
LINPHONE_PUBLIC LinphoneFriendListContactUpdatedCb linphone_friend_list_cbs_get_contact_updated(const LinphoneFriendListCbs *cbs);
/**
* Set the contact updated callback.
* @param[in] cbs LinphoneFriendListCbs object.
* @param[in] cb The contact updated to be used.
**/
LINPHONE_PUBLIC void linphone_friend_list_cbs_set_contact_updated(LinphoneFriendListCbs *cbs, LinphoneFriendListContactUpdatedCb cb);
/**
*
* @param[in] list LinphoneFriendList object.
......
......@@ -700,6 +700,7 @@ struct _LinphoneFriendListCbs {
void *user_data;
LinphoneFriendListContactCreatedCb contact_created_cb;
LinphoneFriendListContactDeletedCb contact_deleted_cb;
LinphoneFriendListContactUpdatedCb contact_updated_cb;
};
BELLE_SIP_DECLARE_VPTR(LinphoneFriendListCbs);
......
......@@ -395,11 +395,18 @@ static void carddav_contact_deleted(LinphoneFriendList *list, LinphoneFriend *lf
stats->removed_contact_count++;
}
static void carddav_contact_updated(LinphoneFriendList *list, LinphoneFriend *new_friend, LinphoneFriend *old_friend) {
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs);
stats->updated_contact_count++;
}
static void carddav_integration(void) {
LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE);
LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc);
LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Margaux Clerc\r\nIMPP;TYPE=work:sip:margaux@sip.linphone.org\r\nEND:VCARD\r\n");
LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc);
LinphoneVCard *lvc2 = NULL;
LinphoneFriend *lf2 = NULL;
LinphoneFriendListCbs *cbs = NULL;
LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1);
......@@ -408,6 +415,7 @@ static void carddav_integration(void) {
linphone_friend_list_cbs_set_user_data(cbs, stats);
linphone_friend_list_cbs_set_contact_created(cbs, carddav_contact_created);
linphone_friend_list_cbs_set_contact_deleted(cbs, carddav_contact_deleted);
linphone_friend_list_cbs_set_contact_updated(cbs, carddav_contact_updated);
linphone_core_add_friend_list(manager->lc, lfl);
BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc));
......@@ -425,12 +433,21 @@ static void carddav_integration(void) {
BC_ASSERT_EQUAL_FATAL(_linphone_friend_list_add_friend(lfl, lf), LinphoneFriendListOK, int, "%d");
linphone_friend_unref(lf);
lvc2 = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nFN:Sylvain Berfini\r\nIMPP:sip:sylvain.linphone.org\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nEND:VCARD\r\n");
linphone_vcard_set_url(lvc2, "/sabredav/addressbookserver.php/addressbooks/sylvain/default/me.vcf");
lf2 = linphone_friend_new_from_vcard(lvc2);
BC_ASSERT_EQUAL_FATAL(_linphone_friend_list_add_friend(lfl, lf2), LinphoneFriendListOK, int, "%d");
linphone_friend_unref(lf2);
lf2 = NULL;
BC_ASSERT_EQUAL(lfl->revision, 0, int, "%i");
linphone_friend_list_synchronize_friends_from_server(lfl);
wait_for_until(manager->lc, NULL, &stats->new_contact_count, 1, 2000);
BC_ASSERT_EQUAL(stats->new_contact_count, 1, int, "%i");
wait_for_until(manager->lc, NULL, &stats->new_contact_count, 0, 2000);
BC_ASSERT_EQUAL(stats->new_contact_count, 0, int, "%i");
wait_for_until(manager->lc, NULL, &stats->removed_contact_count, 1, 2000);
BC_ASSERT_EQUAL(stats->removed_contact_count, 1, int, "%i");
wait_for_until(manager->lc, NULL, &stats->updated_contact_count, 1, 2000);
BC_ASSERT_EQUAL(stats->updated_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");
......
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