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