diff --git a/coreapi/bellesip_sal/sal_impl.c b/coreapi/bellesip_sal/sal_impl.c index c98dbec7f..19fb28cea 100644 --- a/coreapi/bellesip_sal/sal_impl.c +++ b/coreapi/bellesip_sal/sal_impl.c @@ -976,12 +976,11 @@ typedef struct { unsigned char node[6]; } sal_uuid_t; - -int sal_create_uuid(Sal*ctx, char *uuid, size_t len){ +int sal_generate_uuid(char *uuid, size_t len) { sal_uuid_t uuid_struct; int i; int written; - + if (len==0) return -1; /*create an UUID as described in RFC4122, 4.4 */ belle_sip_random_bytes((unsigned char*)&uuid_struct, sizeof(sal_uuid_t)); @@ -1000,10 +999,17 @@ int sal_create_uuid(Sal*ctx, char *uuid, size_t len){ for (i = 0; i < 6; i++) written+=snprintf(uuid+written,len-written,"%2.2x", uuid_struct.node[i]); uuid[len-1]='\0'; - sal_set_uuid(ctx,uuid); return 0; } +int sal_create_uuid(Sal*ctx, char *uuid, size_t len) { + if (sal_generate_uuid(uuid, len) == 0) { + sal_set_uuid(ctx, uuid); + return 0; + } + return -1; +} + static void make_supported_header(Sal *sal){ MSList *it; char *alltags=NULL; diff --git a/coreapi/carddav.c b/coreapi/carddav.c index ea7b0b63b..f9ea99f73 100644 --- a/coreapi/carddav.c +++ b/coreapi/carddav.c @@ -274,9 +274,8 @@ static void process_response_from_carddav_request(void *data, const belle_http_r if (event->response) { int code = belle_http_response_get_status_code(event->response); - if (code == 207 || code == 200) { + if (code == 207 || code == 200 || code == 201 || code == 204) { const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response); - query->status = LinphoneCardDavQueryStatusOk; switch(query->type) { case LinphoneCardDavQueryTypePropfind: linphone_carddav_ctag_fetched(query->context, parse_ctag_value_from_xml_response(body)); @@ -287,10 +286,38 @@ static void process_response_from_carddav_request(void *data, const belle_http_r case LinphoneCardDavQueryTypeAddressbookMultiget: linphone_carddav_vcards_pulled(query->context, parse_vcards_from_xml_response(body)); break; + case LinphoneCardDavQueryTypePut: + { + belle_sip_header_t *header = belle_sip_message_get_header((belle_sip_message_t *)event->response, "ETag"); + LinphoneFriend *lf = (LinphoneFriend *)query->user_data; + if (lf) { + LinphoneVCard *lvc = linphone_friend_get_vcard(lf); + if (header && lvc && !linphone_vcard_get_etag(lvc)) { + const char *etag = belle_sip_header_get_unparsed_value(header); + ms_debug("eTag for newly created vCard is: %s", etag); + linphone_vcard_set_etag(lvc, etag); + } + linphone_carddav_sync_done(query->context, TRUE, ""); + linphone_friend_unref(lf); + } else { + linphone_carddav_sync_done(query->context, FALSE, "No LinphoneFriend found in user_date field of query"); + } + } + break; + case LinphoneCardDavQueryTypeDelete: + linphone_carddav_sync_done(query->context, TRUE, ""); + break; + default: + ms_error("Unknown request: %i", query->type); + break; } } else { - query->status = LinphoneCardDavQueryStatusFailed; + char msg[100]; + snprintf(msg, sizeof(msg), "Unexpected HTTP response code: %i", code); + linphone_carddav_sync_done(query->context, FALSE, msg); } + } else { + linphone_carddav_sync_done(query->context, FALSE, "No response found"); } ms_free(query); } @@ -298,7 +325,6 @@ static void process_response_from_carddav_request(void *data, const belle_http_r 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); linphone_carddav_sync_done(query->context, FALSE, "I/O error during CardDAV request sending"); } @@ -316,7 +342,6 @@ static void process_auth_requested_from_carddav_request(void *data, belle_sip_au belle_sip_auth_event_set_ha1(event, context->ha1); } } else { - query->status = LinphoneCardDavQueryStatusFailed; ms_error("Authentication requested during CardDAV request sending, and username/password weren't provided"); linphone_carddav_sync_done(query->context, FALSE, "Authentication requested during CardDAV request sending, and username/password weren't provided"); } @@ -331,18 +356,33 @@ static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { uri = belle_generic_uri_parse(query->url); if (!uri) { + LinphoneCardDavContext *cdc = query->context; + if (cdc && cdc->sync_done_cb) { + cdc->sync_done_cb(cdc, FALSE, "Could not send request, URL is invalid"); + } 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 (query->depth) { + 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); + } else if (query->ifmatch) { + req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), belle_sip_header_create("If-Match", query->ifmatch), NULL); + } else { + if (strcmp(query->method, "PUT")) { + req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), belle_sip_header_create("If-None-Match", "*"), NULL); + } else { + req = belle_http_request_create(query->method, uri, belle_sip_header_content_type_create("application", "xml; charset=utf-8"), NULL); + } + } if (!req) { + LinphoneCardDavContext *cdc = query->context; + if (cdc && cdc->sync_done_cb) { + cdc->sync_done_cb(cdc, FALSE, "Could not create belle_http_request_t"); + } 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)); @@ -354,12 +394,106 @@ static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { belle_http_provider_send_request(query->context->lc->http_provider, req, l); } +static LinphoneCardDavQuery* linphone_carddav_create_put_query(LinphoneCardDavContext *cdc, LinphoneVCard *lvc) { + LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); + query->context = cdc; + query->depth = NULL; + query->ifmatch = linphone_vcard_get_etag(lvc); + query->body = linphone_vcard_as_vcard4_string(lvc); + query->method = "PUT"; + query->url = linphone_vcard_get_url(lvc); + query->type = LinphoneCardDavQueryTypePut; + return query; +} + +static char* generate_url_from_server_address_and_uid(const char *server_url) { + if (server_url) { + char uuid[32]; + if (sal_generate_uuid(uuid, sizeof(uuid)) == 0) { + char url[300]; + snprintf(url, sizeof(url), "%s/linphone-%s.vcf", server_url, uuid); + ms_debug("Generated url is %s", url); + return ms_strdup(url); + } + } + return NULL; +} + void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { - //TODO + LinphoneVCard *lvc = linphone_friend_get_vcard(lf); + if (lvc && linphone_vcard_get_uid(lvc)) { + LinphoneCardDavQuery *query = NULL; + + if (!linphone_vcard_get_url(lvc)) { + char *url = generate_url_from_server_address_and_uid(cdc->server_url); + linphone_vcard_set_url(lvc, url); + ms_free(url); + } + + query = linphone_carddav_create_put_query(cdc, lvc); + query->user_data = linphone_friend_ref(lf); + linphone_carddav_send_query(query); + } else { + const char *msg = NULL; + if (!lvc) { + msg = "LinphoneVCard is NULL"; + } else if (!linphone_vcard_get_url(lvc)) { + msg = "LinphoneVCard doesn't have an UID"; + } + + if (msg) { + ms_error("%s", msg); + } + + if (cdc && cdc->sync_done_cb) { + cdc->sync_done_cb(cdc, FALSE, msg); + } + } +} + +static LinphoneCardDavQuery* linphone_carddav_create_delete_query(LinphoneCardDavContext *cdc, LinphoneVCard *lvc) { + LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); + query->context = cdc; + query->depth = NULL; + query->ifmatch = linphone_vcard_get_etag(lvc); + query->body = linphone_vcard_as_vcard4_string(lvc); + query->method = "DELETE"; + query->url = linphone_vcard_get_url(lvc); + query->type = LinphoneCardDavQueryTypeDelete; + return query; } void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) { - //TODO + LinphoneVCard *lvc = linphone_friend_get_vcard(lf); + if (lvc && linphone_vcard_get_uid(lvc) && linphone_vcard_get_etag(lvc)) { + LinphoneCardDavQuery *query = NULL; + + if (!linphone_vcard_get_url(lvc)) { + char *url = generate_url_from_server_address_and_uid(cdc->server_url); + linphone_vcard_set_url(lvc, url); + ms_free(url); + } + + query = linphone_carddav_create_delete_query(cdc, lvc); + linphone_carddav_send_query(query); + } else { + const char *msg = NULL; + if (!lvc) { + msg = "LinphoneVCard is NULL"; + } else if (!linphone_vcard_get_uid(lvc)) { + msg = "LinphoneVCard doesn't have an UID"; + } else if (!linphone_vcard_get_etag(lvc)) { + msg = "LinphoneVCard doesn't have an eTag"; + } + + if (msg) { + ms_error("%s", msg); + } + + if (cdc && cdc->sync_done_cb) { + cdc->sync_done_cb(cdc, FALSE, msg); + } + } } void linphone_carddav_set_synchronization_done_callback(LinphoneCardDavContext *cdc, LinphoneCardDavSynchronizationDoneCb cb) { @@ -382,11 +516,11 @@ static LinphoneCardDavQuery* linphone_carddav_create_propfind_query(LinphoneCard LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); query->context = cdc; query->depth = "0"; + query->ifmatch = NULL; query->body = ""; query->method = "PROPFIND"; query->url = cdc->server_url; query->type = LinphoneCardDavQueryTypePropfind; - query->status = LinphoneCardDavQueryStatusIdle; return query; } @@ -399,11 +533,11 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_query(LinphoneC LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); query->context = cdc; query->depth = "1"; + query->ifmatch = NULL; query->body = ""; query->method = "REPORT"; query->url = cdc->server_url; query->type = LinphoneCardDavQueryTypeAddressbookQuery; - query->status = LinphoneCardDavQueryStatusIdle; return query; } @@ -414,22 +548,22 @@ void linphone_carddav_fetch_vcards(LinphoneCardDavContext *cdc) { static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query(LinphoneCardDavContext *cdc, MSList *vcards) { LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)ms_new0(LinphoneCardDavQuery, 1); - char body[(ms_list_size(vcards)+1)*100]; + char body[(ms_list_size(vcards)+1)*300]; MSList *iterator = vcards; query->context = cdc; query->depth = "1"; + query->ifmatch = NULL; query->method = "REPORT"; query->url = cdc->server_url; query->type = LinphoneCardDavQueryTypeAddressbookMultiget; - query->status = LinphoneCardDavQueryStatusIdle; sprintf(body, "%s", ""); while (iterator) { LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)iterator->data; if (response) { - char temp_body[100]; - sprintf(temp_body, "%s", response->url); + char temp_body[300]; + snprintf(temp_body, sizeof(temp_body), "%s", response->url); sprintf(body, "%s%s", body, temp_body); iterator = ms_list_next(iterator); } diff --git a/coreapi/carddav.h b/coreapi/carddav.h index 1a8a22b26..dac895066 100644 --- a/coreapi/carddav.h +++ b/coreapi/carddav.h @@ -23,22 +23,22 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifdef __cplusplus extern "C" { #endif + +/** + * @addtogroup carddav_vcard + * @{ + */ typedef struct _LinphoneCardDavContext LinphoneCardDavContext; typedef enum _LinphoneCardDavQueryType { LinphoneCardDavQueryTypePropfind, LinphoneCardDavQueryTypeAddressbookQuery, - LinphoneCardDavQueryTypeAddressbookMultiget + LinphoneCardDavQueryTypeAddressbookMultiget, + LinphoneCardDavQueryTypePut, + LinphoneCardDavQueryTypeDelete } LinphoneCardDavQueryType; -typedef enum _LinphoneCardDavQueryStatus { - LinphoneCardDavQueryStatusIdle, - LinphoneCardDavQueryStatusPending, - LinphoneCardDavQueryStatusOk, - LinphoneCardDavQueryStatusFailed -} LinphoneCardDavQueryStatus; - typedef struct _LinphoneCardDavQuery LinphoneCardDavQuery; typedef struct _LinphoneCardDavResponse LinphoneCardDavResponse; @@ -157,6 +157,10 @@ void linphone_carddav_fetch_vcards(LinphoneCardDavContext *cdc); */ void linphone_carddav_pull_vcards(LinphoneCardDavContext *cdc, MSList *vcards_to_pull); +/** + * @} + */ + #ifdef __cplusplus } #endif diff --git a/coreapi/private.h b/coreapi/private.h index afeb75781..03ae84a36 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1244,8 +1244,9 @@ struct _LinphoneCardDavQuery { const char *method; const char *body; const char *depth; + const char *ifmatch; + void *user_data; LinphoneCardDavQueryType type; - LinphoneCardDavQueryStatus status; }; struct _LinphoneCardDavResponse { diff --git a/coreapi/vcard.cc b/coreapi/vcard.cc index c8d94c5b2..c9b9153bf 100644 --- a/coreapi/vcard.cc +++ b/coreapi/vcard.cc @@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "vcard.h" #include "belcard/belcard.hpp" #include "belcard/belcard_parser.hpp" +#include "sal/sal.h" struct _LinphoneVCard { shared_ptr belCard; @@ -27,20 +28,24 @@ struct _LinphoneVCard { const char *url; }; -extern "C" LinphoneVCard* linphone_vcard_new(void) { +#ifdef __cplusplus +extern "C" { +#endif + +LinphoneVCard* linphone_vcard_new(void) { LinphoneVCard* vCard = (LinphoneVCard*) ms_new0(LinphoneVCard, 1); vCard->belCard = belcard::BelCardGeneric::create(); return vCard; } -extern "C" void linphone_vcard_free(LinphoneVCard *vCard) { +void linphone_vcard_free(LinphoneVCard *vCard) { if (!vCard) return; vCard->belCard.reset(); ms_free(vCard); } -extern "C" MSList* linphone_vcard_list_from_vcard4_file(const char *filename) { +MSList* linphone_vcard_list_from_vcard4_file(const char *filename) { MSList *result = NULL; if (filename && ortp_file_exist(filename) == 0) { belcard::BelCardParser parser = belcard::BelCardParser::getInstance(); @@ -57,7 +62,7 @@ extern "C" MSList* linphone_vcard_list_from_vcard4_file(const char *filename) { return result; } -extern "C" MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) { +MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) { MSList *result = NULL; if (buffer) { belcard::BelCardParser parser = belcard::BelCardParser::getInstance(); @@ -74,7 +79,7 @@ extern "C" MSList* linphone_vcard_list_from_vcard4_buffer(const char *buffer) { return result; } -extern "C" LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer) { +LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buffer) { LinphoneVCard *vCard = NULL; if (buffer) { belcard::BelCardParser parser = belcard::BelCardParser::getInstance(); @@ -89,13 +94,13 @@ extern "C" LinphoneVCard* linphone_vcard_new_from_vcard4_buffer(const char *buff return vCard; } -extern "C" const char * linphone_vcard_as_vcard4_string(LinphoneVCard *vCard) { +const char * linphone_vcard_as_vcard4_string(LinphoneVCard *vCard) { if (!vCard) return NULL; return vCard->belCard->toFoldedString().c_str(); } -extern "C" void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name) { +void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *name) { if (!vCard || !name) return; shared_ptr fn = belcard::BelCardGeneric::create(); @@ -103,14 +108,14 @@ extern "C" void linphone_vcard_set_full_name(LinphoneVCard *vCard, const char *n vCard->belCard->setFullName(fn); } -extern "C" const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard) { +const char* linphone_vcard_get_full_name(const LinphoneVCard *vCard) { if (!vCard) return NULL; const char *result = vCard->belCard->getFullName() ? vCard->belCard->getFullName()->getValue().c_str() : NULL; return result; } -extern "C" void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address) { +void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char *sip_address) { if (!vCard || !sip_address) return; shared_ptr impp = belcard::BelCardGeneric::create(); @@ -118,7 +123,7 @@ extern "C" void linphone_vcard_add_sip_address(LinphoneVCard *vCard, const char vCard->belCard->addImpp(impp); } -extern "C" void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const char *sip_address) { +void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const char *sip_address) { if (!vCard) return; for (auto it = vCard->belCard->getImpp().begin(); it != vCard->belCard->getImpp().end(); ++it) { @@ -130,7 +135,7 @@ extern "C" void linphone_vcard_remove_sip_address(LinphoneVCard *vCard, const ch } } -extern "C" 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) { if (!vCard || !sip_address) return; if (vCard->belCard->getImpp().size() > 0) { @@ -143,7 +148,7 @@ extern "C" void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, const } } -extern "C" MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) { +MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) { MSList *result = NULL; if (!vCard) return NULL; @@ -156,27 +161,56 @@ extern "C" MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) return result; } -extern "C" const char* linphone_vcard_get_uid(const LinphoneVCard *vCard) { +bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard) { + char uuid[64]; + + if (vCard) { + if (linphone_vcard_get_uid(vCard)) { + return FALSE; + } + if (sal_generate_uuid(uuid, sizeof(uuid)) == 0) { + char vcard_uuid[sizeof(uuid)+4]; + snprintf(vcard_uuid, sizeof(vcard_uuid), "urn:%s", uuid); + linphone_vcard_set_uid(vCard, ms_strdup(vcard_uuid)); + return TRUE; + } + } + return FALSE; +} + +void linphone_vcard_set_uid(LinphoneVCard *vCard, const char *uid) { + if (!vCard || !uid) return; + + shared_ptr uniqueId = belcard::BelCardGeneric::create(); + uniqueId->setValue(uid); + vCard->belCard->setUniqueId(uniqueId); +} + +const char* linphone_vcard_get_uid(const LinphoneVCard *vCard) { if (vCard && vCard->belCard->getUniqueId()) { return vCard->belCard->getUniqueId()->getValue().c_str(); } return NULL; } -extern "C" void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag) { +void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag) { vCard->etag = ms_strdup(etag); } -extern "C" const char* linphone_vcard_get_etag(const LinphoneVCard *vCard) { +const char* linphone_vcard_get_etag(const LinphoneVCard *vCard) { if (!vCard) return NULL; return vCard->etag; } -extern "C" void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url) { +void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url) { vCard->url = ms_strdup(url); } -extern "C" const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { +const char* linphone_vcard_get_url(const LinphoneVCard *vCard) { if (!vCard) return NULL; return vCard->url; -} \ No newline at end of file +} + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/coreapi/vcard.h b/coreapi/vcard.h index c8eeec45d..f9a0782d3 100644 --- a/coreapi/vcard.h +++ b/coreapi/vcard.h @@ -32,7 +32,7 @@ extern "C" #endif /** - * @addtogroup buddy_list + * @addtogroup carddav_vcard * @{ */ @@ -119,12 +119,54 @@ LINPHONE_PUBLIC void linphone_vcard_edit_main_sip_address(LinphoneVCard *vCard, */ LINPHONE_PUBLIC MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard); +/** + * Generates a random unique id for the vCard. + * If is required to be able to synchronize the vCard with a CardDAV server + * @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); + +/** + * Sets the unique ID of the vCard + * @param[in] vCard the LinphoneVCard + * @param[in] uid the unique id + */ +void linphone_vcard_set_uid(LinphoneVCard *vCard, const char *uid); + +/** + * Gets the UID of the vCard + * @param[in] vCard the LinphoneVCard + * @return the UID of the vCard, otherwise NULL + */ const char* linphone_vcard_get_uid(const LinphoneVCard *vCard); +/** + * Sets the eTAG of the vCard + * @param[in] vCard the LinphoneVCard + * @param[in] etag the eTAG + */ void linphone_vcard_set_etag(LinphoneVCard *vCard, const char * etag); + +/** + * Gets the eTag of the vCard + * @param[in] vCard the LinphoneVCard + * @return the eTag of the vCard in the CardDAV server, otherwise NULL + */ const char* linphone_vcard_get_etag(const LinphoneVCard *vCard); +/** + * Sets the URL of the vCard + * @param[in] vCard the LinphoneVCard + * @param[in] url the URL + */ void linphone_vcard_set_url(LinphoneVCard *vCard, const char * url); + +/** + * Gets the URL of the vCard + * @param[in] vCard the LinphoneVCard + * @return the URL of the vCard in the CardDAV server, otherwise NULL + */ const char* linphone_vcard_get_url(const LinphoneVCard *vCard); /** diff --git a/coreapi/vcard_stubs.c b/coreapi/vcard_stubs.c index 148858e09..4309e7b7b 100644 --- a/coreapi/vcard_stubs.c +++ b/coreapi/vcard_stubs.c @@ -71,6 +71,14 @@ MSList* linphone_vcard_get_sip_addresses(const LinphoneVCard *vCard) { return NULL; } +bool_t linphone_vcard_generate_unique_id(LinphoneVCard *vCard) { + return FALSE; +} + +void linphone_vcard_set_uid(LinphoneVCard *vCard, const char *uid) { + +} + const char* linphone_vcard_get_uid(const LinphoneVCard *vCard) { return NULL; } diff --git a/include/sal/sal.h b/include/sal/sal.h index d8106f6b7..c1ed0dc21 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -618,6 +618,7 @@ void sal_verify_server_certificates(Sal *ctx, bool_t verify); void sal_verify_server_cn(Sal *ctx, bool_t verify); void sal_set_uuid(Sal*ctx, const char *uuid); int sal_create_uuid(Sal*ctx, char *uuid, size_t len); +int sal_generate_uuid(char *uuid, size_t len); LINPHONE_PUBLIC void sal_enable_test_features(Sal*ctx, bool_t enabled); void sal_use_no_initial_route(Sal *ctx, bool_t enabled); diff --git a/tester/vcard_tester.c b/tester/vcard_tester.c index c146ac7f7..774aec654 100644 --- a/tester/vcard_tester.c +++ b/tester/vcard_tester.c @@ -200,7 +200,6 @@ typedef struct _LinphoneCardDAVStats { static void carddav_sync_done(LinphoneCardDavContext *c, bool_t success, const char *message) { LinphoneCardDAVStats *stats = (LinphoneCardDAVStats *)linphone_carddav_get_user_data(c); BC_ASSERT_TRUE(success); - linphone_carddav_destroy(c); stats->sync_done_count++; } @@ -250,6 +249,7 @@ static void carddav_sync(void) { BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); ms_free(stats); + linphone_carddav_destroy(c); linphone_core_manager_destroy(manager); } @@ -288,6 +288,7 @@ static void carddav_sync_2(void) { ms_free(stats); unlink(friends_db); ms_free(friends_db); + linphone_carddav_destroy(c); linphone_core_manager_destroy(manager); } @@ -325,6 +326,40 @@ static void carddav_sync_3(void) { ms_free(stats); unlink(friends_db); ms_free(friends_db); + linphone_carddav_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); + 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); + + 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); + + 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_carddav_put_vcard(c, lf); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 1, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 1, int, "%i"); + + linphone_carddav_delete_vcard(c, lf); + wait_for_until(manager->lc, NULL, &stats->sync_done_count, 2, 2000); + BC_ASSERT_EQUAL(stats->sync_done_count, 2, int, "%i"); + + linphone_friend_unref(lf); + ms_free(stats); + linphone_carddav_destroy(c); linphone_core_manager_destroy(manager); } @@ -346,6 +381,7 @@ test_t vcard_tests[] = { { "CardDAV synchronization", carddav_sync }, { "CardDAV synchronization 2", carddav_sync_2 }, { "CardDAV synchronization 3", carddav_sync_3 }, + { "CardDAV synchronization 4", carddav_sync_4 }, #else { "Dummy test", dummy_test } #endif