GOIP 无线网关 (GSM网关) 电话接通后前几秒没声音原理

最近很多电话机器人用户反应GOIP在内网,自动外呼接通后,偶尔出现前几秒听不到声音,由于找不到一个测试环境,一直没去分析,昨天jake提供了一个测试环境给我,我经FS源代码分析和抓包分析,终于搞清楚了问题的原因。

怎么样重现这个问题

jake给我提供的测试的是 鼎信通达网关(dinstar),上面不是说了是偶尔出现吗?任何问题应该独有规律的,那么出现规律是什么呢?

  • 一般要被叫手机没开通彩铃(没具体测试,我猜的)
  • 被叫电话接起来后不要发出任何声音(就是被叫接通后不要说话)

重现问题的条件

  • 外呼的时候设置了 ignore_early_media=true这个变量。
  • 网关在NAT后面,SDP的RTP地址是内网地址。

    v=0
    o=- 14055 14057 IN IP4 192.168.1.236
    s=VOS2009
    c=IN IP4 192.168.1.236
    t=0 0
    m=audio 8048 RTP/AVP 0
    a=rtpmap:0 PCMU/8000
    a=ptime:20
    a=sendrecv
  • 网关开启了静音抑制功能,就是静音的时候发送 Comfore noise,而不在发送RTP包了。

为什么会出现这个问题

  • 设置了ignore_early_media=true这个变量后freeswitch 就会忽略早期媒体。电话应答后才开始处理RTP包。
  • 电话接通后 200 OK的 SDP 是内网IP,freeswitch会把包发送到了这个不可达的内网Ip。
  • 网关开启了静音抑制(如果电话接通后用户不说话),网关就不会向freeswitch发送RTP包。
  • 用户说话后或者外部出现一定噪音,网关发送RTP到freeswitch,freeswitch收到RTP包后,就会把RTP发送到这个正确的IP地址了。

怎么解决这个问题

  • 方法1.网关关闭静音抑制功能。
  • 方法2 不设置 ignore_early_media=true,使用 wait_for_answer来等待用户接听,也可以解决这个问题。因为没设置ignore_early_media的时候fs接收到,网关发送过来的早期媒体(彩铃,回铃)的时候,就可以知道网关的正确RTP地址了。

下载本次分析的抓包文件