sip hold 解決方法【原創】
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用的都是具有特殊含義的固定值。