前几天做项目的时候,在配置OCS和OXE集成的时候,出现了一个奇怪的问题,OCS用户在呼叫PSTN的电话之后,在通话几秒钟之后就会被挂断。后来经过研究数据包之后发现,原来在初始会话之后,OXE会认为OCS已经挂了电话了,所以就自己切断了电话,然后用户就会听到被挂断了。那么为什么OXE会认为OCS已经挂了电话呢。经过分析,发现原来是SDP中的ptime在做怪。

不熟悉的人就会问什么是SDP,什么又是ptime呢,我们通过一个数据包来说明问题。

 

INVITE sip:1234@192.168.1.188;user=phone SIP/2.0
Via: SIP/2.0/TCP 192.168.0.187;branch=z9hG4bKac1249113045;alias
Max-Forwards: 70
From: <sip:8806@192.168.0.187>;tag=1c1249104277
To: <sip:1234@192.168.1.188;user=phone>
Call-ID: 1249103873932000223659@192.168.0.187
CSeq: 1 INVITE
Contact: <sip:8806@192.168.0.187;transport=tcp>
Supported: em,timer,replaces,path,resource-priority
Allow: REGISTER,OPTIONS,INVITE,ACK,CANCEL,BYE,NOTIFY,PRACK,REFER,INFO,SUBSCRIBE,UPDATE
User-Agent: Audiocodes-Sip-Gateway-MP-118 FXS_FXO/v.5.20A.043
Content-Type: application/sdp
Content-Length: 235

v=0
o=AudiocodesGW 1249096399 1249096282 IN IP4 192.168.0.187
s=Phone-Call
c=IN IP4 192.168.0.187
t=0 0
m=audio 6000 RTP/AVP 8 101
a=rtpmap:8 PCMA/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-15
a=ptime:20
a=sendrecv

上面就是我们一个再也熟悉不过的SIP数据包了。而SDP全称是Session Description Protocol,就是会话描述协议,上面红色部门部门就是SDP的内容了,通过SDP,建立会话的UA之间会协商好RTP流的一些基本内容,比如说负载的类型等。而ptime也是SDP的内容之一。

官方给出的ptime的定义是:ptime gives the length of time in milliseconds represented by the media in a packet。简单来讲就是一个数据包中媒体的时长,以毫秒为单位。ptime:20就是定义为20毫秒。上面这条由User-Agent: Audiocodes-Sip-Gateway-MP-118 FXS_FXO/v.5.20A.043所发出来的消息就是告诉对方,要和交流的话,你就要按照我描述的这一些规则来,比如说媒体的时长就应该为20毫秒。

由OCS中介服务器发出的sip invite中,通过抓包我们可以看出ptime为20。而通过查看OXE的配置发现,默认的不是20,而是30。虽然数据不一样,但是两者居然还可以通讯,也是奇怪。后来把OXE中相关的参数修改为20后,问题得到完美解决,没有再发生通话过程中掉线的情况。

顺便提一下标蓝色部分一个非常关键的部分,中文翻译为负载。一般的媒体协商不成功都是这个值出现不匹配。以后再详细分析一下这个字段。