diff options
-rw-r--r-- | pjsip/include/pjsua-lib/pjsua.h | 29 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_core.c | 39 | ||||
-rw-r--r-- | pjsip/src/pjsua-lib/pjsua_pres.c | 5 |
3 files changed, 72 insertions, 1 deletions
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h index bb6558db..d6db65b9 100644 --- a/pjsip/include/pjsua-lib/pjsua.h +++ b/pjsip/include/pjsua-lib/pjsua.h @@ -1751,6 +1751,22 @@ PJ_DECL(pj_status_t) pjsua_transport_close( pjsua_transport_id id, /** + * Maximum time to wait for unpublication transaction(s) to complete + * during shutdown process, before sending unregistration. The library + * tries to wait for the unpublication (un-PUBLISH) to complete before + * sending REGISTER request to unregister the account, during library + * shutdown process. If the value is set too short, it is possible that + * the unregistration is sent before unpublication completes, causing + * unpublication request to fail. + * + * Default: 2000 (2 seconds) + */ +#ifndef PJSUA_UNPUBLISH_MAX_WAIT_TIME_MSEC +# define PJSUA_UNPUBLISH_MAX_WAIT_TIME_MSEC 2000 +#endif + + +/** * This structure describes account configuration to be specified when * adding a new account with #pjsua_acc_add(). Application MUST initialize * this structure first by calling #pjsua_acc_config_default(). @@ -1802,6 +1818,19 @@ typedef struct pjsua_acc_config pjsip_publishc_opt publish_opt; /** + * Maximum time to wait for unpublication transaction(s) to complete + * during shutdown process, before sending unregistration. The library + * tries to wait for the unpublication (un-PUBLISH) to complete before + * sending REGISTER request to unregister the account, during library + * shutdown process. If the value is set too short, it is possible that + * the unregistration is sent before unpublication completes, causing + * unpublication request to fail. + * + * Default: PJSUA_UNPUBLISH_MAX_WAIT_TIME_MSEC + */ + unsigned unpublish_max_wait_time_msec; + + /** * Authentication preference. */ pjsip_auth_clt_pref auth_pref; diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c index cc26bc87..39ad80d8 100644 --- a/pjsip/src/pjsua-lib/pjsua_core.c +++ b/pjsip/src/pjsua-lib/pjsua_core.c @@ -162,6 +162,7 @@ PJ_DEF(void) pjsua_acc_config_default(pjsua_acc_config *cfg) cfg->reg_timeout = PJSUA_REG_INTERVAL; pjsip_publishc_opt_default(&cfg->publish_opt); + cfg->unpublish_max_wait_time_msec = PJSUA_UNPUBLISH_MAX_WAIT_TIME_MSEC; cfg->transport_id = PJSUA_INVALID_ID; cfg->allow_contact_rewrite = PJ_TRUE; cfg->require_100rel = pjsua_var.ua_cfg.require_100rel; @@ -1228,6 +1229,8 @@ PJ_DEF(pj_status_t) pjsua_destroy(void) } if (pjsua_var.endpt) { + unsigned max_wait; + /* Terminate all calls. */ pjsua_call_hangup_all(); @@ -1242,6 +1245,42 @@ PJ_DEF(pj_status_t) pjsua_destroy(void) /* Terminate all presence subscriptions. */ pjsua_pres_shutdown(); + /* Wait for sometime until all publish client sessions are done + * (ticket #364) + */ + /* First stage, get the maximum wait time */ + max_wait = 100; + for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) { + if (!pjsua_var.acc[i].valid) + continue; + if (pjsua_var.acc[i].cfg.unpublish_max_wait_time_msec > max_wait) + max_wait = pjsua_var.acc[i].cfg.unpublish_max_wait_time_msec; + } + + /* Second stage, wait for unpublications to complete */ + for (i=0; i<(int)(max_wait/50); ++i) { + unsigned j; + for (j=0; j<PJ_ARRAY_SIZE(pjsua_var.acc); ++j) { + if (!pjsua_var.acc[j].valid) + continue; + + if (pjsua_var.acc[j].publish_sess) + break; + } + if (j != PJ_ARRAY_SIZE(pjsua_var.acc)) + busy_sleep(50); + else + break; + } + + /* Third stage, forcefully destroy unfinished unpublications */ + for (i=0; i<PJ_ARRAY_SIZE(pjsua_var.acc); ++i) { + if (pjsua_var.acc[i].publish_sess) { + pjsip_publishc_destroy(pjsua_var.acc[i].publish_sess); + pjsua_var.acc[i].publish_sess = NULL; + } + } + /* Unregister all accounts */ for (i=0; i<(int)PJ_ARRAY_SIZE(pjsua_var.acc); ++i) { if (!pjsua_var.acc[i].valid) diff --git a/pjsip/src/pjsua-lib/pjsua_pres.c b/pjsip/src/pjsua-lib/pjsua_pres.c index bef8af92..4515636c 100644 --- a/pjsip/src/pjsua-lib/pjsua_pres.c +++ b/pjsip/src/pjsua-lib/pjsua_pres.c @@ -992,7 +992,7 @@ static void publish_cb(struct pjsip_publishc_cbparam *param) } } else { - if (param->expiration == -1) { + if (param->expiration < 1) { /* Could happen if server "forgot" to include Expires header * in the response. We will not renew, so destroy the pubc. */ @@ -1201,10 +1201,13 @@ void pjsua_pres_delete_acc(int acc_id) if (acc->publish_sess) { acc->online_status = PJ_FALSE; send_publish(acc_id, PJ_FALSE); + /* By ticket #364, don't destroy the session yet (let the callback + destroy it) if (acc->publish_sess) { pjsip_publishc_destroy(acc->publish_sess); acc->publish_sess = NULL; } + */ acc_cfg->publish_enabled = PJ_FALSE; } } |