团队博客

SIPp 的 uac-prack.xml 和 uas-prack

韩小仿  2024-05

要实现下面的呼叫流程:

  ----------> INVITE 
  <---------- 183    
  ----------> PRACK  
  <---------- 200    
  <---------- 200    
  ----------> ACK    
  ----------> BYE    
  <---------- 200

uac-prack.xml 的内容为:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">

<scenario name="Basic UC360 UAC">

  <send retrans="500">
    <![CDATA[

      INVITE sip:[service]@[remote_ip]:[remote_port] SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
      From: 16001 <sip:16001@[remote_ip]:[remote_port]>;tag=[call_number]
      To: <sip:[service]@[remote_ip]:[remote_port]>
      Call-ID: [call_id]
      CSeq: 10 INVITE
      Contact: <sip:16001@[local_ip]:[local_port];transport=[transport]>
      Content-Type: application/sdp
      Max-Forwards: 70
      Supported: 100rel
      Require: 100rel
      Content-Length: [len]

      v=0
      o=16001 0 0 IN IP[local_ip_type] [local_ip]
      s=-
      c=IN IP[media_ip_type] [media_ip]
      t=0 0
      m=audio [media_port] RTP/AVP 0 8 101
      a=sendrecv
      a=rtpmap:0 PCMU/8000
      a=rtpmap:8 PCMA/8000
      a=rtpmap:101 telephone-event/8000
      a=fmtp:101 0-11,15

    ]]>
  </send>

  <recv response="100" optional="true">
  </recv>

  <recv response="183" rrs="true">
    <action>
      <ereg regexp=".*" search_in="hdr" header="CSeq:" check_it="true" assign_to="cseq" />
      <ereg regexp=".*" search_in="hdr" header="RSeq:" check_it="true" assign_to="rseq" />
    </action>
  </recv>

  <send retrans="500">
    <![CDATA[

      PRACK [next_url] SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
      From: 16001 <sip:16001@[local_ip]:[local_port]>;tag=[call_number]
      To: <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
      Call-ID: [call_id]
      CSeq: 11 PRACK
      [routes]
      RAck: [$rseq][$cseq]
      Contact: <sip:16001@[local_ip]:[local_port];transport=[transport]>
      Max-Forwards: 70
      Content-Length: 0

    ]]>
  </send>

  <!-- receive 200 OK / PRACK  -->
  <recv response="200">
  </recv>

  <!-- receive 200 OK / INVITE -->
  <recv response="200">
  </recv>

  <send>
    <![CDATA[

      ACK [next_url] SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch-5]
      From: "16001" <sip:16001@[remote_ip]:[remote_port]>;tag=[call_number]
      To: <sip:[service]@[remote_ip]:[remote_port]>[peer_tag_param]
      Call-ID: [call_id]
      CSeq: 10 ACK
      [routes]
      Content-Length: 0

    ]]>
  </send>

  <pause/>

  <send retrans="500">
    <![CDATA[

      BYE [next_url] SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch-1]
      From: "16001" <sip:16001@[remote_ip]:[remote_port]>;tag=[call_number]
      To: <sip:[service]@[remote_ip]>[peer_tag_param]
      Call-ID: [call_id]
      CSeq: 12 BYE
      [routes]
      Contact: <sip:16001@[local_ip]:[local_port];transport=[transport]>
      Max-Forwards: 70
      Content-Length: 0

    ]]>
  </send>

  <recv response="200">
  </recv>

  <!-- 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>

uas-prack.xml 的内容为:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE scenario SYSTEM "sipp.dtd">

<scenario name="Basic UAS">
  <recv request="INVITE" rrs="true">
    <action>
      <ereg regexp=".*" search_in="hdr" header="CSeq:" check_it="true" assign_to="invite_cseq" />
      <ereg regexp=".*" search_in="hdr" header="Via:" check_it="true" assign_to="invite_via" />
    </action>
  </recv>

  <send>
    <![CDATA[

      SIP/2.0 183 Session in Progress
      [last_Via:]
      [last_From:]
      [last_To:];tag=[call_number]
      [last_Call-ID:]
      [last_CSeq:]
      [last_Record-Route:]
      Require: 100rel
      RSeq: 1
      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
      Content-Length: [len]

      v=0
      o=16002 0 0 IN IP[local_ip_type] [local_ip]
      s=-
      c=IN IP[media_ip_type] [media_ip]
      t=0 0
      m=audio [media_port] RTP/AVP 0 8 101
      a=sendrecv
      a=rtpmap:0 PCMU/8000
      a=rtpmap:8 PCMA/8000
      a=rtpmap:101 telephone-event/8000
      a=fmtp:101 0-11,15

    ]]>
  </send>

  <recv request="PRACK">
  </recv>

  <send>
    <![CDATA[

      SIP/2.0 200 OK
      [last_Via:]
      [last_From:]
      [last_To:]
      [last_Call-ID:]
      [last_CSeq:]
      [last_Record-Route:]
      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
      Content-Length:  0

    ]]>
  </send>

  <send retrans="500">
    <![CDATA[

      SIP/2.0 200 OK
      Via: [$invite_via]
      [last_From:]
      [last_To:]
      [last_Call-ID:]
      [last_Record-Route:]
      CSeq: [$invite_cseq]
      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
      Content-Type: application/sdp
      Content-Length: [len]

      v=0
      o=16002 0 0 IN IP[local_ip_type] [local_ip]
      s=-
      c=IN IP[media_ip_type] [media_ip]
      t=0 0
      m=audio [media_port] RTP/AVP 0 8 101
      a=sendrecv
      a=rtpmap:0 PCMU/8000
      a=rtpmap:8 PCMA/8000
      a=rtpmap:101 telephone-event/8000
      a=fmtp:101 0-11,15

    ]]>
  </send>

  <recv request="ACK">
  </recv>

  <recv request="BYE">
  </recv>

  <send>
    <![CDATA[
      SIP/2.0 200 OK
      [last_Via:]
      [last_From:]
      [last_To:]
      [last_Call-ID:]
      [last_CSeq:]
      Content-Length: 0
    ]]>
  </send>

  <!-- 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>

这两个 xml 都支持 SIP Proxy Server,如 Kamailio 和 OpenSIPS。与此相关的元素有 rrs[routes][next_url 以及 [last_Record-Route:]

此外,我们可以留意到 uac-prack.xml 里面 INVITE 是一个事务,该事务在结束之前又有一个新的 PRACK 事务,

需要在收到 INVITE 消息把 CSeq 以及 Via 记到变量,等 PRACK 事务处理完毕,回 200 INVITE 时恢复 CSeq 和 Via 的值。

Poly 终端配置说明