From 2d27c6a42c01019e542aef023000901384388574 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Thu, 4 Jun 2009 22:16:47 +0000 Subject: 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 --- pjsip/src/pjsip-ua/sip_xfer.c | 10 ++++++++-- pjsip/src/pjsua-lib/pjsua_call.c | 32 +++++++++++++++++++++++++++++++- 2 files changed, 39 insertions(+), 3 deletions(-) (limited to 'pjsip') 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 #include +/* 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); -- cgit v1.2.3