Commit 0b2d04d6 authored by Simon Morlat's avatar Simon Morlat
Browse files

many improvements

* re-send SUBSCRIBEs after network gets reachable again
* allow to set the default SUBSCRIBE expires using [sip] "subscribe_expires" property
* re-send initial SUBSCRIBE if remote peer lost the dialog context
parent 83268b31
......@@ -56,6 +56,20 @@ static void presence_process_dialog_terminated(void *ctx, const belle_sip_dialog
}
}
static void presence_refresher_listener( const belle_sip_refresher_t* refresher, void* user_pointer, unsigned int status_code, const char* reason_phrase){
SalOp* op = (SalOp*)user_pointer;
switch(status_code){
case 481:
ms_message("The server or remote ua lost the SUBSCRIBE dialog context. Let's restart a new one.");
belle_sip_refresher_stop(op->refresher);
belle_sip_object_unref(op->refresher);
op->refresher=NULL;
sal_subscribe_presence(op,NULL,NULL,-1);
break;
}
}
static void presence_response_event(void *op_base, const belle_sip_response_event_t *event){
SalOp* op = (SalOp*)op_base;
belle_sip_dialog_state_t dialog_state;
......@@ -96,6 +110,7 @@ static void presence_response_event(void *op_base, const belle_sip_response_even
}
if (expires>0){
op->refresher=belle_sip_client_transaction_create_refresher(client_transaction);
belle_sip_refresher_set_listener(op->refresher,presence_refresher_listener,op);
}
}
break;
......@@ -246,7 +261,7 @@ void sal_op_presence_fill_cbs(SalOp*op) {
/*presence Subscribe/notify*/
int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
int sal_subscribe_presence(SalOp *op, const char *from, const char *to, int expires){
belle_sip_request_t *req=NULL;
if (from)
sal_op_set_from(op,from);
......@@ -255,10 +270,16 @@ int sal_subscribe_presence(SalOp *op, const char *from, const char *to){
sal_op_presence_fill_cbs(op);
/*???sal_exosip_fix_route(op); make sure to ha ;lr*/
if (expires==-1){
if (op->refresher){
expires=belle_sip_refresher_get_expires(op->refresher);
}else{
ms_error("sal_subscribe_presence(): cannot guess expires from previous refresher.");
}
}
req=sal_op_build_request(op,"SUBSCRIBE");
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Event","presence"));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(600)));
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(belle_sip_header_expires_create(expires)));
return sal_op_send_request(op,req);
}
......
......@@ -111,6 +111,7 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
char *friend=NULL;
const char *from=NULL;
LinphoneProxyConfig *cfg;
LinphoneCore *lc=fr->lc;
friend=linphone_address_as_string(fr->uri);
cfg=linphone_core_lookup_known_proxy(fr->lc,linphone_friend_get_address(fr));
......@@ -129,9 +130,9 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
sal_op_release(fr->outsub);
fr->outsub=NULL;
}
fr->outsub=sal_op_new(fr->lc->sal);
linphone_configure_op(fr->lc,fr->outsub,fr->uri,NULL,TRUE);
sal_subscribe_presence(fr->outsub,from,friend);
fr->outsub=sal_op_new(lc->sal);
linphone_configure_op(lc,fr->outsub,fr->uri,NULL,TRUE);
sal_subscribe_presence(fr->outsub,from,friend,lp_config_get_int(lc->config,"sip","subscribe_expires",600));
fr->subscribe_active=TRUE;
ms_free(friend);
}
......@@ -243,6 +244,14 @@ static void linphone_friend_unsubscribe(LinphoneFriend *lf){
}
}
static void linphone_friend_invalidate_subscription(LinphoneFriend *lf){
if (lf->outsub!=NULL) {
sal_op_release(lf->outsub);
lf->outsub=NULL;
lf->subscribe_active=FALSE;
}
}
void linphone_friend_close_subscriptions(LinphoneFriend *lf){
linphone_friend_unsubscribe(lf);
if (lf->insub){
......@@ -383,9 +392,7 @@ void linphone_friend_apply(LinphoneFriend *fr, LinphoneCore *lc){
break;
case LinphoneSPAccept:
if (fr->lc!=NULL)
{
linphone_friend_notify(fr,fr->lc->presence_model);
}
break;
case LinphoneSPDeny:
linphone_friend_notify(fr,NULL);
......@@ -440,12 +447,22 @@ void linphone_core_remove_friend(LinphoneCore *lc, LinphoneFriend* fl){
}
void linphone_core_send_initial_subscribes(LinphoneCore *lc){
const MSList *elem;
if (lc->initial_subscribes_sent) return;
for(elem=lc->friends;elem!=NULL;elem=elem->next){
LinphoneFriend *f=(LinphoneFriend*)elem->data;
linphone_friend_apply(f,lc);
}
lc->initial_subscribes_sent=TRUE;
}
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;
if (f->commit)
linphone_friend_apply(f,lc);
linphone_friend_invalidate_subscription(f);
}
lc->initial_subscribes_sent=FALSE;
}
void linphone_friend_set_ref_key(LinphoneFriend *lf, const char *key){
......
......@@ -2206,10 +2206,9 @@ void linphone_core_iterate(LinphoneCore *lc){
linphone_core_run_hooks(lc);
linphone_core_do_plugin_tasks(lc);
if (lc->initial_subscribes_sent==FALSE && lc->netup_time!=0 &&
(curtime-lc->netup_time)>3){
if (lc->network_reachable && lc->netup_time!=0 && (curtime-lc->netup_time)>3){
/*not do that immediately, take your time.*/
linphone_core_send_initial_subscribes(lc);
lc->initial_subscribes_sent=TRUE;
}
if (one_second_elapsed) {
......@@ -5581,13 +5580,15 @@ static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t cu
lc->netup_time=curtime;
lc->network_reachable=isReachable;
if (!lc->network_reachable) linphone_core_invalidate_friend_subscriptions(lc);
if(!isReachable) {
sal_reset_transports(lc->sal);
}
#ifdef BUILD_UPNP
if(lc->upnp == NULL) {
if(isReachable && lc->net_conf.firewall_policy == LinphonePolicyUseUpnp) {
lc->upnp = linphone_upnp_context_new(lc);
lc->upnp = linphone_upnp_context_new(lc);
}
} else {
if(!isReachable && lc->net_conf.firewall_policy == LinphonePolicyUseUpnp) {
......@@ -5595,7 +5596,7 @@ static void set_network_reachable(LinphoneCore* lc,bool_t isReachable, time_t cu
lc->upnp = NULL;
}
}
#endif
#endif
}
void linphone_core_refresh_registers(LinphoneCore* lc) {
......
......@@ -758,6 +758,8 @@ void linphone_event_set_reason(LinphoneEvent *lev, LinphoneReason reason);
LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatus ss);
const LinphoneContent *linphone_content_from_sal_body(LinphoneContent *obj, const SalBody *ref);
void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc);
#ifdef __cplusplus
}
#endif
......
......@@ -534,7 +534,7 @@ int sal_text_send(SalOp *op, const char *from, const char *to, const char *text)
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg);
/*presence Subscribe/notify*/
int sal_subscribe_presence(SalOp *op, const char *from, const char *to);
int sal_subscribe_presence(SalOp *op, const char *from, const char *to, int expires);
int sal_notify_presence(SalOp *op, SalPresenceModel *presence);
int sal_notify_presence_close(SalOp *op);
......
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