Commit bce8c3cc authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Started rework of friend lists management in linphone + database storage of friend lists

parent 6cbaaf68
......@@ -112,7 +112,6 @@ static void linphone_carddav_vcards_pulled(LinphoneCardDavContext *cdc, MSList *
LinphoneFriend *lf2 = (LinphoneFriend *)local_friend->data;
if (cdc->contact_updated_cb) {
ms_debug("Contact updated: %s", linphone_friend_get_name(lf));
lf2 = linphone_friend_ref(lf2);
cdc->contact_updated_cb(cdc, lf, lf2);
}
} else {
......@@ -173,6 +172,7 @@ static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend
LinphoneVCard *lvc2 = linphone_friend_get_vcard(lf);
const char *uid1 = NULL, *uid2 = NULL;
if (!lvc1 || !lvc2) {
if (lvc1) linphone_vcard_free(lvc1);
return 1;
}
uid1 = linphone_vcard_get_uid(lvc1);
......@@ -187,17 +187,15 @@ static int find_matching_vcard(LinphoneCardDavResponse *response, LinphoneFriend
static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList *vCards) {
if (vCards != NULL && ms_list_size(vCards) > 0) {
MSList *friends = cdc->friend_list->friends;
MSList *friends_to_remove = NULL;
while (friends) {
LinphoneFriend *lf = (LinphoneFriend *)friends->data;
if (lf) {
MSList *vCard = ms_list_find_custom(vCards, (int (*)(const void*, const void*))find_matching_vcard, lf);
if (!vCard) {
ms_debug("Local friend %s isn't in the remote vCard list, delete it", linphone_friend_get_name(lf));
if (cdc->contact_removed_cb) {
ms_debug("Contact removed: %s", linphone_friend_get_name(lf));
lf = linphone_friend_ref(lf);
cdc->contact_removed_cb(cdc, lf);
}
ms_error("Local friend %s isn't in the remote vCard list, delete it", linphone_friend_get_name(lf));
friends_to_remove = ms_list_append(friends_to_remove, lf);
} else {
LinphoneCardDavResponse *response = (LinphoneCardDavResponse *)vCard->data;
ms_debug("Local friend %s is in the remote vCard list, check eTag", linphone_friend_get_name(lf));
......@@ -213,6 +211,18 @@ static void linphone_carddav_vcards_fetched(LinphoneCardDavContext *cdc, MSList
}
friends = ms_list_next(friends);
}
while(friends_to_remove) {
LinphoneFriend *lf = (LinphoneFriend *)friends_to_remove->data;
if (lf) {
if (cdc->contact_removed_cb) {
ms_error("Contact removed: %s", linphone_friend_get_name(lf));
cdc->contact_removed_cb(cdc, lf);
}
}
friends_to_remove = ms_list_next(friends_to_remove);
}
friends_to_remove = ms_list_free(friends_to_remove);
linphone_carddav_pull_vcards(cdc, vCards);
}
ms_list_free(vCards);
......@@ -376,7 +386,33 @@ 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) {
//TODO //FIXME: find a way around this
LinphoneCardDavQuery *query = (LinphoneCardDavQuery *)data;
LinphoneCardDavContext *cdc = query->context;
const char *realm = belle_sip_auth_event_get_realm(event);
belle_generic_uri_t *uri = belle_generic_uri_parse(query->url);
const char *domain = belle_generic_uri_get_host(uri);
LinphoneCore *lc = cdc->friend_list->lc;
const MSList *auth_infos = linphone_core_get_auth_info_list(lc);
ms_debug("Looking for auth info for domain %s and realm %s", domain, realm);
while (auth_infos) {
LinphoneAuthInfo *auth_info = (LinphoneAuthInfo *)auth_infos->data;
if (auth_info->domain && strcmp(domain, auth_info->domain) == 0) {
if (!auth_info->realm || strcmp(realm, auth_info->realm) == 0) {
belle_sip_auth_event_set_username(event, auth_info->username);
belle_sip_auth_event_set_passwd(event, auth_info->passwd);
belle_sip_auth_event_set_ha1(event, auth_info->ha1);
break;
}
}
auth_infos = ms_list_next(auth_infos);
}
if (!auth_infos) {
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");
linphone_carddav_query_free(query);
}
}
static void linphone_carddav_send_query(LinphoneCardDavQuery *query) {
......
This diff is collapsed.
......@@ -280,8 +280,8 @@ static void linphone_friend_list_destroy(LinphoneFriendList *list) {
if (list->event != NULL) linphone_event_unref(list->event);
if (list->uri != NULL) ms_free(list->uri);
if (list->cbs) linphone_friend_list_cbs_unref(list->cbs);
list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))linphone_friend_unref);
list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))_linphone_friend_release);
list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref);
list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))_linphone_friend_release);
}
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriendList);
......@@ -316,9 +316,9 @@ void _linphone_friend_list_release(LinphoneFriendList *list){
linphone_friend_list_cbs_unref(list->cbs);
list->cbs = NULL;
}
list->dirty_friends_to_update = ms_list_free_with_data(list->dirty_friends_to_update, (void (*)(void *))linphone_friend_unref);
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);
linphone_friend_list_unref(list);
}
void linphone_friend_list_unref(LinphoneFriendList *list) {
......@@ -361,6 +361,23 @@ void linphone_friend_list_set_rls_uri(LinphoneFriendList *list, const char *rls_
}
}
LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf) {
if (lf->uri == NULL || lf->friend_list) {
if (!lf->uri)
ms_error("linphone_friend_list_add_friend(): invalid friend, no sip uri");
if (lf->friend_list)
ms_error("linphone_friend_list_add_friend(): invalid friend, already in list");
return LinphoneFriendListInvalidFriend;
}
list->friends = ms_list_append(list->friends, linphone_friend_ref(lf));
lf->friend_list = list;
lf->lc = list->lc;
#ifdef FRIENDS_SQL_STORAGE_ENABLED
linphone_core_store_friend_in_db(lf->lc, lf);
#endif
return LinphoneFriendListOK;
}
LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf) {
if (lf->uri == NULL || lf->friend_list) {
if (!lf->uri)
......@@ -386,6 +403,10 @@ LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *
list->friends = ms_list_append(list->friends, linphone_friend_ref(lf));
list->dirty_friends_to_update = ms_list_append(list->dirty_friends_to_update, linphone_friend_ref(lf));
lf->friend_list = list;
lf->lc = list->lc;
#ifdef FRIENDS_SQL_STORAGE_ENABLED
linphone_core_store_friend_in_db(lf->lc, lf);
#endif
return LinphoneFriendListOK;
}
......@@ -425,19 +446,18 @@ void linphone_friend_list_update_dirty_friends(LinphoneFriendList *list) {
}
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);
}
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) {
LinphoneFriendList *lfl = cdc->friend_list;
lfl->friends = ms_list_append(lfl->friends, linphone_friend_ref(lf));
_linphone_friend_list_add_friend(lfl, lf);
if (cdc->friend_list->cbs->contact_created_cb) {
cdc->friend_list->cbs->contact_created_cb(lfl, linphone_friend_ref(lf));
cdc->friend_list->cbs->contact_created_cb(lfl, lf);
}
}
linphone_friend_unref(lf);
}
static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) {
......@@ -448,10 +468,9 @@ static void carddav_removed(LinphoneCardDavContext *cdc, LinphoneFriend *lf) {
lfl->friends = ms_list_remove_link(lfl->friends, elem);
}
if (cdc->friend_list->cbs->contact_deleted_cb) {
cdc->friend_list->cbs->contact_deleted_cb(lfl, linphone_friend_ref(lf));
cdc->friend_list->cbs->contact_deleted_cb(lfl, lf);
}
}
linphone_friend_unref(lf);
}
static void carddav_updated(LinphoneCardDavContext *cdc, LinphoneFriend *lf_new, LinphoneFriend *lf_old) {
......
......@@ -62,11 +62,32 @@ typedef struct _LinphoneFriendList LinphoneFriendList;
LINPHONE_PUBLIC LinphoneFriendList * linphone_core_create_friend_list(LinphoneCore *lc);
/**
* Set the friend list.
* Add a friend list.
* @param[in] lc LinphoneCore object
* @param[in] list LinphoneFriendList object
*/
LINPHONE_PUBLIC void linphone_core_set_friend_list(LinphoneCore *lc, LinphoneFriendList *list);
LINPHONE_PUBLIC void linphone_core_add_friend_list(LinphoneCore *lc, LinphoneFriendList *list);
/**
* Removes a friend list.
* @param[in] lc LinphoneCore object
* @param[in] list LinphoneFriendList object
*/
LINPHONE_PUBLIC void linphone_core_remove_friend_list(LinphoneCore *lc, LinphoneFriendList *list);
/**
* Retrieves the list of LinphoneFriendList from the core.
* @param[in] lc LinphoneCore object
* @return \mslist{LinphoneFriendList} a list of LinphoneFriendList
*/
LINPHONE_PUBLIC const MSList * linphone_core_get_friends_lists(const LinphoneCore *lc);
/**
* Retrieves the first list of LinphoneFriend from the core.
* @param[in] lc LinphoneCore object
* @return the first LinphoneFriendList object or NULL
*/
LINPHONE_PUBLIC LinphoneFriendList * linphone_core_get_default_friend_list(const LinphoneCore *lc);
/**
* Acquire a reference to the friend list.
......@@ -130,6 +151,7 @@ LINPHONE_PUBLIC void linphone_friend_list_set_rls_uri(LinphoneFriendList *list,
* @return LinphoneFriendListOK if successfully added, LinphoneFriendListInvalidFriend if the friend is not valid.
**/
LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *afriend);
LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *afriend);
/**
* Remove a friend from a friend list.
......
......@@ -1679,7 +1679,7 @@ static void linphone_core_register_default_codecs(LinphoneCore *lc){
static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, const LinphoneContent *body) {
if (strcmp(notified_event, "Presence") == 0) {
linphone_friend_list_notify_presence_received(lc->friendlist, lev, body);
linphone_friend_list_notify_presence_received(linphone_core_get_default_friend_list(lc), lev, body);
}
}
......@@ -1687,13 +1687,23 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab
const char *remote_provisioning_uri = NULL;
LinphoneCoreVTable* local_vtable= linphone_core_v_table_new();
LinphoneCoreVTable *internal_vtable = linphone_core_v_table_new();
LinphoneFriendList *list = NULL;
const char *rls_uri = NULL;
ms_message("Initializing LinphoneCore %s", linphone_core_get_version());
lc->config=lp_config_ref(config);
lc->data=userdata;
lc->ringstream_autorelease=TRUE;
linphone_core_set_friend_list(lc, NULL);
list = linphone_core_create_friend_list(lc);
rls_uri = lp_config_get_string(lc->config, "sip", "rls_uri", NULL);
if (rls_uri && lp_config_get_int(lc->config, "sip", "use_rls_presence", 0)) {
linphone_friend_list_set_rls_uri(list, rls_uri);
}
linphone_core_add_friend_list(lc, list);
linphone_friend_list_unref(list);
linphone_task_list_init(&lc->hooks);
internal_vtable->notify_received = linphone_core_internal_notify_received;
......@@ -1930,24 +1940,47 @@ bool_t linphone_core_generic_confort_noise_enabled(const LinphoneCore *lc){
return lp_config_get_int(lc->config, "misc", "use_cn", FALSE);
}
const MSList * linphone_core_get_friend_list(const LinphoneCore *lc)
{
return lc->friendlist->friends;
const MSList* linphone_core_get_friend_list(const LinphoneCore *lc) {
if (lc->friends_lists && lc->friends_lists->data) {
LinphoneFriendList *list = (LinphoneFriendList *)lc->friends_lists->data;
return list->friends;
}
return NULL;
}
const MSList* linphone_core_get_friends_lists(const LinphoneCore *lc) {
return lc->friends_lists;
}
void linphone_core_set_friend_list(LinphoneCore *lc, LinphoneFriendList *list) {
if (lc->friendlist != NULL) {
linphone_friend_list_unref(lc->friendlist);
lc->friendlist = NULL;
LinphoneFriendList* linphone_core_get_default_friend_list(const LinphoneCore *lc) {
LinphoneFriendList *list = NULL;
if (!lc->friends_lists) {
return NULL;
}
if (list != NULL) {
lc->friendlist = linphone_friend_list_ref(list);
} else {
const char *rls_uri = NULL;
lc->friendlist = linphone_core_create_friend_list(lc);
rls_uri = lp_config_get_string(lc->config, "sip", "rls_uri", NULL);
if (rls_uri && lp_config_get_int(lc->config, "sip", "use_rls_presence", 0))
linphone_friend_list_set_rls_uri(lc->friendlist, rls_uri);
list = (LinphoneFriendList *)lc->friends_lists->data;
return list;
}
void linphone_core_remove_friend_list(LinphoneCore *lc, LinphoneFriendList *list) {
MSList *elem = ms_list_find(lc->friends_lists, list);
if (elem == NULL) return;
list->lc = NULL;
linphone_friend_list_unref(list);
lc->friends_lists = ms_list_remove_link(lc->friends_lists, elem);
#ifdef FRIENDS_SQL_STORAGE_ENABLED
linphone_core_remove_friends_list_from_db(lc, list);
#endif
}
void linphone_core_add_friend_list(LinphoneCore *lc, LinphoneFriendList *list) {
if (list) {
if (!list->lc) {
list->lc = lc;
}
lc->friends_lists = ms_list_append(lc->friends_lists, linphone_friend_list_ref(list));
#ifdef FRIENDS_SQL_STORAGE_ENABLED
linphone_core_store_friends_list_in_db(lc, list);
#endif
}
}
......@@ -2733,11 +2766,15 @@ void linphone_core_iterate(LinphoneCore *lc){
}
if (one_second_elapsed) {
MSList *elem = NULL;
if (lp_config_needs_commit(lc->config)) {
lp_config_sync(lc->config);
}
if (lc->friendlist->dirty_friends_to_update) {
linphone_friend_list_update_dirty_friends(lc->friendlist);
for (elem = lc->friends_lists; elem != NULL; elem = ms_list_next(elem)) {
LinphoneFriendList *list = (LinphoneFriendList *)elem->data;
if (list->dirty_friends_to_update) {
linphone_friend_list_update_dirty_friends(list);
}
}
}
......@@ -6354,10 +6391,14 @@ static void codecs_config_uninit(LinphoneCore *lc)
void ui_config_uninit(LinphoneCore* lc)
{
MSList *elem = NULL;
ms_message("Destroying friends.");
_linphone_friend_list_release(lc->friendlist);
lc->friendlist = NULL;
if (lc->subscribers){
for (elem = lc->friends_lists; elem != NULL; elem = ms_list_next(elem)) {
LinphoneFriendList *list = (LinphoneFriendList *)elem->data;
_linphone_friend_list_release(list);
}
lc->friends_lists = NULL;
if (lc->subscribers) {
lc->subscribers = ms_list_free_with_data(lc->subscribers, (void (*)(void *))_linphone_friend_release);
}
if (lc->presence_model) {
......@@ -6385,18 +6426,22 @@ LpConfig * linphone_core_create_lp_config(LinphoneCore *lc, const char *filename
static void linphone_core_uninit(LinphoneCore *lc)
{
MSList *elem = NULL;
linphone_task_list_free(&lc->hooks);
lc->video_conf.show_local = FALSE;
while(lc->calls)
{
while(lc->calls) {
LinphoneCall *the_call = lc->calls->data;
linphone_core_terminate_call(lc,the_call);
linphone_core_iterate(lc);
ms_usleep(50000);
}
linphone_friend_list_close_subscriptions(lc->friendlist);
for (elem = lc->friends_lists; elem != NULL; elem = ms_list_next(elem)) {
LinphoneFriendList *list = (LinphoneFriendList *)elem->data;
linphone_friend_list_close_subscriptions(list);
}
lc->chatrooms = ms_list_free_with_data(lc->chatrooms, (MSIterateFunc)linphone_chat_room_release);
linphone_core_set_state(lc,LinphoneGlobalShutdown,"Shutting down");
......@@ -6455,10 +6500,12 @@ static void linphone_core_uninit(LinphoneCore *lc)
if (lc->ringtoneplayer) {
linphone_ringtoneplayer_destroy(lc->ringtoneplayer);
}
linphone_core_free_payload_types(lc);
if (lc->supported_formats) ms_free(lc->supported_formats);
linphone_core_message_storage_close(lc);
linphone_core_call_log_storage_close(lc);
linphone_core_friends_storage_close(lc);
ms_exit();
linphone_core_set_state(lc,LinphoneGlobalOff,"Off");
linphone_core_deactivate_log_serialization_if_needed();
......
......@@ -1469,7 +1469,7 @@ void linphone_core_notify_all_friends(LinphoneCore *lc, LinphonePresenceModel *p
char *activity_str = linphone_presence_activity_to_string(activity);
ms_message("Notifying all friends that we are [%s]", activity_str);
if (activity_str != NULL) ms_free(activity_str);
linphone_friend_list_notify_presence(lc->friendlist, presence);
linphone_friend_list_notify_presence(linphone_core_get_default_friend_list(lc), presence);
}
void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){
......@@ -1483,8 +1483,8 @@ void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){
ms_message("Receiving new subscription from %s.",from);
/* check if we answer to this subscription */
if (lc->friendlist != NULL) {
lf = linphone_friend_list_find_friend_by_address(lc->friendlist, uri);
if (linphone_core_get_default_friend_list(lc) != NULL) {
lf = linphone_friend_list_find_friend_by_address(linphone_core_get_default_friend_list(lc), uri);
}
if (lf!=NULL){
linphone_friend_add_incoming_subscription(lf, op);
......@@ -1854,11 +1854,11 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa
LinphoneAddress *friend=NULL;
LinphonePresenceModel *presence = model ? (LinphonePresenceModel *)model:linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline, NULL);
if (lc->friendlist != NULL)
lf=linphone_friend_list_find_friend_by_out_subscribe(lc->friendlist,op);
if (linphone_core_get_default_friend_list(lc) != NULL)
lf=linphone_friend_list_find_friend_by_out_subscribe(linphone_core_get_default_friend_list(lc), op);
if (lf==NULL && lp_config_get_int(lc->config,"sip","allow_out_of_subscribe_presence",0)){
const SalAddress *addr=sal_op_get_from_address(op);
lf = linphone_friend_list_find_friend_by_address(lc->friendlist, (LinphoneAddress *)addr);
lf = linphone_friend_list_find_friend_by_address(linphone_core_get_default_friend_list(lc), (LinphoneAddress *)addr);
}
if (lf!=NULL){
LinphonePresenceActivity *activity = NULL;
......@@ -1904,8 +1904,8 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa
void linphone_subscription_closed(LinphoneCore *lc, SalOp *op){
LinphoneFriend *lf = NULL;
if (lc->friendlist != NULL)
lf=linphone_friend_list_find_friend_by_inc_subscribe(lc->friendlist,op);
if (linphone_core_get_default_friend_list(lc) != NULL)
lf = linphone_friend_list_find_friend_by_inc_subscribe(linphone_core_get_default_friend_list(lc), op);
if (lf!=NULL){
/*this will release the op*/
......
......@@ -420,8 +420,12 @@ void linphone_core_friends_storage_init(LinphoneCore *lc);
void linphone_core_friends_storage_close(LinphoneCore *lc);
void linphone_core_store_friend_in_db(LinphoneCore *lc, LinphoneFriend *lf);
void linphone_core_remove_friend_from_db(LinphoneCore *lc, LinphoneFriend *lf);
MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc);
void linphone_core_store_friends_list_in_db(LinphoneCore *lc, LinphoneFriendList *list);
void linphone_core_remove_friends_list_from_db(LinphoneCore *lc, LinphoneFriendList *list);
MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFriendList *list);
MSList* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc);
LinphoneFriendListStatus linphone_friend_list_import_friend(LinphoneFriendList *list, LinphoneFriend *lf);
LinphoneFriendListStatus _linphone_friend_list_add_friend(LinphoneFriendList *list, LinphoneFriend *lf);
int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, socklen_t *socklen, int default_port);
......@@ -897,7 +901,7 @@ struct _LinphoneCore
ui_config_t ui_conf;
autoreplier_config_t autoreplier_conf;
LinphoneProxyConfig *default_proxy;
LinphoneFriendList *friendlist;
MSList *friends_lists;
MSList *auth_info;
struct _RingStream *ringstream;
time_t dmfs_playing_start_time;
......
......@@ -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
......
This diff is collapsed.
[net]
mtu=1300
[sip]
ping_with_options=0
sip_random_port=1
[auth_info_0]
domain=192.168.0.230
username=sylvain
ha1=4747ce2517a985f2fc20234a38f068b6
realm=SabreDAV
\ No newline at end of file
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment