diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am
index 728a9fe14..e6fe1eeef 100644
--- a/coreapi/Makefile.am
+++ b/coreapi/Makefile.am
@@ -91,10 +91,9 @@ liblinphone_la_SOURCES=\
xml.c \
xmlrpc.c \
vtables.c \
- carddav.cc \
+ carddav.c \
$(GITVERSION_FILE)
-liblinphone_la_CXXFLAGS=-std=c++11
if BUILD_UPNP
liblinphone_la_SOURCES+=upnp.c upnp.h
endif
@@ -121,6 +120,7 @@ endif
if BUILD_VCARD
liblinphone_la_SOURCES+=vcard.cc vcard.h
+liblinphone_la_CXXFLAGS=-std=c++11
else
liblinphone_la_SOURCES+=vcard_stubs.c vcard.h
endif
diff --git a/coreapi/carddav.c b/coreapi/carddav.c
new file mode 100644
index 000000000..55c8860f6
--- /dev/null
+++ b/coreapi/carddav.c
@@ -0,0 +1,234 @@
+/*
+carddav.c
+Copyright (C) 2015 Belledonne Communications SARL
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+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 *carddav_context = NULL;
+
+ if (!lc) {
+ 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);
+#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) {
+ if (cdc) {
+ ms_free(cdc);
+ }
+}
+
+void linphone_carddav_set_user_data(LinphoneCardDavContext *cdc, void *ud) {
+ cdc->user_data = ud;
+}
+
+void* linphone_carddav_get_user_data(LinphoneCardDavContext *cdc) {
+ return cdc->user_data;
+}
+
+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);
+ //TODO: find out if there are new/delete URLs and compare eTags with the current vCards
+ }
+ if (cdc->sync_done_cb) {
+ cdc->sync_done_cb(cdc, TRUE, "TODO: remove lated");
+ }
+}
+
+static void linphone_carddav_ctag_fetched(LinphoneCardDavContext *cdc, int ctag) {
+ if (ctag == -1 || ctag > cdc->ctag) {
+ cdc->ctag = ctag;
+ linphone_carddav_fetch_vcards(cdc);
+ } else {
+ ms_message("No changes found on server, skipping sync");
+ if (cdc->sync_done_cb) {
+ cdc->sync_done_cb(cdc, TRUE, "Synchronization skipped because cTag already up to date");
+ }
+ }
+}
+
+void linphone_carddav_synchronize(LinphoneCardDavContext *cdc) {
+ linphone_carddav_get_current_ctag(cdc);
+}
+
+static void process_response_from_carddav_request(void *data, const belle_http_response_event_t *event) {
+ LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data;
+
+ if (event->response) {
+ int code = belle_http_response_get_status_code(event->response);
+ if (code == 207 || code == 200) {
+ const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response);
+ ms_message("CardDAV query response body: %s", body);
+ query->status = LinphoneCardDavQueryStatusOk;
+ switch(query->type) {
+ case LinphoneCardDavQueryTypePropfind:
+ linphone_carddav_ctag_fetched(query->context, 0);//TODO parse value from body
+ break;
+ case LinphoneCardDavQueryTypeAddressbookQuery:
+ linphone_carddav_vcards_fetched(query->context, NULL);//TODO parse value from body
+ break;
+ case LinphoneCardDavQueryTypeAddressbookMultiget:
+ break;
+ }
+ } else {
+ query->status = LinphoneCardDavQueryStatusFailed;
+ }
+ }
+ ms_free(query);
+}
+
+static void process_io_error_from_carddav_request(void *data, const belle_sip_io_error_event_t *event) {
+ LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data;
+ ms_error("I/O Error during CardDAV request sending");
+ query->status = LinphoneCardDavQueryStatusFailed;
+ ms_free(query);
+ if (query->context->sync_done_cb) {
+ query->context->sync_done_cb(query->context, FALSE, "I/O Error during CardDAV request sending");
+ }
+}
+
+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 {
+ query->status = LinphoneCardDavQueryStatusFailed;
+ ms_error("Authentication error during CardDAV request sending");
+ if (query->context->sync_done_cb) {
+ query->context->sync_done_cb(query->context, FALSE, "Authentication error during CardDAV request sending");
+ }
+ }
+}
+
+static void linphone_carddav_send_query(LinphoneCardDavQuery *query) {
+ belle_http_request_listener_callbacks_t cbs = { 0 };
+ belle_http_request_listener_t *l = NULL;
+ belle_generic_uri_t *uri = NULL;
+ belle_http_request_t *req = NULL;
+ belle_sip_memory_body_handler_t *bh = NULL;
+
+ uri = belle_generic_uri_parse(query->url);
+ if (!uri) {
+ belle_sip_error("Could not send request, URL %s is invalid", query->url);
+ query->status = LinphoneCardDavQueryStatusFailed;
+ return;
+ }
+ req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), belle_sip_header_create("Depth", query->depth), NULL);
+ if (!req) {
+ belle_sip_object_unref(uri);
+ belle_sip_error("Could not create belle_http_request_t");
+ query->status = LinphoneCardDavQueryStatusFailed;
+ return;
+ }
+ query->status = LinphoneCardDavQueryStatusPending;
+
+ bh = belle_sip_memory_body_handler_new_copy_from_buffer(query->body, strlen(query->body), NULL, NULL);
+ belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(bh));
+
+ cbs.process_response = process_response_from_carddav_request;
+ cbs.process_io_error = process_io_error_from_carddav_request;
+ cbs.process_auth_requested = process_auth_requested_from_carddav_request;
+ l = belle_http_request_listener_create_from_callbacks(&cbs, query);
+ belle_http_provider_send_request(query->context->lc->http_provider, req, l);
+}
+
+void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) {
+ //TODO
+}
+
+void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) {
+ //TODO
+}
+
+void linphone_carddav_set_synchronization_done_callback(LinphoneCardDavContext *cdc, LinphoneCardDavSynchronizationDoneCb cb) {
+ cdc->sync_done_cb = cb;
+}
+
+static LinphoneCardDavQuery* linphone_carddav_create_propfind_query(LinphoneCardDavContext *cdc) {
+ LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1);
+ query->context = cdc;
+ query->depth = "0";
+ query->body = "";
+ query->method = "PROPFIND";
+ query->url = cdc->server_url;
+ query->type = LinphoneCardDavQueryTypePropfind;
+ query->status = LinphoneCardDavQueryStatusIdle;
+ return query;
+}
+
+void linphone_carddav_get_current_ctag(LinphoneCardDavContext *cdc) {
+ LinphoneCardDavQuery *query = linphone_carddav_create_propfind_query(cdc);
+ linphone_carddav_send_query(query);
+}
+
+static LinphoneCardDavQuery* linphone_carddav_create_addressbook_query(LinphoneCardDavContext *cdc) {
+ LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1);
+ query->context = cdc;
+ query->depth = "1";
+ query->body = "";
+ query->method = "REPORT";
+ query->url = cdc->server_url;
+ query->type = LinphoneCardDavQueryTypeAddressbookQuery;
+ query->status = LinphoneCardDavQueryStatusIdle;
+ return query;
+}
+
+void linphone_carddav_fetch_vcards(LinphoneCardDavContext *cdc) {
+ LinphoneCardDavQuery *query = linphone_carddav_create_addressbook_query(cdc);
+ linphone_carddav_send_query(query);
+}
+
+static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query(LinphoneCardDavContext *cdc, MSList *vcards) {
+ LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1);
+ query->context = cdc;
+ query->depth = "1";
+ query->method = "REPORT";
+ query->url = cdc->server_url;
+ query->type = LinphoneCardDavQueryTypeAddressbookMultiget;
+ query->status = LinphoneCardDavQueryStatusIdle;
+ //TODO: body
+ return query;
+}
+
+void linphone_carddav_pull_vcards(LinphoneCardDavContext *cdc, MSList *vcards_to_pull) {
+ LinphoneCardDavQuery *query = linphone_carddav_create_addressbook_multiget_query(cdc, vcards_to_pull);
+ linphone_carddav_send_query(query);
+}
\ No newline at end of file
diff --git a/coreapi/carddav.cc b/coreapi/carddav.cc
deleted file mode 100644
index 1c96ab246..000000000
--- a/coreapi/carddav.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
-carddav.cc
-Copyright (C) 2015 Belledonne Communications SARL
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-*/
-
-#include "carddav.h"
-
-extern "C" void linphone_core_start_carddav_sync(LinphoneCore *lc) {
-#ifdef VCARD_ENABLED
-
-#else
- ms_error("vCard isn't available (maybe it wasn't compiled), can't do CardDAV sync");
-#endif
-}
\ No newline at end of file
diff --git a/coreapi/carddav.h b/coreapi/carddav.h
index 5d85838e5..8cb4b5bc1 100644
--- a/coreapi/carddav.h
+++ b/coreapi/carddav.h
@@ -23,10 +23,118 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifdef __cplusplus
extern "C" {
#endif
+
+typedef struct _LinphoneCardDavContext LinphoneCardDavContext;
-#include "linphonecore.h"
+typedef enum _LinphoneCardDavQueryType {
+ LinphoneCardDavQueryTypePropfind,
+ LinphoneCardDavQueryTypeAddressbookQuery,
+ LinphoneCardDavQueryTypeAddressbookMultiget
+} LinphoneCardDavQueryType;
-LINPHONE_PUBLIC void linphone_core_start_carddav_sync(LinphoneCore *lc);
+typedef enum _LinphoneCardDavQueryStatus {
+ LinphoneCardDavQueryStatusIdle,
+ LinphoneCardDavQueryStatusPending,
+ LinphoneCardDavQueryStatusOk,
+ LinphoneCardDavQueryStatusFailed
+} LinphoneCardDavQueryStatus;
+
+typedef struct _LinphoneCardDavQuery LinphoneCardDavQuery;
+
+typedef struct _LinphoneCardDavResponse LinphoneCardDavResponse;
+
+/**
+ * Callback used to notify a new contact has been created on the CardDAV server
+**/
+typedef void (*LinphoneCardDavContactCreatedCb)(LinphoneFriend *lf);
+
+/**
+ * Callback used to notify a contact has been updated on the CardDAV server
+**/
+typedef void (*LinphoneCardDavContactUpdatedCb)(LinphoneFriend *lf);
+
+/**
+ * Callback used to notify a contact has been removed on the CardDAV server
+**/
+typedef void (*LinphoneCardDavContactRemovedCb)(LinphoneFriend *lf);
+
+/**
+ * Callback used to notify a contact has been removed on the CardDAV server
+**/
+typedef void (*LinphoneCardDavSynchronizationDoneCb)(LinphoneCardDavContext *cdc, bool_t success, const char *message);
+
+/**
+ * Creates a CardDAV context for all related operations
+ * @param lc LinphoneCore 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);
+
+/**
+ * Deletes a LinphoneCardDavContext object
+ * @param cdc LinphoneCardDavContext object
+ */
+LINPHONE_PUBLIC void linphone_carddav_destroy(LinphoneCardDavContext *cdc);
+
+/**
+ * Sets a user pointer to the LinphoneCardDAVContext object
+ * @param cdc LinphoneCardDavContext object
+ * @param ud The user data pointer
+ */
+LINPHONE_PUBLIC void linphone_carddav_set_user_data(LinphoneCardDavContext *cdc, void *ud);
+
+/**
+ * Gets the user pointer set in the LinphoneCardDAVContext object
+ * @param cdc LinphoneCardDavContext object
+ * @return The user data pointer if set, NULL otherwise
+ */
+LINPHONE_PUBLIC void* linphone_carddav_get_user_data(LinphoneCardDavContext *cdc);
+
+/**
+ * Starts a synchronization with the remote server to update local friends with server changes
+ * @param cdc LinphoneCardDavContext object
+ */
+LINPHONE_PUBLIC void linphone_carddav_synchronize(LinphoneCardDavContext *cdc);
+
+/**
+ * Sends a LinphoneFriend to the CardDAV server for update or creation
+ * @param cdc LinphoneCardDavContext object
+ * @param lf a LinphoneFriend object to update/create on the server
+ */
+LINPHONE_PUBLIC void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf);
+
+/**
+ * Deletes a LinphoneFriend on the CardDAV server
+ * @param cdc LinphoneCardDavContext object
+ * @param lf a LinphoneFriend object to delete on the server
+ */
+LINPHONE_PUBLIC void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf);
+
+/**
+ * Set the synchronization done callback.
+ * @param cdc LinphoneCardDavContext object
+ * @param cb The synchronization done callback to be used.
+ */
+LINPHONE_PUBLIC void linphone_carddav_set_synchronization_done_callback(LinphoneCardDavContext *cdc, LinphoneCardDavSynchronizationDoneCb cb);
+
+/**
+ * Retrieves the current cTag value for the remote server
+ * @param cdc LinphoneCardDavContext object
+ */
+void linphone_carddav_get_current_ctag(LinphoneCardDavContext *cdc);
+
+/**
+ * Retrieves a list of all the vCards on server side to be able to detect changes
+ * @param cdc LinphoneCardDavContext object
+ */
+void linphone_carddav_fetch_vcards(LinphoneCardDavContext *cdc);
+
+/**
+ * Download asked vCards from the server
+ * @param cdc LinphoneCardDavContext object
+ * @param vcards_to_pull a MSList of LinphoneCardDavResponse objects with at least the url field filled
+ */
+void linphone_carddav_pull_vcards(LinphoneCardDavContext *cdc, MSList *vcards_to_pull);
#ifdef __cplusplus
}
diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c
index 863f8dae7..3a306ad78 100644
--- a/coreapi/linphonecore.c
+++ b/coreapi/linphonecore.c
@@ -7437,12 +7437,81 @@ 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) {
- ms_free(lc->carddav_server_url);
- lc->carddav_server_url = NULL;
- }
- if (carddav_server_url) {
- lc->carddav_server_url = ms_strdup(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", -1);
+ }
+ return -1;
+}
\ No newline at end of file
diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h
index 3ee4144e4..235f09c62 100644
--- a/coreapi/linphonecore.h
+++ b/coreapi/linphonecore.h
@@ -410,6 +410,7 @@ 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"
@@ -418,6 +419,7 @@ 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);
@@ -4252,6 +4254,10 @@ 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
@@ -4259,6 +4265,54 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneCallParams *linphone_core_create_def
*/
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);
+
#ifdef __cplusplus
}
#endif
diff --git a/coreapi/private.h b/coreapi/private.h
index 7f774cbfe..f3c21934d 100644
--- a/coreapi/private.h
+++ b/coreapi/private.h
@@ -972,7 +972,6 @@ struct _LinphoneCore
jmethodID multicast_lock_acquire_id;
jmethodID multicast_lock_release_id;
#endif
- char *carddav_server_url;
};
@@ -1223,9 +1222,57 @@ struct _LinphoneAccountCreator {
BELLE_SIP_DECLARE_VPTR(LinphoneAccountCreator);
+/*****************************************************************************
+ * CardDAV interface *
+ ****************************************************************************/
+
+struct _LinphoneCardDavContext {
+ LinphoneCore *lc;
+ 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;
+ LinphoneCardDavContactRemovedCb contact_removed_cb;
+ LinphoneCardDavSynchronizationDoneCb sync_done_cb;
+};
+
+struct _LinphoneCardDavQuery {
+ LinphoneCardDavContext *context;
+ const char *url;
+ const char *method;
+ const char *body;
+ const char *depth;
+ LinphoneCardDavQueryType type;
+ LinphoneCardDavQueryStatus status;
+};
+
+struct _LinphoneCardDavResponse {
+ LinphoneCardDavContext *context;
+ const char *etag;
+ const char *url;
+ 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 *
+ * REMOTE PROVISIONING FUNCTIONS *
****************************************************************************/
void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfiguringState state, const char *message);
@@ -1233,7 +1280,7 @@ int linphone_remote_provisioning_download_and_apply(LinphoneCore *lc, const char
LINPHONE_PUBLIC int linphone_remote_provisioning_load_file( LinphoneCore* lc, const char* file_path);
/*****************************************************************************
- * Player interface
+ * Player interface *
****************************************************************************/
struct _LinphonePlayer{
diff --git a/tester/Makefile.am b/tester/Makefile.am
index d2da519a5..ec46807a9 100644
--- a/tester/Makefile.am
+++ b/tester/Makefile.am
@@ -69,7 +69,8 @@ RCFILES = \
rcfiles/stun_rc\
rcfiles/upnp_rc\
rcfiles/zero_length_params_rc\
- rcfiles/friends_rc
+ rcfiles/friends_rc\
+ rcfiles/carddav_rc
IMAGE_FILES = images/nowebcamCIF.jpg
diff --git a/tester/rcfiles/carddav_rc b/tester/rcfiles/carddav_rc
new file mode 100644
index 000000000..c4d35f470
--- /dev/null
+++ b/tester/rcfiles/carddav_rc
@@ -0,0 +1,11 @@
+[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 4b47e622d..7a1506cf1 100644
--- a/tester/vcard_tester.c
+++ b/tester/vcard_tester.c
@@ -19,6 +19,7 @@
#include "linphonecore.h"
#include "private.h"
#include "liblinphone_tester.h"
+#include "carddav.h"
#include
@@ -182,6 +183,27 @@ end:
linphone_core_manager_destroy(manager);
}
#endif
+
+static void carddav_sync_done(LinphoneCardDavContext *c, bool_t success, const char *message) {
+ BC_ASSERT_TRUE(success);
+ linphone_carddav_destroy(c);
+}
+
+static void carddav_sync(void) {
+ LinphoneCoreManager *manager = linphone_core_manager_new2("carddav_rc", FALSE);
+ LinphoneCardDavContext *c = linphone_core_create_carddav_context(manager->lc);
+
+ 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_synchronization_done_callback(c, carddav_sync_done);
+ linphone_carddav_synchronize(c);
+
+ wait_for_until(manager->lc, NULL, NULL, 1, 1000);
+ linphone_core_manager_destroy(manager);
+}
#else
static void dummy_test(void) {
@@ -196,7 +218,8 @@ test_t vcard_tests[] = {
{ "Friends working if no db set", friends_if_no_db_set },
{ "Friends storage migration from rc to db", friends_migration },
{ "Friends storage in sqlite database", friends_sqlite_storage },
-#endif
+#endif
+ { "CardDAV synchronization", carddav_sync }
#else
{ "Dummy test", dummy_test }
#endif