一、FreeSWITCH概况
FreeSWITCH是一个强大而灵活的开源通信平台,广泛应用于构建VoIP系统、呼叫中心、会议系统等。最初由一群Asterisk开发者创建,旨在提供一个高性能、灵活且可扩展的通信解决方案。它支持多种通信协议,包括SIP(会话初始协议)、RTP(实时传输协议)和WebRTC,使其成为构建语音、视频和消息传递应用的理想选择。
FreeSWITCH 使用线程模型来处理并发请求,每个连接都在单独的线程中进行处理。这不仅能提供最大强度的并发,更重要的是,即使某路电话发生问题,也只影响到它所在的线程,而不会影响到其它电话。FreeSWITCH 的核心非常短小精悍,这也是保持稳定的关键。所有其它功能都在外围的模块中。模块是可以动态加载(以及卸载)的,在实际应用中可以只加载用到的模块。外围模块通过核心提供的 Public API 与核心进行通信,而核心则通过回调机制执行外围模块中的代码。
官方文档:安装包下载
(1)FreeSWITCH的特点
- 高性能:采用高效的C语言编写,能够处理大量并发呼叫,适用于高流量的通信应用。
- 模块化设计:模块化架构允许用户根据需要加载不同的模块,从而实现定制化的解决方案。
- 多协议支持:支持SIP、H.323、WebRTC等多种协议,提供广泛的互操作性。
- 多脚本支持:支持Lua、JavaScript、Python等多种语言,方便复杂的逻辑和自动化任务。
- 丰富的功能:内置IVR、会议、呼叫录音等丰富的通信功能,满足各种应用需求。
(2)应用场景
- VoIP系统:FreeSWITCH可以作为一个SIP服务器,用于构建IP电话系统。
- 呼叫中心:通过FreeSWITCH的强大功能模块,实现呼叫路由和管理,适用于大型呼叫中心。
- 会议系统:支持多方会议功能,可用于企业内部会议系统。
- WebRTC应用:通过mod_verto模块,支持WebRTC协议,方便构建基于浏览器的通信应用。
- 自定义通信平台:利用FreeSWITCH的脚本和模块化设计,快速搭建定制化的通信解决方案。
(3)核心组件
- 核心:FreeSWITCH的核心部分,负责处理所有基础功能,如呼叫控制、媒体流处理等。
- 模块:扩展FreeSWITCH功能的插件,可以按需加载。常用模块包括mod_sofia(SIP支持)、mod_conference(会议支持)、mod_dptools(拨号工具)等。
- 配置文件:位于/etc/freeswitch/目录下,主要配置文件包括freeswitch.xml(全局配置)、vars.xml(变量配置)、sip_profiles(SIP配置)等。
- 事件系统(Event System):FreeSWITCH采用事件驱动架构,所有操作都通过事件处理,支持异步事件和自定义事件。
(4)核心功能
- SIP服务器:处理SIP协议的呼叫和信令。
- 媒体服务器:管理媒体流,包括语音、视频和文本。
- 会议服务器:支持多方会议功能。
- IVR系统:创建交互式语音应答系统。
- 录音和播放:录制和播放语音文件。
- 模块化设计:通过加载不同的模块,扩展FreeSWITCH的功能。
二、安装目录
在linux类系统上默认的安装位置:/usr/local/freeswitch,
Windows系统上默认的安装路径:C:\Programming Files\FreeSWITCH
在这两种系统上,FreeSWITCH的目录结构大致相同:
三、目录作用
sounds:sounds目录中存放了各种声音文件。FreeSWITCH支持多种频率的通话,因而也支持多种频率的声音文件。
四、配置文件
配置文件由许多XML文件组成。在系统装载时,XML解析器会将所有XML文件组织在一起,并读入内存,组成一个大的XML文档(Document),称为XML注册表。XML文档本身非常适合描述复杂的数据结构,在FreeSWITCH中可以非常灵活地使用这些数据。这种设计的好处是可以帮助实现非常高的可扩展性。并且,XML也是一个国际通用的标准,其他外部应用程序也可以很容易地生成XML,从而很容易地与FreeSWITCH集成。另外,系统还允许在某些XML节点上安装回调函数,当这些节点的数据变化时(如在reloadxml时),系统便自动调用这些回调函数,以更新系统的内部数据或状态等。
(1)配置文件位置:/usr/local/freeswitch/conf/
(2)conf文件目录:
完整的XML文档分为以下几个重要的部分:configuration(配置)、freeswitch.xml(根配置),dialplan(拨号计划)、chatplan(聊天计划)、directory(用户目录)及phrase(分词),每一部分又有不同的配置。
简单解释如下:
dialplan目录:该目录下的文件定义了XML拨号计划(Dialplan)。拨号计划是Free-SWITCH中很重要的一部分,它用于对进电话进行路由。
ivr_menues目录:该目录下存放了默认的一些IVR菜单的例子。
directory目录:该目录中的配置文件决定了当FreeSWITCH作为注册服务器时,哪些用户可以注册,即用于配置本地用户,其中的配置信息称为用户目录。FreeSWITCH的用户目录支持多个域(Domain),每个域可以写到一个XML文件中。默认的配置包括一个default.xml,其中定义了1000~1019一共20个用户(实际上是装入了下一级子目录中的20个配置文件)。
由于完整的XML非常大,而且大的XML文档已经对X-PRE-PROCESS标签进行处理,隐藏了很多配置的细节。
(3)配置文件框架图:
(4)FreeSWITCH的加载顺序:
1、顶层:freeswitch.xml
2、vars.xml| 一些常用变量
3、dialplan/default.xml| 缺省的拨号计划
4、directory/default/*.xml | SIP用户,每用户一个文件
5、sip_profiles/internal.xml| 一个SIP profile,或称作一个SIP-UA,监听在本地IP及端口5060,一般供内网用户使用
6、sip_profiles/externa.xml| 另一个SIP-UA,用作外部连接,端口5080
7、autoload_configs/modules.conf.xml| 配置当FreeSWITCH启动时自动装载哪些模块
(5)freeswitch.xml是所有XML文件的黏合剂
freeswitch.xml的作用是将所有配置文件“粘”到一起,其中,X-PRE-PROCESS标签是FreeSWITCH中特有的,它称为预处理指令,用于设置一些变量和装入其他配置文件。
在XML加载阶段,FreeSWITCH的XML解析器会先将预处理命令展开,在FreeSWITCH内部生成一个大的XML文档。
log/freeswitch.xml.fsxml是FreeSWITCH内部XML的一个内存镜像(注意,它在log目录中,而不是在conf目录中,由于它是动态生成的,所以用户不应该手工编辑它)。
它对调试非常有用:假设你不慎弄错了某个标签,又不知道它错在哪了,可以尝试让FreeSWITCH重新加载XML(reloadxml),这时在FreeSWITCH的日志中就可以看到XML某一行出错的提示,在freeswitch.xml.fsxml就能很容易地定位到这一行。
<?xml version="1.0"?>
<document type="freeswitch/xml">
<X-PRE-PROCESS cmd="include" data="vars.xml"/>
<section name="configuration" description="Various Configuration">
<X-PRE-PROCESS cmd="include" data="autoload_configs/*.xml"/>
</section>
</document>
document是树的根文件,在document中,有许多Section,每个Section都对应一部分功能。其中有两个X-PRE-PROCESS预处理指令,它们的作用是将data参数指定的文件内容包含(include)到当前文件中来。上述freeSwitch.xml文件没有特别的作用,它就是将不同的配置文件“包含”到不同的部分(Section)中,从而生成一个大的XML配置文件。
最后大的配置文件将类似下列代码所示:
<?xml version="1.0"?>
<document type="freeswitch/xml">
<section name="configuration" description="Various Configuration">
<configuration name="mod1.conf" description="Mod 1"/>
<configuration name="mod2.conf" description="Mod 2"/>
<configuration name="mod3.conf" description="Mod 3"/>
</section>
<section name="dialplan" description="XML Dialplan ">
<context name="default " description="default Dialplan"/>
<context name="public" description="public Dialplan"/>
</section>
</document>
可以看出,configuration这个Section中有很多configuration,而dialplan这个Section中有很多Context。关于这些配置项的具体含义我们将在后面相关的章节讲解,在此就不多讲了。
由于X-PRE-PROCESS是一个预处理指令,FreeSWITCH在加载阶段只对其进行简单替换,并不进行语法分析,因此对它进行注释是没有效果的,这是一个新手常犯的错误
(6)vars.xml主要通过X-PRE-PROCESS指令定义了一些全局变量
<X-PRE-PROCESS cmd="set" data="domain=$${local_ip_v4}"/>
<X-PRE-PROCESS cmd="set" data="domain_name=$${domain}"/>
<X-PRE-PROCESS cmd="set" data="hold_music=local_stream://moh"/>
<X-PRE-PROCESS cmd="set" data="use_profile=internal"/>
该指令使用set表示要设置一个变量。
全局变量:
在这里使用X-PRE-PROCESS设置的变量都称为全局变量,在FreeSWITCH运行期间永远都是有效的。
局部变量:
它们通常在拨号计划中,在一个呼叫的生命周期中才有效。如果需要引用这些变量,则全局变量以$var 表示,临时变量以 {var}表示。
默认设置全局变量
在加载vars.xml之前,FreeSWITCH就已经“算”出并设置了一些全局变量,也就是说有些变量是系统在运行时自动设置的,其有默认的值
这些变量是在vars.xml加载前设置的,因而可以在varx.xml中覆盖它们,如:
<X-PRE-PROCESS cmd="set" data="local_ip_v4=192.168.1.123"/>
因为有时候FreeSWITCH自动“算”出的值可能不是你想要的,如上面的local_ip_v4的值,在服务器有多个网卡的情况下,可能希望它能得到另外一个网卡的IP地址,这时候就可以通过手动的方式设置该变量的IP来实现。
global_getvar查看全局变量
#查看语音路径
freeswitch> global_getvar sound_prefix
/usr/local/freeswitch/sounds/en/us/callie
#查看终端ip
freeswitch > global_getvar local_ip_v4
192.168.7.6
(8)autoload_configs目录
autoload_configs目录下的各种配置文件会在系统启动时装入。一般来说都是模块级的配置文件,每个模块对应一个(注意,并不是所有的模块都有配置文件)。文件名一般以“模块名.conf.xml”的方式命名(模块名中不包含“mod_”,如sofia.conf.xml),各模块的配置文件不尽相同,其中的配置项也都是由不同的模块分别解析的。
sofia.conf.xml配置
<configuration name="sofia.conf" description="sofia Endpoint">
<global_settings>
<param name="log-level" value="0"/>
<!-- <param name="auto-restart" value="false"/> -->
<param name="debug-presence" value="0"/>
<!-- <param name="capture-server" value="udp:homer.domain.com:5060"/> -->
</global_settings>
<profiles>
<X-PRE-PROCESS cmd="include" data="../sip_profiles/*.xml"/>
</profiles>
</configuration>
首先它定义了一个configuration标签,其中name表示名字,这里是sofia.conf,而后面的description是一个简单的描述。
这个配置文件中的configuration标签的name属性,mod_sofia在启动时会向XML注册表中查找name为“sofia.conf”的configuration,进而访问其下面的配置参数。
global_settings标签定义了一些全局参数,具体参数的意义我们在此就不多解释了。
profiles标签可通过X-PRE-PROCESS指令装入其他的配置文件,这些配置文件一般都是每个文件描述了一个profile(见默认的conf/sip_profiles/internal.xml),在此我们仅看一下profile装入后的效果,具体如下:
<profiles>
<profile name="profile1"></profile>
<profile name="profile2"></profile>
</profiles>
modules.conf.xml
其决定了FreeSWITCH启动时自动加载哪些模块。如下面的配置片断,如果需要在FreeSWITCH启动时自动加载某个模块,就在这里添加一行,如果不需要,就注释掉或直接删除:
<configuration name="modules.conf" description="Modules">
<modules>
<!-- Loggers (I'd load these first) -->
<load module="mod_console"/>
<load module="mod_logfile"/>
<!-- <load module="mod_syslog"/> -->
</modules>
</configuration>
post_load_modules.conf.xml文件,其格式和用法与modules.conf.xml差不多,不同的是其中定义的模块加载时间比较晚。
(4)具体配置文件 :
├── freeswitch.xml
├── mime.types
├── notify-voicemail.tpl
├── tetris.ttml
├── vars.xml
├── voicemail.tpl
├── web-vm.tpl
├── autoload_configs
├── chatplan
├── dialplan
├── default
├── public
└── skinny-patterns
├── directory
└── default
├── ivr_menus
├── jingle_profiles
├── lang
├── en
├── demo
├── dir
├── ivr
└── vm
├── fr
├── demo
├── dir
└── vm
├── mrcp_profiles
├── sip_profiles
├── external
└── internal
└── skinny_profiles
五、mod应用目录
该目录下的模块提供了大部分的应用功能,有的模块实现了多种Interface不好归类也会存在该目录中。
(1)applications
- mod_abstraction:用于创建新的API命令。新的命令可以基于原有的API创建,相当于创建原有命令的别名或快捷方式。
- mod_avmd:avmd是Advanced Voice Mail Detection的缩写,即高级语音邮件检测。它是mod_vmd的高级版。详见mod_vmd。
- mod_blacklist:黑名单功能。它提供了一些通过Dialplan来添加、删除以及检查黑名单的方法。
- mod_callcenter:一个比较强大的呼叫中心类应用。
- mod_cidlookup:用于主叫号码查询,即可根据主叫号码从本地数据库或网络上查询到主叫的名字。
- mod_cluechoo:该模块是一个例子模块,主要是教大家怎么写模块。另外,它还带了一个好玩的例子,如在命令行上执行cluechoo命令,在屏幕上将会看到开过一个小火车。
- mod_commands:提供了大部分系统的命令API。
- mod_conference:多人语音即视频会议。
- mod_curl:使用libcurl作为一个HTTP客户端向Web服务器发送请求,也可以得到返回的结果。
- mod_db:该模块提供一组接口,用于使用API或APP对数据库表进行增删改查等操作。
- mod_directory:该模块用于按姓名呼叫用户。如果不知道用户的分机号,但知道用户的名字,则可以通过输入该用户名字的前几位进行拨叫。
- mod_distributor:如果需要通过多个网关出局,则该模块可以帮助将呼叫根据一定的比例分发到不同的网关。
- mod_dptools:提供了大部分系统的APP。
- mod_easyroute:用于根据号码路由,对大规模的DID比较有用。
- mod_enum:通过ENUM查询可以根据E164号码找到用户的SIP地址。该模块也提供了一个enum Dialplan。
- mod_esf:esf是Extended SIP Functionality的缩写,即扩展的SIP功能。它提供通过Multicast方法实现组拨的功能。
- mod_esl:该模块用于实现两个FreeSWITCH间的ESL对接,即一个FreeSWITCH可以作为另一个FreeSWITCH的ESL客户端访问它。
- mod_expr:提供expr表达式计算。
- mod_fifo:一个先进先出队列,可以用于简单的呼叫中心排队。
- mod_fsk:收发FSK(Frequency-shift keying,频移键控)信息。
- mod_fsv:fsv是FreeSWITCH Video的缩写,它使用了一种私有的格式来进行视频录制,可以支持任何编码的视频格式。它只存储原始的RTP包,对视频流不进行任何处理。音频轨道用L16编码保存。
- mod_hash:用于操作系统内部的哈希表。可以存储一些简单的数据。
- mod_httpapi:一种HTTP格式的API接口,可以通过HTTP方式写IVR。
- mod_http_cache:通过HTTP方式上传和下载文件,并可以进行本地缓存。
- mod_ladspa:使用ladspa库对声音进行处理,可以让声音更好听。
- mod_lcr:LCR是Least Cost Routing的缩写,即最省钱的路由。它会根据数据库配置的路由信息和费率找到最省钱的路由。
- mod_limit:用于系统资源限制。
- mod_memcache:与Memcache交互,类似于把mod_hash的数据存到远程的Memcache中。
- mod_mongo:与MongoDB交互,类似mod_memcache。
- mod_mp4:提供MP4文件的播放支持。
- mod_nibblebill:一些简单的计费功能,可用于预付费和电话卡类的应用。
- mod_oreka:使用oreka进行录音。oreka是一款开源的录音软件。
- mod_osp:通过Open Settlement Protocol查找路由或上报CDR。
- mod_rad_auth:使用radius服务器进行鉴权。
- mod_random:通过访问/dev/hwrandom设备影响随机数的熵。
- mod_redis:与redis服务器交互,类似于mod_memcache。
- mod_rss:访问RSS(Really Simple Syndication,简易信息聚合)数据。
- mod_skel:一个模块的例子框架。
- mod_sms:处理文本消息,如收发SIP MESSAGE消息等。它实现了消息路由(Chatplan),类似于Dialplan。
- mod_snapshot:可以截取一段声音的快照。
- mod_snipe_hunt:一个简单的例子模块。
- mod_snom:用于snom话机的一些特性。
- mod_sonar:该模块类似于一个真正的声呐。首先你可以在远端启动一个服务器,其能对来话执行echo APP。然后在本地的FreeSWITCH上产生一些铃声,发送到远端的服务器上再反射回来,然后使用VAD检测功能可以检测这些铃声,从而可以在某种程度上确定网络的质量。
- mod_soundtouch:使用soundtouch库对声音进行处理,可以增加音效。
- mod_spandsp:使用spandsp支持一些语音编码及传真功能。
- mod_spy:用于监视某个话机,当该话机有通话时,本机振铃同时可以监听。
- mod_stress:使用快速傅里叶变换(Fast Fourier Transform,FFT)检测重音。
- mod_translate:通过既定的规则对号码进行翻译。
- mod_valet_parking:电话停靠。类似于泊车,有来电时可以将来电停靠在某个泊位上,然后通知某人拨打指定的号码将来话接走。
- mod_vmd:提供Voicemail声音检测。在国外,好多电话都有自动应答功能,如“您好,主人不在家,请留言”。使用该模块可检测到这种声音,应用程序在自动外呼时就可以根据它的结果判断是人工接听的还是机器接听的。
- mod_voicemail:语音邮箱。
- mod_voicemail_ivr:带IVR导航的语音邮箱。
(2)ars_tts
该目录下的模块提供自动语音识别及语音合成的功能。
- mod_cepstral:使用Cepstral语音库支持TTS。
- mod_flite:使用Festival Lite库支持TTS。只支持英文。
- mod_pocketsphinx:使用pocketsphinx库支持语音识别。
- mod_tts_commandline:通过命令行程序使用TTS。
- mod_unimrcp:通过uniMRCP协议与其他ASR/TTS产品对接。uniMRCP是一个标准的协议,很多语音产品都支持它。
(3)codecs:各种类型的音、视频编码。
- mod_amr:AMR编解码,仅支持透传。
- mod_amrwb:AMR编解码,宽带,仅支持透传。
- mod_b64: Base64编码,可以传输任何数据。
- mod_bv: BroadVoice的编码。
- mod_celt:CELT编解码。
- mod_codec2:Codec2编解码,非常节省带宽,仅2-4k。
- mod_com_g729: 商业的G.729编码,可转码,需要许可证。
- mod_dahdi_codec: 通过DAHDI库提供的编码。
- mod_g723_1:G723编解码,仅支持透传。
- mod_g729:仅支持透传。
- mod_h26x:提供H261,H263,H264等视频编码,仅支持透传
- mod_ilbc:iLBC编解码。
- mod_isac:iSac编解码。
- mod_mp4v:mp4v编解码,仅支持透传。
- mod_openh264:使用思科OpenH264库支持H264编解码。
- mod_opus:OPUS编解码。
- mod_sangoma_codec:通过硬件板卡支持包括G729、iLBC等多种编码
- mod_silk:SILK编解码。
- mod_siren:Siren编解码。
- mod_skel_codec:例子模块。
- mod_speex:SpeeX编解码模块。在1.4版中已移至核心中,不再以独立模块的形式存在
- mod_theora:Theora编解码。
- mod_vp8:在1.6中已被
mod_vpx
代替。 - mod_vpx:VP8、VP9编解码模块。
- mod_dialplan_asterisk:类似于Asterisk格式的拨号计划。
- mod_dialplan_directory:通过LDAP查询拨号计划。
- mod_dialplan_xml:XML拨号计划。
- mod_ldap:通过LDAP提供目录服务。
- mod_alsa: 使用ALSA声卡。
- mod_dingaling: 连接Google Talk。
- mod_gsmopen: 使用无线上网卡上的GSM接口或使用手机上的GSM接口与外界发短信或通话。
- mod_h323: 连接H.323设备。使用OpenH323库实现。
- mod_khomp: 使用KHOMP板卡。
- mod_loopback: 提供loopback回环接口。
- mod_opal: 连接H.323设备,使用OPAL库实现。
- mod_portaudio:通过Portaudio库支持本地声卡。
- mod_reference:未知。
- mod_rtmp: 通过Adobe的rtmp协议与浏览器中的Flash电话进行通话。
- mod_skinny: 支持思科的SCCP协议话机。
- mod_skypopen: 与Skype互通。
- mod_sofia: SIP模块。
- mod_unicall:未知。
- mod_verto:FreeSWITCH特定的基于WebSocket和JSON的协议,支持WebRTC。
- mod_amqp:AMQP模块,支持与RabbitMQ连接,发送事件,执行命令等。
- mod_cdr_csv: CSV格式的话单。
- mod_cdr_mongodb: 将话单写入Mongodb。
- mod_cdr_pg_csv: 将话单写入PostgreSQL数据库。
- mod_cdr_sqlite: 将话单写入SQLite数据库。
- mod_erlang_event:对接Erlang节点,提供事件、日志、命令接口等。
- mod_event_multicast:将事件通过组播方式发出去。
- mod_event_socket:通过ESL库与第三方的接口。
- mod_event_test:测试。
- mod_event_zmq:使用ZeroMQ协议与第三方对接。
- mod_format_cdr: JSON和XML格式的CDR。
- mod_json_cdr: JSON格式的CDR。
- mod_kazoo:2600Hz使用的Erlang模块,解决了
mod_erlang_event
的一些问题。 - mod_radius_cdr:将CDR写入Radius服务器。
- mod_rayo:Rayo支持。
- mod_smpp:使用SMPP协议发送即时消息。
- mod_snmp:SNMP网管接口。
- mod_imagick:使用ImageMagick库支持Gif、PDF等。
- mod_local_stream: 从本地文件生成媒体流。
- mod_native_file: 支持原生文件读写,如直接读写
.PCMU
或.G729
格式的文件。 - mod_png:支持PNG文件。
- mod_portaudio_stream: 使用
portaudio
库从本地声卡生成媒体流。 - mod_shell_stream: 从Shell命令中生成媒体流。
- mod_shout: MP3文件格式支持,远程Shoutcast服务器支持。
- mod_sndfile: 使用
libsndfile
支持大多数的声音文件。 - mod_ssml: SSML格式的文件支持。
- mod_tone_stream: 生成铃流音。
- mod_vlc: 使用libvlc提供媒体文件格式的支持。
- mod_webm:支持webm文件。
- mod_basic:Basic。
- mod_java: Java。
- mod_lua: Lua。
- mod_managed: 微软平台的语言接品,如C#、VB.NET等。
- mod_perl: Perl。
- mod_python:Python。
- mod_spidermonkey:Javascript,已被
mod_v8
替代。 - mod_v8:Javascript。
- mod_yaml:Yaml。
- mod_console: 控制台日志。
- mod_graylog2: 使用graylog2写日志文件。
- mod_logfile: 日志文件。
- mod_syslog: 将日志写到Syslog。
- mod_say_de: 德语。
- mod_say_en: 英语。
- mod_say_es: 西班牙语。
- mod_say_es_ar: 西班牙语。
- mod_say_fa: 波斯语。
- mod_say_fr: 法语。
- mod_say_he: 希伯来语。
- mod_say_hr: 克罗地亚语。
- mod_say_hu: 匈牙利语。
- mod_say_it: 意大利语。
- mod_say_ja: 日语。
- mod_say_nl: 荷兰语。
- mod_say_pl: 波兰语。
- mod_say_pt: 葡萄牙语。
- mod_say_ru: 俄语。
- mod_say_sv: 萨尔瓦多语。
- mod_say_th: 泰语。
- mod_say_zh: 汉语。
- mod_posix_timer:Posix定时器。
- mod_timerfd: 使用Linux内核中的
timerfd
定时器。
- mod_xml_cdr:使用XML格式写CDR。
- mod_xml_curl: 从远程HTTP服务器获取XML配置。
- mod_xml_ldap: 从远程LDAP服务器获取XML配置。
- mod_xml_radius: 从远程Radius服务器获取XML配置。
- mod_xml_rpc: 使用XMLRPC接口与第三方交互,提供命令、日志及事件接口等,本身也是一个简单的Web服务器,并提供一个简单的Web管理界面。
- mod_xml_scgi: 使用SCGI协议获取XML配置。