先用两台话机做一个小闭环
沿用 7101、7102 和前几期的 training-internal 测试入口。7101 拨 7813,看到话机已接听后按 12,预期 7102 响铃。按 99 或一直不按,应该重试,机会用完就转到失败分支。7813 是收号入口,7814 是本例的失败路由,7102 是目录里的 SIP 分机。这个实验直接呼叫分机,队列 agent 的联系地址和 tier 的分配关系沿用原来的设置。
准备一套可回退的测试实例,两台已经能双向通话的话机和抓包权限。先让媒体经过 FS 正常处理,沿用第 11 期已验证的共同编码。第 12 期若还保留了代理或绕过媒体的试验设置,先恢复普通媒体路径。下面的配置依据 v1.11.2 版本模板和源码、现行手册及 RFC 4733 核对,预期结果需在本机验收。
把传输方式和菜单规则分开看
DTMF 是电话按键。常见传法有三种。RTP telephone-event 把按键编号、持续时间和结束标记放进媒体流的事件包。SIP INFO 把按键送在对话内的信令消息里,消息内容还要与对端约定。带内按键音则混在语音里,由接收侧从音频识别。能听见对方说话时,按键仍可能走另一套传法。
这个实验先让 7101 使用电话事件模式,话机菜单上常写 RFC2833 或 RTP Event。标准后来由 RFC 4733 更新,配置名称仍沿用旧叫法。通话建立时,查 7101 那条腿的音频 SDP 有没有协商 telephone-event,再按当通的 payload type 解码抓包。101 是官方模板里的常见值,换中继或话机后可能不同。负载类型数字用于区分 RTP 载荷格式,按下的数字另在事件字段里。
FS 的 SIP Profile 用 dtmf-type 指定发送方式。实验 Profile 已能协商电话事件时,可以先保留现有设置。若测试入口被改成 info,就在备份后核对 sip_profiles/training-internal.xml 的 settings,在实验窗口改回 rfc2833 并重启该 Profile,接着重新注册话机。只改话机或只改发送方式都可能留下方向不一致的问题,抓包要看实际接收的那条腿。
加一条能成功也能失败的收号路由
在 fs_cli 执行 eval $${conf_dir} 查看配置根目录,也可从现有启动参数确认。检查 7101 认证后进入的 context,下面以 default 为例。保存为 dialplan/default/00_training_dtmf_13.xml,先确认 7813、7814 未被占用,且目录已被包含。若用其他受控 context,把文件放进对应加载路径,并同步改失败转移里的 default。这个测试入口放在已认证的内网路由内。
<include>
<extension name="fs_dtmf_lab_13">
<condition field="destination_number" expression="^7813$">
<!-- 接听后收两个键,仅接受12 -->
<action application="answer"/>
<action application="unset" data="lab_digits"/>
<!-- 失败跳到7814,两次机会,首键5秒、键间2秒 -->
<action application="play_and_get_digits"
data="2 2 2 5000 # silence_stream://500 silence_stream://300 lab_digits ^12$ 2000 '7814 XML default'"/>
<!-- 这里只记录实验输入通过,避免把按键值写进日志 -->
<action application="log" data="INFO DTMF_LAB_ACCEPTED"/>
<action application="set" data="hangup_after_bridge=true"/>
<!-- 使用现有目录域定位被叫分机 -->
<action application="bridge" data="user/7102@${domain_name}"/>
</condition>
</extension>
<extension name="fs_dtmf_lab_13_failed">
<condition field="destination_number" expression="^7814$">
<!-- 实验收号失败,结束当前通话 -->
<action application="log" data="INFO DTMF_LAB_REJECTED"/>
<action application="hangup" data="NORMAL_CLEARING"/>
</condition>
</extension>
</include>
前两个 2 是最少和最多数字位数,第三个 2 是总尝试次数。5000 是每轮开始收号后等待首键的毫秒值,2000 是已收到首键后的键间等待。井号可以提前结束收号,达到最大位数也能完成,按完 12 可以直接等结果。只按一个数字就结束时,长度不够,按 99 则会因正则不符进入重试。
两个 silence_stream 分别给正常提示和错误提示留出 500、300 毫秒的静音,便于无语音文件的测试机执行。使用安装了对应音频文件接口的常规构建。实际菜单可换成可读取的提示音,带空格的路径需按应用参数规则处理。正则 ^12$ 限定整个输入,lab_digits 用来存收号结果,失败转移字段指定号码、拨号计划和 context。清除旧变量后再收号,便于同一通道重复进入时辨认新结果。
成功分支通过目录查找 7102,domain_name 应当与上期已验证的目录域一致。失败分支只记测试标记并挂机。业务日志一般保留结果和通道标识即可,收号内容可能是账号或密码,采集测试抓包也用虚拟输入。
加载与逐层验收
在 fs_cli 执行 reloadxml,然后从 7101 新拨 7813。只改拨号计划无需重启 Profile。核对进入的 extension、接听状态和实际 bridge 目标。按 12 应看到成功标记及 7102 响铃,接起后听一遍双向语音。另拨一次按 99,再另拨一次不按键,验证两轮后进入 7814。还可以按 1 后等超过两秒,确认键间超时能进重试。实际等待还包括提示音与应用处理,观察时分开计时。
如果终端发了按键而没有桥接,按同一通道和时间对照入口抓包、FS DTMF 事件与拨号计划日志。包没进来,先检查电话事件协商及网络路径。事件已经进 FS,但应用仍失败,就核对按键长度、正则、首键与键间等待,并看有没有其他应用先消费了按键。若收号通过却没响铃,再查 7102 注册定位和桥接结果。
几个常见设置怎样配合
- 对端只发 SIP INFO。先看真实 INFO 消息和对端约定,再单独测试支持该方式的路线。发送方向可核对 dtmf-type 或呼叫级 dtmf_type,避免为一条中继修改全局。
- 能听见按键音,FS 没有事件。确认是带内音后,在普通媒体模式的收号前试用 start_dtmf,结束检测时用 stop_dtmf,或者由测试通话结束清理。在同时有电话事件的线路上,要检查两路是否重复触发。
- 持续时间或间隔被混为一谈。模板中的 dtmf-duration 是生成事件的持续时间,按 8000 Hz 时钟计,2000 对应 250 毫秒。rtp-digit-delay 用毫秒控制发送的键间延迟。两者都与应用等待用户下一键的 digit_timeout 分开。
- 一次按键在抓包里有多个事件包。普通短按的多个报告可共享起始时间戳,结束报告也可能重复。先在同一 RTP 流里核对事件和时间戳,再看 FS 实际交给应用几个数字。liberal-dtmf 可以扩大接收兼容范围,启用后仍应验证单键、长按与连续同键都按预期处理。
试验结束时结束测试通话,把新增 XML 移出包含目录并 reloadxml。如果调整了 Profile 或话机传输设置,恢复备份,在测试窗口重启对应 Profile 并重新注册。用原来的 7101、7102 互拨和实际 IVR 回归,确认测试号码不再命中这条实验路由。