<p>Jenkins2 <strong>merged</strong> this change.</p><p><a href="https://gerrit.asterisk.org/5901">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Joshua Colp: Verified
  George Joseph: Looks good to me, approved
  Jenkins2: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res/res_pjsip_t38 add test to verify T.38 gets quickly rejected<br><br>this test makes sure asterisk rejects the call quickly when the<br>B leg has T.38 disabled<br><br>Change-Id: Ida087c3d410c95c87aeca506c81eabe8bde062ef<br>---<br>A tests/fax/pjsip/t38_fast_reject/check_reinvite_rtt.pl<br>A tests/fax/pjsip/t38_fast_reject/configs/ast1/extensions.conf<br>A tests/fax/pjsip/t38_fast_reject/configs/ast1/pjsip.conf<br>A tests/fax/pjsip/t38_fast_reject/run-test<br>A tests/fax/pjsip/t38_fast_reject/sipp/A_PARTY.xml<br>A tests/fax/pjsip/t38_fast_reject/sipp/B_PARTY.xml<br>A tests/fax/pjsip/t38_fast_reject/test-config.yaml<br>M tests/fax/pjsip/tests.yaml<br>8 files changed, 492 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">diff --git a/tests/fax/pjsip/t38_fast_reject/check_reinvite_rtt.pl b/tests/fax/pjsip/t38_fast_reject/check_reinvite_rtt.pl<br>new file mode 100644<br>index 0000000..1744aef<br>--- /dev/null<br>+++ b/tests/fax/pjsip/t38_fast_reject/check_reinvite_rtt.pl<br>@@ -0,0 +1,43 @@<br>+#!/usr/bin/perl<br>+use strict;<br>+use Text::CSV;<br>+use Data::Dumper;<br>+<br>+my $filename = $ARGV[0];<br>+open(my $fh, '<:utf8', $filename)<br>+    or die "Can't open $filename: $!";<br>+<br>+my $csv = Text::CSV->new({sep_char => ';'})<br>+    or die "Text::CSV error: " . Text::CSV->error_diag;<br>+<br>+my $header = <$fh>; <br>+# define column names    <br>+$csv->parse($header);<br>+$csv->column_names([$csv->fields]);<br>+<br>+my $ret = 0;<br>+# parse the rest<br>+while (my $row = $csv->getline_hr($fh)) {<br>+    if (!defined  $row->{'ResponseTimereinvite(P)'} ) {<br>+          print "column not found! make sure scenario is correct!\n";<br>+        $ret = -1;<br>+           last;<br>+    }<br>+ <br>+    my $pkey = $row->{'ResponseTimereinvite(P)'};<br>+    my ($hour, $minute, $second, $msec) = split(/:/, $pkey);<br>+    $minute += $hour*60;<br>+    $second += $minute*60;<br>+    $msec += $second * 1000;<br>+    <br>+    if ($msec > 500) {<br>+            print "Slow 488 Rejection detected ($msec)!\n";<br>+            $ret = -2;<br>+           last;<br>+    }<br>+}<br>+<br>+$csv->eof or $csv->error_diag;<br>+close $fh;<br>+<br>+exit $ret;<br>diff --git a/tests/fax/pjsip/t38_fast_reject/configs/ast1/extensions.conf b/tests/fax/pjsip/t38_fast_reject/configs/ast1/extensions.conf<br>new file mode 100644<br>index 0000000..ad7b155<br>--- /dev/null<br>+++ b/tests/fax/pjsip/t38_fast_reject/configs/ast1/extensions.conf<br>@@ -0,0 +1,11 @@<br>+[general]<br>+static=yes<br>+writeprotect=yes<br>+autofallthrough=yes<br>+clearglobalvars=no<br>+priorityjumping=yes<br>+<br>+[globals]<br>+<br>+[default]<br>+exten => _X.,1,Dial(pjsip/sbc,180)<br>diff --git a/tests/fax/pjsip/t38_fast_reject/configs/ast1/pjsip.conf b/tests/fax/pjsip/t38_fast_reject/configs/ast1/pjsip.conf<br>new file mode 100644<br>index 0000000..280e204<br>--- /dev/null<br>+++ b/tests/fax/pjsip/t38_fast_reject/configs/ast1/pjsip.conf<br>@@ -0,0 +1,81 @@<br>+;--<br>+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<br>+Non mapped elements start<br>+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<br>+<br>+[general]<br>+sipdebug = yes<br>+<br>+[PEER_A]<br>+port = 5061<br>+<br>+[sbc]<br>+port = 5700<br>+<br>+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<br>+Non mapped elements end<br>+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;<br>+--;<br>+<br>+<br>+[global]<br>+type = global<br>+debug = yes<br>+<br>+[transport-udp6]<br>+type = transport<br>+protocol = udp<br>+bind = [::]:5060<br>+<br>+[transport-udp]<br>+type = transport<br>+protocol = udp<br>+bind = 0.0.0.0:5060<br>+<br>+[PEER_A]<br>+type = aor<br>+contact = sip:127.0.0.1:5061<br>+<br>+[PEER_A]<br>+type = identify<br>+endpoint = PEER_A<br>+match = 127.0.0.1<br>+<br>+[PEER_A]<br>+type = endpoint<br>+context = default<br>+dtmf_mode = rfc4733<br>+disallow = all<br>+allow = alaw<br>+allow = ulaw<br>+allow = g729<br>+allow = h263p<br>+allow = h264<br>+direct_media = no<br>+send_rpid = yes<br>+sdp_session = session<br>+aors = PEER_A<br>+t38_udptl = yes<br>+t38_udptl_ec = none<br>+<br>+[sbc]<br>+type = aor<br>+contact = sip:127.0.0.1:5700<br>+<br>+[sbc]<br>+type = endpoint<br>+context = callcontrol<br>+dtmf_mode = rfc4733<br>+disallow = all<br>+allow = alaw<br>+allow = ulaw<br>+allow = g729<br>+allow = h263p<br>+allow = h264<br>+direct_media = no<br>+send_rpid = yes<br>+sdp_session = session<br>+aors = sbc<br>+t38_udptl = no<br>+t38_udptl_ec = none<br>+<br>diff --git a/tests/fax/pjsip/t38_fast_reject/run-test b/tests/fax/pjsip/t38_fast_reject/run-test<br>new file mode 100644<br>index 0000000..a93ef43<br>--- /dev/null<br>+++ b/tests/fax/pjsip/t38_fast_reject/run-test<br>@@ -0,0 +1,103 @@<br>+#!/usr/bin/env python<br>+# vim: sw=3 et:<br>+'''<br>+Copyright (C) 2017, Voxbone, SA<br>+Torrey Searle <torrey@voxbone.com><br>+<br>+This program is free software, distributed under the terms of<br>+the GNU General Public License Version 2.<br>+'''<br>+<br>+import sys<br>+import os<br>+import re<br>+import shutil<br>+import logging<br>+import signal<br>+import subprocess<br>+import time<br>+<br>+from twisted.internet import reactor<br>+<br>+sys.path.append("lib/python")<br>+sys.path.append("utils")<br>+from asterisk.asterisk import Asterisk<br>+from asterisk.sipp import SIPpTest<br>+<br>+logger = logging.getLogger(__name__)<br>+WORKING_DIR = os.path.abspath(os.path.dirname(__file__))<br>+TEST_DIR = os.path.dirname(os.path.realpath(__file__))<br>+<br>+e164 = "3200000000"<br>+sippA_logfile = WORKING_DIR + "/A_PARTY.log"<br>+sippA_errfile = WORKING_DIR + "/A_PARTY_ERR.log"<br>+sippA_statfile = WORKING_DIR + "/A_PARTY_STAT.log"<br>+<br>+sippB_logfile = WORKING_DIR + "/B_PARTY.log"<br>+sippB_errfile = WORKING_DIR + "/B_PARTY_ERR.log"<br>+<br>+SIPP_SCENARIOS = [<br>+    {<br>+        'scenario' : 'B_PARTY.xml',<br>+        '-i' : '127.0.0.1',<br>+        '-p' : '5700',<br>+        '-message_file' : sippB_logfile,<br>+        '-error_file' : sippB_errfile,<br>+        '-trace_msg' : '-trace_err',<br>+    },<br>+    {<br>+        'scenario' : 'A_PARTY.xml',<br>+        '-i' : '127.0.0.1',<br>+        '-p' : '5061',<br>+        '-s' : e164,<br>+        '-message_file' : sippA_logfile,<br>+        '-error_file' : sippA_errfile,<br>+        '-trace_msg' : '-trace_err',<br>+        '-trace_stat' : '-trace_stat',<br>+        '-stf' : sippA_statfile,<br>+    }<br>+]<br>+<br>+def main():<br>+    test = SIPpTest(WORKING_DIR, TEST_DIR, SIPP_SCENARIOS)<br>+    logger.info ("Running against asterisk version %s" %test.ast_version)<br>+              <br>+    test.reactor_timeout = 100;<br>+<br>+    dump_A = WORKING_DIR + "/carrier_rtp.log"<br>+    dump_B = WORKING_DIR + "/customer_rtp.log"<br>+    rtpdump_A = subprocess.Popen(["rtpdump", "-t","5", "-F","ascii","-d","101","-o",dump_A, "127.0.0.1/9000"])<br>+    rtpdump_B = subprocess.Popen(["rtpdump", "-t","5", "-F","ascii","-d","101","-o",dump_B, "127.0.0.1/8000"])<br>+<br>+    time.sleep(10) #Wait 10 seconds to ensure that all the sockets are open before running the test    <br>+<br>+    reactor.run()<br>+<br>+    # Kill the RTPDUMP, pass it the signal"<br>+    rtpdump_A.send_signal(signal.SIGINT)        <br>+    rtpdump_A.wait()<br>+    rtpdump_B.send_signal(signal.SIGINT)      <br>+    rtpdump_B.wait()<br>+<br>+    #Verify that audio packets were routed in both directions after G711 fallback<br>+    if (os.path.getsize(dump_B) == 0):<br>+      logger.error("No RTP routed towards customer ...failing the test")<br>+ return 1<br>+    if (os.path.getsize(dump_A) == 0):<br>+            logger.error("No RTP routed towards carrier ...failing the test")<br>+  return 1<br>+<br>+    if not test.passed:<br>+        return 1<br>+<br>+    ret_A = subprocess.call([WORKING_DIR + "/check_reinvite_rtt.pl", WORKING_DIR+"/A_PARTY_STAT.log"])<br>+<br>+    if (ret_A != 0):<br>+       logger.debug("Slow ReInvite Detected!")<br>+            return 1<br>+<br>+    return 0<br>+<br>+if __name__ == "__main__":<br>+    sys.exit(main() or 0)<br>+<br>diff --git a/tests/fax/pjsip/t38_fast_reject/sipp/A_PARTY.xml b/tests/fax/pjsip/t38_fast_reject/sipp/A_PARTY.xml<br>new file mode 100644<br>index 0000000..118d2f9<br>--- /dev/null<br>+++ b/tests/fax/pjsip/t38_fast_reject/sipp/A_PARTY.xml<br>@@ -0,0 +1,153 @@<br>+<?xml version="1.0" encoding="ISO-8859-1" ?><br>+<!DOCTYPE scenario SYSTEM "sipp.dtd"><br>+<br>+<scenario name="T38 REINVTE"><br>+  <send retrans="500"><br>+    <![CDATA[<br>+<br>+      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0<br>+      Via: SIP/2.0/UDP [local_ip]:[local_port];branch=[branch]<br>+      From: <sip:390415094280@[local_ip]:[local_port]>;tag=[pid]SIPpTag00[call_number]<br>+      To: <sip:[service]@[remote_ip]:[remote_port]><br>+      Call-ID: [call_id]<br>+      Supported: rel1xx,timer,replaces<br>+      Min-SE:  181<br>+      User-Agent: Cisco-SIPGateway/IOS-12.x<br>+      Allow: INVITE, OPTIONS, BYE, CANCEL, ACK, PRACK, COMET, REFER, SUBSCRIBE, NOTIFY, INFO, UPDATE, REGISTER<br>+      CSeq: 101 INVITE<br>+      Max-Forwards: 69<br>+      Contact: <sip:390415094280@[local_ip]:[local_port]><br>+      Expires: 180<br>+      Allow-Events: telephone-event<br>+      Content-Type: application/sdp<br>+      Content-Length: [len]<br>+      <br>+      v=0<br>+      o=CiscoSystemsSIP-GW-UserAgent 9624 5279 IN IP4 [local_ip]<br>+      s=SIP Call<br>+      c=IN IP4 [media_ip]<br>+      t=0 0<br>+      m=audio 9000 RTP/AVP 0 18 101<br>+      c=IN IP[local_ip_type] [local_ip]<br>+      a=rtpmap:101 telephone-event/101<br>+<br>+    ]]><br>+  </send><br>+<br>+  <recv response="100"><br>+  </recv><br>+<br>+  <recv response="100" optional="true"><br>+  </recv><br>+<br>+  <recv response="100" optional="true"><br>+  </recv><br>+<br>+  <recv response="180" optional="true"><br>+  </recv><br>+  <recv response="183" optional="true"><br>+  </recv><br>+<br>+  <recv response="200" rrs="true"><br>+    <action><br>+            <ereg regexp="[[:punct:]](.*)[[:punct:]]" search_in="hdr" header="Contact:" check_it="true" assign_to="6,1" /><br>+       <ereg regexp=".*" search_in="hdr" header="From:" check_it="true" assign_to="2" /><br>+            <ereg regexp=".*" search_in="hdr" header="To:" check_it="true" assign_to="3" /><br>+      <log message="Log to avoid the problem of not using $6 [$6]"/><br>+    </action><br>+  </recv><br>+<br>+  <send><br>+    <![CDATA[<br>+<br>+      ACK [next_url] SIP/2.0<br>+      [routes]<br>+      Via: SIP/2.0/UDP [local_ip]:[local_port];branch=[branch]<br>+      From: [$2]<br>+      To: [$3]<br>+      Call-ID: [call_id]<br>+      Max-Forwards: 69<br>+      CSeq: 101 ACK<br>+      Content-Length: [len]<br>+<br>+    ]]><br>+  </send><br>+<br>+<br>+  <!--Send the T38 REINVITE --><br>+  <send retrans="500" start_rtd="reinvite"><br>+    <![CDATA[<br>+<br>+      INVITE [$1] SIP/2.0<br>+      Via: SIP/2.0/UDP [local_ip]:[local_port];branch=[branch]<br>+      From: [$2]<br>+      To: [$3]<br>+      Call-ID: [call_id]<br>+      User-Agent: Cisco-SIPGateway/IOS-12.x<br>+      CSeq: 102 INVITE<br>+      Max-Forwards: 69<br>+      Contact: <sip:390415094280@[local_ip]:[local_port]><br>+      Allow-Events: telephone-event<br>+      Content-Type: application/sdp<br>+      Content-Length: [len]<br>+            <br>+      v=0<br>+      o=CiscoSystemsSIP-GW-UserAgent 9624 5280 IN IP4 [local_ip]<br>+      s=Asterisk PBX 1.6.2.0<br>+      c=IN IP[local_ip_type] [local_ip]<br>+      t=0 0<br>+      m=image 4389 udptl t38<br>+      a=T38FaxVersion:0<br>+      a=T38MaxBitRate:14400<br>+      a=T38FaxRateManagement:transferredTCF<br>+      a=T38FaxMaxDatagram:1400<br>+      a=T38FaxUdpEC:t38UDPRedundancy<br>+<br>+    ]]><br>+  </send><br>+<br>+  <recv response="100" optional="true"><br>+  </recv><br>+<br>+  <recv response="488" rtd="reinvite" crlf="true"><br>+  </recv><br>+<br>+  <send><br>+  <![CDATA[<br>+<br>+  ACK [$1] SIP/2.0<br>+  Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]<br>+  [last_Call-ID:]<br>+  From: [$2]<br>+  To: [$3]<br>+  CSeq: 102 ACK<br>+  Max-Forwards: 69<br>+  Content-Length: 0<br>+<br>+  ]]><br>+  </send><br>+<br>+  <pause milliseconds="50000" /><br>+<br>+  <send retrans="500"><br>+    <![CDATA[<br>+<br>+      BYE [$1] SIP/2.0<br>+      Via: SIP/2.0/UDP [local_ip]:[local_port];branch=[branch]<br>+      From: [$2]<br>+      To: [$3]<br>+      Call-ID: [call_id]<br>+      User-Agent: Cisco-SIPGateway/IOS-12.x<br>+      Max-Forwards: 69<br>+      CSeq: 104 BYE<br>+      Content-Length: 0<br>+<br>+    ]]><br>+  </send><br>+<br>+  <recv response="200"><br>+  </recv><br>+<br>+<br>+</scenario><br>+<br>diff --git a/tests/fax/pjsip/t38_fast_reject/sipp/B_PARTY.xml b/tests/fax/pjsip/t38_fast_reject/sipp/B_PARTY.xml<br>new file mode 100644<br>index 0000000..3262911<br>--- /dev/null<br>+++ b/tests/fax/pjsip/t38_fast_reject/sipp/B_PARTY.xml<br>@@ -0,0 +1,87 @@<br>+<?xml version="1.0" encoding="ISO-8859-1" ?><br>+<!DOCTYPE scenario SYSTEM "sipp.dtd"><br>+<br>+<scenario name="T38 REINVITE"><br>+<br>+<recv request="INVITE" crlf="true" rrs="true"><br>+</recv><br>+<br>+<br>+<br>+<send><br>+<![CDATA[<br>+<br>+SIP/2.0 100 Trying<br>+[last_Via:]<br>+[last_Call-ID:]<br>+[last_From:]<br>+[last_To:]<br>+[last_CSeq:]<br>+Content-Length: 0<br>+<br>+]]><br>+</send><br>+<br>+<send retrans="500"><br>+<![CDATA[<br>+<br>+SIP/2.0 200 OK<br>+[last_Via:]<br>+[last_Call-ID:]<br>+[last_From:]<br>+[last_To:];tag=[call_number]<br>+[last_CSeq:]<br>+[last_Record-Route]<br>+Contact: <sip:bansallaptop@[local_ip]:[local_port];user=phone><br>+Content-Type: application/sdp<br>+Content-Length: [len]<br>+<br>+v=0<br>+o=HuaweiSoftX3000 6644052 6644052 IN IP[local_ip_type] [local_ip]<br>+s=Sip Call<br>+c=IN IP[media_ip_type] [media_ip]<br>+t=0 0<br>+m=audio 8000 RTP/AVP 0 100 101<br>+a=rtpmap:0 PCMU/8000<br>+a=rtpmap:100 NSE/8000<br>+a=rtpmap:101 telephone-event/101<br>+<br>+]]><br>+</send><br>+<br>+<recv request="ACK"<br>+      rtd="true"<br>+      crlf="true"><br>+</recv><br>+<br>+<recv request="BYE"><br>+</recv><br>+<br>+<send><br>+    <![CDATA[<br>+<br>+      SIP/2.0 200 OK<br>+      [last_Via:]<br>+      [last_From:]<br>+      [last_To:]<br>+      [last_Call-ID:]<br>+      [last_CSeq:]<br>+      Contact: <sip:[local_ip]:[local_port];transport=[transport]><br>+      Content-Length: 0<br>+<br>+    ]]><br>+</send><br>+<br>+<!-- Keep the call open for a while in case the 200 is lost to be     --><br>+<!-- able to retransmit it if we receive the BYE again.               --><br>+<pause milliseconds="4000"/><br>+<br>+<br>+<!-- definition of the response time repartition table (unit is ms)   --><br>+<ResponseTimeRepartition value="10, 20, 30, 40, 50, 100, 150, 200"/><br>+<br>+<!-- definition of the call length repartition table (unit is ms)     --><br>+<CallLengthRepartition value="10, 50, 100, 500, 1000, 5000, 10000"/><br>+<br>+</scenario><br>+<br>diff --git a/tests/fax/pjsip/t38_fast_reject/test-config.yaml b/tests/fax/pjsip/t38_fast_reject/test-config.yaml<br>new file mode 100644<br>index 0000000..64b4883<br>--- /dev/null<br>+++ b/tests/fax/pjsip/t38_fast_reject/test-config.yaml<br>@@ -0,0 +1,13 @@<br>+testinfo:<br>+    summary: 'Test that asterisk does not drop the call after it rejects the T38 reinvite from the carrier side because customer does not suport it.  It also makes sure that the rejection happends quickly'<br>+    description: |<br>+        'Test that asterisk does not drop the call after it rejects the T38 reinvite from the carrier side because customer does not suport it.  I also measures the 488 response time and make sure it happends quckly'<br>+<br>+properties:<br>+    minversion: '13.16.0'<br>+    dependencies:<br>+        - python : 'twisted'<br>+        - python : 'starpy'<br>+<br>+    tags:<br>+        - PJSIP<br>diff --git a/tests/fax/pjsip/tests.yaml b/tests/fax/pjsip/tests.yaml<br>index a7e8bda..3edf0c2 100644<br>--- a/tests/fax/pjsip/tests.yaml<br>+++ b/tests/fax/pjsip/tests.yaml<br>@@ -6,3 +6,4 @@<br>     - test: 'directmedia_reinvite_t38'<br>     - test: 'gateway_t38_g711'<br>     - test: 'gateway_native_t38'<br>+    - test: 't38_fast_reject'<br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/5901">change 5901</a>. To unsubscribe, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/5901"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: testsuite </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ida087c3d410c95c87aeca506c81eabe8bde062ef </div>
<div style="display:none"> Gerrit-Change-Number: 5901 </div>
<div style="display:none"> Gerrit-PatchSet: 4 </div>
<div style="display:none"> Gerrit-Owner: Torrey Searle <tsearle@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins2 </div>
<div style="display:none"> Gerrit-Reviewer: Joshua Colp <jcolp@digium.com> </div>