FreeSWITCH被叫忙处理

问题:1002分机与1001分机正在通话,此时1003分机打给1001,怎么让1003分机知道1001正忙,拨一段语音,diaplan要怎么配置?

类似的问题有很多同学问到,这里,我们来看一下解决方案。

在传统的PSTN电话中,一个电话只能接听一路呼叫,如果被叫忙,主叫就会听到忙音。而在SIP电话中,大多数的SIP话机或者软电话都可以支持多路通话,所以,被叫一般不会那么“忙”。但,总是有些人怀念原来的习惯,希望SIP电话也跟以前用的电话表现起来一模一样。

最理想的解决方案,就是什么都不干。如A通过FS呼叫B,在B忙的情况下,B的终端会回486 BUSY HERE SIP消息,FS收到后转发给A,A收到486消息,播放指定的声音(这个声音可以在A的客户端配置,由于SIP终端本身就是智能终端,这不是什么事)。

然后,现实世界总是不那么理想。尤其是,现实世界是多样的。比方说,A可能是个PSTN话机,这样的话,就需要依赖FS给A播放一段声音。

好吧,我们继续尝试其实的解决方案。其实解决该问题,最简单的办法我们曾经讲过(参见『阅读原文』)。找一个仅支持一路呼叫的SIP话机,如果第二路呼叫进来,话机就会拒绝,并发送486(代表忙)SIP消息。在FreeSWITCH中就能收到USER_BUSY的挂机原因,然后,……

说到这里,还有没有其它的解决方案呢?当然有,只有想不到,没有做不到。

FreeSWITCH提供了一个limit App,专门做限制。当然,要理解limit,还需要多了解FS的一些基础知识。

好吧,我们先来做个实验。对于本节的问题,我们做如下Dialplan:

<extension name="busy">
  <condition field="destination_number" expression="^(100[1-3])$">
    <action application="bridge" data="user/$1"/>
  </condition>
</extension>

上面这个Dialplan大家都比较熟悉了,当1002呼叫1001时,使用bridge把两者桥接起来。

好了,祭出我们的limit大神。limit的语法如下:

limit <backend> <realm> <resource> <max[/interval]> [<transfer_destination_number> [<dialplan> [<context>]]

其中,backendlimit的后台,可以是hash(存在内存的哈希表里),db(存在数据库里)以及redis(存在redis里)等;而realm是一个域,可以是任意值,在多租户环境下,一般用当前的domainresource表示对哪些资源进行限制,可以是一个分机号;max是限制的最大值,后面有个可选的interval,表示在多长时间内该最大值有效;transfer_destination_numberdialplancontext是可选的,表示,如果超出限制,要transfer到哪个Dialplan。

参照上面的语法,我们做如下Dialplan:

<extension name="busy">
  <condition field="destination_number" expression="^(100[1-3])$">
    <action application="limit" data="hash ${domain} $1 1 user_busy XML default"/>
    <action application="bridge" data="user/$1"/>
  </condition>
</extension>


<extension name="busy">
  <condition field="destination_number" expression="^user_busy$">
    <action application="playback" data="user_busy.wav"/>
  </condition>
</extension>

有了上述Dialplan,当有用户呼叫1001时,会先执行limit,对当前的被叫号码1001的资源占用数加1。如果在通话过程中用第二个电话呼叫1001,则由于超出了资源限制,系统会自动转接到user_busy处,播放一个用户忙的语音提示 user_busy.wav

细心的读者可能发现,其实我们上面做的不够全面。如果1002呼叫1001,那么,当有用户呼叫主叫号码1002时,也应该播放忙音。原来的问题没有说明1001到底是主叫还是被叫,这是提问者提的不够完善的地方,不过,无论如何,我们可以同时用两个limit限制两个资源,如:

<action application="limit" data="hash ${domain} $1 1 user_busy XML default"/>
<action application="limit" data="hash ${domain} ${caller_id_number} 1 user_busy"/>

好了,打个电话,我们可以在日志里看到类似如下的内容:

[DEBUG] switch_limit.c:126 incr called: 192.168.7.6_1002 max:1, interval:0
[DEBUG] mod_hash.c:196 Usage for 192.168.7.6_1002 is now 1/1
[DEBUG] switch_limit.c:126 incr called: 192.168.7.6_1001 max:1, interval:0
[DEBUG] mod_hash.c:196 Usage for 192.168.7.6_1001 is now 1/1

挂断电话,看到资源被释放了:

[DEBUG] mod_hash.c:297 Usage for 192.168.7.6_1002 is now 0
[DEBUG] mod_hash.c:297 Usage for 192.168.7.6_1001 is now 0

在上述解决方案中,如果主被叫都是在内网上,当然是没有问题的。但是,如果主叫是PSTN呼入的,一般的运营商不允许你在应答(answer)前播放语音(即它们不会透传Early Media),所以,你需要在playback前加上一个answer,这是运营商的限制。不过,加了answer以后又破坏了这么做的语义,本来你是想在应答之前通过Early Media通知主叫被叫忙,电话打不通本来不应该收费的,加了answer会触发计费。

所以,如果你有PSTN的主叫的话,你可以尝试直接在SIP中返回用户忙,由运营商来给主叫用户播放忙音提示。Dialplan如下:

<extension name="busy">
  <condition field="destination_number" expression="^user_busy$">
    <action application="respond" data="486"/>
  </condition>
</extension>

部分日志供参考:

[INFO] mod_hash.c:183 Usage for 192.168.7.6_1002 is already at max value (1)
[NOTICE] switch_ivr.c:2167 Transfer sofia/internal/1000@192.168.7.6 to XML[user_busy@default]
Dialplan: sofia/internal/1000@192.168.7.6 parsing [default->busy] continue=false
[DEBUG] switch_core_state_machine.c:328 sofia/internal/1000@192.168.7.6 Standard EXECUTE
EXECUTE sofia/internal/1000@192.168.7.6 respond(486)
[DEBUG] switch_core_state_machine.c:60 sofia/internal/1000@192.168.7.6 Standard HANGUP, cause: USER_BUSY
send 869 bytes to udp/[192.168.7.6]:16664 at 14:37:53.273916:
   ------------------------------------------------------------------------
   SIP/2.0 486 Busy Here

在本文完成后,笔者又发现了另一种用法。如果最后只是返回USER BUSY,不用单独写一个Dialplan Extension,而是直接在limit的参数中写上即可,如:

<action application="limit" data="hash ${domain} $1 1 !USER_BUSY"/>

注意,USER_BUSY前面应该有个叹号。


转自:https://blog.csdn.net/jiangzhengcn/article/details/52093841
本文转自FreeSWITCH中文社区微信公众号

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值