Fixed #1095 (New option to control the Route headers in REGISTER request). Details:
 - added new account config setting: reg_use_proxy. This contains bitmask values to indicate whether outbound proxies and account proxies are to be added in the REGISTER request. Default value is to add both.
 - added new pjsua cmdline option to control this: --reg-use-proxy
 - miscellaneous minor fixes in other pjsua cmdline arguments


git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@3216 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip/include/pjsua-lib/pjsua.h b/pjsip/include/pjsua-lib/pjsua.h
index 2826c9f..36a1148 100644
--- a/pjsip/include/pjsua-lib/pjsua.h
+++ b/pjsip/include/pjsua-lib/pjsua.h
@@ -1924,6 +1924,20 @@
 
 
 /**
+ * Bit value used in pjsua_acc_config.reg_use_proxy field to indicate that
+ * the global outbound proxy list should be added to the REGISTER request.
+ */
+#define PJSUA_REG_USE_OUTBOUND_PROXY		1
+
+
+/**
+ * Bit value used in pjsua_acc_config.reg_use_proxy field to indicate that
+ * the account proxy list should be added to the REGISTER request.
+ */
+#define PJSUA_REG_USE_ACC_PROXY			2
+
+
+/**
  * 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().
@@ -2224,6 +2238,18 @@
      */
     pj_bool_t	     drop_calls_on_reg_fail;
 
+    /**
+     * Specify how the registration uses the outbound and account proxy
+     * settings. This controls if and what Route headers will appear in
+     * the REGISTER request of this account. The value is bitmask combination
+     * of PJSUA_REG_USE_OUTBOUND_PROXY and PJSUA_REG_USE_ACC_PROXY bits.
+     * If the value is set to 0, the REGISTER request will not use any proxy
+     * (i.e. it will not have any Route headers).
+     *
+     * Default: 3 (PJSUA_REG_USE_OUTBOUND_PROXY | PJSUA_REG_USE_ACC_PROXY)
+     */
+    unsigned	     reg_use_proxy;
+
 } pjsua_acc_config;
 
 
diff --git a/pjsip/include/pjsua-lib/pjsua_internal.h b/pjsip/include/pjsua-lib/pjsua_internal.h
index f20b73d..f9146fb 100644
--- a/pjsip/include/pjsua-lib/pjsua_internal.h
+++ b/pjsip/include/pjsua-lib/pjsua_internal.h
@@ -285,6 +285,9 @@
     pj_status_t		 nat_status;	/**< Detection status.		*/
     pj_bool_t		 nat_in_progress; /**< Detection in progress	*/
 
+    /* List of outbound proxies: */
+    pjsip_route_hdr	 outbound_proxy;
+
     /* Account: */
     unsigned		 acc_cnt;	     /**< Number of accounts.	*/
     pjsua_acc_id	 default_acc;	     /**< Default account ID	*/
diff --git a/pjsip/src/pjsua-lib/pjsua_acc.c b/pjsip/src/pjsua-lib/pjsua_acc.c
index 925c71a..9bd3020 100644
--- a/pjsip/src/pjsua-lib/pjsua_acc.c
+++ b/pjsip/src/pjsua-lib/pjsua_acc.c
@@ -199,21 +199,15 @@
      */
     pj_list_init(&acc->route_set);
 
-    for (i=0; i<pjsua_var.ua_cfg.outbound_proxy_cnt; ++i) {
-    	pj_str_t hname = { "Route", 5};
+    if (!pj_list_empty(&pjsua_var.outbound_proxy)) {
 	pjsip_route_hdr *r;
-	pj_str_t tmp;
 
-	pj_strdup_with_null(acc->pool, &tmp, 
-			    &pjsua_var.ua_cfg.outbound_proxy[i]);
-	r = (pjsip_route_hdr*)
-	    pjsip_parse_hdr(acc->pool, &hname, tmp.ptr, tmp.slen, NULL);
-	if (r == NULL) {
-	    pjsua_perror(THIS_FILE, "Invalid outbound proxy URI",
-			 PJSIP_EINVALIDURI);
-	    return PJSIP_EINVALIDURI;
+	r = pjsua_var.outbound_proxy.next;
+	while (r != &pjsua_var.outbound_proxy) {
+	    pj_list_push_back(&acc->route_set,
+			      pjsip_hdr_shallow_clone(acc->pool, r));
+	    r = r->next;
 	}
-	pj_list_push_back(&acc->route_set, r);
     }
 
     for (i=0; i<acc_cfg->proxy_cnt; ++i) {
@@ -602,24 +596,14 @@
 				      pjsua_var.ua_cfg.outbound_proxy_cnt);
     if (global_route_crc != acc->global_route_crc) {
 	pjsip_route_hdr *r;
-	unsigned i;
 
-	/* Validate the global route and save it to temporary var */
+	/* Copy from global outbound proxies */
 	pj_list_init(&global_route);
-	for (i=0; i < pjsua_var.ua_cfg.outbound_proxy_cnt; ++i) {
-    	    pj_str_t hname = { "Route", 5};
-	    pj_str_t tmp;
-
-	    pj_strdup_with_null(acc->pool, &tmp, 
-				&pjsua_var.ua_cfg.outbound_proxy[i]);
-	    r = (pjsip_route_hdr*)
-		pjsip_parse_hdr(acc->pool, &hname, tmp.ptr, tmp.slen, NULL);
-	    if (r == NULL) {
-		status = PJSIP_EINVALIDURI;
-		pjsua_perror(THIS_FILE, "Invalid outbound proxy URI", status);
-		goto on_return;
-	    }
-	    pj_list_push_back(&global_route, r);
+	r = pjsua_var.outbound_proxy.next;
+	while (r != &pjsua_var.outbound_proxy) {
+	    pj_list_push_back(&global_route,
+		              pjsip_hdr_shallow_clone(acc->pool, r));
+	    r = r->next;
 	}
     }
 
@@ -1610,8 +1594,36 @@
 
     /* Set route-set
      */
-    if (!pj_list_empty(&acc->route_set)) {
-	pjsip_regc_set_route_set( acc->regc, &acc->route_set );
+    if (acc->cfg.reg_use_proxy) {
+	pjsip_route_hdr route_set;
+	const pjsip_route_hdr *r;
+
+	pj_list_init(&route_set);
+
+	if (acc->cfg.reg_use_proxy & PJSUA_REG_USE_OUTBOUND_PROXY) {
+	    r = pjsua_var.outbound_proxy.next;
+	    while (r != &pjsua_var.outbound_proxy) {
+		pj_list_push_back(&route_set, pjsip_hdr_shallow_clone(pool, r));
+		r = r->next;
+	    }
+	}
+
+	if (acc->cfg.reg_use_proxy & PJSUA_REG_USE_ACC_PROXY &&
+	    acc->cfg.proxy_cnt)
+	{
+	    int cnt = acc->cfg.proxy_cnt;
+	    pjsip_route_hdr *pos = route_set.prev;
+	    int i;
+
+	    r = acc->route_set.prev;
+	    for (i=0; i<cnt; ++i) {
+		pj_list_push_front(pos, pjsip_hdr_shallow_clone(pool, r));
+		r = r->prev;
+	    }
+	}
+
+	if (!pj_list_empty(&route_set))
+	    pjsip_regc_set_route_set( acc->regc, &route_set );
     }
 
     /* Add other request headers. */
diff --git a/pjsip/src/pjsua-lib/pjsua_core.c b/pjsip/src/pjsua-lib/pjsua_core.c
index 888b3db..3d13f2e 100644
--- a/pjsip/src/pjsua-lib/pjsua_core.c
+++ b/pjsip/src/pjsua-lib/pjsua_core.c
@@ -64,6 +64,7 @@
     pjsua_var.stun_status = PJ_EUNKNOWN;
     pjsua_var.nat_status = PJ_EPENDING;
     pj_list_init(&pjsua_var.stun_res);
+    pj_list_init(&pjsua_var.outbound_proxy);
 
     pjsua_config_default(&pjsua_var.ua_cfg);
 }
@@ -179,6 +180,8 @@
 #endif
     cfg->reg_retry_interval = PJSUA_REG_RETRY_INTERVAL;
     cfg->contact_rewrite_method = PJSUA_CONTACT_REWRITE_METHOD;
+    cfg->reg_use_proxy = PJSUA_REG_USE_OUTBOUND_PROXY |
+			 PJSUA_REG_USE_ACC_PROXY;
 }
 
 PJ_DEF(void) pjsua_buddy_config_default(pjsua_buddy_config *cfg)
@@ -665,6 +668,7 @@
     pjsua_media_config	 default_media_cfg;
     const pj_str_t	 STR_OPTIONS = { "OPTIONS", 7 };
     pjsip_ua_init_param  ua_init_param;
+    unsigned i;
     pj_status_t status;
 
 
@@ -783,6 +787,36 @@
 	PJ_ASSERT_RETURN(status == PJ_SUCCESS, status);
     }
 
+    /* Parse outbound proxies */
+    for (i=0; i<ua_cfg->outbound_proxy_cnt; ++i) {
+	pj_str_t tmp;
+    	pj_str_t hname = { "Route", 5};
+	pjsip_route_hdr *r;
+
+	pj_strdup_with_null(pjsua_var.pool, &tmp, &ua_cfg->outbound_proxy[i]);
+
+	r = (pjsip_route_hdr*)
+	    pjsip_parse_hdr(pjsua_var.pool, &hname, tmp.ptr,
+			    (unsigned)tmp.slen, NULL);
+	if (r == NULL) {
+	    pjsua_perror(THIS_FILE, "Invalid outbound proxy URI",
+			 PJSIP_EINVALIDURI);
+	    return PJSIP_EINVALIDURI;
+	}
+
+	if (pjsua_var.ua_cfg.force_lr) {
+	    pjsip_sip_uri *sip_url;
+	    if (!PJSIP_URI_SCHEME_IS_SIP(r->name_addr.uri) &&
+		!PJSIP_URI_SCHEME_IS_SIP(r->name_addr.uri))
+	    {
+		return PJSIP_EINVALIDSCHEME;
+	    }
+	    sip_url = (pjsip_sip_uri*)r->name_addr.uri;
+	    sip_url->lr_param = 1;
+	}
+
+	pj_list_push_back(&pjsua_var.outbound_proxy, r);
+    }
     
 
     /* Initialize PJSUA call subsystem: */