From 1d262248587f003b4615f6b1f14b6d8ee8d332b2 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 13 Jan 2016 17:05:49 +0100 Subject: [PATCH] Started CardDAV integration into liblinphone friends API --- coreapi/Makefile.am | 6 +- coreapi/account_creator.h | 3 +- coreapi/carddav.c | 75 +++++++++----------- coreapi/carddav.h | 8 ++- coreapi/conference.h | 3 +- coreapi/friend.c | 20 +++++- coreapi/friendlist.c | 141 ++++++++++++++++++++++++++++++++++++-- coreapi/friendlist.h | 110 +++++++++++++++++++++++++++++ coreapi/linphonecore.c | 82 +--------------------- coreapi/linphonecore.h | 63 +---------------- coreapi/private.h | 39 +++++------ coreapi/vcard.cc | 34 ++++++++- coreapi/vcard.h | 39 +++++++---- coreapi/vcard_stubs.c | 8 +++ tester/Makefile.am | 3 +- tester/rcfiles/carddav_rc | 11 --- tester/vcard_tester.c | 135 +++++++++++++++++++++++------------- 17 files changed, 486 insertions(+), 294 deletions(-) delete mode 100644 tester/rcfiles/carddav_rc diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 0dc338351..01582a10d 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -43,6 +43,7 @@ linphone_include_HEADERS=\ sipsetup.h \ xml2lpc.h \ xmlrpc.h \ + vcard.h \ carddav.h lib_LTLIBRARIES=liblinphone.la @@ -120,10 +121,10 @@ liblinphone_la_SOURCES+=linphone_tunnel_stubs.c linphone_tunnel.h endif if BUILD_VCARD -liblinphone_la_SOURCES+=vcard.cc vcard.h +liblinphone_la_SOURCES+=vcard.cc liblinphone_la_CXXFLAGS=-std=c++11 else -liblinphone_la_SOURCES+=vcard_stubs.c vcard.h +liblinphone_la_SOURCES+=vcard_stubs.c endif liblinphone_la_LDFLAGS= -version-info $(LIBLINPHONE_SO_VERSION) -no-undefined @@ -157,6 +158,7 @@ liblinphone_la_LIBADD= \ AM_CPPFLAGS=\ + -DIN_LINPHONE \ -I$(top_srcdir) -I$(top_srcdir)/include -I$(builddir) \ $(ORTP_CFLAGS) \ $(MEDIASTREAMER_CFLAGS) \ diff --git a/coreapi/account_creator.h b/coreapi/account_creator.h index 41730dcfa..94c16670a 100644 --- a/coreapi/account_creator.h +++ b/coreapi/account_creator.h @@ -20,13 +20,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef LINPHONE_ACCOUNT_CREATOR_H_ #define LINPHONE_ACCOUNT_CREATOR_H_ +#include "linphonecore.h" #ifdef __cplusplus extern "C" { #endif -#include "linphonecore.h" - /** * @addtogroup misc * @{ diff --git a/coreapi/carddav.c b/coreapi/carddav.c index c7a911c80..449561e14 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -20,29 +20,28 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphonecore.h" #include "private.h" -LinphoneCardDavContext* linphone_core_create_carddav_context(LinphoneCore *lc) { +LinphoneCardDavContext* linphone_carddav_context_new(LinphoneFriendList *lfl) { LinphoneCardDavContext *carddav_context = NULL; - if (!lc) { + if (!lfl || !lfl->uri) { return NULL; } #ifdef VCARD_ENABLED carddav_context = (LinphoneCardDavContext *)ms_new0(LinphoneCardDavContext, 1); - carddav_context->lc = lc; - carddav_context->server_url = linphone_core_get_carddav_server_url(lc); - carddav_context->ctag = linphone_core_get_carddav_last_ctag(lc); - carddav_context->username = linphone_core_get_carddav_username(lc); - carddav_context->password = linphone_core_get_carddav_password(lc); - carddav_context->ha1 = linphone_core_get_carddav_ha1(lc); + carddav_context->friend_list = linphone_friend_list_ref(lfl); #else ms_error("vCard isn't available (maybe it wasn't compiled), can't do CardDAV sync"); #endif return carddav_context; } -void linphone_carddav_destroy(LinphoneCardDavContext *cdc) { +void linphone_carddav_context_destroy(LinphoneCardDavContext *cdc) { if (cdc) { + if (cdc->friend_list) { + linphone_friend_list_unref(cdc->friend_list); + cdc->friend_list = NULL; + } ms_free(cdc); } } @@ -62,7 +61,7 @@ void linphone_carddav_synchronize(LinphoneCardDavContext *cdc) { static void linphone_carddav_sync_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) { if (success) { ms_debug("CardDAV sync successful, saving new cTag: %i", cdc->ctag); - linphone_core_set_carddav_current_ctag(cdc->lc, cdc->ctag); + linphone_friend_list_update_revision(cdc->friend_list, cdc->ctag); } else { ms_error("CardDAV sync failure: %s", msg); } @@ -75,8 +74,12 @@ static void linphone_carddav_sync_done(LinphoneCardDavContext *cdc, bool_t succe static int find_matching_friend(LinphoneFriend *lf1, LinphoneFriend *lf2) { LinphoneVCard *lvc1 = linphone_friend_get_vcard(lf1); LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf2); - const char *uid1 = linphone_vcard_get_uid(lvc1); - const char *uid2 = linphone_vcard_get_uid(lvc2); + const char *uid1 = NULL, *uid2 = NULL; + if (!lvc1 || !lvc2) { + return 1; + } + uid1 = linphone_vcard_get_uid(lvc1); + uid2 = linphone_vcard_get_uid(lvc2); if (!uid1 || !uid2) { return 1; } @@ -85,7 +88,7 @@ static int find_matching_friend(LinphoneFriend *lf1, LinphoneFriend *lf2) { static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList *vCards) { if (vCards != NULL && ms_list_size(vCards) > 0) { - MSList *localFriends = linphone_core_fetch_friends_from_db(cdc->lc); + MSList *friends = cdc->friend_list->friends; while (vCards) { LinphoneCardDavResponse *vCard = (LinphoneCardDavResponse *)vCards->data; if (vCard) { @@ -97,13 +100,13 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * // Compute downloaded vCards' URL and save it (+ eTag) char *vCard_name = strrchr(vCard->url, '/'); char full_url[300]; - snprintf(full_url, sizeof(full_url), "%s%s", cdc->server_url, vCard_name); + snprintf(full_url, sizeof(full_url), "%s%s", cdc->friend_list->uri, vCard_name); linphone_vcard_set_url(lvc, full_url); linphone_vcard_set_etag(lvc, vCard->etag); ms_debug("Downloaded vCard etag/url are %s and %s", vCard->etag, full_url); } lf = linphone_friend_new_from_vcard(lvc); - local_friend = ms_list_find_custom(localFriends, (int (*)(const void*, const void*))find_matching_friend, lf); + local_friend = ms_list_find_custom(friends, (int (*)(const void*, const void*))find_matching_friend, lf); if (local_friend) { LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data; @@ -121,7 +124,6 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * } vCards = ms_list_next(vCards); } - localFriends = ms_list_free_with_data(localFriends, (void (*)(void *))linphone_friend_unref); } ms_list_free(vCards); linphone_carddav_sync_done(cdc, TRUE, ""); @@ -169,8 +171,12 @@ 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 = linphone_vcard_get_uid(lvc1); - const char *uid2 = linphone_vcard_get_uid(lvc2); + const char *uid1 = NULL, *uid2 = NULL; + if (!lvc1 || !lvc2) { + return 1; + } + uid1 = linphone_vcard_get_uid(lvc1); + uid2 = linphone_vcard_get_uid(lvc2); linphone_vcard_free(lvc1); if (!uid1 || !uid2) { return 1; @@ -180,8 +186,7 @@ static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) { if (vCards != NULL && ms_list_size(vCards) > 0) { - MSList *localFriends = linphone_core_fetch_friends_from_db(cdc->lc); - MSList *friends = localFriends; + MSList *friends = cdc->friend_list->friends; while (friends) { LinphoneFriend *lf = (LinphoneFriend *)friends->data; if (lf) { @@ -208,7 +213,6 @@ static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList } friends = ms_list_next(friends); } - localFriends = ms_list_free_with_data(localFriends, (void (*)(void *))linphone_friend_unref); linphone_carddav_pull_vcards(cdc, vCards); } ms_list_free(vCards); @@ -372,22 +376,7 @@ static void process_io_error_from_carddav_request(void *data, const belle_sip_io } static void process_auth_requested_from_carddav_request(void *data, belle_sip_auth_event_t *event) { - LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data; - LinphoneCardDavContext *context = query->context; - - if (context->username && (context->password || context->ha1)) { - belle_sip_auth_event_set_username(event, context->username); - if (context->password) { - belle_sip_auth_event_set_passwd(event, context->password); - } - if (context->ha1) { - belle_sip_auth_event_set_ha1(event, context->ha1); - } - } else { - ms_error("Authentication requested during CardDAV request sending, and username/password weren't provided"); - linphone_carddav_query_free(query); - linphone_carddav_sync_done(query->context, FALSE, "Authentication requested during CardDAV request sending, and username/password weren't provided"); - } + //TODO //FIXME: find a way around this } static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { @@ -434,7 +423,7 @@ static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { cbs.process_io_error = process_io_error_from_carddav_request; cbs.process_auth_requested = process_auth_requested_from_carddav_request; query->http_request_listener = belle_http_request_listener_create_from_callbacks(&cbs, query); - belle_http_provider_send_request(query->context->lc->http_provider, req, query->http_request_listener); + belle_http_provider_send_request(query->context->friend_list->lc->http_provider, req, query->http_request_listener); } static LinphoneCardDavQuery* linphone_carddav_create_put_query(LinphoneCardDavContext *cdc, LinphoneVCard *lvc) { @@ -468,7 +457,7 @@ void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) LinphoneCardDavQuery *query = NULL; if (!linphone_vcard_get_url(lvc)) { - char *url = generate_url_from_server_address_and_uid(cdc->server_url); + char *url = generate_url_from_server_address_and_uid(cdc->friend_list->uri); linphone_vcard_set_url(lvc, url); ms_free(url); } @@ -512,7 +501,7 @@ void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend * LinphoneCardDavQuery *query = NULL; if (!linphone_vcard_get_url(lvc)) { - char *url = generate_url_from_server_address_and_uid(cdc->server_url); + char *url = generate_url_from_server_address_and_uid(cdc->friend_list->uri); linphone_vcard_set_url(lvc, url); ms_free(url); } @@ -562,7 +551,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_propfind_query(LinphoneCard query->ifmatch = NULL; query->body = ""; query->method = "PROPFIND"; - query->url = cdc->server_url; + query->url = cdc->friend_list->uri; query->type = LinphoneCardDavQueryTypePropfind; return query; } @@ -579,7 +568,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_query(LinphoneC query->ifmatch = NULL; query->body = ""; query->method = "REPORT"; - query->url = cdc->server_url; + query->url = cdc->friend_list->uri; query->type = LinphoneCardDavQueryTypeAddressbookQuery; return query; } @@ -598,7 +587,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query( query->depth = "1"; query->ifmatch = NULL; query->method = "REPORT"; - query->url = cdc->server_url; + query->url = cdc->friend_list->uri; query->type = LinphoneCardDavQueryTypeAddressbookMultiget; sprintf(body, "%s", ""); diff --git a/coreapi/carddav.h b/coreapi/carddav.h index dac895066..8ef3d70dd 100644 --- a/coreapi/carddav.h +++ b/coreapi/carddav.h @@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef LINPHONE_CARDDAV_H #define LINPHONE_CARDDAV_H +#include "linphonecore.h" + #ifdef __cplusplus extern "C" { #endif @@ -65,16 +67,16 @@ typedef void (*LinphoneCardDavSynchronizationDoneCb)(LinphoneCardDavContext *cdc /** * Creates a CardDAV context for all related operations - * @param lc LinphoneCore object + * @param lfl LinphoneFriendList object * @return LinphoneCardDavContext object if vCard support is enabled and server URL is available, NULL otherwise */ -LINPHONE_PUBLIC LinphoneCardDavContext* linphone_core_create_carddav_context(LinphoneCore *lc); +LINPHONE_PUBLIC LinphoneCardDavContext* linphone_carddav_context_new(LinphoneFriendList *lfl); /** * Deletes a LinphoneCardDavContext object * @param cdc LinphoneCardDavContext object */ -LINPHONE_PUBLIC void linphone_carddav_destroy(LinphoneCardDavContext *cdc); +LINPHONE_PUBLIC void linphone_carddav_context_destroy(LinphoneCardDavContext *cdc); /** * Sets a user pointer to the LinphoneCardDAVContext object diff --git a/coreapi/conference.h b/coreapi/conference.h index 6192850a3..5c4b4b403 100644 --- a/coreapi/conference.h +++ b/coreapi/conference.h @@ -26,11 +26,12 @@ #ifndef CONFERENCE_H #define CONFERENCE_H +#include "linphonecore.h" + #ifdef __cplusplus extern "C" { #endif -#include "linphonecore.h" //typedef struct _LinphoneConference LinphoneConference; diff --git a/coreapi/friend.c b/coreapi/friend.c index 586077be3..bacab20f0 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -155,8 +155,8 @@ void* linphone_friend_get_user_data(const LinphoneFriend *lf){ return lf->user_data; } -bool_t linphone_friend_in_list(const LinphoneFriend *lf){ - return lf->in_list; +bool_t linphone_friend_in_list(const LinphoneFriend *lf) { + return lf->friend_list != NULL; } void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char **result){ @@ -529,13 +529,27 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc) { } void linphone_friend_edit(LinphoneFriend *fr) { + if (fr && fr->vcard) { + linphone_vcard_compute_md5_hash(fr->vcard); + } } void linphone_friend_done(LinphoneFriend *fr) { + const char *previous_md5 = NULL; + ms_return_if_fail(fr); - if (!fr->lc || !fr->in_list) return; + 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) { + 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); + } + } } LinphoneFriend * linphone_core_create_friend(LinphoneCore *lc) { diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index c8a602146..e78eb9a91 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -22,6 +22,55 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriendListCbs); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneFriendListCbs, belle_sip_object_t, + NULL, // destroy + NULL, // clone + NULL, // Marshall + FALSE +); + +static LinphoneFriendListCbs * linphone_friend_list_cbs_new(void) { + return belle_sip_object_new(LinphoneFriendListCbs); +} + +LinphoneFriendListCbs * linphone_friend_list_get_callbacks(const LinphoneFriendList *list) { + return list->cbs; +} + +LinphoneFriendListCbs * linphone_friend_list_cbs_ref(LinphoneFriendListCbs *cbs) { + belle_sip_object_ref(cbs); + return cbs; +} + +void linphone_friend_list_cbs_unref(LinphoneFriendListCbs *cbs) { + belle_sip_object_unref(cbs); +} + +void *linphone_friend_list_cbs_get_user_data(const LinphoneFriendListCbs *cbs) { + return cbs->user_data; +} + +void linphone_friend_list_cbs_set_user_data(LinphoneFriendListCbs *cbs, void *ud) { + cbs->user_data = ud; +} + +LinphoneFriendListContactCreatedCb linphone_friend_list_cbs_get_contact_created(const LinphoneFriendListCbs *cbs) { + return cbs->contact_created_cb; +} + +void linphone_friend_list_cbs_set_contact_created(LinphoneFriendListCbs *cbs, LinphoneFriendListContactCreatedCb cb) { + cbs->contact_created_cb = cb; +} + +LinphoneFriendListContactDeletedCb linphone_friend_list_cbs_get_contact_deleted(const LinphoneFriendListCbs *cbs) { + return cbs->contact_deleted_cb; +} + +void linphone_friend_list_cbs_set_contact_deleted(LinphoneFriendListCbs *cbs, LinphoneFriendListContactDeletedCb cb) { + cbs->contact_deleted_cb = cb; +} static char * create_resource_list_xml(const LinphoneFriendList *list) { char *xml_content = NULL; @@ -219,6 +268,7 @@ static bool_t linphone_friend_list_has_subscribe_inactive(const LinphoneFriendLi static LinphoneFriendList * linphone_friend_list_new(void) { LinphoneFriendList *list = belle_sip_object_new(LinphoneFriendList); + list->cbs = linphone_friend_list_cbs_new(); belle_sip_object_ref(list); return list; } @@ -228,7 +278,10 @@ static void linphone_friend_list_destroy(LinphoneFriendList *list) { if (list->rls_uri != NULL) ms_free(list->rls_uri); if (list->content_digest != NULL) ms_free(list->content_digest); if (list->event != NULL) linphone_event_unref(list->event); + if (list->uri != NULL) ms_free(list->uri); + if (list->cbs) linphone_friend_list_cbs_unref(list->cbs); list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))linphone_friend_unref); + list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))_linphone_friend_release); } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriendList); @@ -259,7 +312,12 @@ void _linphone_friend_list_release(LinphoneFriendList *list){ linphone_event_unref(list->event); list->event = NULL; } + if (list->cbs) { + linphone_friend_list_cbs_unref(list->cbs); + list->cbs = NULL; + } list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release); + list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))_linphone_friend_release); belle_sip_object_unref(list); } @@ -304,10 +362,10 @@ void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, const char *rls_ } LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf) { - if (lf->uri == NULL || lf->in_list) { + if (lf->uri == NULL || lf->friend_list) { if (!lf->uri) ms_error("linphone_friend_list_add_friend(): invalid friend, no sip uri"); - if (lf->in_list) + if (lf->friend_list) ms_error("linphone_friend_list_add_friend(): invalid friend, already in list"); return LinphoneFriendListInvalidFriend; } @@ -326,24 +384,81 @@ LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *lis LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf) { if ((lf->lc != NULL) || (lf->uri == NULL)) return LinphoneFriendListInvalidFriend; list->friends = ms_list_append(list->friends, linphone_friend_ref(lf)); - lf->in_list = TRUE; + list->dirty_friends_to_update = ms_list_append(list->dirty_friends_to_update, linphone_friend_ref(lf)); + lf->friend_list = list; return LinphoneFriendListOK; } +static void carddav_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) { + linphone_carddav_context_destroy(cdc); +} + 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); if (elem == NULL) return LinphoneFriendListNonExistentFriend; #ifdef FRIENDS_SQL_STORAGE_ENABLED linphone_core_remove_friend_from_db(lf->lc, lf); #endif + if (cdc) { + cdc->sync_done_cb = carddav_done; + linphone_carddav_delete_vcard(cdc, lf); + } - lf->in_list = FALSE; + lf->friend_list = NULL; linphone_friend_unref(lf); list->friends = ms_list_remove_link(list->friends, elem); return LinphoneFriendListOK; } +void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list) { + LinphoneCardDavContext *cdc = linphone_carddav_context_new(list); + MSList *dirty_friends = list->dirty_friends_to_update; + + if (cdc) { + cdc->sync_done_cb = carddav_done; + while (dirty_friends) { + LinphoneFriend *lf = (LinphoneFriend *)dirty_friends->data; + if (lf) { + linphone_carddav_put_vcard(cdc, lf); + } + dirty_friends = ms_list_next(dirty_friends); + } + } + list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref); +} + +static void carddav_created(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { + if (cdc && cdc->friend_list->cbs->contact_created_cb) { + LinphoneFriendList *lfl = cdc->friend_list; + lfl->friends = ms_list_append(lfl->friends, linphone_friend_ref(lf)); + cdc->friend_list->cbs->contact_created_cb(lfl, linphone_friend_ref(lf)); + } + linphone_friend_unref(lf); +} + +static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { + if (cdc && cdc->friend_list->cbs->contact_deleted_cb) { + LinphoneFriendList *lfl = cdc->friend_list; + MSList *elem = ms_list_find(lfl->friends, lf); + lfl->friends = ms_list_remove_link(lfl->friends, elem); + cdc->friend_list->cbs->contact_deleted_cb(lfl, linphone_friend_ref(lf)); + } + linphone_friend_unref(lf); +} + +void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *list) { + LinphoneCardDavContext *cdc = linphone_carddav_context_new(list); + + if (cdc) { + cdc->contact_created_cb = carddav_created; + cdc->contact_removed_cb = carddav_removed; + cdc->sync_done_cb = carddav_done; + linphone_carddav_synchronize(cdc); + } +} + LinphoneFriend * linphone_friend_list_find_friend_by_address(const LinphoneFriendList *list, const LinphoneAddress *address) { LinphoneFriend *lf = NULL; const MSList *elem; @@ -487,3 +602,21 @@ void linphone_friend_list_notify_presence_received(LinphoneFriendList *list, Lin linphone_content_unref(first_part); } } + +const char * linphone_friend_list_get_uri(const LinphoneFriendList *list) { + return list->uri; +} + +void linphone_friend_list_set_uri(LinphoneFriendList *list, const char *uri) { + if (list->uri != NULL) { + ms_free(list->uri); + list->uri = NULL; + } + if (uri != NULL) { + list->uri = ms_strdup(uri); + } +} + +void linphone_friend_list_update_revision(LinphoneFriendList *list, int rev) { + list->revision = rev; +} \ No newline at end of file diff --git a/coreapi/friendlist.h b/coreapi/friendlist.h index e69cae707..9efe9824b 100644 --- a/coreapi/friendlist.h +++ b/coreapi/friendlist.h @@ -174,6 +174,116 @@ LINPHONE_PUBLIC void linphone_friend_list_update_subscriptions(LinphoneFriendLis **/ LINPHONE_PUBLIC void linphone_friend_list_notify_presence(LinphoneFriendList *list, LinphonePresenceModel *presence); +/** + * Get the URI associated with the friend list. + * @param[in] list LinphoneFriendList object. + * @return The URI associated with the friend list. +**/ +LINPHONE_PUBLIC const char * linphone_friend_list_get_uri(const LinphoneFriendList *list); + +/** + * Set the URI associated with the friend list. + * @param[in] list LinphoneFriendList object. + * @param[in] rls_uri The URI to associate with the friend list. +**/ +LINPHONE_PUBLIC void linphone_friend_list_set_uri(LinphoneFriendList *list, const char *uri); + +/** + * Sets the revision from the last synchronization. + * @param[in] list LinphoneFriendList object. + * @param[in] rev The revision + */ +void linphone_friend_list_update_revision(LinphoneFriendList *list, int rev); + +/** + * An object to handle the callbacks for LinphoneFriend synchronization. +**/ +typedef struct _LinphoneFriendListCbs LinphoneFriendListCbs; + +/** + * Callback used to notify a new contact has been created on the CardDAV server and downloaded locally +**/ +typedef void (*LinphoneFriendListContactCreatedCb)(LinphoneFriendList *list, LinphoneFriend *lf); + +/** + * Callback used to notify a contact has been deleted on the CardDAV server +**/ +typedef void (*LinphoneFriendListContactDeletedCb)(LinphoneFriendList *list, LinphoneFriend *lf); + +/** + * Get the LinphoneFriendListCbs object associated with a LinphoneFriendList. + * @param[in] request LinphoneXmlRpcRequest object + * @return The LinphoneFriendListCbs object associated with the LinphoneFriendList. +**/ +LINPHONE_PUBLIC LinphoneFriendListCbs * linphone_friend_list_get_callbacks(const LinphoneFriendList *list); + +/** + * Acquire a reference to a LinphoneFriendListCbs object. + * @param[in] cbs LinphoneFriendListCbs object. + * @return The same LinphoneFriendListCbs object. +**/ +LINPHONE_PUBLIC LinphoneFriendListCbs * linphone_friend_list_cbs_ref(LinphoneFriendListCbs *cbs); + +/** + * Release a reference to a LinphoneFriendListCbs object. + * @param[in] cbs LinphoneFriendListCbs object. +**/ +LINPHONE_PUBLIC void linphone_friend_list_cbs_unref(LinphoneFriendListCbs *cbs); + +/** + * Retrieve the user pointer associated with a LinphoneFriendListCbs object. + * @param[in] cbs LinphoneFriendListCbs object. + * @return The user pointer associated with the LinphoneFriendListCbs object. +**/ +LINPHONE_PUBLIC void *linphone_friend_list_cbs_get_user_data(const LinphoneFriendListCbs *cbs); + +/** + * Assign a user pointer to a LinphoneFriendListCbs object. + * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] ud The user pointer to associate with the LinphoneFriendListCbs object. +**/ +LINPHONE_PUBLIC void linphone_friend_list_cbs_set_user_data(LinphoneFriendListCbs *cbs, void *ud); + +/** + * Get the contact created callback. + * @param[in] cbs LinphoneFriendListCbs object. + * @return The current contact created callback. +**/ +LINPHONE_PUBLIC LinphoneFriendListContactCreatedCb linphone_friend_list_cbs_get_contact_created(const LinphoneFriendListCbs *cbs); + +/** + * Set the contact created callback. + * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cb The contact created to be used. +**/ +LINPHONE_PUBLIC void linphone_friend_list_cbs_set_contact_created(LinphoneFriendListCbs *cbs, LinphoneFriendListContactCreatedCb cb); + +/** + * Get the contact deleted callback. + * @param[in] cbs LinphoneFriendListCbs object. + * @return The current contact deleted callback. +**/ +LINPHONE_PUBLIC LinphoneFriendListContactDeletedCb linphone_friend_list_cbs_get_contact_deleted(const LinphoneFriendListCbs *cbs); + +/** + * Set the contact deleted callback. + * @param[in] cbs LinphoneFriendListCbs object. + * @param[in] cb The contact deleted to be used. +**/ +LINPHONE_PUBLIC void linphone_friend_list_cbs_set_contact_deleted(LinphoneFriendListCbs *cbs, LinphoneFriendListContactDeletedCb cb); + +/** + * + * @param[in] list LinphoneFriendList object. + */ +LINPHONE_PUBLIC void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *list); + +/** + * + * @param[in] list LinphoneFriendList object. + */ +void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list); + /** * @} */ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 0c89d5aa5..bba34d427 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2736,6 +2736,9 @@ void linphone_core_iterate(LinphoneCore *lc){ if (lp_config_needs_commit(lc->config)) { lp_config_sync(lc->config); } + if (lc->friendlist->dirty_friends_to_update) { + linphone_friend_list_update_dirty_friends(lc->friendlist); + } } if (liblinphone_serialize_logs == TRUE) { @@ -7431,85 +7434,6 @@ const char *linphone_stream_type_to_string(const LinphoneStreamType type) { return "INVALID"; } -/***************************************************************************** - * CardDAV interface * - ****************************************************************************/ - -void linphone_core_set_carddav_server_url(LinphoneCore *lc, const char *carddav_server_url) { - if (lc && carddav_server_url) { - LpConfig *lpc = linphone_core_get_config(lc); - lp_config_set_string(lpc, "carddav", "server_url", carddav_server_url); - } -} - -const char *linphone_core_get_carddav_server_url(LinphoneCore *lc) { - if (lc) { - LpConfig *lpc = linphone_core_get_config(lc); - return lp_config_get_string(lpc, "carddav", "server_url", NULL); - } - return NULL; -} - -void linphone_core_set_carddav_username(LinphoneCore *lc, const char *username) { - if (lc && username) { - LpConfig *lpc = linphone_core_get_config(lc); - lp_config_set_string(lpc, "carddav", "username", username); - } -} - -const char *linphone_core_get_carddav_username(LinphoneCore *lc) { - if (lc) { - LpConfig *lpc = linphone_core_get_config(lc); - return lp_config_get_string(lpc, "carddav", "username", NULL); - } - return NULL; -} - -void linphone_core_set_carddav_password(LinphoneCore *lc, const char *password) { - if (lc && password) { - LpConfig *lpc = linphone_core_get_config(lc); - lp_config_set_string(lpc, "carddav", "password", password); - } -} - -const char *linphone_core_get_carddav_password(LinphoneCore *lc) { - if (lc) { - LpConfig *lpc = linphone_core_get_config(lc); - return lp_config_get_string(lpc, "carddav", "password", NULL); - } - return NULL; -} - -void linphone_core_set_carddav_ha1(LinphoneCore *lc, const char *ha1) { - if (lc && ha1) { - LpConfig *lpc = linphone_core_get_config(lc); - lp_config_set_string(lpc, "carddav", "ha1", ha1); - } -} - -const char *linphone_core_get_carddav_ha1(LinphoneCore *lc) { - if (lc) { - LpConfig *lpc = linphone_core_get_config(lc); - return lp_config_get_string(lpc, "carddav", "ha1", NULL); - } - return NULL; -} - -void linphone_core_set_carddav_current_ctag(LinphoneCore *lc, int ctag) { - if (lc) { - LpConfig *lpc = linphone_core_get_config(lc); - lp_config_set_int(lpc, "carddav", "ctag", ctag); - } -} - -int linphone_core_get_carddav_last_ctag(LinphoneCore *lc) { - if (lc) { - LpConfig *lpc = linphone_core_get_config(lc); - return lp_config_get_int(lpc, "carddav", "ctag", 0); - } - return 0; -} - LinphoneRingtonePlayer *linphone_core_get_ringtoneplayer(LinphoneCore *lc) { return lc->ringtoneplayer; } diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 1369365ac..c728a521a 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -417,7 +417,6 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy); #include "event.h" #include "linphonefriend.h" #include "xmlrpc.h" -#include "carddav.h" #else #include "linphone/buffer.h" #include "linphone/call_log.h" @@ -426,7 +425,6 @@ LINPHONE_PUBLIC const char* linphone_privacy_to_string(LinphonePrivacy privacy); #include "linphone/event.h" #include "linphone/linphonefriend.h" #include "linphone/xmlrpc.h" -#include "linphone/carddav.h" #endif LINPHONE_PUBLIC LinphoneAddress * linphone_address_new(const char *addr); @@ -1211,9 +1209,11 @@ LINPHONE_PUBLIC LinphoneAuthInfo * linphone_auth_info_new_from_config_file(LpCon #ifdef IN_LINPHONE #include "account_creator.h" #include "friendlist.h" +#include "carddav.h" #else #include "linphone/account_creator.h" #include "linphone/friendlist.h" +#include "linphone/carddav.h" #endif @@ -4360,65 +4360,6 @@ LINPHONE_PUBLIC LinphoneTransportType linphone_transport_parse(const char* trans */ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *lc); -/***************************************************************************** - * CardDAV interface * - ****************************************************************************/ - -/** - * Sets the CardDAV server URL - * @param lc LinphoneCore object - * @param carddav_server_url the URL to the CardDAV server - */ -LINPHONE_PUBLIC void linphone_core_set_carddav_server_url(LinphoneCore *lc, const char *carddav_server_url); - -/** - * Gets the CardDAV server URL if set - * @param lc LinphoneCore object - * @return the URL to the CardDAV server if set, otherwise NULL - */ -LINPHONE_PUBLIC const char *linphone_core_get_carddav_server_url(LinphoneCore *lc); -/** - * Sets the CardDAV server username - * @param lc LinphoneCore object - * @param username the username for the CardDAV server - */ -LINPHONE_PUBLIC void linphone_core_set_carddav_username(LinphoneCore *lc, const char *username); - -/** - * Gets the CardDAV server username - * @param lc LinphoneCore object - * @return the username for the CardDAV server if set, otherwise NULL - */ -LINPHONE_PUBLIC const char *linphone_core_get_carddav_username(LinphoneCore *lc); - -/** - * Sets the CardDAV server password - * @param lc LinphoneCore object - * @param password the password for the CardDAV server - */ -LINPHONE_PUBLIC void linphone_core_set_carddav_password(LinphoneCore *lc, const char *password); - -/** - * Gets the CardDAV server password - * @param lc LinphoneCore object - * @return the password for the CardDAV server if set, otherwise NULL - */ -LINPHONE_PUBLIC const char *linphone_core_get_carddav_password(LinphoneCore *lc); - -/** - * Sets the CardDAV server hashed password - * @param lc LinphoneCore object - * @param ha1 the hashed password for the CardDAV server - */ -LINPHONE_PUBLIC void linphone_core_set_carddav_ha1(LinphoneCore *lc, const char *ha1); - -/** - * Gets the CardDAV server hashed password - * @param lc LinphoneCore object - * @return the hashed password for the CardDAV server if set, otherwise NULL - */ -LINPHONE_PUBLIC const char *linphone_core_get_carddav_ha1(LinphoneCore *lc); - typedef struct _LinphoneRingtonePlayer LinphoneRingtonePlayer; LINPHONE_PUBLIC LinphoneRingtonePlayer *linphone_core_get_ringtoneplayer(LinphoneCore *lc); diff --git a/coreapi/private.h b/coreapi/private.h index d0c00596b..e778bc8f9 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -675,7 +675,6 @@ struct _LinphoneFriend{ struct _LinphoneCore *lc; BuddyInfo *info; char *refkey; - bool_t in_list; bool_t subscribe; bool_t subscribe_active; bool_t inc_subscribe_pending; @@ -684,10 +683,19 @@ struct _LinphoneFriend{ bool_t presence_received; LinphoneVCard *vcard; unsigned int storage_id; + LinphoneFriendList *friend_list; }; BELLE_SIP_DECLARE_VPTR(LinphoneFriend); +struct _LinphoneFriendListCbs { + belle_sip_object_t base; + void *user_data; + LinphoneFriendListContactCreatedCb contact_created_cb; + LinphoneFriendListContactDeletedCb contact_deleted_cb; +}; + +BELLE_SIP_DECLARE_VPTR(LinphoneFriendListCbs); struct _LinphoneFriendList { belle_sip_object_t base; @@ -699,11 +707,17 @@ struct _LinphoneFriendList { MSList *friends; unsigned char *content_digest; int expected_notification_version; + unsigned int storage_id; + char *uri; + MSList *dirty_friends_to_update; + int revision; + LinphoneFriendListCbs *cbs; }; BELLE_SIP_DECLARE_VPTR(LinphoneFriendList); + typedef struct sip_config { char *contact; @@ -1227,12 +1241,8 @@ BELLE_SIP_DECLARE_VPTR(LinphoneAccountCreator); ****************************************************************************/ struct _LinphoneCardDavContext { - LinphoneCore *lc; + LinphoneFriendList *friend_list; int ctag; - const char *server_url; - const char *username; - const char *password; - const char *ha1; void *user_data; LinphoneCardDavContactCreatedCb contact_created_cb; LinphoneCardDavContactUpdatedCb contact_updated_cb; @@ -1259,20 +1269,6 @@ struct _LinphoneCardDavResponse { const char *vcard; }; -/** - * Sets the CardDAV server current cTag - * @param lc LinphoneCore object - * @param ctag the current cTag for the CardDAV server - */ -void linphone_core_set_carddav_current_ctag(LinphoneCore *lc, int ctag); - -/** - * Gets the CardDAV server last cTag - * @param lc LinphoneCore object - * @return the last cTag for the CardDAV server if set, otherwise -1 - */ -int linphone_core_get_carddav_last_ctag(LinphoneCore *lc); - /***************************************************************************** * REMOTE PROVISIONING FUNCTIONS * ****************************************************************************/ @@ -1381,7 +1377,8 @@ BELLE_SIP_TYPE_ID(LinphoneFriendList), BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequest), BELLE_SIP_TYPE_ID(LinphoneXmlRpcRequestCbs), BELLE_SIP_TYPE_ID(LinphoneXmlRpcSession), -BELLE_SIP_TYPE_ID(LinphoneTunnelConfig) +BELLE_SIP_TYPE_ID(LinphoneTunnelConfig), +BELLE_SIP_TYPE_ID(LinphoneFriendListCbs) BELLE_SIP_DECLARE_TYPES_END diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index c9b9153bf..77d136642 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -24,8 +24,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. struct _LinphoneVCard { shared_ptr belCard; - const char *etag; - const char *url; + char *etag; + char *url; + char *md5; }; #ifdef __cplusplus @@ -194,6 +195,12 @@ const char* linphone_vcard_get_uid(const LinphoneVCard *vCard) { } void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag) { + if (!vCard) { + return; + } + if (vCard->etag) { + ms_free(vCard->etag); + } vCard->etag = ms_strdup(etag); } @@ -203,6 +210,12 @@ const char* linphone_vcard_get_etag(const LinphoneVCard *vCard) { } void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url) { + if (!vCard) { + return; + } + if (vCard->url) { + ms_free(vCard->url); + } vCard->url = ms_strdup(url); } @@ -211,6 +224,23 @@ const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { return vCard->url; } +void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard) { + if (!vCard) { + return; + } + if (vCard->md5) { + ms_free(vCard->md5); + } + //TODO: compute md5 hash +} + +const char *linphone_vcard_get_md5_hash(LinphoneVCard *vCard) { + if (!vCard) { + return NULL; + } + return vCard->md5; +} + #ifdef __cplusplus } #endif \ No newline at end of file diff --git a/coreapi/vcard.h b/coreapi/vcard.h index f9a0782d3..70f61b41c 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -41,83 +41,83 @@ typedef struct _LinphoneVCard LinphoneVCard; /** * Creates a LinphoneVCard object that has a pointer to an empty vCard */ -LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new(void); +LinphoneVCard* linphone_vcard_new(void); /** * Deletes a LinphoneVCard object properly * @param[in] vCard the LinphoneVCard to destroy */ -LINPHONE_PUBLIC void linphone_vcard_free(LinphoneVCard *vCard); +void linphone_vcard_free(LinphoneVCard *vCard); /** * Uses belcard to parse the content of a file and returns all the vcards it contains as LinphoneVCards, or NULL if it contains none. * @param[in] file the path to the file to parse * @return \mslist{LinphoneVCard} */ -LINPHONE_PUBLIC MSList* linphone_vcard_list_from_vcard4_file(const char *file); +MSList* linphone_vcard_list_from_vcard4_file(const char *file); /** * Uses belcard to parse the content of a buffer and returns all the vcards it contains as LinphoneVCards, or NULL if it contains none. * @param[in] buffer the buffer to parse * @return \mslist{LinphoneVCard} */ -LINPHONE_PUBLIC MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer); +MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer); /** * Uses belcard to parse the content of a buffer and returns one vCard if possible, or NULL otherwise. * @param[in] buffer the buffer to parse * @return a LinphoneVCard if one could be parsed, or NULL otherwise */ -LINPHONE_PUBLIC LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer); +LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer); /** * Returns the vCard4 representation of the LinphoneVCard. * @param[in] vCard the LinphoneVCard * @return a const char * that represents the vCard */ -LINPHONE_PUBLIC const char* linphone_vcard_as_vcard4_string(LinphoneVCard *vCard); +const char* linphone_vcard_as_vcard4_string(LinphoneVCard *vCard); /** * Sets the FN attribute of the vCard (which is mandatory). * @param[in] vCard the LinphoneVCard * @param[in] name the display name to set for the vCard */ -LINPHONE_PUBLIC void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name); +void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name); /** * Returns the FN attribute of the vCard, or NULL if it isn't set yet. * @param[in] vCard the LinphoneVCard * @return the display name of the vCard, or NULL */ -LINPHONE_PUBLIC const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard); +const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard); /** * Adds a SIP address in the vCard, using the IMPP property * @param[in] vCard the LinphoneVCard * @param[in] sip_address the SIP address to add */ -LINPHONE_PUBLIC void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address); +void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address); /** * Removes a SIP address in the vCard (if it exists), using the IMPP property * @param[in] vCard the LinphoneVCard * @param[in] sip_address the SIP address to remove */ -LINPHONE_PUBLIC void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const char *sip_address); +void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const char *sip_address); /** * Edits the preferred SIP address in the vCard (or the first one), using the IMPP property * @param[in] vCard the LinphoneVCard * @param[in] sip_address the new SIP address */ -LINPHONE_PUBLIC void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_address); +void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const char *sip_address); /** * Returns the list of SIP addresses (as const char *) 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 *} */ -LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard); +MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard); /** * Generates a random unique id for the vCard. @@ -125,7 +125,7 @@ LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vC * @param[in] vCard the LinphoneVCard * @return TRUE if operation is successful, otherwise FALSE (for example if it already has an unique ID) */ -LINPHONE_PUBLIC bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard); +bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard); /** * Sets the unique ID of the vCard @@ -169,6 +169,19 @@ void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url); */ const char* linphone_vcard_get_url(const LinphoneVCard *vCard); +/** + * Computes the md5 hash for the vCard + * @param[in] vCard the LinphoneVCard + */ +void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard); + +/** + * Computes the md5 hash for the vCard + * @param[in] vCard the LinphoneVCard + * @return the last md5 hash computed for the vCard, or NULL if it wasn't computed yet + */ +const char *linphone_vcard_get_md5_hash(LinphoneVCard *vCard); + /** * @} */ diff --git a/coreapi/vcard_stubs.c b/coreapi/vcard_stubs.c index 4309e7b7b..4f12c0415 100644 --- a/coreapi/vcard_stubs.c +++ b/coreapi/vcard_stubs.c @@ -97,4 +97,12 @@ void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url) { const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { return NULL; +} + +void linphone_vcard_compute_md5_hash(LinphoneVCard *vCard) { + +} + +const char *linphone_vcard_get_md5_hash(LinphoneVCard *vCard) { + return NULL; } \ No newline at end of file diff --git a/tester/Makefile.am b/tester/Makefile.am index ec46807a9..d2da519a5 100644 --- a/tester/Makefile.am +++ b/tester/Makefile.am @@ -69,8 +69,7 @@ RCFILES = \ rcfiles/stun_rc\ rcfiles/upnp_rc\ rcfiles/zero_length_params_rc\ - rcfiles/friends_rc\ - rcfiles/carddav_rc + rcfiles/friends_rc IMAGE_FILES = images/nowebcamCIF.jpg diff --git a/tester/rcfiles/carddav_rc b/tester/rcfiles/carddav_rc deleted file mode 100644 index c4d35f470..000000000 --- a/tester/rcfiles/carddav_rc +++ /dev/null @@ -1,11 +0,0 @@ -[net] -mtu=1300 - -[sip] -ping_with_options=0 -sip_random_port=1 - -[carddav] -server_url=http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default -username=sylvain -ha1=4747ce2517a985f2fc20234a38f068b6 \ No newline at end of file diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index 48e6abc21..e838ef035 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -206,7 +206,6 @@ 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++; } @@ -214,7 +213,6 @@ static void carddav_new_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { static void carddav_removed_contact(LinphoneCardDavContext *c, LinphoneFriend *lf) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(lf); - linphone_core_remove_friend(c->lc, lf); linphone_friend_unref(lf); stats->removed_contact_count++; } @@ -223,24 +221,21 @@ static void carddav_updated_contact(LinphoneCardDavContext *c, LinphoneFriend *n LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_PTR_NOT_NULL_FATAL(new_lf); BC_ASSERT_PTR_NOT_NULL_FATAL(old_lf); - linphone_core_remove_friend(c->lc, old_lf); - linphone_core_add_friend(c->lc, new_lf); linphone_friend_unref(new_lf); linphone_friend_unref(old_lf); stats->updated_contact_count++; } static void carddav_sync(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); + LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); - const MSList *friends = NULL; - LinphoneFriend *lf = NULL; + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneCardDavContext *c = NULL; + linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_core_set_friend_list(manager->lc, lfl); + c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); - BC_ASSERT_PTR_NOT_NULL(c->server_url); - BC_ASSERT_PTR_NOT_NULL(c->username); - BC_ASSERT_PTR_NOT_NULL(c->ha1); linphone_carddav_set_user_data(c, stats); linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); @@ -254,40 +249,30 @@ 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(friends); - if (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_friend_list_unref(lfl); + linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } static void carddav_sync_2(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); + LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); LinphoneFriend *lf = linphone_friend_new_with_address("\"Sylvain\" "); char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneCardDavContext *c = NULL; + + linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_core_set_friend_list(manager->lc, 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_core_add_friend(manager->lc, lf); linphone_friend_unref(lf); - BC_ASSERT_PTR_NOT_NULL_FATAL(c); - BC_ASSERT_PTR_NOT_NULL(c->server_url); - BC_ASSERT_PTR_NOT_NULL(c->username); - BC_ASSERT_PTR_NOT_NULL(c->ha1); - linphone_carddav_set_user_data(c, stats); linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); linphone_carddav_set_new_contact_callback(c, carddav_new_contact); @@ -306,28 +291,30 @@ static void carddav_sync_2(void) { ms_free(stats); unlink(friends_db); ms_free(friends_db); - linphone_carddav_destroy(c); + linphone_friend_list_unref(lfl); + linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } static void carddav_sync_3(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); + LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); LinphoneVCard *lvc = linphone_vcard_new_from_vcard4_buffer("BEGIN:VCARD\r\nVERSION:4.0\r\nUID:1f08dd48-29ac-4097-8e48-8596d7776283\r\nFN:Sylvain Berfini\r\nIMPP;TYPE=work:sip:sylvain@sip.linphone.org\r\nEND:VCARD\r\n"); LinphoneFriend *lf = linphone_friend_new_from_vcard(lvc); char *friends_db = create_filepath(bc_tester_get_writable_dir_prefix(), "friends", "db"); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneCardDavContext *c = NULL; + + linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_core_set_friend_list(manager->lc, 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_core_add_friend(manager->lc, lf); linphone_friend_unref(lf); - BC_ASSERT_PTR_NOT_NULL_FATAL(c); - BC_ASSERT_PTR_NOT_NULL(c->server_url); - BC_ASSERT_PTR_NOT_NULL(c->username); - BC_ASSERT_PTR_NOT_NULL(c->ha1); - linphone_carddav_set_user_data(c, stats); linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); linphone_carddav_set_new_contact_callback(c, carddav_new_contact); @@ -344,24 +331,29 @@ static void carddav_sync_3(void) { ms_free(stats); unlink(friends_db); ms_free(friends_db); - linphone_carddav_destroy(c); + linphone_friend_list_unref(lfl); + linphone_carddav_context_destroy(c); linphone_core_manager_destroy(manager); } static void carddav_sync_4(void) { - LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE); - LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc); + LinphoneCoreManager *manager = linphone_core_manager_new2("empty_rc", FALSE); LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); 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); + LinphoneFriendList *lfl = linphone_core_create_friend_list(manager->lc); + LinphoneCardDavContext *c = NULL; + linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + linphone_core_set_friend_list(manager->lc, lfl); + c = linphone_carddav_context_new(lfl); BC_ASSERT_PTR_NOT_NULL_FATAL(c); - BC_ASSERT_PTR_NOT_NULL(c->server_url); - BC_ASSERT_PTR_NOT_NULL(c->username); - BC_ASSERT_PTR_NOT_NULL(c->ha1); linphone_carddav_set_user_data(c, stats); linphone_carddav_set_synchronization_done_callback(c, carddav_sync_done); + linphone_carddav_set_new_contact_callback(c, carddav_new_contact); + linphone_carddav_set_removed_contact_callback(c, carddav_removed_contact); + linphone_carddav_set_updated_contact_callback(c, carddav_updated_contact); BC_ASSERT_PTR_NULL(linphone_vcard_get_uid(lvc)); BC_ASSERT_TRUE(linphone_vcard_generate_unique_id(lvc)); @@ -377,13 +369,61 @@ static void carddav_sync_4(void) { linphone_friend_unref(lf); ms_free(stats); - linphone_carddav_destroy(c); + linphone_friend_list_unref(lfl); + linphone_carddav_context_destroy(c); + linphone_core_manager_destroy(manager); +} + +static void carddav_contact_created(LinphoneFriendList *list, LinphoneFriend *lf) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); + stats->new_contact_count++; + linphone_friend_unref(lf); +} + +static void carddav_contact_deleted(LinphoneFriendList *list, LinphoneFriend *lf) { + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_friend_list_cbs_get_user_data(list->cbs); + stats->removed_contact_count++; + linphone_friend_unref(lf); +} + +static void carddav_integration(void) { + LinphoneCoreManager *manager = linphone_core_manager_new2("empty_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); + LinphoneFriendListCbs *cbs = NULL; + LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)ms_new0(LinphoneCardDAVStats, 1); + + linphone_friend_list_set_uri(lfl, "http://192.168.0.230/sabredav/addressbookserver.php/addressbooks/sylvain/default"); + cbs = linphone_friend_list_get_callbacks(lfl); + 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_core_set_friend_list(manager->lc, lfl); + + 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); + 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); + + 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"); + BC_ASSERT_NOT_EQUAL(lfl->revision, 0, int, "%i"); + + ms_free(stats); + linphone_friend_unref(lf); + linphone_friend_list_unref(lfl); linphone_core_manager_destroy(manager); } #else static void dummy_test(void) { - } #endif @@ -400,6 +440,7 @@ test_t vcard_tests[] = { { "CardDAV synchronization 2", carddav_sync_2 }, { "CardDAV synchronization 3", carddav_sync_3 }, { "CardDAV synchronization 4", carddav_sync_4 }, + { "CardDAV integration", carddav_integration }, #else { "Dummy test", dummy_test } #endif