分类: LINUX
2012-11-22 16:37:32
author:张继飞
voip的呼叫保持(hold)是在 SDP 协议中实现的,记得以前做这部分时,曾出现过voip一方操作hold之后,在 SDP 包里面的media 参数里带有sendonly,服务器回复的200OK消息 SDP 包的media参数里面没有recvonly,而是sendrecv,这样的话,表示服务器没有识别出该re-invite是hold,便不会给对方播放 hold music,导致rtp的流向也出现差错。
后来经过多方查阅资料,以及对SDP协议的分析,发现在hold时,需要将SDP 包中的connection information 中的address 改为0.0.0.0,resume后,在改为当前的media-address。
但后来更新了sip server的版本后,又发生了server不识别hold的问题。 因为将Trixbox升级到了2.8.0.4才出现的问题,所以下载了最新的Asterisk进行分析,找到sever处理hold部分的源码,在各个分 支处发现对SDP的owner是有要求的,该 o 字段主要包括 username session ID,session Version,network type,address type和address。这里需要关注的是session Version,第一个re-invite要比invite的session Version 值大,后面的re-invite要比前面的re-invite的session Version值大;我在初始invite时便用随机方式产生一个session Version值,然后在re-invite时便对该值进行++操作,便解决了这个问题。同理作为被叫时,在对invite回复200OK时也是用随机方 式给session Version赋值。
因为之前我对于session ID 和session Version用的都是具有特殊含义的固定值。
c=IN IP4 0.0.0.0 就hold了。