diff --git a/coreapi/friend.c b/coreapi/friend.c index 487cfd2a4..01990400a 100644 --- a/coreapi/friend.c +++ b/coreapi/friend.c @@ -88,25 +88,6 @@ MSList *linphone_find_friend_by_address(MSList *fl, const LinphoneAddress *addr, return res; } -LinphoneFriend *linphone_find_friend_by_inc_subscribe(MSList *l, SalOp *op){ - MSList *elem; - for (elem=l;elem!=NULL;elem=elem->next){ - LinphoneFriend *lf=(LinphoneFriend*)elem->data; - if (ms_list_find(lf->insubs, op)) return lf; - } - return NULL; -} - -LinphoneFriend *linphone_find_friend_by_out_subscribe(MSList *l, SalOp *op){ - MSList *elem; - LinphoneFriend *lf; - for (elem=l;elem!=NULL;elem=elem->next){ - lf=(LinphoneFriend*)elem->data; - if (lf->outsub && (lf->outsub == op || sal_op_is_forked_of(lf->outsub, op))) return lf; - } - return NULL; -} - void __linphone_friend_do_subscribe(LinphoneFriend *fr){ LinphoneCore *lc=fr->lc; @@ -259,7 +240,7 @@ static void linphone_friend_unsubscribe(LinphoneFriend *lf){ } } -static void linphone_friend_invalidate_subscription(LinphoneFriend *lf){ +void linphone_friend_invalidate_subscription(LinphoneFriend *lf){ if (lf->outsub!=NULL) { LinphoneCore *lc=lf->lc; sal_op_release(lf->outsub); @@ -491,47 +472,27 @@ LinphoneFriend * linphone_core_create_friend_with_address(LinphoneCore *lc, cons return linphone_friend_new_with_address(address); } -void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) -{ - ms_return_if_fail(lf->lc==NULL); - ms_return_if_fail(lf->uri!=NULL); - if (ms_list_find(lc->friends,lf)!=NULL){ - char *tmp=NULL; - const LinphoneAddress *addr=linphone_friend_get_address(lf); - if (addr) tmp=linphone_address_as_string(addr); - ms_warning("Friend %s already in list, ignored.", tmp ? tmp : "unknown"); - if (tmp) ms_free(tmp); - return ; - } - lc->friends=ms_list_append(lc->friends,linphone_friend_ref(lf)); - if (ms_list_find(lc->subscribers, lf)){ +void linphone_core_add_friend(LinphoneCore *lc, LinphoneFriend *lf) { + if (linphone_friend_list_add_friend(lc->friendlist, lf) != LinphoneFriendListOK) return; + if (ms_list_find(lc->subscribers, lf)) { /*if this friend was in the pending subscriber list, now remove it from this list*/ lc->subscribers = ms_list_remove(lc->subscribers, lf); linphone_friend_unref(lf); } - lf->lc=lc; - if ( linphone_core_ready(lc)) linphone_friend_apply(lf,lc); - else lf->commit=TRUE; - return ; + lf->lc = lc; + if (linphone_core_ready(lc)) linphone_friend_apply(lf, lc); + else lf->commit = TRUE; } -void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){ - MSList *el=ms_list_find(lc->friends,fl); - if (el!=NULL){ - linphone_friend_unref((LinphoneFriend*)el->data); - lc->friends=ms_list_remove_link(lc->friends,el); - linphone_core_write_friends_config(lc); - }else{ - ms_error("linphone_core_remove_friend(): friend [%p] is not part of core's list.",fl); +void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend *lf) { + if (linphone_friend_list_remove_friend(lc->friendlist, lf) == LinphoneFriendListNonExistentFriend) { + ms_error("linphone_core_remove_friend(): friend [%p] is not part of core's list.", lf); } } void linphone_core_update_friends_subscriptions(LinphoneCore *lc, LinphoneProxyConfig *cfg, bool_t only_when_registered){ - const MSList *elem; - for(elem=lc->friends;elem!=NULL;elem=elem->next){ - LinphoneFriend *f=(LinphoneFriend*)elem->data; - linphone_friend_update_subscribes(f,cfg,only_when_registered); - } + if (lc->friendlist != NULL) + linphone_friend_list_update_subscriptions(lc->friendlist, cfg, only_when_registered); } bool_t linphone_core_should_subscribe_friends_only_when_registered(const LinphoneCore *lc){ @@ -545,11 +506,8 @@ void linphone_core_send_initial_subscribes(LinphoneCore *lc){ } void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc){ - const MSList *elem; - for(elem=lc->friends;elem!=NULL;elem=elem->next){ - LinphoneFriend *f=(LinphoneFriend*)elem->data; - linphone_friend_invalidate_subscription(f); - } + if (lc->friendlist != NULL) + linphone_friend_list_invalidate_subscriptions(lc->friendlist); lc->initial_subscribes_sent=FALSE; } @@ -569,34 +527,15 @@ const char *linphone_friend_get_ref_key(const LinphoneFriend *lf){ } LinphoneFriend *linphone_core_find_friend(const LinphoneCore *lc, const LinphoneAddress *addr){ - LinphoneFriend *lf=NULL; - MSList *elem; - for(elem=lc->friends;elem!=NULL;elem=ms_list_next(elem)){ - lf=(LinphoneFriend*)elem->data; - if (linphone_address_weak_equal(lf->uri,addr)) - break; - lf=NULL; - } - return lf; + return linphone_friend_list_find_friend_by_address(lc->friendlist, addr); } LinphoneFriend *linphone_core_get_friend_by_address(const LinphoneCore *lc, const char *uri){ - LinphoneAddress *puri=linphone_address_new(uri); - LinphoneFriend *lf=puri ? linphone_core_find_friend(lc,puri) : NULL; - if (puri) linphone_address_unref(puri); - return lf; + return linphone_friend_list_find_friend_by_uri(lc->friendlist, uri); } LinphoneFriend *linphone_core_get_friend_by_ref_key(const LinphoneCore *lc, const char *key){ - const MSList *elem; - if (key==NULL) return NULL; - for(elem=linphone_core_get_friend_list(lc);elem!=NULL;elem=elem->next){ - LinphoneFriend *lf=(LinphoneFriend*)elem->data; - if (lf->refkey!=NULL && strcmp(lf->refkey,key)==0){ - return lf; - } - } - return NULL; + return linphone_friend_list_find_friend_by_ref_key(lc->friendlist, key); } #define key_compare(s1,s2) strcmp(s1,s2) @@ -702,7 +641,7 @@ void linphone_core_write_friends_config(LinphoneCore* lc) MSList *elem; int i; if (! linphone_core_ready(lc)) return; /*dont write config when reading it !*/ - for (elem=lc->friends,i=0; elem!=NULL; elem=ms_list_next(elem),i++){ + for (elem=lc->friendlist->friends,i=0; elem!=NULL; elem=ms_list_next(elem),i++){ linphone_friend_write_to_config_file(lc->config,(LinphoneFriend*)elem->data,i); } linphone_friend_write_to_config_file(lc->config,NULL,i); /* set the end */ diff --git a/coreapi/friendlist.c b/coreapi/friendlist.c index b221717fb..0fd49a14a 100644 --- a/coreapi/friendlist.c +++ b/coreapi/friendlist.c @@ -25,6 +25,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. static void linphone_friend_list_destroy(LinphoneFriendList *list) { if (list->display_name != NULL) ms_free(list->display_name); if (list->rls_uri != NULL) ms_free(list->rls_uri); + list->friends = ms_list_free_with_data(list->friends, (void (*)(void *))linphone_friend_unref); } BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneFriendList); @@ -103,9 +104,85 @@ LinphoneFriendListStatus linphone_friend_list_add_friend(LinphoneFriendList *lis } LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *friend) { - MSList *el = ms_list_find(list->friends, friend); - if (el == NULL) return LinphoneFriendListNonExistentFriend; - linphone_friend_unref((LinphoneFriend *)el->data); - list->friends = ms_list_remove_link(list->friends, el); + MSList *elem = ms_list_find(list->friends, friend); + if (elem == NULL) return LinphoneFriendListNonExistentFriend; + linphone_friend_unref((LinphoneFriend *)elem->data); + list->friends = ms_list_remove_link(list->friends, elem); return LinphoneFriendListOK; } + +LinphoneFriend * linphone_friend_list_find_friend_by_address(const LinphoneFriendList *list, const LinphoneAddress *address) { + LinphoneFriend *friend = NULL; + const MSList *elem; + for (elem = list->friends; elem != NULL; elem = elem->next) { + friend = (LinphoneFriend *)elem->data; + if (linphone_address_weak_equal(friend->uri, address)) + return friend; + } + return NULL; +} + +LinphoneFriend * linphone_friend_list_find_friend_by_uri(const LinphoneFriendList *list, const char *uri) { + LinphoneAddress *address = linphone_address_new(uri); + LinphoneFriend *friend = address ? linphone_friend_list_find_friend_by_address(list, address) : NULL; + if (address) linphone_address_unref(address); + return friend; +} + +LinphoneFriend * linphone_friend_list_find_friend_by_ref_key(const LinphoneFriendList *list, const char *ref_key) { + const MSList *elem; + if (ref_key == NULL) return NULL; + for (elem = list->friends; elem != NULL; elem = elem->next) { + LinphoneFriend *friend = (LinphoneFriend *)elem->data; + if ((friend->refkey != NULL) && (strcmp(friend->refkey, ref_key) == 0)) return friend; + } + return NULL; +} + +LinphoneFriend * linphone_friend_list_find_friend_by_inc_subscribe(const LinphoneFriendList *list, SalOp *op) { + const MSList *elem; + for (elem = list->friends; elem != NULL; elem = elem->next) { + LinphoneFriend *friend = (LinphoneFriend *)elem->data; + if (ms_list_find(friend->insubs, op)) return friend; + } + return NULL; +} + +LinphoneFriend * linphone_friend_list_find_friend_by_out_subscribe(const LinphoneFriendList *list, SalOp *op) { + const MSList *elem; + for (elem = list->friends; elem != NULL; elem = elem->next) { + LinphoneFriend *friend = (LinphoneFriend *)elem->data; + if (friend->outsub && ((friend->outsub == op) || sal_op_is_forked_of(friend->outsub, op))) return friend; + } + return NULL; +} + +void linphone_friend_list_close_subscriptions(LinphoneFriendList *list) { + /* FIXME we should wait until subscription to complete. */ + if (list->friends) + ms_list_for_each(list->friends, (void (*)(void *))linphone_friend_close_subscriptions); +} + +void linphone_friend_list_update_subscriptions(LinphoneFriendList *list, LinphoneProxyConfig *cfg, bool_t only_when_registered) { + const MSList *elem; + for (elem = list->friends; elem != NULL; elem = elem->next) { + LinphoneFriend *friend = (LinphoneFriend *)elem->data; + linphone_friend_update_subscribes(friend, cfg, only_when_registered); + } +} + +void linphone_friend_list_invalidate_subscriptions(LinphoneFriendList *list) { + const MSList *elem; + for (elem = list->friends; elem != NULL; elem = elem->next) { + LinphoneFriend *friend = (LinphoneFriend *)elem->data; + linphone_friend_invalidate_subscription(friend); + } +} + +void linphone_friend_list_notify_presence(LinphoneFriendList *list, LinphonePresenceModel *presence) { + const MSList *elem; + for(elem = list->friends; elem != NULL; elem = elem->next) { + LinphoneFriend *friend = (LinphoneFriend *)elem->data; + linphone_friend_notify(friend, presence); + } +} diff --git a/coreapi/friendlist.h b/coreapi/friendlist.h index 1d01bce39..7a94d4641 100644 --- a/coreapi/friendlist.h +++ b/coreapi/friendlist.h @@ -23,6 +23,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "linphonefriend.h" +#include "linphonepresence.h" #ifdef __cplusplus @@ -125,6 +126,20 @@ LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_add_friend(Linphon **/ LINPHONE_PUBLIC LinphoneFriendListStatus linphone_friend_list_remove_friend(LinphoneFriendList *list, LinphoneFriend *friend); +LINPHONE_PUBLIC LinphoneFriend * linphone_friend_list_find_friend_by_address(const LinphoneFriendList *list, const LinphoneAddress *address); + +LINPHONE_PUBLIC LinphoneFriend * linphone_friend_list_find_friend_by_uri(const LinphoneFriendList *list, const char *uri); + +LINPHONE_PUBLIC LinphoneFriend * linphone_friend_list_find_friend_by_ref_key(const LinphoneFriendList *list, const char *ref_key); + +LINPHONE_PUBLIC void linphone_friend_list_close_subscriptions(LinphoneFriendList *list); + +LINPHONE_PUBLIC void linphone_friend_list_update_subscriptions(LinphoneFriendList *list, LinphoneProxyConfig *cfg, bool_t only_when_registered); + +LINPHONE_PUBLIC void linphone_friend_list_invalidate_subscriptions(LinphoneFriendList *list); + +LINPHONE_PUBLIC void linphone_friend_list_notify_presence(LinphoneFriendList *list, LinphonePresenceModel *presence); + /** * @} */ diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 5cd5c6322..4fbef8b9a 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -1672,6 +1672,7 @@ static void linphone_core_init(LinphoneCore * lc, const LinphoneCoreVTable *vtab lc->config=lp_config_ref(config); lc->data=userdata; lc->ringstream_autorelease=TRUE; + lc->friendlist = linphone_friend_list_new(); linphone_task_list_init(&lc->hooks); memcpy(local_vtable,vtable,sizeof(LinphoneCoreVTable)); @@ -1905,7 +1906,7 @@ bool_t linphone_core_generic_confort_noise_enabled(const LinphoneCore *lc){ const MSList * linphone_core_get_friend_list(const LinphoneCore *lc) { - return lc->friends; + return lc->friendlist->friends; } void linphone_core_enable_audio_adaptive_jittcomp(LinphoneCore* lc, bool_t val) @@ -6323,9 +6324,8 @@ static void codecs_config_uninit(LinphoneCore *lc) void ui_config_uninit(LinphoneCore* lc) { ms_message("Destroying friends."); - if (lc->friends){ - lc->friends = ms_list_free_with_data(lc->friends, (void (*)(void *))linphone_friend_unref); - } + linphone_friend_list_unref(lc->friendlist); + lc->friendlist = NULL; if (lc->subscribers){ lc->subscribers = ms_list_free_with_data(lc->subscribers, (void (*)(void *))linphone_friend_unref); } @@ -6365,9 +6365,7 @@ static void linphone_core_uninit(LinphoneCore *lc) ms_usleep(50000); } - if (lc->friends) /* FIXME we should wait until subscription to complete*/ - ms_list_for_each(lc->friends,(void (*)(void *))linphone_friend_close_subscriptions); - + linphone_friend_list_close_subscriptions(lc->friendlist); lc->chatrooms = ms_list_free_with_data(lc->chatrooms, (MSIterateFunc)linphone_chat_room_release); linphone_core_set_state(lc,LinphoneGlobalShutdown,"Shutting down"); diff --git a/coreapi/presence.c b/coreapi/presence.c index f69ddec6e..d97ff865f 100644 --- a/coreapi/presence.c +++ b/coreapi/presence.c @@ -1464,15 +1464,11 @@ void linphone_core_reject_subscriber(LinphoneCore *lc, LinphoneFriend *lf){ } void linphone_core_notify_all_friends(LinphoneCore *lc, LinphonePresenceModel *presence){ - MSList *elem; LinphonePresenceActivity *activity = linphone_presence_model_get_activity(presence); 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); - for(elem=lc->friends;elem!=NULL;elem=elem->next){ - LinphoneFriend *lf=(LinphoneFriend *)elem->data; - linphone_friend_notify(lf,presence); - } + linphone_friend_list_notify_presence(lc->friendlist, presence); } void linphone_subscription_new(LinphoneCore *lc, SalOp *op, const char *from){ @@ -1486,7 +1482,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 (linphone_find_friend_by_address(lc->friends,uri,&lf)!=NULL){ + lf = linphone_friend_list_find_friend_by_address(lc->friendlist, uri); + if (lf!=NULL){ linphone_friend_add_incoming_subscription(lf, op); lf->inc_subscribe_pending=TRUE; sal_subscribe_accept(op); @@ -1850,15 +1847,15 @@ void linphone_notify_convert_presence_to_xml(SalOp *op, SalPresenceModel *presen void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model){ char *tmp; - LinphoneFriend *lf; + LinphoneFriend *lf = NULL; LinphoneAddress *friend=NULL; LinphonePresenceModel *presence = model ? (LinphonePresenceModel *)model:linphone_presence_model_new_with_activity(LinphonePresenceActivityOffline, NULL); - lf=linphone_find_friend_by_out_subscribe(lc->friends,op); + if (lc->friendlist != NULL) + lf=linphone_friend_list_find_friend_by_out_subscribe(lc->friendlist,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=NULL; - linphone_find_friend_by_address(lc->friends,(LinphoneAddress*)addr,&lf); + lf = linphone_friend_list_find_friend_by_address(lc->friendlist, (LinphoneAddress *)addr); } if (lf!=NULL){ LinphonePresenceActivity *activity = NULL; @@ -1904,9 +1901,11 @@ void linphone_notify_recv(LinphoneCore *lc, SalOp *op, SalSubscribeStatus ss, Sa } void linphone_subscription_closed(LinphoneCore *lc, SalOp *op){ - LinphoneFriend *lf; - lf=linphone_find_friend_by_inc_subscribe(lc->friends,op); - + LinphoneFriend *lf = NULL; + + if (lc->friendlist != NULL) + lf=linphone_friend_list_find_friend_by_inc_subscribe(lc->friendlist,op); + if (lf!=NULL){ /*this will release the op*/ linphone_friend_remove_incoming_subscription(lf, op); diff --git a/coreapi/private.h b/coreapi/private.h index 078ed768b..0820bdb14 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -376,13 +376,14 @@ void _linphone_proxy_config_release(LinphoneProxyConfig *cfg); * */ const LinphoneAddress* linphone_proxy_config_get_service_route(const LinphoneProxyConfig* cfg); +void linphone_friend_invalidate_subscription(LinphoneFriend *lf); void linphone_friend_close_subscriptions(LinphoneFriend *lf); void linphone_friend_update_subscribes(LinphoneFriend *fr, LinphoneProxyConfig *cfg, bool_t only_when_registered); void linphone_friend_notify(LinphoneFriend *lf, LinphonePresenceModel *presence); void linphone_friend_add_incoming_subscription(LinphoneFriend *lf, SalOp *op); void linphone_friend_remove_incoming_subscription(LinphoneFriend *lf, SalOp *op); -LinphoneFriend *linphone_find_friend_by_inc_subscribe(MSList *l, SalOp *op); -LinphoneFriend *linphone_find_friend_by_out_subscribe(MSList *l, SalOp *op); +LinphoneFriend *linphone_friend_list_find_friend_by_inc_subscribe(const LinphoneFriendList *list, SalOp *op); +LinphoneFriend *linphone_friend_list_find_friend_by_out_subscribe(const LinphoneFriendList *list, SalOp *op); MSList *linphone_find_friend_by_address(MSList *fl, const LinphoneAddress *addr, LinphoneFriend **lf); bool_t linphone_core_should_subscribe_friends_only_when_registered(const LinphoneCore *lc); void linphone_core_update_friends_subscriptions(LinphoneCore *lc, LinphoneProxyConfig *cfg, bool_t only_when_registered); @@ -850,7 +851,7 @@ struct _LinphoneCore ui_config_t ui_conf; autoreplier_config_t autoreplier_conf; LinphoneProxyConfig *default_proxy; - MSList *friends; + LinphoneFriendList *friendlist; MSList *auth_info; struct _RingStream *ringstream; time_t dmfs_playing_start_time;