团队博客
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 的值。