麒麟V10 安装FreeSwitch 1.10.11并连接达梦(DM8)数据库实现通过lua脚本查询数据库数据动态注册用户
安装编译工具和依赖包
yum update -y
sudo yum install epel-release vim tcpdump net-tools.x86_64 -y
sudo yum install gcc-c++ sqlite-devel zlib-devel libcurl-devel pcre-devel speex-devel ldns-devel libedit-devel openssl-devel git -y
yum install yasm nasm opus-devel -y
yum groupinstall perl* -y
yum install python -y
yum install bzip2 -y
yum install -y libshout-devel lame-devel libmpg123-devel
yum install bc -y
sudo yum install -y openssl-devel curl-devel
yum install curl -y
yum install expect telnet -y
yum install -y yum-plugin-ovl centos-release-scl rpmdevtools yum-utils git wget vim devtoolset-7-gcc* devtoolset-7 libtiff-devel cmake3 libatomic unixODBC unixODBC-devel.x86_64 postgresql-libs postgresql-devel libpqxx-devel
yum install -y gcc-c++ autoconf automake libtool ncurses-devel zlib-devel libjpeg-devel openssl-devel e2fsprogs-devel sqlite-devel libcurl-devel pcre-devel speex-devel ldns-devel libedit-devel libxml2-devel libyuv-devel libvpx-devel libvpx2* libdb4* libidn-devel unbound-devel libuuid-devel lua-devel libsndfile-devel yasm-devel
yum install -y git
yum install -y wget
yum install -y autoconf
yum install -y automake
yum install -y cmake
yum install -y bison
yum install -y openssl-devel
yum install -y curl-devel
yum install -y gdbm-devel
yum install -y gcc-c++
yum install -y gnutls-devel
yum install -y libjpeg-devel
yum install -y libogg-devel
yum install -y libtiff-devel
yum install -y libtool
yum install -y uuid-devel
yum install -y libuuid-devel
yum install -y libxml2-devel
yum install -y ncurses-devel
yum install -y opus-devel
yum install -y pcre-devel
yum install -y pkgconfig
yum install -y postgresql-devel
yum install -y sqlite-devel
yum install -y unixODBC-devel
yum install -y zlib-devel
yum install -y yasm
yum install -y libedit-devel
yum install -y libatomic
yum install -y speex-devel
yum install -y speexdsp-devel
yum install -y libsndfile-devel
yum install -y readline-devel
yum install -y swig patch
reboot
拉取freeswitch源码
cd /root
git clone --branch v1.10.11 https://github.com/signalwire/freeswitch.git
编译安装sofia-sip模块
cd /root/freeswitch
git clone https://github.com/freeswitch/sofia-sip
cd sofia-sip
./bootstrap.sh -j
./configure
make
make install
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:${PKG_CONFIG_PATH}
ldconfig
扩展:如果make编译报错:undefined reference to `OPENSSL_init_ssl’,处理方法如下:
# 编译前需要添加openssl LIB的目录
export LDFLAGS=-L/usr/local/lib64/
./configure
make
make install
export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig:${PKG_CONFIG_PATH}
ldconfig
编译安装spandsp模块
cd /root/freeswitch
git clone https://github.com/freeswitch/spandsp.git
cd spandsp
./bootstrap.sh -j
./configure
make
make install
ldconfig
注意:该步骤如果按照上面,后面编译freeswitch的时候会报错
mod_spandsp_dsp.c:159:10: error: ‘V18_MODE_5BIT_4545’ undeclared (first use in this function)
正确步骤如下:
git clone https://github.com/freeswitch/spandsp.git
cd spandsp
git checkout -b finecode20230705 0d2e6ac65e0e8f53d652665a743015a88bf048d4
./bootstrap.sh -j
./configure
make
make install
麒麟操作系统配置连接DM8
安装odbc
yum install -y unixODBC unixODBC-devel
编辑/etc/odbcinst.ini
添加如下内容:
[DM8 ODBC DRIVER]
Description = DM ODBC driver for DM8
# 注意这里指定的是DM数据库安装目录/home/dmdba/dmdbms下的odbc驱动
Driver = /home/dmdba/dmdbms/drivers/odbc/libdodbc.so
编辑/etc/odbc.ini
[DM8]
DRIVER=DM8 ODBC DRIVER
SERVER=192.168.101.39
UID=ROOT
PWD=123456
TCP_PORT=5236
连接测试
isql dm8 -v
报错处理:
Can’t open lib ‘/home/dmdba/dmdbms/drivers/odbc/libdodbc.so’ : file not found
vim /etc/profile
# 配置dm的安装路径
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/dm8/bin"
source /etc/profile
连接成功显示:
+---------------------------------------+
| Connected! |
| |
| sql-statement |
| help [tablename] |
| quit |
| |
+---------------------------------------+
SQL>
设置要启用的模块
cd /root/freeswitch
./bootstrap.sh
sed -i 's/#formats\/mod_shout/formats\/mod_shout/g' /root/freeswitch/modules.conf
sed -i 's/applications\/mod_signalwire/#applications\/mod_signalwire/g' /root/freeswitch/modules.conf
sed -i 's/endpoints\/mod_verto/#endpoints\/mod_verto/g' /root/freeswitch/modules.conf
sed -i 's/applications\/mod_av/#applications\/mod_av/g' /root/freeswitch/modules.conf
sed -i 's/codecs\/mod_opus/#codecs\/mod_opus/g' /root/freeswitch/modules.conf
sed -i 's/#applications\/mod_callcenter/applications\/mod_callcenter/g' /root/freeswitch/modules.conf
sed -i 's/#applications\/mod_httapi/applications\/mod_httapi/g' /root/freeswitch/modules.conf
sed -i 's/#event_handlers\/mod_odbc_cdr/event_handlers\/mod_odbc_cdr/g' /root/freeswitch/modules.conf
编译安装freeswitch
./bootstrap.sh
./configure --enable-portable-binary --prefix=/usr/local/freeswitch --with-gnu-ld --with-python --with-openssl --enable-core-odbc-support --enable-zrtp
make
make install
make -j cd-sounds-install
make -j cd-moh-install
麒麟操作系统编译报错处理:
1、 libluamod_la-mod_lua.lo] Error 1
yum install lua-devel
2、You must install libshout3-dev to build mod_shout。
yum install libshout-devel
3、You must install libmpg123-dev to build mod_shout。
yum install mpg123-devel
4、You must install libmp3lame-dev to build mod_shout。
yum install lame-devel
设置软链接和开机启动
sudo ln -sf /usr/local/freeswitch/bin/freeswitch /usr/local/bin/
sudo ln -sf /usr/local/freeswitch/bin/fs_cli /usr/local/bin/
cp -r /usr/local/freeswitch/bin/freeswitch /etc/rc.d/init.d
echo -e "/etc/init.d/freeswitch -nonat -nc" >> /etc/rc.d/rc.local
chmod +x /etc/rc.d/rc.local
配置DM数据库管理Freeswitch
修改freeswitch/etc/freeswitch目录下的配置(不同的配置可能在不同的目录)如下:
<!-- vi conf/autoload_configs/db.conf.xml -->
<param name="odbc-dsn" value="DM8:ROOT:123456"/>
<!-- vi conf/autoload_configs/switch.conf.xml -->
<param name="core-db-dsn" value="DM8:ROOT:123456" />
<param name="odbc-dsn" value="DM8:ROOT:123456"/>
<!-- vi conf/autoload_configs/voicemail.conf.xml -->
<param name="odbc-dsn" value="DM8:ROOT:123456"/>
<!-- vi conf/autoload_configs/callcenter.conf.xml -->
<param name="odbc-dsn" value="DM8:ROOT:123456"/>
<!-- vi conf/sip_profiles/external.xml -->
<param name="odbc-dsn" value="DM8:ROOT:123456"/>
<!-- vi conf/sip_profiles/internal.xml -->
<param name="odbc-dsn" value="DM8:ROOT:123456"/>
<!-- vi conf/sip_profiles/internal-ipv6.xml -->
<param name="odbc-dsn" value="DM8:ROOT:123456"/>
<!-- vi conf/sip_profiles/external-ipv6.xml -->
<param name="odbc-dsn" value="DM8:ROOT:123456"/>
<!-- vi conf/autoload_configs/fifo.conf.xml -->
<settings>
<param name="delete-all-outbound-member-on-startup" value="false"/>
<param name="odbc-dsn" value="DM8:ROOT:123456"/>
</settings>
<!-- vi conf/vars.xml -->
<X-PRE-PROCESS cmd="set" data="json_db_handle=odbc://DM8:ROOT:123456"/>
配置DM动态管理FreeSwitch用户
一、准备数据
#创建用户表
CREATE TABLE tb_sip_account(id INT NOT NULL primary key identity(1,1),account VARCHAR(10) NOT NULL,password VARCHAR(30) NOT NULL,status INT NOT NULL);
#插入用户
insert into tb_sip_account (account,password,status) values('8001','1234', 0);
insert into tb_sip_account (account,password,status) values('8002','1234', 0)
二、将用户验证转接到lua脚本
1、将/freeswitch/etc/freeswitch/autoload_configs/lua.conf.xml中的两行代码修改为如下所示
<param name="script-directory" value="$${script_dir}/?.lua"/>
<param name="xml-handler-script" value="gen_dir_user_xml.lua" />
<param name="xml-handler-bindings" value="directory" />
2、让lua脚本接管用户注册验证,这里调用的脚本是/usr/local/freeswitch/share/freeswitch/scripts/gen_dir_user_xml.lua内容如下,默认无该脚本,需自行创建
freeswitch.consoleLog("NOTICE","lua take the users\r\n");
local req_domain = params:getHeader("domain")
local req_key = params:getHeader("key")
local req_user = params:getHeader("user")
local req_password = params:getHeader("pass")
local dbh = freeswitch.Dbh("DM8","ROOT","123456789");
if dbh:connected() == false then
freeswitch.consoleLog("NOTICE", "gen_dir_user_xml.lua cannot connect to database\n")
return
end
if req_user ~= nil then
freeswitch.consoleLog("NOTICE","lua take the users:"..req_user.."\r\n");
freeswitch.consoleLog("NOTICE","req_user..."..req_user.."\r\n");
local my_query = "select * from tb_sip_account where status = 0 and account="..req_user.." limit 1;";
freeswitch.consoleLog("NOTICE", "the query string is:"..my_query.."\n")
dbh:query(my_query,function(u)
if u == nil then
freeswitch.consoleLog("NOTICE", "user not exist\n")
return
end
req_password=u.password
end);
dbh:release();
freeswitch.consoleLog("NOTICE","info:"..req_domain.."--"..req_key.."--"..req_user.."\n");
--assert (req_domain and req_key and req_user,
--"This example script only supports generating directory xml for a single user !\n")
if req_domain ~= nil and req_key~=nil and req_user~=nil and req_password~=nil then
XML_STRING =
[[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="freeswitch/xml">
<section name="directory">
<domain name="]]..req_domain..[[">
<params>
<param name="dial-string"
value="{presence_id=${dialed_user}@${dialed_domain}}${sofia_contact(${dialed_user}@${dialed_domain})}"/>
</params>
<groups>
<group name="default">
<users>
<user id="]] ..req_user..[[">
<params>
<param name="password" value="]]..req_password..[["/>
<param name="vm-password" value="]]..req_password..[["/>
</params>
<variables>
<variable name="toll_allow" value="domestic,international,local"/>
<variable name="accountcode" value="]] ..req_user..[["/>
<variable name="user_context" value="default"/>
<variable name="directory-visible" value="true"/>
<variable name="directory-exten-visible" value="true"/>
<variable name="limit_max" value="15"/>
<variable name="effective_caller_id_name" value="Extension ]] ..req_user..[["/>
<variable name="effective_caller_id_number" value="]] ..req_user..[["/>
<variable name="outbound_caller_id_name" value="${outbound_caller_name}"/>
<variable name="outbound_caller_id_number" value="${outbound_caller_id}"/>
<variable name="callgroup" value="techsupport"/>
</variables>
</user>
</users>
</group>
</groups>
</domain>
</section>
</document>]]
else
XML_STRING =
[[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="freeswitch/xml">
<section name="directory">
</section>
</document>]]
end
end
-- comment the following line for production:
--freeswitch.consoleLog("notice", "Debug from init_user_xml.lua, generated XML:\n" .. XML_STRING .. "\n");
注:脚本中local dbh = freeswitch.Dbh(“DM8”,“ROOT”,“123456”);是连接数据库,ROOT和123456是dm8的账号密码,DM8是数据源。
三、修改default,让lua接管用户注册
修改freeswitch/etc/freeswitch/directory/default.xml中的一部分内容,使得通过xml验证用户的功能失效,这样lua才能真正接管用户注册,删除的内容如下:
<group name="default">
<users>
<X-PRE-PROCESS cmd="include" data="default/*.xml"/>
</users>
</group>
四、修改拨号计划(重要,不修改会导致非内置用户无法正常拨号)
修改拨号计划
修改/usr/local/freeswitch/etc/freeswitch/dialplan/default.xml
修改如下内容,好让所有的拨号通过以下的条件
<extension name="Local_Extension">
<!--<condition field="destination_number" expression="^(10[01][0-9])$">-->
<condition field="destination_number" expression="^(.*)$">
修改/usr/local/freeswitch/etc/freeswitch/dialplan/pubilc.xml
修改如下内容,好让所有的拨号通过以下的条件
<extension name="public_extensions">
<!--
<condition field="destination_number" expression="^(10[01][0-9])$">
-->
<condition field="destination_number" expression="^(.*)$">
<action application="transfer" data="$1 XML default"/>
</condition>
</extension>
还有就是每次修改xml后都需要重启或者重新在freeswitch控制台、fs_cli下执行reloadxml,使得修改生效。修改lua脚本,则不需要如上操作。
五、使用客户端进行测试
重启freeswitch 并使用客户端测试。
常用命令
# 启动freeswitch
freeswitch
# 关闭freeswitch
shutdown
# 后台启动
freeswitch -nc
# 关闭后台freeswitch
freeswitch -stop
# 查看FreeSWITCH是否正常启动
netstat -anp | grep freeswitch
# 查看状态
sofia status
# 显示哪些用户已注册
sofia status profile internal reg
# 控制台显示info级别日志
fs_cli -l info
# 开启sip消息显示/关闭
sofia global siptrace on/off
# 退出fs_cli(不关闭fs)
/exit
防火墙开放端口
FireWall Ports Network Protocol Application Protocol Description
1719 UDP H.323 Gatekeeper RAS port
1720 TCP H.323 Call Signaling
3478 UDP STUN service Used for NAT traversal
3479 UDP STUN service Used for NAT traversal
5002 TCP MLP protocol server
5003 UDP Neighborhood service
5060 UDP & TCP SIP UAS Used for SIP signaling (Standard SIP Port, for default Internal Profile)
5070 UDP & TCP SIP UAS Used for SIP signaling (For default "NAT" Profile)
5080 UDP & TCP SIP UAS Used for SIP signaling (For default "External" Profile)
8021 TCP ESL Used for mod_event_socket *
16384-32768 UDP RTP/ RTCP multimedia streaming Used for audio/video data in SIP and other protocols
5066 TCP Websocket Used for WebRTC
7443 TCP Websocket Used for WebRTC
Java ESL 连接FreeSwitch
一、修改FreeSwitch配置
/usr/local/freeswitch/etc/freeswitch/autoload_configs/event_socket.conf.xml修改你的freeswitch服务器
<configuration name="event_socket.conf" description="Socket Client">
<settings>
<param name="nat-map" value="false"/>
<param name="listen-ip" value="0.0.0.0"/>
<param name="listen-port" value="8021"/>
<param name="password" value="ClueCon"/>
<param name="apply-inbound-acl" value="lan"/>
<!--<param name="stop-on-bind-error" value="true"/>-->
</settings>
</configuration>
在/usr/local/freeswitch/etc/freeswitch/autoload_configsacl.conf.xml中增加:
<list name="domains" default="deny">
<!-- domain= is special it scans the domain from the directory to build the ACL -->
<!-- <node type="allow" domain="$${domain}"/> -->
<node type="allow" cidr="0.0.0.0/0"/>
<!-- use cidr= if you wish to allow ip ranges to this domains acl. -->
<!-- <node type="allow" cidr="192.168.0.0/24"/> -->
</list>
二、SpringBoot 整合FreeSwitch ESL
1、添加依赖
<dependency>
<groupId>link.thingscloud</groupId>
<artifactId>freeswitch-esl-spring-boot-starter</artifactId>
<version>2.0.0</version>
</dependency>
2、添加yml配置
link:
thingscloud:
freeswitch:
esl:
inbound:
# 配置连接地址
defaultPassword: ClueCon
performance: false
performanceCostTime: 200
#read-timeout-seconds: 0
# 配置要连接的freeswitch的event-socket的地址,支持集群连接
servers:
- host: 192.168.101.39
port: 8021
timeoutSeconds: 30
# 配置要监听的事件
events:
- all
3、通过Java代码操作FreeSwitch
package com.sgsd.micro.fire.station.demo;
import com.alibaba.fastjson.JSON;
import link.thingscloud.freeswitch.esl.InboundClient;
import link.thingscloud.freeswitch.esl.transport.message.EslMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.util.List;
@Component
public class FreeSwitchTest {
@Autowired
private InboundClient inboundClient;
@Scheduled(fixedDelay = 2000L)
public void test(){
/**
* conference test bgdial user/8001
* 上面的命令表示,发起1个名为test的会话,同时拨打1004用户,如果该用户接听了,就相当于加入会议。注:如果8001是第1个加入会议的人,此时会议室还没有人,只能听到背景音乐等待其它人加入。
* 重复以上命令拉取不同的用户进入会议
*/
EslMessage eslMessage1 = inboundClient.sendSyncApiCommand("192.168.101.39:8021", "conference", "test bgdial user/8001");
EslMessage eslMessage2 = inboundClient.sendSyncApiCommand("192.168.101.39:8021", "conference", "test bgdial user/8002");
// 获取到会议中在会人员的列表
EslMessage eslMessage3 = inboundClient.sendSyncApiCommand("192.168.101.39:8021", "conference", "test list");
// 6;sofia/internal/8001@192.168.101.126:13085;096ffed2-86d3-4b1d-af63-7e3c9a201960;Outbound Call;8001;hear|speak;0;0;100
// 8;sofia/internal/8002@192.168.101.156:12432;c7b6e1fc-cfc9-44ca-b417-8e8e8fd00209;Outbound Call;8002;hear|speak|video;0;0;100
List<String> bodyLines = eslMessage3.getBodyLines();
// 将member-id为6的人踢出test会议
EslMessage eslMessage4 = inboundClient.sendSyncApiCommand("192.168.101.39:8021", "conference", "test kick 6");
// 将member-id为8的人静音
EslMessage eslMessage5 = inboundClient.sendSyncApiCommand("192.168.101.39:8021", "conference", "test mute 8");
// 将member-id为8的人解除静音
EslMessage eslMessage6 = inboundClient.sendSyncApiCommand("192.168.101.39:8021", "conference", "test tmute 8");
// 让member-id为8的人听不到会议内容
EslMessage eslMessage7 = inboundClient.sendSyncApiCommand("192.168.101.39:8021", "conference", "test deaf 8");
// 让member-id为8的人恢复听到会议内容
EslMessage eslMessage8 = inboundClient.sendSyncApiCommand("192.168.101.39:8021", "conference", "test undeaf 8");
// 结束会议
EslMessage eslMessage9 = inboundClient.sendSyncApiCommand("192.168.101.39:8021", "conference", "test hup all");
System.out.println(JSON.toJSONString(eslMessage3));
}
}
注意:其他涉及命令请自行查阅相关文档
指定IP
在内网环境部署时,如果没有手动指定内网ip,会导致座机无法正常注册到freeswitch。
修改/usr/local/freeswitch/etc/freeswitch/vars.xml的如下内容指定ip地址
<!-- <X-PRE-PROCESS cmd="stun-set" data="external_rtp_ip=stun:stun.freeswitch.org"/> -->
<X-PRE-PROCESS cmd="stun-set" data="external_rtp_ip=192.168.101.21"/>
<!-- <X-PRE-PROCESS cmd="stun-set" data="external_sip_ip=stun:stun.freeswitch.org"/> -->
<X-PRE-PROCESS cmd="stun-set" data="external_sip_ip=192.168.101.21"/>
取消拨号10s延迟
修改/usr/local/freeswitch/etc/freeswitch/dialplan/default.xml
<condition field="${default_password}" expression="^1234$" break="never">
<action application="log" data="CRIT WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING "/>
<action application="log" data="CRIT Open $${conf_dir}/vars.xml and change the default_password."/>
<action application="log" data="CRIT Once changed type 'reloadxml' at the console."/>
<action application="log" data="CRIT WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING "/>
<!-- 注释该内容即可取消拨号延迟-->
<!-- <action application="sleep" data="10000"/> -->
</condition>
修改使用中文提示音
一、下载中文语言包
访问网址: https://github.com/springleng/freeswitch-zh-cn-sounds.git 下载中文语言包
二、安装中文语言包
在/usr/local/freeswitch/share/freeswitch/sounds目录下创建zh文件夹,并将下载好的语音上传到到zh文件夹下

安装mod_say_zh
cd /root/freeswitch/src/mod/say/mod_say_zh
make && make install
修改vars.xml(/usr/local/freeswitch/etc/freeswitch目录下)
<X-PRE-PROCESS cmd="set" data="sound_prefix=$${sounds_dir}/zh/cn/link"/>
<X-PRE-PROCESS cmd="set" data="default_language=zh"/>
<X-PRE-PROCESS cmd="set" data="default_dialect=cn"/>
<X-PRE-PROCESS cmd="set" data="default_voice=link"/>
修改中文SAY配置
cd /usr/local/freeswitch/etc/freeswitch/lang
cp -fr en zh
cd zh
mv en.xml cn.xml
修改 cn.xml
<language name="zh" say-module="zh" sound-prefix="$${sounds_dir}/zh/cn/link" tts-engine="cepstral" tts-voice="link">
修改freeswitch.xml(/usr/local/freeswitch/etc/freeswitch目录下)
<X-PRE-PROCESS cmd="include" data="lang/zh/*.xml"/>
修改modules.conf.xml(/usr/local/freeswitch/etc/freeswitch/autoload_configs目录下),取消mod_say_zh的注释使其生效
<load module="mod_say_zh"/>
重启freeswitch 使最新配置生效。
更多推荐
所有评论(0)