先看这段代码:
应用调用 senddtmf,这段代码会检查 dtmf-type 这个通道变量的值
- 如果为 DTMF_2833,那么调用核心的 queue_rfc2833 函数
- 如果为 DTMF_INFO,如果为 w 或者 W 就延时相应的时间,或者是其它字符,那么发送 SIP INFO 请求
- 如果为 NONE(inband),那么什么都不做(如果想发inband dtmf,不要用 sendmf,要用TGML)
为了讲述方便,还是分开来说
如果是 dtmf-type 为 DTMF_2833,调用 queue_rfc2833 函数,后者记录到通道的发送缓冲区,最后是在 switch_rtp.c 的 do_2833() 函数里面处理,有兴趣的读者可以去查阅对应的源代码。需要留意的是,这个操作是异步的,比如有些应用可能这样调用:
1.senddtmf("1234567890")
2.playback("welcome.wav")
但执行的结果出于的您的意料,senddtmf 会干扰 playback
正确的操作应该是:
1.senddtmf("1234567890")
2.sleep
3.playback("welcome.wav")
需要延时多长时间,我没做研究
下面讨论 DTMF_INFO 的情况
1. senddtmf 一次只能发送一个字符
2. 如果要连续发送多个字符,中间应该不需要延时(或者很少延时)
3. 发送 SIP INFO 要比 2833 快
4. 需要远端支持 SIP INFO,如果远端正好是 FreeSWITCH,那么建议配置 liberal-dtmf
最后还有一点需要提及的是,如果 dtmf-type 配置为 DTMF_2833, 还是可以发送 SIP INFO 的,但是不能用 senddtmf,而是用 uuid_send_info,但要记得设置通道变量 fs_send_unsupported_info 为 true
下面是例子:
# 也可以把这个变量配置为全局
uuid_setvar 2fa023f5-9bc1-4e81-9330-54a205eef06f fs_send_unsupported_info true
uuid_send_info 2fa023f5-9bc1-4e81-9330-54a205eef06f application dtmf-relay Signal=6\r\nDuration=300\r\n
发出去的 SIP 消息如下:
INFO sip:1002@192.168.43.68:1025 SIP/2.0
Via: SIP/2.0/UDP 192.168.43.68;rport;branch=z9hG4bKav8y77Q71vySQ
Max-Forwards: 70
From: "9196" <sip:9196@192.168.43.68>;tag=c6aUcg81j9gpp
To: <sip:1002@192.168.43.68>;tag=5b554b38
Call-ID: N2IyODI2NmYwYTAzMmMwZjg2N2M1MDg4ODBkMGQzMWI.
CSeq: 82334666 INFO
Contact: <sip:9196@192.168.43.68:5060;transport=udp>
Allow: INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, INFO, UPDATE, REGISTER, REFER, NOTIFY, PUBLISH, SUBSCRIBE
Supported: timer, path, replaces
Content-Type: application/dtmf-relay
Content-Length: 24Signal=6
Duration=300
dmtf 的故事实在多了去