VOIP中DTMF传输方式和实现
可以通过三种模式参考下面链接。
DTMF三种模式(SIPINFO,RFC2833,INBAND) - 闯爷88 - 博客园
根据业务需要和代码的实现方便考虑,最终决定用SIP去获取UA客户端上来的DTMF按键值。
1)我们使用了三汇的电话网关,在配置页面中找到发送DTMF模式,我们选择信令发送,即SIP发送。

2)拨打电话使电话网关发送Sip协议的数据到我们开发的软电话中。
3)使用wireshark抓取Sip包,分析DTMF数据存在的位置。
目前Cisco SIPINFO为标准,通过SIPINFO包中的signal字段识别DTMF按键。
三汇网关中同样SIP协议INFO包作为DTMF发送数据包。signal同样表示了一个按键的信息。
下图一串便是,我们按键的信息。一此按键一条数据。比如现在第一条我们按下是“1”。

4)通过代码解析出来,做后续业务的开发。
我们需要把按键都解析出来,同时判断是否“#”。如果收到#表示用户输入结束。
比如我这里要求输入密码:在收到DTMF的数字后,我们和后台数据库数据比较,如果正确就认证通过,能执行广播操作。
代码解析,主体是思路是读取message body的信息,然后获取signal字段信息。
部分代码如下:
package net.sourceforge.peers.sip.syntaxencoding;
import net.sourceforge.peers.sip.transport.SipRequest;
public class Dtmf {
public static byte getDtmfValue(SipRequest sipRequest){
byte[] body = sipRequest.getBody();
byte dtmf = 0;
if(body[7] == '1'){
if(body[8]=='1'){
dtmf = '#';
}else{
dtmf = body[7];
}
}else {
dtmf = body[7];
}
return dtmf;
}
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步