Integration of Sipit24 branch, many tickets involved:
 - #793: AMR encoder should regard 'mode-set' param specified by remote decoder.
 - #831: Automatically switch to TCP transport when sending large request
 - #832: Support for outbound proxy setting without using Route header
 - #849: Modify conference audio switch behavior in connecting ports.
 - #850: Remove 'Require=replaces' param in 'Refer-To' header (in call transfer with replaces).
 - #851: Support for regular nomination in ICE
 - #852: --ip-addr support for IPv6 for media transport in pjsua
 - #854: Adding SOFTWARE attribute in all outgoing requests may cause compatibility problem with older STUN server (thanks Alexei Kuznetsov for the report)
 - #855: Bug in digit map frequencies for DTMF digits (thanks FCCH for the report)
 - #856: Put back the ICE candidate priority values according to the default values in the draft-mmusic-ice
 - #857: Support for ICE keep-alive with Binding indication
 - #858: Do not authenticate STUN 438 response
 - #859: AMR-WB format param in the SDP is not negotiated correctly.
 - #867: Return error instead of asserting when PJSUA-LIB fails to open log file




git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@2724 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip-apps/src/pjsua/pjsua_app.c b/pjsip-apps/src/pjsua/pjsua_app.c
index dd81f9e..8be930f 100644
--- a/pjsip-apps/src/pjsua/pjsua_app.c
+++ b/pjsip-apps/src/pjsua/pjsua_app.c
@@ -264,7 +264,8 @@
     puts  ("");
     puts  ("Media Transport Options:");
     puts  ("  --use-ice           Enable ICE (default:no)");
-    puts  ("  --ice-no-host       Disable ICE host candidates (default: no)");
+    puts  ("  --ice-regular       Use ICE regular nomination (default: aggressive)");
+    puts  ("  --ice-max-hosts=N   Set maximum number of ICE host candidates");
     puts  ("  --ice-no-rtcp       Disable RTCP component in ICE (default: no)");
     puts  ("  --rtp-port=N        Base port to try for RTP (default=4000)");
     puts  ("  --rx-drop-pct=PCT   Drop PCT percent of RX RTP (for pkt lost sim, default: 0)");
@@ -476,8 +477,8 @@
 	   OPT_ADD_BUDDY, OPT_OFFER_X_MS_MSG, OPT_NO_PRESENCE,
 	   OPT_AUTO_ANSWER, OPT_AUTO_PLAY, OPT_AUTO_PLAY_HANGUP, OPT_AUTO_LOOP,
 	   OPT_AUTO_CONF, OPT_CLOCK_RATE, OPT_SND_CLOCK_RATE, OPT_STEREO,
-	   OPT_USE_ICE, OPT_USE_SRTP, OPT_SRTP_SECURE,
-	   OPT_USE_TURN, OPT_ICE_NO_HOST, OPT_ICE_NO_RTCP, OPT_TURN_SRV, 
+	   OPT_USE_ICE, OPT_ICE_REGULAR, OPT_USE_SRTP, OPT_SRTP_SECURE,
+	   OPT_USE_TURN, OPT_ICE_MAX_HOSTS, OPT_ICE_NO_RTCP, OPT_TURN_SRV, 
 	   OPT_TURN_TCP, OPT_TURN_USER, OPT_TURN_PASSWD,
 	   OPT_PLAY_FILE, OPT_PLAY_TONE, OPT_RTP_PORT, OPT_ADD_CODEC, 
 	   OPT_ILBC_MODE, OPT_REC_FILE, OPT_AUTO_REC,
@@ -553,8 +554,9 @@
 	{ "rtp-port",	1, 0, OPT_RTP_PORT},
 
 	{ "use-ice",    0, 0, OPT_USE_ICE},
+	{ "ice-regular",0, 0, OPT_ICE_REGULAR},
 	{ "use-turn",	0, 0, OPT_USE_TURN},
-	{ "ice-no-host",0, 0, OPT_ICE_NO_HOST},
+	{ "ice-max-hosts",1, 0, OPT_ICE_MAX_HOSTS},
 	{ "ice-no-rtcp",0, 0, OPT_ICE_NO_RTCP},
 	{ "turn-srv",	1, 0, OPT_TURN_SRV},
 	{ "turn-tcp",	0, 0, OPT_TURN_TCP},
@@ -992,12 +994,16 @@
 	    cfg->media_cfg.enable_ice = PJ_TRUE;
 	    break;
 
+	case OPT_ICE_REGULAR:
+	    cfg->media_cfg.ice_opt.aggressive = PJ_FALSE;
+	    break;
+
 	case OPT_USE_TURN:
 	    cfg->media_cfg.enable_turn = PJ_TRUE;
 	    break;
 
-	case OPT_ICE_NO_HOST:
-	    cfg->media_cfg.ice_no_host_cands = PJ_TRUE;
+	case OPT_ICE_MAX_HOSTS:
+	    cfg->media_cfg.ice_max_host_cands = my_atoi(pj_optarg);
 	    break;
 
 	case OPT_ICE_NO_RTCP:
@@ -1644,11 +1650,17 @@
     if (config->media_cfg.enable_ice)
 	pj_strcat2(&cfg, "--use-ice\n");
 
+    if (config->media_cfg.ice_opt.aggressive == PJ_FALSE)
+	pj_strcat2(&cfg, "--ice-regular\n");
+
     if (config->media_cfg.enable_turn)
 	pj_strcat2(&cfg, "--use-turn\n");
 
-    if (config->media_cfg.ice_no_host_cands)
-	pj_strcat2(&cfg, "--ice-no-host\n");
+    if (config->media_cfg.ice_max_host_cands >= 0) {
+	pj_ansi_sprintf(line, "--ice_max_host_cands %d\n",
+			config->media_cfg.ice_max_host_cands);
+	pj_strcat2(&cfg, line);
+    }
 
     if (config->media_cfg.ice_no_rtcp)
 	pj_strcat2(&cfg, "--ice-no-rtcp\n");
@@ -1885,7 +1897,7 @@
 	pj_strcat2(&cfg, "--use-compact-form\n");
     }
 
-    if (config->cfg.force_lr) {
+    if (!config->cfg.force_lr) {
 	pj_strcat2(&cfg, "--no-force-lr\n");
     }
 
@@ -3687,7 +3699,9 @@
 		    pj_list_push_back(&msg_data.hdr_list, &refer_sub);
 		}
 
-		pjsua_call_xfer_replaces(call, dst_call, 0, &msg_data);
+		pjsua_call_xfer_replaces(call, dst_call, 
+					 PJSUA_XFER_NO_REQUIRE_REPLACES, 
+					 &msg_data);
 	    }
 	    break;
 
@@ -4718,19 +4732,62 @@
 
     for (i=0; i<app_config.cfg.max_calls; ++i) {
 	enum { MAX_RETRY = 10 };
+	pj_sock_t sock[2];
+	pjmedia_sock_info si;
 	unsigned j;
 
 	/* Get rid of uninitialized var compiler warning with MSVC */
 	status = PJ_SUCCESS;
 
 	for (j=0; j<MAX_RETRY; ++j) {
-	    status = pjmedia_transport_udp_create3(pjsua_get_pjmedia_endpt(), 
-						   pj_AF_INET6(),
-						   NULL, 
-						   &app_config.rtp_cfg.bound_addr,
-						   port, 
-						   0, &tp[i].transport);
+	    unsigned k;
 
+	    for (k=0; k<2; ++k) {
+		pj_sockaddr bound_addr;
+
+		status = pj_sock_socket(pj_AF_INET6(), pj_SOCK_DGRAM(), 0, &sock[k]);
+		if (status != PJ_SUCCESS)
+		    break;
+
+		status = pj_sockaddr_init(pj_AF_INET6(), &bound_addr,
+					  &app_config.rtp_cfg.bound_addr, 
+					  (unsigned short)(port+k));
+		if (status != PJ_SUCCESS)
+		    break;
+
+		status = pj_sock_bind(sock[k], &bound_addr, 
+				      pj_sockaddr_get_len(&bound_addr));
+		if (status != PJ_SUCCESS)
+		    break;
+	    }
+	    if (status != PJ_SUCCESS) {
+		if (k==1)
+		    pj_sock_close(sock[0]);
+
+		if (port != 0)
+		    port += 10;
+		else
+		    break;
+
+		continue;
+	    }
+
+	    pj_bzero(&si, sizeof(si));
+	    si.rtp_sock = sock[0];
+	    si.rtcp_sock = sock[1];
+	
+	    pj_sockaddr_init(pj_AF_INET6(), &si.rtp_addr_name, 
+			     &app_config.rtp_cfg.public_addr, 
+			     (unsigned short)(port));
+	    pj_sockaddr_init(pj_AF_INET6(), &si.rtcp_addr_name, 
+			     &app_config.rtp_cfg.public_addr, 
+			     (unsigned short)(port+1));
+
+	    status = pjmedia_transport_udp_attach(pjsua_get_pjmedia_endpt(),
+						  NULL,
+						  &si,
+						  0,
+						  &tp[i].transport);
 	    if (port != 0)
 		port += 10;
 	    else
diff --git a/pjsip-apps/src/samples/debug.c b/pjsip-apps/src/samples/debug.c
index 1a145b9..5417a79 100644
--- a/pjsip-apps/src/samples/debug.c
+++ b/pjsip-apps/src/samples/debug.c
@@ -28,5 +28,5 @@
  * E.g.:
  *  #include "playfile.c"
  */
-#include "auddemo.c"
+#include "icedemo.c"
 
diff --git a/pjsip-apps/src/samples/icedemo.c b/pjsip-apps/src/samples/icedemo.c
index 1c13cf3..f3f7c6c 100644
--- a/pjsip-apps/src/samples/icedemo.c
+++ b/pjsip-apps/src/samples/icedemo.c
@@ -39,7 +39,8 @@
     {
 	unsigned    comp_cnt;
 	pj_str_t    ns;
-	pj_bool_t   no_host;
+	int	    max_host;
+	pj_bool_t   regular;
 	pj_str_t    stun_srv;
 	pj_str_t    turn_srv;
 	pj_bool_t   turn_tcp;
@@ -306,8 +307,15 @@
 
     /* -= Start initializing ICE stream transport config =- */
 
-    /* Disable host candidates? */
-    icedemo.ice_cfg.stun.no_host_cands = icedemo.opt.no_host;
+    /* Maximum number of host candidates */
+    if (icedemo.opt.max_host != -1)
+	icedemo.ice_cfg.stun.max_host_cands = icedemo.opt.max_host;
+
+    /* Nomination strategy */
+    if (icedemo.opt.regular)
+	icedemo.ice_cfg.opt.aggressive = PJ_FALSE;
+    else
+	icedemo.ice_cfg.opt.aggressive = PJ_TRUE;
 
     /* Configure STUN/srflx candidate resolution */
     if (icedemo.opt.stun_srv.slen) {
@@ -960,7 +968,7 @@
     }
     */
 
-    if (comp_id > pj_ice_strans_get_running_comp_cnt(icedemo.icest)) {
+    if (comp_id<1||comp_id>pj_ice_strans_get_running_comp_cnt(icedemo.icest)) {
 	PJ_LOG(1,(THIS_FILE, "Error: invalid component ID"));
 	return;
     }
@@ -1137,7 +1145,8 @@
     puts(" --comp-cnt, -c N          Component count (default=1)");
     puts(" --nameserver, -n IP       Configure nameserver to activate DNS SRV");
     puts("                           resolution");
-    puts(" --no-host, -H             Disable host candidates");
+    puts(" --max-host, -H N          Set max number of host candidates to N");
+    puts(" --regular, -R             Use regular nomination (default aggressive)");
     puts(" --help, -h                Display this screen.");
     puts("");
     puts("STUN related options:");
@@ -1165,21 +1174,23 @@
     struct pj_getopt_option long_options[] = {
 	{ "comp-cnt",           1, 0, 'c'},
 	{ "nameserver",		1, 0, 'n'},
-	{ "no-host",		0, 0, 'H'},
+	{ "max-host",		1, 0, 'H'},
 	{ "help",		0, 0, 'h'},
 	{ "stun-srv",		1, 0, 's'},
 	{ "turn-srv",		1, 0, 't'},
 	{ "turn-tcp",		0, 0, 'T'},
 	{ "turn-username",	1, 0, 'u'},
 	{ "turn-password",	1, 0, 'p'},
-	{ "turn-fingerprint",	0, 0, 'F'}
+	{ "turn-fingerprint",	0, 0, 'F'},
+	{ "regular",		0, 0, 'R'}
     };
     int c, opt_id;
     pj_status_t status;
 
     icedemo.opt.comp_cnt = 1;
+    icedemo.opt.max_host = -1;
 
-    while((c=pj_getopt_long(argc,argv, "n:s:t:u:p:HhTF", long_options, &opt_id))!=-1) {
+    while((c=pj_getopt_long(argc,argv, "c:n:s:t:u:p:H:hTFR", long_options, &opt_id))!=-1) {
 	switch (c) {
 	case 'c':
 	    icedemo.opt.comp_cnt = atoi(pj_optarg);
@@ -1192,7 +1203,7 @@
 	    icedemo.opt.ns = pj_str(pj_optarg);
 	    break;
 	case 'H':
-	    icedemo.opt.no_host = PJ_TRUE;
+	    icedemo.opt.max_host = atoi(pj_optarg);
 	    break;
 	case 'h':
 	    icedemo_usage();
@@ -1215,6 +1226,9 @@
 	case 'F':
 	    icedemo.opt.turn_fingerprint = PJ_TRUE;
 	    break;
+	case 'R':
+	    icedemo.opt.regular = PJ_TRUE;
+	    break;
 	default:
 	    printf("Argument \"%s\" is not valid. Use -h to see help",
 		   argv[pj_optind]);
diff --git a/pjsip-apps/src/samples/siprtp_report.c b/pjsip-apps/src/samples/siprtp_report.c
index e63ef94..84c0072 100644
--- a/pjsip-apps/src/samples/siprtp_report.c
+++ b/pjsip-apps/src/samples/siprtp_report.c
@@ -77,7 +77,7 @@
 
     /* Call identification */
     len = pjsip_hdr_print_on(dlg->remote.info, userinfo, sizeof(userinfo));
-    if (len < 1)
+    if (len < 0)
 	pj_ansi_strcpy(userinfo, "<--uri too long-->");
     else
 	userinfo[len] = '\0';