Commit 1d262248 authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Started CardDAV integration into liblinphone friends API

parent 3ae31c37
...@@ -43,6 +43,7 @@ linphone_include_HEADERS=\ ...@@ -43,6 +43,7 @@ linphone_include_HEADERS=\
sipsetup.h \ sipsetup.h \
xml2lpc.h \ xml2lpc.h \
xmlrpc.h \ xmlrpc.h \
vcard.h \
carddav.h carddav.h
lib_LTLIBRARIES=liblinphone.la lib_LTLIBRARIES=liblinphone.la
...@@ -120,10 +121,10 @@ liblinphone_la_SOURCES+=linphone_tunnel_stubs.c linphone_tunnel.h ...@@ -120,10 +121,10 @@ liblinphone_la_SOURCES+=linphone_tunnel_stubs.c linphone_tunnel.h
endif endif
if BUILD_VCARD if BUILD_VCARD
liblinphone_la_SOURCES+=vcard.cc vcard.h liblinphone_la_SOURCES+=vcard.cc
liblinphone_la_CXXFLAGS=-std=c++11 liblinphone_la_CXXFLAGS=-std=c++11
else else
liblinphone_la_SOURCES+=vcard_stubs.c vcard.h liblinphone_la_SOURCES+=vcard_stubs.c
endif endif
liblinphone_la_LDFLAGS= -version-info $(LIBLINPHONE_SO_VERSION) -no-undefined liblinphone_la_LDFLAGS= -version-info $(LIBLINPHONE_SO_VERSION) -no-undefined
...@@ -157,6 +158,7 @@ liblinphone_la_LIBADD= \ ...@@ -157,6 +158,7 @@ liblinphone_la_LIBADD= \
AM_CPPFLAGS=\ AM_CPPFLAGS=\
-DIN_LINPHONE \
-I$(top_srcdir) -I$(top_srcdir)/include -I$(builddir) \ -I$(top_srcdir) -I$(top_srcdir)/include -I$(builddir) \
$(ORTP_CFLAGS) \ $(ORTP_CFLAGS) \
$(MEDIASTREAMER_CFLAGS) \ $(MEDIASTREAMER_CFLAGS) \
......
...@@ -20,13 +20,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -20,13 +20,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef LINPHONE_ACCOUNT_CREATOR_H_ #ifndef LINPHONE_ACCOUNT_CREATOR_H_
#define LINPHONE_ACCOUNT_CREATOR_H_ #define LINPHONE_ACCOUNT_CREATOR_H_
#include "linphonecore.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "linphonecore.h"
/** /**
* @addtogroup misc * @addtogroup misc
* @{ * @{
......
...@@ -20,29 +20,28 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -20,29 +20,28 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "linphonecore.h" #include "linphonecore.h"
#include "private.h" #include "private.h"
LinphoneCardDavContext* linphone_core_create_carddav_context(LinphoneCore *lc) { LinphoneCardDavContext* linphone_carddav_context_new(LinphoneFriendList *lfl) {
LinphoneCardDavContext *carddav_context = NULL; LinphoneCardDavContext *carddav_context = NULL;
if (!lc) { if (!lfl || !lfl->uri) {
return NULL; return NULL;
} }
#ifdef VCARD_ENABLED #ifdef VCARD_ENABLED
carddav_context = (LinphoneCardDavContext *)ms_new0(LinphoneCardDavContext, 1); carddav_context = (LinphoneCardDavContext *)ms_new0(LinphoneCardDavContext, 1);
carddav_context->lc = lc; carddav_context->friend_list = linphone_friend_list_ref(lfl);
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 #else
ms_error("vCard isn't available (maybe it wasn't compiled), can't do CardDAV sync"); ms_error("vCard isn't available (maybe it wasn't compiled), can't do CardDAV sync");
#endif #endif
return carddav_context; return carddav_context;
} }
void linphone_carddav_destroy(LinphoneCardDavContext *cdc) { void linphone_carddav_context_destroy(LinphoneCardDavContext *cdc) {
if (cdc) { if (cdc) {
if (cdc->friend_list) {
linphone_friend_list_unref(cdc->friend_list);
cdc->friend_list = NULL;
}
ms_free(cdc); ms_free(cdc);
} }
} }
...@@ -62,7 +61,7 @@ void linphone_carddav_synchronize(LinphoneCardDavContext *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) { static void linphone_carddav_sync_done(LinphoneCardDavContext *cdc, bool_t success, const char *msg) {
if (success) { if (success) {
ms_debug("CardDAV sync successful, saving new cTag: %i", cdc->ctag); 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 { } else {
ms_error("CardDAV sync failure: %s", msg); ms_error("CardDAV sync failure: %s", msg);
} }
...@@ -75,8 +74,12 @@ static void linphone_carddav_sync_done(LinphoneCardDavContext *cdc, bool_t succe ...@@ -75,8 +74,12 @@ static void linphone_carddav_sync_done(LinphoneCardDavContext *cdc, bool_t succe
static int find_matching_friend(LinphoneFriend *lf1, LinphoneFriend *lf2) { static int find_matching_friend(LinphoneFriend *lf1, LinphoneFriend *lf2) {
LinphoneVCard *lvc1 = linphone_friend_get_vcard(lf1); LinphoneVCard *lvc1 = linphone_friend_get_vcard(lf1);
LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf2); LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf2);
const char *uid1 = linphone_vcard_get_uid(lvc1); const char *uid1 = NULL, *uid2 = NULL;
const char *uid2 = linphone_vcard_get_uid(lvc2); if (!lvc1 || !lvc2) {
return 1;
}
uid1 = linphone_vcard_get_uid(lvc1);
uid2 = linphone_vcard_get_uid(lvc2);
if (!uid1 || !uid2) { if (!uid1 || !uid2) {
return 1; return 1;
} }
...@@ -85,7 +88,7 @@ static int find_matching_friend(LinphoneFriend *lf1, LinphoneFriend *lf2) { ...@@ -85,7 +88,7 @@ static int find_matching_friend(LinphoneFriend *lf1, LinphoneFriend *lf2) {
static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList *vCards) { static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList *vCards) {
if (vCards != NULL && ms_list_size(vCards) > 0) { 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) { while (vCards) {
LinphoneCardDavResponse *vCard = (LinphoneCardDavResponse *)vCards->data; LinphoneCardDavResponse *vCard = (LinphoneCardDavResponse *)vCards->data;
if (vCard) { if (vCard) {
...@@ -97,13 +100,13 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * ...@@ -97,13 +100,13 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList *
// Compute downloaded vCards' URL and save it (+ eTag) // Compute downloaded vCards' URL and save it (+ eTag)
char *vCard_name = strrchr(vCard->url, '/'); char *vCard_name = strrchr(vCard->url, '/');
char full_url[300]; 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_url(lvc, full_url);
linphone_vcard_set_etag(lvc, vCard->etag); linphone_vcard_set_etag(lvc, vCard->etag);
ms_debug("Downloaded vCard etag/url are %s and %s", vCard->etag, full_url); ms_debug("Downloaded vCard etag/url are %s and %s", vCard->etag, full_url);
} }
lf = linphone_friend_new_from_vcard(lvc); 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) { if (local_friend) {
LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data; LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data;
...@@ -121,7 +124,6 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList * ...@@ -121,7 +124,6 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList *
} }
vCards = ms_list_next(vCards); vCards = ms_list_next(vCards);
} }
localFriends = ms_list_free_with_data(localFriends, (void (*)(void *))linphone_friend_unref);
} }
ms_list_free(vCards); ms_list_free(vCards);
linphone_carddav_sync_done(cdc, TRUE, ""); linphone_carddav_sync_done(cdc, TRUE, "");
...@@ -169,8 +171,12 @@ end: ...@@ -169,8 +171,12 @@ end:
static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend *lf) { static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend *lf) {
LinphoneVCard *lvc1 = linphone_vcard_new_from_vcard4_buffer(response->vcard); LinphoneVCard *lvc1 = linphone_vcard_new_from_vcard4_buffer(response->vcard);
LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf); LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf);
const char *uid1 = linphone_vcard_get_uid(lvc1); const char *uid1 = NULL, *uid2 = NULL;
const char *uid2 = linphone_vcard_get_uid(lvc2); if (!lvc1 || !lvc2) {
return 1;
}
uid1 = linphone_vcard_get_uid(lvc1);
uid2 = linphone_vcard_get_uid(lvc2);
linphone_vcard_free(lvc1); linphone_vcard_free(lvc1);
if (!uid1 || !uid2) { if (!uid1 || !uid2) {
return 1; return 1;
...@@ -180,8 +186,7 @@ static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend ...@@ -180,8 +186,7 @@ static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend
static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) { static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) {
if (vCards != NULL && ms_list_size(vCards) > 0) { if (vCards != NULL && ms_list_size(vCards) > 0) {
MSList *localFriends = linphone_core_fetch_friends_from_db(cdc->lc); MSList *friends = cdc->friend_list->friends;
MSList *friends = localFriends;
while (friends) { while (friends) {
LinphoneFriend *lf = (LinphoneFriend *)friends->data; LinphoneFriend *lf = (LinphoneFriend *)friends->data;
if (lf) { if (lf) {
...@@ -208,7 +213,6 @@ static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList ...@@ -208,7 +213,6 @@ static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList
} }
friends = ms_list_next(friends); friends = ms_list_next(friends);
} }
localFriends = ms_list_free_with_data(localFriends, (void (*)(void *))linphone_friend_unref);
linphone_carddav_pull_vcards(cdc, vCards); linphone_carddav_pull_vcards(cdc, vCards);
} }
ms_list_free(vCards); ms_list_free(vCards);
...@@ -372,22 +376,7 @@ static void process_io_error_from_carddav_request(void *data, const belle_sip_io ...@@ -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) { static void process_auth_requested_from_carddav_request(void *data, belle_sip_auth_event_t *event) {
LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data; //TODO //FIXME: find a way around this
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");
}
} }
static void linphone_carddav_send_query(LinphoneCardDavQuery *query) { static void linphone_carddav_send_query(LinphoneCardDavQuery *query) {
...@@ -434,7 +423,7 @@ 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_io_error = process_io_error_from_carddav_request;
cbs.process_auth_requested = process_auth_requested_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); 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) { static LinphoneCardDavQuery* linphone_carddav_create_put_query(LinphoneCardDavContext *cdc, LinphoneVCard *lvc) {
...@@ -468,7 +457,7 @@ void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf) ...@@ -468,7 +457,7 @@ void linphone_carddav_put_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *lf)
LinphoneCardDavQuery *query = NULL; LinphoneCardDavQuery *query = NULL;
if (!linphone_vcard_get_url(lvc)) { 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); linphone_vcard_set_url(lvc, url);
ms_free(url); ms_free(url);
} }
...@@ -512,7 +501,7 @@ void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend * ...@@ -512,7 +501,7 @@ void linphone_carddav_delete_vcard(LinphoneCardDavContext *cdc, LinphoneFriend *
LinphoneCardDavQuery *query = NULL; LinphoneCardDavQuery *query = NULL;
if (!linphone_vcard_get_url(lvc)) { 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); linphone_vcard_set_url(lvc, url);
ms_free(url); ms_free(url);
} }
...@@ -562,7 +551,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_propfind_query(LinphoneCard ...@@ -562,7 +551,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_propfind_query(LinphoneCard
query->ifmatch = NULL; query->ifmatch = NULL;
query->body = "<d:propfind xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\"><d:prop><cs:getctag /></d:prop></d:propfind>"; query->body = "<d:propfind xmlns:d=\"DAV:\" xmlns:cs=\"http://calendarserver.org/ns/\"><d:prop><cs:getctag /></d:prop></d:propfind>";
query->method = "PROPFIND"; query->method = "PROPFIND";
query->url = cdc->server_url; query->url = cdc->friend_list->uri;
query->type = LinphoneCardDavQueryTypePropfind; query->type = LinphoneCardDavQueryTypePropfind;
return query; return query;
} }
...@@ -579,7 +568,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_query(LinphoneC ...@@ -579,7 +568,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_query(LinphoneC
query->ifmatch = NULL; query->ifmatch = NULL;
query->body = "<card:addressbook-query xmlns:d=\"DAV:\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\"><d:prop><d:getetag /></d:prop></card:addressbook-query>"; query->body = "<card:addressbook-query xmlns:d=\"DAV:\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\"><d:prop><d:getetag /></d:prop></card:addressbook-query>";
query->method = "REPORT"; query->method = "REPORT";
query->url = cdc->server_url; query->url = cdc->friend_list->uri;
query->type = LinphoneCardDavQueryTypeAddressbookQuery; query->type = LinphoneCardDavQueryTypeAddressbookQuery;
return query; return query;
} }
...@@ -598,7 +587,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query( ...@@ -598,7 +587,7 @@ static LinphoneCardDavQuery* linphone_carddav_create_addressbook_multiget_query(
query->depth = "1"; query->depth = "1";
query->ifmatch = NULL; query->ifmatch = NULL;
query->method = "REPORT"; query->method = "REPORT";
query->url = cdc->server_url; query->url = cdc->friend_list->uri;
query->type = LinphoneCardDavQueryTypeAddressbookMultiget; query->type = LinphoneCardDavQueryTypeAddressbookMultiget;
sprintf(body, "%s", "<card:addressbook-multiget xmlns:d=\"DAV:\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\"><d:prop><d:getetag /><card:address-data content-type='text/vcard' version='4.0'/></d:prop>"); sprintf(body, "%s", "<card:addressbook-multiget xmlns:d=\"DAV:\" xmlns:card=\"urn:ietf:params:xml:ns:carddav\"><d:prop><d:getetag /><card:address-data content-type='text/vcard' version='4.0'/></d:prop>");
......
...@@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef LINPHONE_CARDDAV_H #ifndef LINPHONE_CARDDAV_H
#define LINPHONE_CARDDAV_H #define LINPHONE_CARDDAV_H
#include "linphonecore.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
...@@ -65,16 +67,16 @@ typedef void (*LinphoneCardDavSynchronizationDoneCb)(LinphoneCardDavContext *cdc ...@@ -65,16 +67,16 @@ typedef void (*LinphoneCardDavSynchronizationDoneCb)(LinphoneCardDavContext *cdc
/** /**
* Creates a CardDAV context for all related operations * 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 * @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 * Deletes a LinphoneCardDavContext object
* @param cdc 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 * Sets a user pointer to the LinphoneCardDAVContext object
......
...@@ -26,11 +26,12 @@ ...@@ -26,11 +26,12 @@
#ifndef CONFERENCE_H #ifndef CONFERENCE_H
#define CONFERENCE_H #define CONFERENCE_H
#include "linphonecore.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include "linphonecore.h"
//typedef struct _LinphoneConference LinphoneConference; //typedef struct _LinphoneConference LinphoneConference;
......
...@@ -155,8 +155,8 @@ void* linphone_friend_get_user_data(const LinphoneFriend *lf){ ...@@ -155,8 +155,8 @@ void* linphone_friend_get_user_data(const LinphoneFriend *lf){
return lf->user_data; return lf->user_data;
} }
bool_t linphone_friend_in_list(const LinphoneFriend *lf){ bool_t linphone_friend_in_list(const LinphoneFriend *lf) {
return lf->in_list; return lf->friend_list != NULL;
} }
void linphone_core_interpret_friend_uri(LinphoneCore *lc, const char *uri, char **result){ 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) { ...@@ -529,13 +529,27 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc) {
} }
void linphone_friend_edit(LinphoneFriend *fr) { void linphone_friend_edit(LinphoneFriend *fr) {
if (fr && fr->vcard) {
linphone_vcard_compute_md5_hash(fr->vcard);
}
} }
void linphone_friend_done(LinphoneFriend *fr) { void linphone_friend_done(LinphoneFriend *fr) {
const char *previous_md5 = NULL;
ms_return_if_fail(fr); 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_apply(fr, fr->lc);
linphone_friend_save(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) { LinphoneFriend * linphone_core_create_friend(LinphoneCore *lc) {
......
...@@ -22,6 +22,55 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ...@@ -22,6 +22,55 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <polarssl/md5.h> #include <polarssl/md5.h>
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) { static char * create_resource_list_xml(const LinphoneFriendList *list) {
char *xml_content = NULL; char *xml_content = NULL;
...@@ -219,6 +268,7 @@ static bool_t linphone_friend_list_has_subscribe_inactive(const LinphoneFriendLi ...@@ -219,6 +268,7 @@ static bool_t linphone_friend_list_has_subscribe_inactive(const LinphoneFriendLi
static LinphoneFriendList * linphone_friend_list_new(void) { static LinphoneFriendList * linphone_friend_list_new(void) {
LinphoneFriendList *list = belle_sip_object_new(LinphoneFriendList); LinphoneFriendList *list = belle_sip_object_new(LinphoneFriendList);
list->cbs = linphone_friend_list_cbs_new();
belle_sip_object_ref(list); belle_sip_object_ref(list);
return list; return list;
} }
...@@ -228,7 +278,10 @@ static void linphone_friend_list_destroy(LinphoneFriendList *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->rls_uri != NULL) ms_free(list->rls_uri);
if (list->content_digest != NULL) ms_free(list->content_digest); if (list->content_digest != NULL) ms_free(list->content_digest);
if (list->event != NULL) linphone_event_unref(list->event); 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->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); BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriendList);
...@@ -259,7 +312,12 @@ void _linphone_friend_list_release(LinphoneFriendList *list){ ...@@ -259,7 +312,12 @@ void _linphone_friend_list_release(LinphoneFriendList *list){
linphone_event_unref(list->event); linphone_event_unref(list->event);
list->event = NULL; 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->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); belle_sip_object_unref(list);
} }
...@@ -304,10 +362,10 @@ void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, const char *rls_ ...@@ -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) { 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) if (!lf->uri)
ms_error("linphone_friend_list_add_friend(): invalid friend, no sip 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"); ms_error("linphone_friend_list_add_friend(): invalid friend, already in list");
return LinphoneFriendListInvalidFriend; return LinphoneFriendListInvalidFriend;
} }
...@@ -326,24 +384,81 @@ LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *lis ...@@ -326,24 +384,81 @@ LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *lis
LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf) { LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf) {
if ((lf->lc != NULL) || (lf->uri == NULL)) return LinphoneFriendListInvalidFriend; if ((lf->lc != NULL) || (lf->uri == NULL)) return LinphoneFriendListInvalidFriend;
list->friends = ms_list_append(list->friends, linphone_friend_ref(lf)); 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; 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) { LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *lf) {
MSList *elem = ms_list_find(list->friends, lf); MSList *elem = ms_list_find(list->friends, lf);
LinphoneCardDavContext *cdc = linphone_carddav_context_new(list);
if (elem == NULL) return LinphoneFriendListNonExistentFriend; if (elem == NULL) return LinphoneFriendListNonExistentFriend;
#ifdef FRIENDS_SQL_STORAGE_ENABLED #ifdef FRIENDS_SQL_STORAGE_ENABLED
linphone_core_remove_friend_from_db(lf->lc, lf); linphone_core_remove_friend_from_db(lf->lc, lf);
#endif #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); linphone_friend_unref(lf);
list->friends = ms_list_remove_link(list->friends, elem); list->friends = ms_list_remove_link(list->friends, elem);
return LinphoneFriendListOK; 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 * linphone_friend_list_find_friend_by_address(const LinphoneFriendList *list, const LinphoneAddress *address) {
LinphoneFriend *lf = NULL; LinphoneFriend *lf = NULL;
const MSList *elem; const MSList *elem;
...@@ -487,3 +602,21 @@ void linphone_friend_list_notify_presence_received(LinphoneFriendList *list, Lin ...@@ -487,3 +602,21 @@ void linphone_friend_list_notify_presence_received(LinphoneFriendList *list, Lin
linphone_content_unref(first_part); 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
...@@ -174,6 +174,116 @@ LINPHONE_PUBLIC void linphone_friend_list_update_subscriptions(LinphoneFriendLis ...@@ -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); LINPHONE_PUBLIC void linphone_friend_list_notify_presence(LinphoneFriendList *list, LinphonePresenceModel *presence);