summaryrefslogtreecommitdiff
path: root/pjsip
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-10-13 14:01:59 +0000
committerBenny Prijono <bennylp@teluu.com>2009-10-13 14:01:59 +0000
commitb2aac52d83d6e4fb46e2bef723647fa2bb1ad8be (patch)
treeeabfe4b6c36338b5adb89dff298481f6fcbe85eb /pjsip
parent745a13dbbff423464a61dbc9311aba416c245754 (diff)
Ticket #364: Upon unregistration, (un)REGISTER should be sent only after (un)PUBLISH has completed successfully
- wait for unpublication to complete or some delay expires, before sending unregistration - added unpublish_max_wait_time_msec field in account config to control how long to wait git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2942 74dad513-b988-da41-8d7b-12977e46ad98
Diffstat (limited to 'pjsip')
-rw-r--r--pjsip/include/pjsua-lib/pjsua.h29
-rw-r--r--pjsip/src/pjsua-lib/pjsua_core.c39
-rw-r--r--pjsip/src/pjsua-lib/pjsua_pres.c5
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;
}
}