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: https://svn.pjsip.org/repos/pjproject/trunk@2750 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip/src/pjsua-lib/pjsua_call.c b/pjsip/src/pjsua-lib/pjsua_call.c
index 6e9a939..bb1ab31 100644
--- a/pjsip/src/pjsua-lib/pjsua_call.c
+++ b/pjsip/src/pjsua-lib/pjsua_call.c
@@ -2901,9 +2901,16 @@
 	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 @@
 	    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 @@
 	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 @@
 	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);