summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenny Prijono <bennylp@teluu.com>2009-06-04 22:16:47 +0000
committerBenny Prijono <bennylp@teluu.com>2009-06-04 22:16:47 +0000
commit2d27c6a42c01019e542aef023000901384388574 (patch)
treea322c6c13b467d3d5e0ac6a9b21e6593c17b35a1
parent7aa5e9c1f82139cb7065c95c7c2595bc511589c6 (diff)
Ticket #860:
- will send SUBSCRIBE to refresh REFER subscription (not REFER!), only when required (such as when call transfer is running for longer than REFER subscription expiration, hence need to be refreshed) - replaced hardcoded REFER subscription duration (600s) with a macro, {{{PJSIP_XFER_EXPIRES}}}. - when NOTIFY with "200 OK" sipfrag body is received and subscription state is not terminated, send SUBSCRIBE with Expires=0 to terminate the REFER subscription - for transferee, terminate the subscription in CONNECTING state and not in CONFIRMED state. Terminating the subscription in CONFIRMED state causes redundant NOTIFYs with "200 OK" sipfrag body to be sent, one with active subscription and another with terminated state. git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@2750 74dad513-b988-da41-8d7b-12977e46ad98
-rw-r--r--pjsip/src/pjsip-ua/sip_xfer.c10
-rw-r--r--pjsip/src/pjsua-lib/pjsua_call.c32
2 files changed, 39 insertions, 3 deletions
diff --git a/pjsip/src/pjsip-ua/sip_xfer.c b/pjsip/src/pjsip-ua/sip_xfer.c
index 30351425..eb932655 100644
--- a/pjsip/src/pjsip-ua/sip_xfer.c
+++ b/pjsip/src/pjsip-ua/sip_xfer.c
@@ -28,6 +28,11 @@
#include <pj/pool.h>
#include <pj/string.h>
+/* Subscription expiration */
+#ifndef PJSIP_XFER_EXPIRES
+# define PJSIP_XFER_EXPIRES 600
+#endif
+
/*
* Refer module (mod-refer)
@@ -154,7 +159,8 @@ PJ_DEF(pj_status_t) pjsip_xfer_init_module(pjsip_endpoint *endpt)
if (status != PJ_SUCCESS)
return status;
- status = pjsip_evsub_register_pkg( &mod_xfer, &STR_REFER, 300, 1, &accept);
+ status = pjsip_evsub_register_pkg(&mod_xfer, &STR_REFER,
+ PJSIP_XFER_EXPIRES, 1, &accept);
if (status != PJ_SUCCESS)
return status;
@@ -586,7 +592,7 @@ static void xfer_on_evsub_client_refresh(pjsip_evsub *sub)
pj_status_t status;
pjsip_tx_data *tdata;
- status = pjsip_xfer_initiate(sub, NULL, &tdata);
+ status = pjsip_evsub_initiate(sub, NULL, PJSIP_XFER_EXPIRES, &tdata);
if (status == PJ_SUCCESS)
pjsip_xfer_send_request(sub, tdata);
}
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index 6e9a9395..bb1ab318 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -2901,9 +2901,16 @@ static void pjsua_call_on_state_changed(pjsip_inv_session *inv,
case PJSIP_INV_STATE_EARLY:
case PJSIP_INV_STATE_CONNECTING:
st_code = e->body.tsx_state.tsx->status_code;
- ev_state = PJSIP_EVSUB_STATE_ACTIVE;
+ if (call->inv->state == PJSIP_INV_STATE_CONNECTING)
+ ev_state = PJSIP_EVSUB_STATE_TERMINATED;
+ else
+ ev_state = PJSIP_EVSUB_STATE_ACTIVE;
break;
+#if 0
+/* We don't need this, as we've terminated the subscription in
+ * CONNECTING state.
+ */
case PJSIP_INV_STATE_CONFIRMED:
/* When state is confirmed, send the final 200/OK and terminate
* subscription.
@@ -2911,6 +2918,7 @@ static void pjsua_call_on_state_changed(pjsip_inv_session *inv,
st_code = e->body.tsx_state.tsx->status_code;
ev_state = PJSIP_EVSUB_STATE_TERMINATED;
break;
+#endif
case PJSIP_INV_STATE_DISCONNECTED:
st_code = e->body.tsx_state.tsx->status_code;
@@ -3456,6 +3464,18 @@ static void xfer_client_on_evsub_state( pjsip_evsub *sub, pjsip_event *event)
if (!cont) {
pjsip_evsub_set_mod_data(sub, pjsua_var.mod.id, NULL);
}
+
+ /* If the call transfer has completed but the subscription is
+ * not terminated, terminate it now.
+ */
+ if (status_line.code/100 == 2 && !is_last) {
+ pjsip_tx_data *tdata;
+
+ status = pjsip_evsub_initiate(sub, &pjsip_subscribe_method,
+ 0, &tdata);
+ if (status == PJ_SUCCESS)
+ status = pjsip_evsub_send_request(sub, tdata);
+ }
}
}
@@ -3734,6 +3754,16 @@ static void pjsua_call_on_tsx_state_changed(pjsip_inv_session *inv,
return;
}
+ if (call->inv == NULL) {
+ /* Shouldn't happen. It happens only when we don't terminate the
+ * server subscription caused by REFER after the call has been
+ * transfered (and this call has been disconnected), and we
+ * receive another REFER for this call.
+ */
+ PJSUA_UNLOCK();
+ return;
+ }
+
/* Notify application callback first */
if (pjsua_var.ua_cfg.cb.on_call_tsx_state) {
(*pjsua_var.ua_cfg.cb.on_call_tsx_state)(call->index, tsx, e);