Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 3205)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 3206)
@@ -91,4 +91,10 @@
     char    last_text_buf_[128];    /**< Buffer for last_text.		    */
 
+    struct {
+	pj_timer_entry	 reinv_timer;/**< Reinvite retry timer.		    */
+	pjmedia_sdp_session *new_sdp;/**< The new SDP offer.		    */
+    } lock_codec;		     /**< Data for codec locking when answer
+					  contains multiple codecs.	    */
+
 } pjsua_call;
 
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 3205)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_call.c	(revision 3206)
@@ -23,4 +23,10 @@
 
 #define THIS_FILE		"pjsua_call.c"
+
+
+/* Retry interval of sending re-INVITE for locking a codec when remote
+ * SDP answer contains multiple codec, in milliseconds.
+ */
+#define LOCK_CODEC_RETRY_INTERVAL   200
 
 
@@ -1512,4 +1518,11 @@
 	pjsip_dlg_dec_lock(dlg);
 	return status;
+    }
+
+    /* Stop lock codec timer, if it is active */
+    if (call->lock_codec.reinv_timer.id) {
+	pjsip_endpt_cancel_timer(pjsua_var.endpt, 
+				 &call->lock_codec.reinv_timer);
+	call->lock_codec.reinv_timer.id = PJ_FALSE;
     }
 
@@ -2914,4 +2927,224 @@
 
 
+/* Timer callback to close sound device */
+static void reinv_timer_cb(pj_timer_heap_t *th,
+			   pj_timer_entry *entry)
+{
+    pjsua_call_id call_id = (pjsua_call_id)(pj_size_t)entry->user_data;
+    pjsip_dialog *dlg;
+    pjsua_call *call;
+    pjsip_tx_data *tdata;
+    pj_status_t status;
+
+    PJ_UNUSED_ARG(th);
+
+    pjsua_var.calls[call_id].lock_codec.reinv_timer.id = PJ_FALSE;
+
+    status = acquire_call("reinv_timer_cb()", call_id, &call, &dlg);
+    if (status != PJ_SUCCESS)
+	return;
+
+    /* Verify if another SDP negotiation is in progress, e.g: session timer
+     * or another re-INVITE.
+     */
+    if (call->inv==NULL || call->inv->neg==NULL ||
+	pjmedia_sdp_neg_get_state(call->inv->neg)!=PJMEDIA_SDP_NEG_STATE_DONE)
+    {
+	goto on_return;
+    }
+
+    /* Verify if another SDP negotiation has been completed by comparing
+     * the SDP version.
+     */
+    {
+	const pjmedia_sdp_session *sdp;
+
+	status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &sdp);
+	if (status == PJ_SUCCESS &&
+	    sdp->origin.version > call->lock_codec.new_sdp->origin.version)
+	{
+	    goto on_return;
+	}
+    }
+
+    /* Create re-INVITE with the new offer */
+    status = pjsip_inv_reinvite(call->inv, NULL, call->lock_codec.new_sdp,
+				&tdata);
+    if (status == PJ_EINVALIDOP) {
+	/* Ups, let's reschedule again */
+	pj_time_val delay = {0, LOCK_CODEC_RETRY_INTERVAL};
+	call->lock_codec.reinv_timer.id = PJ_TRUE;
+	pjsip_endpt_schedule_timer(pjsua_var.endpt, 
+				   &call->lock_codec.reinv_timer, &delay);
+    } else if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Failed creating re-INVITE in lock codec",
+		     status);
+    }
+
+    /* Send the UPDATE/re-INVITE request */
+    status = pjsip_inv_send_msg(call->inv, tdata);
+    if (status != PJ_SUCCESS) {
+	pjsua_perror(THIS_FILE, "Failed sending re-INVITE in lock codec",
+		     status);
+    }
+
+on_return:
+    pjsip_dlg_dec_lock(dlg);
+}
+
+
+/* Check if the specified format can be skipped in counting codecs */
+static pj_bool_t is_non_av_fmt(const pjmedia_sdp_media *m,
+				  const pj_str_t *fmt)
+{
+    unsigned pt;
+
+    pt = pj_strtoul(fmt);
+
+    /* Check for comfort noise */
+    if (pt == PJMEDIA_RTP_PT_CN)
+	return PJ_TRUE;
+
+    /* Dynamic PT, check the format name */
+    if (pt >= 96) {
+	pjmedia_sdp_attr *a;
+	pjmedia_sdp_rtpmap rtpmap;
+
+	/* Get the format name */
+	a = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "rtpmap", fmt);
+	if (a && pjmedia_sdp_attr_get_rtpmap(a, &rtpmap)==PJ_SUCCESS) {
+	    /* Check for telephone-event */
+	    if (pj_stricmp2(&rtpmap.enc_name, "telephone-event")==0)
+		return PJ_TRUE;
+	} else {
+	    /* Invalid SDP, should not reach here */
+	    pj_assert(!"SDP should have been validated!");
+	    return PJ_TRUE;
+	}
+    }
+
+    return PJ_FALSE;
+}
+
+
+/* Check if remote answerer has given us more than one codecs. If so,
+ * create another offer with one codec only to lock down the codec.
+ */
+static pj_status_t lock_codec(pjsua_call *call)
+{
+    const pj_str_t st_update = {"UPDATE", 6};
+    pjsip_inv_session *inv = call->inv;
+    const pjmedia_sdp_session *local_sdp;
+    const pjmedia_sdp_session *remote_sdp;
+    const pjmedia_sdp_media *rem_m;
+    pjmedia_sdp_session *new_sdp;
+    pjmedia_sdp_media *m;
+    pjsip_tx_data *tdata;
+    unsigned i, codec_cnt = 0;
+    pj_status_t status;
+
+    if (!pjmedia_sdp_neg_was_answer_remote(inv->neg))
+	return PJ_SUCCESS;
+
+    status = pjmedia_sdp_neg_get_active_local(call->inv->neg, &local_sdp);
+    if (status != PJ_SUCCESS)
+	return status;
+    status = pjmedia_sdp_neg_get_active_remote(call->inv->neg, &remote_sdp);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    PJ_ASSERT_RETURN(call->audio_idx>=0 &&
+		     call->audio_idx < (int)remote_sdp->media_count,
+		     PJ_EINVALIDOP);
+
+    rem_m = remote_sdp->media[call->audio_idx];
+
+    /* Check if media is disabled or only one format in the answer. */
+    if (rem_m->desc.port==0 || rem_m->desc.fmt_count==1)
+	return PJ_SUCCESS;
+
+    /* Count the formats in the answer. */
+    for (i=0; i<rem_m->desc.fmt_count && codec_cnt <= 1; ++i) {
+	if (!is_non_av_fmt(rem_m, &rem_m->desc.fmt[i]))
+	    ++codec_cnt;
+    }
+
+    if (codec_cnt <= 1) {
+	/* Answer contains single codec. */
+	return PJ_SUCCESS;
+    }
+
+    PJ_LOG(3, (THIS_FILE, "Got answer with multiple codecs, start "
+			  "updating media session to use only one codec.."));
+
+    /* Clone the offer */
+    new_sdp = pjmedia_sdp_session_clone(inv->pool_prov, local_sdp);
+    /* Note that the usage of pool_prov above is risky when locking codec
+     * delays the re-INVITE (using timer) and there are two SDP negotiations
+     * done before the re-INVITE.
+     */
+
+    /* Update the new offer so it contains only a codec. Note that formats
+     * order in the offer should have been matched to the answer, so we can
+     * just directly update the offer without looking-up the answer.
+     */
+    m = new_sdp->media[call->audio_idx];
+    codec_cnt = 0;
+    i = 0;
+    while (i < m->desc.fmt_count) {
+	pjmedia_sdp_attr *a;
+	pj_str_t *fmt = &m->desc.fmt[i];
+
+	if (is_non_av_fmt(m, fmt) || (++codec_cnt == 1)) {
+	    ++i;
+	    continue;
+	}
+
+	/* Remove format */
+	a = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "rtpmap", fmt);
+	if (a) pjmedia_sdp_attr_remove(&m->attr_count, m->attr, a);
+	a = pjmedia_sdp_attr_find2(m->attr_count, m->attr, "fmtp", fmt);
+	if (a) pjmedia_sdp_attr_remove(&m->attr_count, m->attr, a);
+	pj_array_erase(m->desc.fmt, sizeof(m->desc.fmt[0]), 
+		       m->desc.fmt_count, i);
+	--m->desc.fmt_count;
+    }
+
+    /* Send new SDP offer via UPDATE or re-INVITE */
+    if (pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL, &st_update)==
+	PJSIP_DIALOG_CAP_SUPPORTED)
+    {
+	/* Create UPDATE with the new offer */
+	status = pjsip_inv_update(inv, NULL, new_sdp, &tdata);
+	if (status != PJ_SUCCESS)
+	    return status;
+
+    } else {
+	/* Create re-INVITE with the new offer */
+	status = pjsip_inv_reinvite(inv, NULL, new_sdp, &tdata);
+	if (status == PJ_EINVALIDOP) {
+	    /* Current INVITE transaction is pending, reschedule re-INVITE. */
+	    pj_time_val delay = {0, LOCK_CODEC_RETRY_INTERVAL};
+
+	    call->lock_codec.new_sdp = new_sdp;
+	    pj_timer_entry_init(&call->lock_codec.reinv_timer, PJ_TRUE,
+				(void*)(pj_size_t)call->index,
+				&reinv_timer_cb);
+	    pjsip_endpt_schedule_timer(pjsua_var.endpt, 
+				       &call->lock_codec.reinv_timer, &delay);
+	    return PJ_SUCCESS;
+
+	} else if (status != PJ_SUCCESS)
+	    return status;
+    }
+
+    /* Send the UPDATE/re-INVITE request */
+    status = pjsip_inv_send_msg(inv, tdata);
+    if (status != PJ_SUCCESS)
+	return status;
+
+    return PJ_SUCCESS;
+}
+
 /*
  * This callback receives notification from invite session when the
@@ -2947,4 +3180,14 @@
 	case PJSIP_INV_STATE_CONFIRMED:
 	    pj_gettimeofday(&call->conn_time);
+
+	    /* Ticket #476, locking a codec in the media session. */
+	    {
+		pj_status_t status;
+		status = lock_codec(call);
+		if (status != PJ_SUCCESS) {
+		    pjsua_perror(THIS_FILE, "Unable to lock codec", status);
+		}
+	    }
+
 	    break;
 	case PJSIP_INV_STATE_DISCONNECTED:
@@ -2966,4 +3209,11 @@
 			   sizeof(call->last_text_buf_));
 	    }
+
+	    /* Stop lock codec timer, if it is active */
+	    if (call->lock_codec.reinv_timer.id) {
+		pjsip_endpt_cancel_timer(pjsua_var.endpt, 
+					 &call->lock_codec.reinv_timer);
+		call->lock_codec.reinv_timer.id = PJ_FALSE;
+	    }
 	    break;
 	default:
@@ -3170,4 +3420,5 @@
     const pjmedia_sdp_session *local_sdp;
     const pjmedia_sdp_session *remote_sdp;
+    const pj_str_t st_update = {"UPDATE", 6};
 
     PJSUA_LOCK();
@@ -3241,4 +3492,15 @@
     }
 
+    /* Ticket #476, handle the case of early media and remote support UPDATE */
+    if (inv->state == PJSIP_INV_STATE_EARLY && 
+	pjmedia_sdp_neg_was_answer_remote(inv->neg) &&
+	pjsip_dlg_remote_has_cap(inv->dlg, PJSIP_H_ALLOW, NULL, &st_update)==
+	PJSIP_DIALOG_CAP_SUPPORTED)
+    {
+	status = lock_codec(call);
+	if (status != PJ_SUCCESS) {
+	    pjsua_perror(THIS_FILE, "Unable to lock codec", status);
+	}
+    }
 
     /* Call application callback, if any */
Index: /pjproject/trunk/tests/pjsua/scripts-sipp/uas-answer-180-multiple-fmts-support-update.xml
===================================================================
--- /pjproject/trunk/tests/pjsua/scripts-sipp/uas-answer-180-multiple-fmts-support-update.xml	(revision 3206)
+++ /pjproject/trunk/tests/pjsua/scripts-sipp/uas-answer-180-multiple-fmts-support-update.xml	(revision 3206)
@@ -0,0 +1,170 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<!-- This program is free software; you can redistribute it and/or      -->
+<!-- modify it under the terms of the GNU General Public License as     -->
+<!-- published by the Free Software Foundation; either version 2 of the -->
+<!-- License, or (at your option) any later version.                    -->
+<!--                                                                    -->
+<!-- This program is distributed in the hope that it will be useful,    -->
+<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->
+<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->
+<!-- GNU General Public License for more details.                       -->
+<!--                                                                    -->
+<!-- You should have received a copy of the GNU General Public License  -->
+<!-- along with this program; if not, write to the                      -->
+<!-- Free Software Foundation, Inc.,                                    -->
+<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->
+<!--                                                                    -->
+<!--                 Sipp default 'uas' scenario.                       -->
+<!--                                                                    -->
+
+<scenario name="UAS answer multiple formats in early media, UAS supports UPDATE method">
+  <!-- By adding rrs="true" (Record Route Sets), the route sets         -->
+  <!-- are saved and used for following messages sent. Useful to test   -->
+  <!-- against stateful SIP proxies/B2BUAs.                             -->
+  <recv request="INVITE" crlf="true">
+    <action>
+	<ereg regexp=".*" search_in="hdr" header="From" assign_to="3"/>
+	<ereg regexp="sip:(.*)>" search_in="hdr" header="Contact" assign_to="4,5"/>
+        <assign assign_to="4" variable="5" />
+	<ereg regexp=".*" search_in="hdr" header="Via" assign_to="6"/>
+	<ereg regexp=".*" search_in="hdr" header="CSeq" assign_to="7"/>
+    </action>
+  </recv>
+
+  <!-- The '[last_*]' keyword is replaced automatically by the          -->
+  <!-- specified header if it was present in the last message received  -->
+  <!-- (except if it was a retransmission). If the header was not       -->
+  <!-- present or if no message has been received, the '[last_*]'       -->
+  <!-- keyword is discarded, and all bytes until the end of the line    -->
+  <!-- are also discarded.                                              -->
+  <!--                                                                  -->
+  <!-- If the specified header was present several times in the         -->
+  <!-- message, all occurences are concatenated (CRLF seperated)        -->
+  <!-- to be used in place of the '[last_*]' keyword.                   -->
+
+  <send>
+    <![CDATA[
+
+      SIP/2.0 180 Ringing
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Content-Type: application/sdp
+      Content-Length: [len]
+      Allow: INVITE, UPDATE, ACK, BYE
+
+      v=0
+      o=- 3441953879 3441953879 IN IP4 192.168.0.15
+      s=pjmedia
+      c=IN IP4 192.168.0.15
+      t=0 0
+      m=audio 4004 RTP/AVP 0 8 3 111
+      a=rtpmap:0 PCMU/8000
+      a=rtpmap:8 PCMA/8000
+      a=rtpmap:3 GSM/8000
+      a=rtpmap:111 telephone-event/8000
+      a=fmtp:111 0-15
+
+    ]]>
+  </send>
+
+
+
+  <recv request="UPDATE" crlf="true">
+  </recv>
+
+  <send>
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Content-Type: application/sdp
+      Content-Length: [len]
+      Allow: INVITE, UPDATE, ACK, BYE
+
+      v=0
+      o=- 3441953879 3441953879 IN IP4 192.168.0.15
+      s=pjmedia
+      c=IN IP4 192.168.0.15
+      t=0 0
+      m=audio 4004 RTP/AVP 0 111
+      a=rtpmap:0 PCMU/8000
+      a=rtpmap:111 telephone-event/8000
+      a=fmtp:111 0-15
+
+    ]]>
+  </send>
+
+  <pause milliseconds="2000"/>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      Via[$6]
+      [last_From:]
+      [last_To:];tag=[call_number]
+      [last_Call-ID:]
+      CSeq[$7]
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Content-Type: application/sdp
+      Content-Length: [len]
+      Allow: INVITE, UPDATE, ACK, BYE
+
+      v=0
+      o=- 3441953879 3441953879 IN IP4 192.168.0.15
+      s=pjmedia
+      c=IN IP4 192.168.0.15
+      t=0 0
+      m=audio 4004 RTP/AVP 0 111
+      a=rtpmap:0 PCMU/8000
+      a=rtpmap:111 telephone-event/8000
+      a=fmtp:111 0-15
+
+    ]]>
+  </send>
+
+  <recv request="ACK" crlf="true">
+  </recv>
+
+  <pause milliseconds="2000"/>
+  
+  <send retrans="500">
+    <![CDATA[
+
+      BYE sip:[$5] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port]
+      From: sipp  <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
+      To[$3]
+      Call-ID: [call_id]
+      Cseq: 1 BYE
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Max-Forwards: 70
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <!-- Keep the call open for a while in case the 200 is lost to be     -->
+  <!-- able to retransmit it if we receive the BYE again.               -->
+  <pause milliseconds="4000"/>
+
+
+  <!-- definition of the response time repartition table (unit is ms)   -->
+  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+  <!-- definition of the call length repartition table (unit is ms)     -->
+  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
Index: /pjproject/trunk/tests/pjsua/scripts-sipp/uas-answer-180-multiple-fmts.xml
===================================================================
--- /pjproject/trunk/tests/pjsua/scripts-sipp/uas-answer-180-multiple-fmts.xml	(revision 3206)
+++ /pjproject/trunk/tests/pjsua/scripts-sipp/uas-answer-180-multiple-fmts.xml	(revision 3206)
@@ -0,0 +1,172 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<!-- This program is free software; you can redistribute it and/or      -->
+<!-- modify it under the terms of the GNU General Public License as     -->
+<!-- published by the Free Software Foundation; either version 2 of the -->
+<!-- License, or (at your option) any later version.                    -->
+<!--                                                                    -->
+<!-- This program is distributed in the hope that it will be useful,    -->
+<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->
+<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->
+<!-- GNU General Public License for more details.                       -->
+<!--                                                                    -->
+<!-- You should have received a copy of the GNU General Public License  -->
+<!-- along with this program; if not, write to the                      -->
+<!-- Free Software Foundation, Inc.,                                    -->
+<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->
+<!--                                                                    -->
+<!--                 Sipp default 'uas' scenario.                       -->
+<!--                                                                    -->
+
+<scenario name="UAS answer with multiple formats in early media">
+  <!-- By adding rrs="true" (Record Route Sets), the route sets         -->
+  <!-- are saved and used for following messages sent. Useful to test   -->
+  <!-- against stateful SIP proxies/B2BUAs.                             -->
+  <recv request="INVITE" crlf="true">
+  </recv>
+
+  <!-- The '[last_*]' keyword is replaced automatically by the          -->
+  <!-- specified header if it was present in the last message received  -->
+  <!-- (except if it was a retransmission). If the header was not       -->
+  <!-- present or if no message has been received, the '[last_*]'       -->
+  <!-- keyword is discarded, and all bytes until the end of the line    -->
+  <!-- are also discarded.                                              -->
+  <!--                                                                  -->
+  <!-- If the specified header was present several times in the         -->
+  <!-- message, all occurences are concatenated (CRLF seperated)        -->
+  <!-- to be used in place of the '[last_*]' keyword.                   -->
+
+  <send>
+    <![CDATA[
+
+      SIP/2.0 180 Ringing
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=- 3441953879 3441953879 IN IP4 192.168.0.15
+      s=pjmedia
+      c=IN IP4 192.168.0.15
+      t=0 0
+      m=audio 4004 RTP/AVP 0 8 3 111
+      a=rtpmap:0 PCMU/8000
+      a=rtpmap:8 PCMA/8000
+      a=rtpmap:3 GSM/8000
+      a=rtpmap:111 telephone-event/8000
+      a=fmtp:111 0-15
+
+    ]]>
+  </send>
+
+  <pause milliseconds="2000"/>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=- 3441953879 3441953879 IN IP4 192.168.0.15
+      s=pjmedia
+      c=IN IP4 192.168.0.15
+      t=0 0
+      m=audio 4004 RTP/AVP 0 8 3 111
+      a=rtpmap:0 PCMU/8000
+      a=rtpmap:8 PCMA/8000
+      a=rtpmap:3 GSM/8000
+      a=rtpmap:111 telephone-event/8000
+      a=fmtp:111 0-15
+
+    ]]>
+  </send>
+
+  <recv request="ACK" crlf="true">
+  </recv>
+
+
+
+  <recv request="INVITE" crlf="true">
+    <action>
+	<ereg regexp=".*" search_in="hdr" header="From" assign_to="3"/>
+	<ereg regexp="sip:(.*)>" search_in="hdr" header="Contact" assign_to="4,5"/>
+        <assign assign_to="4" variable="5" />
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=- 3441953879 3441953879 IN IP4 192.168.0.15
+      s=pjmedia
+      c=IN IP4 192.168.0.15
+      t=0 0
+      m=audio 4004 RTP/AVP 0 111
+      a=rtpmap:0 PCMU/8000
+      a=rtpmap:111 telephone-event/8000
+      a=fmtp:111 0-15
+
+    ]]>
+  </send>
+
+  <recv request="ACK" crlf="true">
+  </recv>
+
+  
+  <pause milliseconds="2000"/>
+
+
+  <send retrans="500">
+    <![CDATA[
+
+      BYE sip:[$5] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port]
+      From: sipp  <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
+      To[$3]
+      Call-ID: [call_id]
+      Cseq: 1 BYE
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Max-Forwards: 70
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <!-- Keep the call open for a while in case the 200 is lost to be     -->
+  <!-- able to retransmit it if we receive the BYE again.               -->
+  <pause milliseconds="4000"/>
+
+
+  <!-- definition of the response time repartition table (unit is ms)   -->
+  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+  <!-- definition of the call length repartition table (unit is ms)     -->
+  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
Index: /pjproject/trunk/tests/pjsua/scripts-sipp/uas-answer-200-multiple-fmts-support-update.xml
===================================================================
--- /pjproject/trunk/tests/pjsua/scripts-sipp/uas-answer-200-multiple-fmts-support-update.xml	(revision 3206)
+++ /pjproject/trunk/tests/pjsua/scripts-sipp/uas-answer-200-multiple-fmts-support-update.xml	(revision 3206)
@@ -0,0 +1,139 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<!-- This program is free software; you can redistribute it and/or      -->
+<!-- modify it under the terms of the GNU General Public License as     -->
+<!-- published by the Free Software Foundation; either version 2 of the -->
+<!-- License, or (at your option) any later version.                    -->
+<!--                                                                    -->
+<!-- This program is distributed in the hope that it will be useful,    -->
+<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->
+<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->
+<!-- GNU General Public License for more details.                       -->
+<!--                                                                    -->
+<!-- You should have received a copy of the GNU General Public License  -->
+<!-- along with this program; if not, write to the                      -->
+<!-- Free Software Foundation, Inc.,                                    -->
+<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->
+<!--                                                                    -->
+<!--                 Sipp default 'uas' scenario.                       -->
+<!--                                                                    -->
+
+<scenario name="UAS answer multiple formats, UAS supports UPDATE method">
+  <!-- By adding rrs="true" (Record Route Sets), the route sets         -->
+  <!-- are saved and used for following messages sent. Useful to test   -->
+  <!-- against stateful SIP proxies/B2BUAs.                             -->
+  <recv request="INVITE" crlf="true">
+    <action>
+	<ereg regexp=".*" search_in="hdr" header="From" assign_to="3"/>
+	<ereg regexp="sip:(.*)>" search_in="hdr" header="Contact" assign_to="4,5"/>
+        <assign assign_to="4" variable="5" />
+    </action>
+  </recv>
+
+  <!-- The '[last_*]' keyword is replaced automatically by the          -->
+  <!-- specified header if it was present in the last message received  -->
+  <!-- (except if it was a retransmission). If the header was not       -->
+  <!-- present or if no message has been received, the '[last_*]'       -->
+  <!-- keyword is discarded, and all bytes until the end of the line    -->
+  <!-- are also discarded.                                              -->
+  <!--                                                                  -->
+  <!-- If the specified header was present several times in the         -->
+  <!-- message, all occurences are concatenated (CRLF seperated)        -->
+  <!-- to be used in place of the '[last_*]' keyword.                   -->
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Content-Type: application/sdp
+      Content-Length: [len]
+      Allow: INVITE, UPDATE, ACK, BYE
+
+      v=0
+      o=- 3441953879 3441953879 IN IP4 192.168.0.15
+      s=pjmedia
+      c=IN IP4 192.168.0.15
+      t=0 0
+      m=audio 4004 RTP/AVP 0 8 3 111
+      a=rtpmap:0 PCMU/8000
+      a=rtpmap:8 PCMA/8000
+      a=rtpmap:3 GSM/8000
+      a=rtpmap:111 telephone-event/8000
+      a=fmtp:111 0-15
+
+    ]]>
+  </send>
+
+  <recv request="ACK" crlf="true">
+  </recv>
+
+
+
+  <recv request="UPDATE" crlf="true">
+  </recv>
+
+  <send>
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Content-Type: application/sdp
+      Content-Length: [len]
+      Allow: INVITE, UPDATE, ACK, BYE
+
+      v=0
+      o=- 3441953879 3441953879 IN IP4 192.168.0.15
+      s=pjmedia
+      c=IN IP4 192.168.0.15
+      t=0 0
+      m=audio 4004 RTP/AVP 0 111
+      a=rtpmap:0 PCMU/8000
+      a=rtpmap:111 telephone-event/8000
+      a=fmtp:111 0-15
+
+    ]]>
+  </send>
+
+  <pause milliseconds="2000"/>
+
+  <send retrans="500">
+    <![CDATA[
+
+      BYE sip:[$5] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port]
+      From: sipp  <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
+      To[$3]
+      Call-ID: [call_id]
+      Cseq: 1 BYE
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Max-Forwards: 70
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <!-- Keep the call open for a while in case the 200 is lost to be     -->
+  <!-- able to retransmit it if we receive the BYE again.               -->
+  <pause milliseconds="4000"/>
+
+
+  <!-- definition of the response time repartition table (unit is ms)   -->
+  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+  <!-- definition of the call length repartition table (unit is ms)     -->
+  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
Index: /pjproject/trunk/tests/pjsua/scripts-sipp/uas-answer-200-multiple-fmts.xml
===================================================================
--- /pjproject/trunk/tests/pjsua/scripts-sipp/uas-answer-200-multiple-fmts.xml	(revision 3206)
+++ /pjproject/trunk/tests/pjsua/scripts-sipp/uas-answer-200-multiple-fmts.xml	(revision 3206)
@@ -0,0 +1,140 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!DOCTYPE scenario SYSTEM "sipp.dtd">
+
+<!-- This program is free software; you can redistribute it and/or      -->
+<!-- modify it under the terms of the GNU General Public License as     -->
+<!-- published by the Free Software Foundation; either version 2 of the -->
+<!-- License, or (at your option) any later version.                    -->
+<!--                                                                    -->
+<!-- This program is distributed in the hope that it will be useful,    -->
+<!-- but WITHOUT ANY WARRANTY; without even the implied warranty of     -->
+<!-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the      -->
+<!-- GNU General Public License for more details.                       -->
+<!--                                                                    -->
+<!-- You should have received a copy of the GNU General Public License  -->
+<!-- along with this program; if not, write to the                      -->
+<!-- Free Software Foundation, Inc.,                                    -->
+<!-- 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA             -->
+<!--                                                                    -->
+<!--                 Sipp default 'uas' scenario.                       -->
+<!--                                                                    -->
+
+<scenario name="UAS answer multiple formats">
+  <!-- By adding rrs="true" (Record Route Sets), the route sets         -->
+  <!-- are saved and used for following messages sent. Useful to test   -->
+  <!-- against stateful SIP proxies/B2BUAs.                             -->
+  <recv request="INVITE" crlf="true">
+  </recv>
+
+  <!-- The '[last_*]' keyword is replaced automatically by the          -->
+  <!-- specified header if it was present in the last message received  -->
+  <!-- (except if it was a retransmission). If the header was not       -->
+  <!-- present or if no message has been received, the '[last_*]'       -->
+  <!-- keyword is discarded, and all bytes until the end of the line    -->
+  <!-- are also discarded.                                              -->
+  <!--                                                                  -->
+  <!-- If the specified header was present several times in the         -->
+  <!-- message, all occurences are concatenated (CRLF seperated)        -->
+  <!-- to be used in place of the '[last_*]' keyword.                   -->
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=- 3441953879 3441953879 IN IP4 192.168.0.15
+      s=pjmedia
+      c=IN IP4 192.168.0.15
+      t=0 0
+      m=audio 4004 RTP/AVP 0 8 3 111
+      a=rtpmap:0 PCMU/8000
+      a=rtpmap:8 PCMA/8000
+      a=rtpmap:3 GSM/8000
+      a=rtpmap:111 telephone-event/8000
+      a=fmtp:111 0-15
+
+    ]]>
+  </send>
+
+  <recv request="ACK" crlf="true">
+  </recv>
+
+
+
+  <recv request="INVITE" crlf="true">
+    <action>
+	<ereg regexp=".*" search_in="hdr" header="From" assign_to="3"/>
+	<ereg regexp="sip:(.*)>" search_in="hdr" header="Contact" assign_to="4,5"/>
+        <assign assign_to="4" variable="5" />
+    </action>
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Content-Type: application/sdp
+      Content-Length: [len]
+
+      v=0
+      o=- 3441953879 3441953879 IN IP4 192.168.0.15
+      s=pjmedia
+      c=IN IP4 192.168.0.15
+      t=0 0
+      m=audio 4004 RTP/AVP 0 111
+      a=rtpmap:0 PCMU/8000
+      a=rtpmap:111 telephone-event/8000
+      a=fmtp:111 0-15
+
+    ]]>
+  </send>
+
+  <recv request="ACK" crlf="true">
+  </recv>
+
+  <pause milliseconds="2000"/>
+
+  <send retrans="500">
+    <![CDATA[
+
+      BYE sip:[$5] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port]
+      From: sipp  <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
+      To[$3]
+      Call-ID: [call_id]
+      Cseq: 1 BYE
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Max-Forwards: 70
+      Content-Length: 0
+
+    ]]>
+  </send>
+
+  <!-- Keep the call open for a while in case the 200 is lost to be     -->
+  <!-- able to retransmit it if we receive the BYE again.               -->
+  <pause milliseconds="4000"/>
+
+
+  <!-- definition of the response time repartition table (unit is ms)   -->
+  <ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/>
+
+  <!-- definition of the call length repartition table (unit is ms)     -->
+  <CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/>
+
+</scenario>
+
