Fixed #1626: Assertion when remote sends re-INVITE with less media

Included in the fix is sipp testing scenario.



git-svn-id: https://svn.pjsip.org/repos/pjproject/trunk@4373 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjsip/src/pjsua-lib/pjsua_media.c b/pjsip/src/pjsua-lib/pjsua_media.c
index bc97915..3b9210b 100644
--- a/pjsip/src/pjsua-lib/pjsua_media.c
+++ b/pjsip/src/pjsua-lib/pjsua_media.c
@@ -1457,12 +1457,12 @@
 /* Clean up media transports in provisional media that is not used
  * by call media.
  */
-void pjsua_media_prov_clean_up(pjsua_call_id call_id)
+static void media_prov_clean_up(pjsua_call_id call_id, int idx)
 {
     pjsua_call *call = &pjsua_var.calls[call_id];
     unsigned i;
 
-    for (i = 0; i < call->med_prov_cnt; ++i) {
+    for (i = idx; i < call->med_prov_cnt; ++i) {
 	pjsua_call_media *call_med = &call->media_prov[i];
 	unsigned j;
 	pj_bool_t used = PJ_FALSE;
@@ -1489,6 +1489,11 @@
     }
 }
 
+void pjsua_media_prov_clean_up(pjsua_call_id call_id)
+{
+    media_prov_clean_up(call_id, 0);
+}
+
 
 pj_status_t pjsua_media_channel_init(pjsua_call_id call_id,
 				     pjsip_role_e role,
@@ -1902,6 +1907,8 @@
 
 	if (rem_sdp && mi >= rem_sdp->media_count) {
 	    /* Remote might have removed some media lines. */
+            media_prov_clean_up(call->index, rem_sdp->media_count);
+            call->med_prov_cnt = rem_sdp->media_count;
 	    break;
 	}
 
diff --git a/tests/pjsua/scripts-sipp/uas-reinv-with-less-media.py b/tests/pjsua/scripts-sipp/uas-reinv-with-less-media.py
new file mode 100644
index 0000000..42b2b88
--- /dev/null
+++ b/tests/pjsua/scripts-sipp/uas-reinv-with-less-media.py
@@ -0,0 +1,8 @@
+# $Id$
+#
+import inc_const as const
+
+PJSUA = ["--null-audio --extra-audio --max-calls=1 $SIPP_URI"]
+
+# Send hold after remote holds (double hold)
+PJSUA_EXPECTS = [[0, const.MEDIA_HOLD, "H"]]
diff --git a/tests/pjsua/scripts-sipp/uas-reinv-with-less-media.xml b/tests/pjsua/scripts-sipp/uas-reinv-with-less-media.xml
new file mode 100644
index 0000000..33ae6a2
--- /dev/null
+++ b/tests/pjsua/scripts-sipp/uas-reinv-with-less-media.xml
@@ -0,0 +1,155 @@
+<?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="Sending OK and re-INVITE with less media (#16xx)">
+  <!-- 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>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      [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 4000 RTP/AVP 0 96
+      a=rtpmap:0 PCMU/8000
+      a=rtpmap:96 telephone-event/8000
+      a=sendrecv
+
+    ]]>
+  </send>
+
+  <recv request="ACK" crlf="true">
+  </recv>
+
+  <pause milliseconds="2000"/>
+
+  <send retrans="500">
+    <![CDATA[
+
+      INVITE sip:[$5] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=z9hG4bK-same-branch
+      From: sipp  <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
+      To[$3]
+      Call-ID: [call_id]
+      Cseq: 2 INVITE
+      Max-Forwards: 70
+      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 4000 RTP/AVP 0 96
+      a=rtpmap:0 PCMU/8000
+      a=rtpmap:96 telephone-event/8000
+      a=sendonly
+
+    ]]>
+  </send>
+
+  <recv response="200" rtd="true">
+  </recv>
+
+  <send>
+    <![CDATA[
+
+      ACK sip:[$5] SIP/2.0
+      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=z9hG4bK-same-branch
+      From: sipp  <sip:sipp@[local_ip]:[local_port]>;tag=[call_number]
+      To[$3]
+      Call-ID: [call_id]
+      Cseq: 1 ACK
+      Contact: sip:sipp@[local_ip]:[local_port]
+      Max-Forwards: 70
+      Content-Length: 0
+
+    ]]>
+  </send>    
+    
+  <recv request="INVITE" crlf="true">
+  </recv>
+
+  <send retrans="500">
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:]
+      [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 4000 RTP/AVP 0 96
+      a=rtpmap:0 PCMU/8000
+      a=rtpmap:96 telephone-event/8000
+      a=inactive
+
+    ]]>
+  </send>
+
+  <recv request="ACK" crlf="true">
+  </recv>
+
+  <!-- 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>
+