From a8e6cc908fff1121ae0cfc2527c2a21cdea0e3d5 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 5 Jan 2016 16:31:20 +0100 Subject: [PATCH] More work on CardDAV sync: doing propfind and addressbook-query requests --- coreapi/Makefile.am | 4 +- coreapi/carddav.c | 234 ++++++++++++++++++++++++++++++++++++++ coreapi/carddav.cc | 28 ----- coreapi/carddav.h | 112 +++++++++++++++++- coreapi/linphonecore.c | 81 ++++++++++++- coreapi/linphonecore.h | 54 +++++++++ coreapi/private.h | 53 ++++++++- tester/Makefile.am | 3 +- tester/rcfiles/carddav_rc | 11 ++ tester/vcard_tester.c | 25 +++- 10 files changed, 562 insertions(+), 43 deletions(-) create mode 100644 coreapi/carddav.c delete mode 100644 coreapi/carddav.cc create mode 100644 tester/rcfiles/carddav_rc 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