跨FreeSWITCH的SIP呼叫
一般情况下,SIP通话很少在同一个FreeSWITCH实例内部,大多会跨FreeSWITCH进行通话(或者走中继线路),下面我们来看看如何实现跨FreeSWITCH通话。
写在前面的话
本次实验涉及到了拨号计划的配置,为了避免原来默认的拨号计划干扰,建议将conf/dialplan
下面的default.xml
和public.xml
备份,然后新建两个纯净的拨号计划。
本次实验中第二个FS使用的拨号计划如下:
- default.xml
1 | <?xml version="1.0" encoding="utf-8"?> |
- public.xml
1 | <include> |
启动多个FreeSWITCH实例
FreeSWITCH是支持在同一台主机上启动多个实例的,如果希望启动多个实例,只需要复制一份原来FreeSWITCH的配置文件,修改一些端口即可。
复制配置文件
1 | mkdir -p /usr/local/freeswitch2/ |
建立软连接是为了确保新实例可以访问声音文件。
修改端口信息
修改Event Socket端口
编辑/usr/local/freeswitch2/conf/autoload_configs/event_socket.conf.xml
,将8021端口修改为28021端口。1
<param name="listen-port" value="28021"/>
修改RTP端口范围
编辑/usr/local/freeswitch2/conf/autoload_configs/switch.conf.xml
1
2<param name="rtp-start-port" value="17000"/>
<param name="rtp-end-port" value="20000"/>注意:多个FS之间的RTP端口不能重叠,否则可能打电话的时候可能会串线。
修改SIP端口
编辑/usr/local/freeswitch2/conf/vars.xml
,找到internal_sip_port, internal_tls_port, external_sip_port, external_tls_port
,把后面的端口前面都加一个2(加2没有任何特殊意义,只是为了和第一个FS的端口进行区分)
启动第二个实例
使用如下命令启动第二个FS实例:
1 | freeswitch -conf /usr/local/freeswitch2/conf/ -db /usr/local/freeswitch2/db -log /usr/local/freeswitch2/log -nc -nonat |
登录控制台
1 | fs_cli -P 28021 |
因为两个FS都是在同一台主机上,上面的命令省略了-H
参数,默认的host就是当前机器。
截止到目前为止,第二个FS的实例已经启动完毕了,接下来在第二个实例中创建一些用户(就从21000开始吧,和第一个FS的用户区分开)。
跨FreeSWITCH的SIP呼叫
网关-注册模式
如果我们拥有另外一个FS的账号,那么我们就可以给另一个FS上的账户进行SIP通话了,这个FS的账号被称为SIP网关。要建立一个SIP网关,只需要在conf/sip_profiles/external
下新建一个xml文件即可,具体内容可以参考同级目录下的example.xml
。
我们新建的网关的配置文件如下:
1 | <gateway name="gw-fs-2"> |
在第一个FS的控制台,执行sofia profile external rescan
即可刷新到新的网关配置,通过sofia status
指令,可以查看新网关是否生效。
1 | freeswitch@ubuntu> sofia status |
如果发现网关处于REGED
状态,说明网关已经成功注册到了第二个FS上。
修改第二个FS的dialplan/public.xml
,增加如下内容,然后在控制台刷新配置reloadxml
。
1 | <extension name="public_extensions_1"> |
此时我们可以尝试使用命令接通两个FS,在第一个FS的控制台输入如下指令:
1 | originate user/1001 &bridge(sofia/gateway/gw-fs-2/02721001) |
如果不出意外的话,此时登录了1001账户的SIP电话会先响铃,接通之后,登录21001的SIP账户也会响铃,双方都接通之后,就可以进行通话了,任何一方挂断之后,整个通话就结束了。
需要说明的是,此时这两个账户是不能通过SIP电话直接进行通话的,因为第一个FS上没有配置相关的拨号计划,如果我们希望从SIP电话上进行测试,需要在第一个FS的conf/dialplan/default
目录下新建一个拨号计划,内容如下:
1 | root@ubuntu:/usr/local/freeswitch/conf/dialplan/default# cat out-call-fs-2.xml |
拨号计划中的正则表达式为^027(21d{3})$
,意思是匹配027
开头的,然后是21开头的5位数字。027
在这里被称为出局字冠(以前叫电话局,拨打外部电话叫出局)。
新建完毕拨号计划之后,需要在第一个FS上执行reloadxml
命令,然后就可以在登录了1001
账户的SIP电话上拨打第二个FS上的账户了,特别要注意的是,拨打21001
的时候,需要在前面增加027
,完整的被叫号码是02721001
需要注意的是<action application="bridge" data="sofia/gateway/gw-fs-2/027$1"/>
,这里的027(027$1)是和第二个FS约定的被叫前缀改写(因为第二个FS的拨号计划要求了匹配027开头的内容,当然,这里的027也可以换成其他的内容,只要保持一致即可),和第一个FS的出局字冠没有关系,为什么需要改写被叫前缀呢,这个后面会讲到。
网关-非注册模式
上面我们使用了网关的注册模式完成了跨FS的电话拨打,这样对接的方式比较安全,但是需要知道另外的FS的账号和密码,对于第二个FS来讲,可能不是那么友好了(如果对接10个FS,岂不是要占用10个账户?)。因此,还有一种网关的对接方式,只需要知道对方的IP即可,通过IP来识别来源是否合法,这个功能就是ACL。
修改第二个FS的ACL控制列表(该文件在freeswitch2/conf/autoload_configs/acl.conf.xml
),允许第一个FS所有服务器的IP访问,内容如下:
1 | <list name="lan" default="allow"> |
第一个FS所有的IP为192.168.3.211。
为了测试,可以删除第一个FS的网关配置文件中的用户和密码,修改之后的内容如下:
1 | <gateway name="gw-fs-2"> |
重新刷新网关的配置文件,然后该网关的状态将会变成NOREG
1 | freeswitch@localhost> sofia profile external rescan |
此时在第一个FS上,执行originate user/1004 &bridge(sofia/gateway/gw-fs-2/02721002)
命令。
如果是按找本文档顺序执行的话,此时应该可以接通两个电话了,但是如果没有执行「网关-非注册模式」中的步骤,则会被第二个FS的拨号计划拦住,应为找不到拨号计划,处理起来也简单,新建相应的拨号计划即可,此处就不再赘述了。
SIP地址的方式拨打
通过网关的方式进行跨FS的电话拨打,无论是否注册,都需要新建网关配置文件,这样也不是特别方便,最简单的是直接通过第二个FS的IP地址发起跨FS的呼叫,当然,这个功能还是要配合ACL一起使用。
在第一个FS上执行如下命令:
1 | originate user/1004 &bridge(sofia/external/sip:[email protected]:25060) |
如果第二个FS的拨号计划没有问题的话,此时1004和21002的电话都响铃了。这个命令其实也好理解,首先呼叫1004
,然后通过SIP地址去呼叫sip:[email protected]:25060
,接通之后,双方做一个桥接即可。
因为21002用户已经注册到了第二个FS上,所以FS2可以找到21002的真实地址,假如我们知道了21002的真实地址,我们也可以直接呼叫这个地址即可。
在第二个FS上执行如下命令可以查看地址:
1 | freeswitch@localhost> sofia_contact 21002 |
找到21002的真实SIP地址后,可以直接在第一个FS上呼叫它:
1 | originate user/1004 &bridge(sofia/internal/sip:[email protected]:1024) |
直接呼叫用户所在的真实SIP地址,既FS1直接呼叫21001的SIP话机,这里不经过FS2的。