Commit a0b7b1f3 authored by Simon Morlat's avatar Simon Morlat
Browse files

rework implementation of SUBSCRIBEs delayed to successful registration.

In case of network errors, SUBSCRIBE could be sent before registration refresh, this should be fixed.
parent 526af17d
...@@ -695,4 +695,9 @@ bool_t sal_op_is_idle(SalOp *op){ ...@@ -695,4 +695,9 @@ bool_t sal_op_is_idle(SalOp *op){
return TRUE; return TRUE;
} }
void sal_op_stop_refreshing(SalOp *op){
if (op->refresher){
belle_sip_refresher_stop(op->refresher);
}
}
...@@ -380,6 +380,37 @@ BuddyInfo * linphone_friend_get_info(const LinphoneFriend *lf){ ...@@ -380,6 +380,37 @@ BuddyInfo * linphone_friend_get_info(const LinphoneFriend *lf){
return lf->info; return lf->info;
} }
/*
* updates the subscriptions.
* If only_when_registered is TRUE, subscribe will be sent only if the friend's corresponding proxy config is in registered.
* Otherwise if the proxy config goes to unregistered state, the subscription refresh will be suspended.
* An optional proxy whose state has changed can be passed to optimize the processing.
**/
void linphone_friend_update_subscribes(LinphoneFriend *fr, LinphoneProxyConfig *proxy, bool_t only_when_registered){
int can_subscribe=1;
if (only_when_registered && (fr->subscribe || fr->subscribe_active)){
LinphoneProxyConfig *cfg=linphone_core_lookup_known_proxy(fr->lc,fr->uri);
if (proxy && proxy!=cfg) return;
if (cfg && cfg->state!=LinphoneRegistrationOk){
char *tmp=linphone_address_as_string(fr->uri);
ms_message("Friend [%s] belongs to proxy config with identity [%s], but this one isn't registered. Subscription is suspended.",
tmp,linphone_proxy_config_get_identity(cfg));
ms_free(tmp);
can_subscribe=0;
}
}
if (can_subscribe && fr->subscribe && fr->subscribe_active==FALSE){
ms_message("Sending a new SUBSCRIBE");
__linphone_friend_do_subscribe(fr);
}else if (can_subscribe && fr->subscribe_active && !fr->subscribe){
linphone_friend_unsubscribe(fr);
}else if (!can_subscribe && fr->outsub){
fr->subscribe_active=FALSE;
sal_op_stop_refreshing(fr->outsub);
}
}
void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
LinphonePresenceModel *model; LinphonePresenceModel *model;
...@@ -407,12 +438,8 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){ ...@@ -407,12 +438,8 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
} }
fr->inc_subscribe_pending=FALSE; fr->inc_subscribe_pending=FALSE;
} }
if (fr->subscribe && fr->subscribe_active==FALSE){ if (fr->lc)
ms_message("Sending a new SUBSCRIBE"); linphone_friend_update_subscribes(fr,NULL,linphone_core_should_subscribe_friends_only_when_registered(fr->lc));
__linphone_friend_do_subscribe(fr);
}else if (fr->subscribe_active && !fr->subscribe){
linphone_friend_unsubscribe(fr);
}
ms_message("linphone_friend_apply() done."); ms_message("linphone_friend_apply() done.");
lc->bl_refresh=TRUE; lc->bl_refresh=TRUE;
fr->commit=FALSE; fr->commit=FALSE;
...@@ -465,31 +492,22 @@ void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){ ...@@ -465,31 +492,22 @@ void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){
} }
} }
void linphone_core_send_initial_subscribes(LinphoneCore *lc){ void linphone_core_update_friends_subscriptions(LinphoneCore *lc, LinphoneProxyConfig *cfg, bool_t only_when_registered){
const MSList *elem; const MSList *elem;
if (lc->initial_subscribes_sent) return;
lc->initial_subscribes_sent=TRUE; /*set to true and see if looping on friends will change this status*/
for(elem=lc->friends;elem!=NULL;elem=elem->next){ for(elem=lc->friends;elem!=NULL;elem=elem->next){
LinphoneFriend *f=(LinphoneFriend*)elem->data; LinphoneFriend *f=(LinphoneFriend*)elem->data;
LinphoneProxyConfig* cfg; linphone_friend_update_subscribes(f,cfg,only_when_registered);
if (f->subscribe && !f->initial_subscribes_sent) {
lc->initial_subscribes_sent=FALSE; /*at least 1 was not sent */
if ((cfg=linphone_core_lookup_known_proxy(f->lc,linphone_friend_get_address(f)))) {
/*check if already registered*/
if (linphone_proxy_config_get_state(cfg) != LinphoneRegistrationOk)
continue; /*skip this friend because not registered yet*/
else {
char* lf_string = linphone_address_as_string(linphone_friend_get_address(f));
ms_message("Identity [%s] registered, we can now subscribe to [%s]",linphone_proxy_config_get_identity(cfg),lf_string);
ms_free(lf_string);
}
}
linphone_friend_apply(f,lc);
f->initial_subscribes_sent=TRUE;
}
} }
}
bool_t linphone_core_should_subscribe_friends_only_when_registered(const LinphoneCore *lc){
return lp_config_get_int(lc->config,"sip","subscribe_presence_only_when_registered",1);
}
void linphone_core_send_initial_subscribes(LinphoneCore *lc){
if (lc->initial_subscribes_sent) return;
lc->initial_subscribes_sent=TRUE;
linphone_core_update_friends_subscriptions(lc,NULL,linphone_core_should_subscribe_friends_only_when_registered(lc));
} }
void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc){ void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc){
......
...@@ -255,13 +255,14 @@ void linphone_proxy_config_write_all_to_config_file(LinphoneCore *lc); ...@@ -255,13 +255,14 @@ void linphone_proxy_config_write_all_to_config_file(LinphoneCore *lc);
* */ * */
const LinphoneAddress* linphone_proxy_config_get_service_route(const LinphoneProxyConfig* cfg); const LinphoneAddress* linphone_proxy_config_get_service_route(const LinphoneProxyConfig* cfg);
int linphone_online_status_to_eXosip(LinphoneOnlineStatus os);
void linphone_friend_close_subscriptions(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_notify(LinphoneFriend *lf, LinphonePresenceModel *presence);
LinphoneFriend *linphone_find_friend_by_inc_subscribe(MSList *l, 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_find_friend_by_out_subscribe(MSList *l, SalOp *op);
MSList *linphone_find_friend_by_address(MSList *fl, const LinphoneAddress *addr, LinphoneFriend **lf); 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);
int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, socklen_t *socklen, int default_port); int parse_hostname_to_addr(const char *server, struct sockaddr_storage *ss, socklen_t *socklen, int default_port);
......
...@@ -1319,14 +1319,21 @@ void * linphone_proxy_config_get_user_data(LinphoneProxyConfig *cr) { ...@@ -1319,14 +1319,21 @@ void * linphone_proxy_config_get_user_data(LinphoneProxyConfig *cr) {
void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrationState state, const char *message){ void linphone_proxy_config_set_state(LinphoneProxyConfig *cfg, LinphoneRegistrationState state, const char *message){
LinphoneCore *lc=cfg->lc; LinphoneCore *lc=cfg->lc;
bool_t update_friends=FALSE;
if (linphone_core_should_subscribe_friends_only_when_registered(lc)){
update_friends=(state==LinphoneRegistrationOk && cfg->state!=LinphoneRegistrationOk)
|| (state!=LinphoneRegistrationOk && cfg->state==LinphoneRegistrationOk);
}
ms_message("Proxy config [%p] for identity [%s] moving from state [%s] to [%s]" , cfg, ms_message("Proxy config [%p] for identity [%s] moving from state [%s] to [%s]" , cfg,
linphone_proxy_config_get_identity(cfg), linphone_proxy_config_get_identity(cfg),
linphone_registration_state_to_string(cfg->state), linphone_registration_state_to_string(cfg->state),
linphone_registration_state_to_string(state)); linphone_registration_state_to_string(state));
if (cfg->state!=state || state==LinphoneRegistrationOk) { /*allow multiple notification of LinphoneRegistrationOk for refreshing*/ if (cfg->state!=state || state==LinphoneRegistrationOk) { /*allow multiple notification of LinphoneRegistrationOk for refreshing*/
cfg->state=state; cfg->state=state;
if (update_friends){
linphone_core_update_friends_subscriptions(lc,cfg,TRUE);
}
if (lc && lc->vtable.registration_state_changed){ if (lc && lc->vtable.registration_state_changed){
lc->vtable.registration_state_changed(lc,cfg,state,message); lc->vtable.registration_state_changed(lc,cfg,state,message);
} }
......
...@@ -567,6 +567,7 @@ void sal_op_set_from_address(SalOp *op, const SalAddress *from); ...@@ -567,6 +567,7 @@ void sal_op_set_from_address(SalOp *op, const SalAddress *from);
void sal_op_set_to(SalOp *op, const char *to); void sal_op_set_to(SalOp *op, const char *to);
void sal_op_set_to_address(SalOp *op, const SalAddress *to); void sal_op_set_to_address(SalOp *op, const SalAddress *to);
SalOp *sal_op_ref(SalOp* h); SalOp *sal_op_ref(SalOp* h);
void sal_op_stop_refreshing(SalOp *op);
void sal_op_release(SalOp *h); void sal_op_release(SalOp *h);
void sal_op_authenticate(SalOp *h, const SalAuthInfo *info); void sal_op_authenticate(SalOp *h, const SalAuthInfo *info);
void sal_op_cancel_authentication(SalOp *h); void sal_op_cancel_authentication(SalOp *h);
......
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