第一章 PSTN与VoIP基础
- VoIP(Voice Over IP):承载于IP网上的语音通信(网络电话)。
- PSTN(Public Switched Telephone Network):公共交换电话网。
1.1 PSTN起源与发展
在漫长的通信历史长河中,PSTN以及电话交换技术的发展经历了很多阶段,如从直接控
制到间接控制再到公共控制、从人工交换到自动交换、从点子交换到程控交换、从模拟到
数字、从电路交换到分组交换、从“硬”交换到软交换。
1.1.1 最早的电话网
第一次语音传输是苏格兰人亚历山大·贝尔(Alexander Granham Bell)在1876年用振铃电
路实现的。
振铃电路实现是没有电话号码的,通话用户之间必须由物理线路连接,同一时间只能一个
用户讲话。
1.1.2 人工电话交换时代
交换机(Switch,又称Exchange)的设备诞生了,线路大大减小。交换连续工作全部由人工
完成。
1.1.3 自动电话交换时代
1889年到1891年期间,美国阿尔蒙·B·史端桥(Almon B Strowger)发明了步进式自动电话交
换机。属于“直接控制”方式。
以后,又出现了旋转式和升降式的交换机。采用“记发器”的部件来接收用户的拨号脉冲,属于
“间接控制”方式。
1919年,瑞典的电话工程师帕尔姆格伦和贝塔兰德发明了“纵横制连接器”。把控制器和话路器
分开。控制部分由标志器和记发器来完成。
1.1.4 半电子交换机时代
控制部分引入了电子技术,而话路部分在较长的一段时间内仍采用机械触电。
1.1.5 空分交换机时代
1965年5月,美国布尔系统的1号电子交换机(ESS No.1)问世了,这是世界上第一部开通使用
的程控电话交换机。当时的交换机话路部分还保留了机械触电,以“空分”方式工作,因此称为
空分交换机。交换的还是模拟信号。
1.1.6 数字交换时代
20世纪60年代初以来,脉冲编码调制(PCM)技术成功地应用于传输系统中,它将“模拟”的信号
数字化,提高了通话质量、增加了传输距离,节约了许多线路成本。1970年,法国开通了世界上
第一部程控数字交换机E10,开始了数字交换的心时代。
1.1.7 现代PSTN时代
随着技术的进步和通信要求的增加,世界上许许多多的交换机也需要相互通信,这些交换机之间
通过中继线(Trunk)相连,随着电子交换机和程控交换机的发展,便出现了现代意义的PSTN网
络。
20世纪70年代后期出现了蜂窝式移动电话(当移动电话小到可以拿到手里的时候就开始叫“手机”了
)系统,这是无线电话发展的里程碑。无限电话的出现,扩展了PSTN网络能力和范围,对PSTN网络
的影响及其深远。
专门用于移动电话交换的通信网络称为移动网,而原来的程控交换网则称为固定电话网,简称固网。
简单来说,移动网就是在普通固网上增加了许多基站(Base Station,可以简单理解为天线),并
增加了归属位置寄存器(Home Location Register,HLR)和拜访位置寄存器(Visitor Location
Register,VLR),以记录用户的位置()、支持异地漫游等。移动交换中心称为MSC(Mobile Switch
Center)。
1.1.8 下一代网络及VoIP时代
随着分组交换的成熟及英特网的发展,人们认识到了将原始的基于电路交换的语音网络与基于分组
交换的英特网络进行融合(即语音通信和数据通信相结合)的必要性,因此一个称为NGN(Next
Generation Network)的概念被提了出来。
经过数年的研究和探索,人们提出了各种NGN解决方案,但最终基本上都统一到了IMS(IP Multimedia
Subsystem)技术。
IMS属于核心交换层的技术,它全部基于IP网络,但在接入层,目前的语音大部分还是基于电路接入
的方式接入的,因此,在一定时间内IMS在接入层要继续兼容电路接入。未来的通信中要求完全取消
低效的电路传输及电路交换,而全部集中在IP通信上来,也就催生了新的无限通信标准LTE。
关于通信网络的演进,简单来说,在无线方面体现为从GSM/CDMA/UMTS等向LTE发展,在核心网方面则
体现为电路交换向IMS发展。
1.2 电话实现技术
1.2.1 电话号码
1.固定电话号码
现行的电话网中采用E.164号码格式。
2.移动电话号码和专用号段
移动电话号码俗称手机号,由于其可移动与漫游的特性,与普通固定电话略有不同。我国的移动电话
都是以1开头,按不同的运营商来划分。
3.短号码
有一类特殊的号码称为短号码,如110,119,120等。
4.800和400号码
800号码用手机打不通,400是可以手机呼叫的。
5.北美电话号码分类计划
加拿大和美国使用北美电话号码分类计划,其区号由3位数字组成,本地号码为7位数字,1为长途接入
码,即长途字冠。
6.电话号码书写格式
国内号码的书写一般采用如下的方式:
- (010)ABCD EFGH (没有国家代码,虽然0不是区号的一部分,但是,习惯了)
- +86(10)ABCD EFGH (固话,8位,国际号码格式)
- +86(535)ABCD EFGH (固话,7位,国际号码格式)
- +86 139 ABCD EFGH (手机,国际号码格式)
1.2.2 模拟信号与数字信号
模拟(Analog)量是连续的变化的量。容易引入噪音。
数字(Digital)信号是不连续的(离散的)。
1.2.3 PCM
PCM(Pulse Code Modulation)的全称是脉冲编码调制。它是一种通用的将模拟信号转换成以0和1表示
的数字信号的方法。
人的音频范围在300~3400Hz之间,通过滤波器将超过4000Hz的频率过滤出去,便得到4000Hz内的模拟信
号。然后根据抽样定理,使用8000Hz进行抽样,便得到离散的数字信号。使用PCM方法得到的数字信号
就称为PCM信号,一般一次抽样会得到16bit的信息。
使用压缩算法,可以将每一个抽样值压缩到8bit。这样1秒的抽样就得到8bit×8000=640000bit信号(简称
64kbit),抽样速率(即传输速率)为64Kbit/s。
PCM通常有两种压缩方式:A律和μ率。北美使用μ律,我国和欧洲使用A率。
1.2.4 局间中继与电路复用技术
连接交换机(局)的E1或T1电路称为局间中继。
1.3 我国电话网结构
我国电话网由本地网与长途网组成,并通过国际交换中心进入国际电话网。
1.4 信令
用户设备(如话机)与端局交换机之间,以及交换机与交换机之间需要进行通信。这些通信所包含的信息有
(但不限于)用户、中继线状态、主叫号码、被叫号码、中继路由的选择等。我们把这些消息称为
信令(Signaling)。
1.4.1 信令分类
按信令的功能分
- 线路信令:具有监视功能,用来监视主被叫的摘、挂机状态及设备忙闲。
- 路由信令:具有选择功能,指主叫所拨的被叫号码,用来选择路由。
- 管理信令:具有操作功能,用于电话网的管理和维护。
按信令的工作区域分
- 用户线信令:是用户终端与交换机之间的信令。
- 局间信令:是交换机和交换机之间的信号,在局间中继线上传送,用来控制呼叫连续和拆线。
按信令的信道分
- 随路信令:信令和话音在同一条话路中传输。
- 公共信道信令:以时分方式在一条高速数据链路上传送一群话路。
其他分类
信令还可以分为带内信令和带外信令、模拟信令和数字信令、向前信令和向后信令、线路信令和记发器信令等。
1.4.2 用户线信令
从用户终端(通常是话机)到端局交换机之间经常需要传送一些控制信息,如用户摘机、挂机、拨号、主叫号码
显示等,这些信息称为用户线信令。用户线信令可以通过模拟或数字信号传递。
1.4.3 局间信令
交换机与交换机之间也需要传送控制信号,用于话路的建立、释放等,这些信号就称为局间信令。
目前在传统的PSTN网络中常见的局间信号有ISDN PRI(Primary Rate Interface,基群速率接口)信令和七号信令。
PRI信令和话路在同一个E1上传送。七号信令可以与话路在同一个E1上传送外,还可以在专门的用于传送信令链路的
E1中继上传送。
1.4.4 七号信令
七号信令(Signaling System No.7,SS7)是我国目前使用的主要信令方式,用于局间通信。我国的电话网络中有专
门的七号信令网。
由于ISUP(ISDN User Part,ISDN用户部分)能与ISDN互联并提供比TUP更多的能力和服务,故其已基本取代TUP成为
我国七号信令网采用的主要信令方式。
1.4.5 H.323与SIP信令
H.323与SIP属于VoIP领域的通信信令,它们适用于用户线信令和局间信令。
H.323是ITU多媒体通信系列标准H.32x的一部分,该系列标准使得在现有通信网络上进行视频会议称为可能。
SIP(Session Initiation Protocol,会话发起协议)是由IETF(Interne 工程任务组)提出的IP电话信令
协议。
1.5 媒体
信令主要传输一些控制信号,而通信双方需要听到的是对方的语音数据,这些语音数据就称为媒体(Media).
在SIP通信中,除文字外,媒体都是在RTP协议中传输的。由于媒体一般都是持续传输的,因此又称RTP流。
1.6 电路交换与分组交换
传统电路交换,两个通信节点间需要建立一个专用通路。而报文交换以报文作为数据交换单位,携带目标地址、源地址
等信息。分组交换是报文交换的特殊情形。
1.6.1 电路交换
传统的电话都是基于电路交换的。
电路交换的优点:
- 由于通信线路为通信双方用户专用,数据直达,所以传输数据的时延性非常小。
- 通信双方之间的物理通路一旦建立,双方可以随时通信,实时性强。
- 双方通信时按发送顺序传输数据,不存在失序问题。
- 电路交换既适用于传输模拟信号,又适用于传输数字信号。
- 进电路交换的设备(交换机等)及控制均较简单
电路交换的缺点:
- 电路交换的平均连接建立时间对计算机通信来说较长。
- 建立电路交换连接后,物理通路被通信双方独占,即使通信线路空闲,也不能供其他用户使用,因而通信利用率低。
- 在进行电路交换时,数据直达,不同类型、不同规格、不同速率的终端很难相互进行通信,也难在通信过程中进行
差错控制。
1.6.2 分组交换
IP交换采用的就是分组交换方式。
分组交换的优点:
- 加快了数据在网络中的传输速度。
- 简化了存储管理。
- 减少了重发几率和重发数据量。
- 由于分组短小,更适用于采用优先级策略。
分组交换的缺点:
- 尽管分组交换比报文交换的传输时延少,但仍存在存储转发时延,而且节点交换机必须有更强的处理能力。
- 分组交换都要加上源、目的地址和分组编号,一定程度降低了通信效率,增加了处理时间,使控制复杂、
时延增加。 - 分组到达目的节点时,要对分组按编号进行排序等工作,增加了麻烦。
1.7 VoIP
IP电话(Voice over Internet Protocol,VoIP,又称宽带电话或网络电话)是一种透过互联网或其他使用
IP技术的网络来实现的新型电话通信。
目前,VoIP呼叫控制协议主要有SIP、H.323、MGCP与H.248/MEGACO等。
1.8 IMS
1.8.1 什么是IMS
IMS的全称是IP多媒体子系统(IP Multimedia Subsystem),它是一个基于IP网提供语音及多媒体的网络体系
架构。
1.8.2 IMS的特点
- 采用SIP作为呼叫控制协议。
- 支持Diameter协议。
- 采用归属控制方式。
- 采用接入无关性。
- 业务、控制、承载层完全分离。
- 增强计费功能。
- 增强多媒体业务。
1.8.3 IMS核心网元
(1)CSCF
CSCF(Call Sessoin Control Function,呼叫会话控制功能)。
- 代理CSCF(P-CSCF)
- 问询CSCF(I-CSCF)
- 服务CSCF(S-CSCF)
(2)MGCF
MGCF(Media Gateway Control Function,媒体网关控制功能)
- 控制IMS-MGW中的媒体信道的连接。
- 与CSCF通信。
- 根据路由号码,为从传统网络来的入局呼叫选择CSCF。
- 执行ISUP协议和IMS呼叫控制协议间的转换。
(3)IM-MGW
IM-MGW(IP Multimedia-Media Gateway Function,多媒体网关功能)
- 通过与MGCF交互来进行资源控制。
- 拥有并维护回声消除器等资源。
- 可能需要多媒体数字信号编、解码器。
(4)MRF
MRF(Multimedia Resource Function,多媒体资源功能)分成两部分,包括MRFC(Multimedia Resource Function
Controller,多媒体资源功能控制器)和MRFP(Multimedia Resource Function Processor,多媒体资源功能处理器)。
(5)SLF
SLF(Subscription Locator Function,签约定位功能)
(6)HSS
HSS(Home Subscriber Server,归属用户服务功能)
(7)BGCF
BGCF(Breakout Gateway Control Function,出口网关控制功能)
(8)SGW
SGW(Singnalling Gateway Function,信令网关功能)
(9)AS
AS(Application Server,应用服务器)
第2章 PSTN、PBX及呼叫中心业务
2.1 PSTN业务
PSTN除了为用户提供基本的语音通话外,还能提供一些附加的业务,如叫醒业务、呼叫转移等。
2.1.1 POTS
POTS(Plain Old Telephone Service)及普通老式电话业务。
2.1.2 商务业务
(1)模拟中继线
(2)数字中继线
(3)虚拟网
(4)立即计费
(5)VPN
2.1.3 其他增值业务
包括预付费业务(电话卡类业务等)、800业务、400业务以及彩铃、电话秘书台等。
2.2 PBX业务
PBX(Private Branch eXchange)的全称是专用小交换机。
2.2.1 呼叫转移
2.2.2 同组代答
2.3 PBX与中继线
用户或企业PBX要想打通外面的电话,或者外面的电话需要打进来,需要走运营商提供的中继线,
以接入到PSTN网上。
2.4 IP-PBX业务
FreeSWITCH的默认配置就是一个家用或小型企业级PBX,它是由纯软件实现的,基于IP网进行通信,
因而又称为IP-PBX。
IP-PBX首先是一个PBX(Private Branch eXchange),它具有传统PBX的绝大部分功能。另外,由于
使用了IP通信,它能够通过IP网提供语音、视频以及即时消息通信。
2.5 呼叫中心
基于企业级的PBX和IP-PBX的通信还只是局限于基础的通信层。而随着企业规模的扩大以及用户对服务
要求的提高,企业需要在业务层和管理层方面为用户提供更好的服务。当这些服务可以通过远程电话
支持的方式解决的情况下,一种称为呼叫中心的业务(Call Center)便产生了。
2.5.1 什么是呼叫中心
呼叫中心又称客户服务中心,它是一种基于CTI技术、充分利用通信网和计算机网的多项功能集成,并
与企业连为一体的一个完整的综合信息服务系统,利用现有的各种先进的通信手段,高效的为客户提供
高质量、高效率、全方位的服务。
通俗的将,呼叫中心是企业或机构建立的以电话为主的主要手段,为客户提供服务于沟通的部门组织及
信息系统。
2.5.2 呼叫中心的历史
(1)第一代呼叫中心
PBX基础上增加电话排队。
(2)第二代呼叫中心
IVR(Interactive Voice Response,交互式语音应答)系统的使用。
(3)第三代呼叫中心
CTI(Computor Telephony Integration,计算机电话集成)技术的应用。
(4)第四代呼叫中心
多媒体呼叫中心或联络中心(Contact Center)。
(5)下一代呼叫中心
融入互联网技术的媒体渠道与沟通渠道。
2.5.3 呼叫中心的分类
按照呼叫中心系统采用的技术架构的不同,呼叫中心可以分为交换机、板卡、软交换(IPCC)三种类型。
2.5.4 呼叫中心的主要技术指标
常见的KPI指标有接通率、呼入项目占有率、呼出项目工作效率、服务水品、客户满意度、平均振铃次数、
监听合格率、一次性解决问题率等。
2.5.5 CTI中间件
CTI(Computer Telephony Integration,计算机电话集成)。
交换机设备厂商开始考虑为交换机增加一个可以受计算机系统控制的接口,有计算机系统通过某种协议
获取交换机用户话机的状态信息以及对呼叫的控制命令。这种连接和控制接口称为CTI-Link。
CTI中间件在下层通过对各种CTI-Link协议的包装和抽象,屏蔽了各种交换机的不同,在上层为呼叫中心
业务软件开发人员提供统一的API开发接口。
2.5.6 FreeSWITCH在呼叫中心的应用
(1)语音交换功能
(2)媒体处理功能
(3)媒体监播功能
(4)电话会议功能
(5)电子传真功能
(6)排队功能
第3章 初识FreeSWITCH
3.1 什么是FreeSWITCH
3.1.1 FreeSWITCH的概念
FreeSWITCH是一个开源的电话交换平台。官方给它的定义是–世界上第一个跨平台的、伸缩性极好的、免费
的、多协议的电话软交换平台。
3.1.2 FreeSWITCH的功能
典型功能:
- 在线计费、预付费功能
- 电话路由服务器
- 语音转码服务器
- 支持资源优先权和QoS的服务器
- 多点会议服务器
- IVR、语音通知服务器
- VoiceMail服务器
- PBX应用和软交换
- 应用层网关
- 防火墙/NAT穿越应用
- 私有服务器
- 第三方呼叫控制应用
- 业务生成环境运行时引擎
- 会话边界控制器
- IMS中的S-CSCF/P-CSCF/I-CSCF
- SIP网间互联网关
- SBC及安全网关
- 传真服务器、T.30到T.38网关
3.2 快速体验
3.2.1 安装基本的FreeSWITCH系统
FreeSWITCH支持Linux、Windows、Mac平台。
1.版本简介
FreeSWITCH的版本号很有规律:版本号有3部分,以点号隔开。其中第1位为主版本,第2位为次版本,第3位作补丁及
更新标志。其中,从第2位看,偶数的版本为稳定版,奇数版本为开发版。
2.在Windows上安装
(1)使用安装包安装
下载地址:http://files.freeswitch.org/windows/installer/
(2)从源码安装
下载地址:http://files.freeswitch.org/freeswitch-releases/
Microsoft提供Visual Studio工具进行开发。
3.在Linux系统上安装
相关环境
CentOS:
yum install -y autoconf automake libtool gcc-c++ ncurses-devel make zlib-devel libjpeg-devl
yum install -y openssl-devel e2fsprogs-devel curl-devel pcre-devel speex-devel sqlite-devel
Ubuntu/Debian:
apt-get -y install build-essential automake autoconf git-core wget libtool
apt-get -y install libncurese5-dev libtiff-dev libjpeg-dev zliblg-dev libssl-dev libsqlite3-dev
apt-get -y install libpcre3-dev libspeexdsp-dev libspeex-dev libcurl4-openssl-dev libopus-dev
(1)从Git仓库安装
git clone git://git.freeswitch.org/freeswitch.git
cd freeswitch #进入源代码目录
git checkout -b v1.2.12 #根据一个tag检出到一个本地分支
或
git checkout -b v1.4.beta #从远程分支检出一个本地分支
或
git clone -b v1.4.beta git://git.freeswitch.org/freeswitch.git #直接在复制时指定一个分支
(2)解压缩源码包安装
wget http://files.freeswitch.org/freeswitch-1.4.0.beta6.tar.bz2
tar xvjf freeswitch-1.4.0.beta6.tar.bz2
cd freeswitch-1.4.0
./configure
make install
(3)最快安装
wget http://www.freeswitch.org.cn/Makefile && make install
4.在Mac系统上安装
需要先下载Apple的Xcode工具,安装命令行工具(Command Line Tools)
FreeSWITCH也依赖于一些第三方的库。一般使用Macports、Flink和HomeBrew等工具包。
ruby -e "$(culr -fsSl https://raw.github.com/mxcl/homebrew/go)"
安装Git和libtiff库
brew install git
brew install libtiff
其他全部和Linux一样
git clone git://git.freeswitch.git/freewitch.git
cd freeswitch
./bootstrap.sh
./configure
make install
5.安装声音文件
声音文件有2种,一种是提示音,另一种是音乐。
在windows是默认安装的。而在Linux和Mac上安装这些声音,源码目录中执行:
make sounds-install
make moh-install
6.安装完成后的操作
FreeSWITCH使用make install 安装完成后,会显示一个有用的帮助。
建议将两个命令做符号链接放到你的搜索路径中,如:
ln -sf /usr/local/freeswitch/bin/freeswitch /usr/bin/
ln -sf /usr/local/freeswitch/bin/fs_cli /usr/bin/
启动在前台,输入shutdown
关闭
freeswitch -nc
后台模式, freeswitch -stop
关闭FreeSWITCH
不管前台还是后台,都可以使用客户端软件fs_cli
连接到它并控制
/exit
或按Ctrl+D
组合键,退出终端。
3.2.2 连接SIP电话
FreeSWITCH最典型的应用是作为一个服务器,并用电话客户端软件连接到它。
FreeSWITCH主要使用的通信协议是SIP。
支持SIP的软电话常用的有X-Lite和Zoiper。
X-Lite配置:
选“Sip Account Setting…”,单击“Add”添加一个账号,填入一下参数:
Display Name:1000
User Name:1000
Password:1234
Authorization user name:1000
Domain:FreeSWITCH服务所在的IP地址
3.3 配置FreeSWITCH
FreeSWITCH配置文件默认放在conf/下。
conf/目录和文件 | 说明 |
---|---|
–vars.xml | 一些常用变量 |
–switch.xml | 主配置文件,它会使用include语句装入其他文件 |
–autoload_configs | 目录,存放自动加载的配置文件 |
—-modules.conf.xml | 配置当FreeSWITCH启动时自动装载哪些模块 |
—-*.xml | 一般来说每个模块都有一个配置文件 |
–chatplan | 聊天计划 |
–dialplan | 拨号计划 |
—-default.xml | 默认的拨号计划配置,一般用于内部用户路由 |
—-public.xml | 默认的拨号计划配置,一般用于外部来的路由 |
–drectory | 用户目录 |
—-default | 默认的用户目录配置 |
——*.xml | SIP用户,每用户一个文件 |
–ivr_menus | IVR菜单 |
–jingle_profiles | 连接Google Talk的相关配置 |
–lang | 多语言支持 |
—-en | 英语 |
—-fr | 法语 |
–mrcp_profiles | MRCP的相关配置,用于跟第三方语音合成和语音识别系统对接 |
–sip_profiles | SIP配置文件 |
—-internal.xml | 一个SIP profile,或称作一个SIP-UA,监听在本地IP及端口5060 |
一般供内网用户使用 | |
—-externa.xml | 另一个SIP-UA,用作外部连接,端口5080 |
–skinny_profiles | 思科SCCP协议话机的配置文件 |
FreeSWITCH默认设置了20个用户,如果你需要更多的用户,3步:
- 在
conf/directory/default/
中增加一个配置文件。 - 修改拨号计划使其他用户可以呼叫到它。
- 重新加载配置文件使其生效。
3.4 FreeSWITCH用作软电话
也可以把FreeSWITCH简单地用作一个软电话。目前唯一支持CELT高清通话的软电话。
FreeSWITCH使用mod_portaudio模块支持你本地的音频设备,默认是不编译的。在源码目录执行:
make mod_portaudio
make mod_portaudio-install
安装完成后控制台执行:
load mod_portaudio
尝试以下命令:
pa looptest (回路测试,echo)
pa call 9196 (呼叫9196)
pa call 1000 (呼叫1000)
pa hangup (挂机)
3.5 配置SIP网关拨打外部电话
如果你拥有某个运营商提供的SIP账号,那么你就可以通过配置SIP来拨打外部电话了。
该SIP账号(或提供该账号的设备)在FreeSWITCH中称为SIP网关(Gateway)。
添加网关需要在conf/sip_profiles/external/
中创建一个XML文件。如gwl.xml:
<gateway name="gwl">
<param name="realm" value="SIP服务器地址,可以是IP或IP:端口号"/>
<param name="username" value="SIP用户名"/>
<param name="password" value="密码"/>
</gateway>
执行命令使之生效:
sofia profile external rescan
显示网关注册状态:
sofia status
如果显示gateway gwl
的状态是REGED
,则表明已正确地注册到了网关上。
先用命令试一下网关是否正常:
originate sofia/gateway/gwl/xxxxxx &echo
该命令会通过网关gwl呼叫号码xxxxxx,被叫号码接听电话后,FreeSWITCH会执行echo程序,
就能听到自己的回音了。
3.5.1 从某一分机上呼出
常见的PBX一般是内部拨小号,打外部电话就需要加拨0或先按9。
<include>
<extension name="call out">
<condition field="destination_number" expression="^0(\d+)$">
<action application="bridge" data="sofia/gateway/gwl/$1" />
</condition>
</extension>
</include>
其中,匹配0后面的变量并存入到变量$1中。然后通过bridge程序通过网关gwl打出该号码。
3.5.2 呼入电话处理
一般来说,呼入的DID就是你的SIP号码。
创建XML文件放到conf/dialplan/public/my_did.xml
中:
<include>
<extension name="public_did">
<condition field="destination_number" expression="^(你的DID)$">
<action application="transfer" data="1000 XML default"/>
</condition>
</extension>
</include>
第4章 运行FreeSWITCH
4.1 命令行参数
一般来讲,FreeSWITCH不需要任何命令行参数就可以启动。
使用freeswitch -h
或freeswitch -help
或freeswitch --help
显示帮助信息
常用的两个:
freeswitch -nc #后台启动
freeswitch -nonat #关掉NAT启动
4.2 系统启动脚本
在调试阶段,可以将FreeSWITCH启动到前台,也可以启动到后台,通过查看log/freeswitch.log
跟踪系统运行情况。
在真正生成系统上,一般需要FreeSWITCH能跟系统一起启动。
- 在UNIX类系统上,启动脚本一般放在etc/init.d/
下。可以在源码目录下找到不同系统启动脚本debian/freeswitch.init
及build/freeswitch.init.*
。
- 在Windows上,可以将FreeSWITCH注册为服务。
4.3 判断FreeSWITCH是否运行
UNIX类系统下:
(1)看进程是否存在。
ps aux | grep freeswitch
(2)看相关端口是否被占用。
netstat -an | grep 5060
netstat -anp | grep 5060
Windows平台:
netstat命令、任务管理器。
4.4 控制台与命令客户端
系统不带参数启动到控制台,在控制台上可以输入各种命令以控制或查询FreeSWITCH的状态。
version -- 显示当前版本
status -- 显示当前状态
sofia status -- 显示sofia状态
help -- 显示帮助
为了调试方便,还在conf/autoload_configs/switch.conf.xml
中定义了一些控制台快捷键。
FreeSWITCH是一个典型的Client/Server结构,不管FreeSWITCH运行在前台还是后台,你都可以使
用客户端软件fs_cli连接FreeSWITCH。
fs_cli使用FreeSWITCH的ESL协议与FreeSWITCH通信。
fs_cli也支持很多命令行参数,值得一提的是-x参数,它允许执行一条命令后退出。
$ bin/fs_cli -x "version" # 显示版本号
$ bin/fs_cli -x "status" # 显示状态
$ bin/fs_cli -x "originate user/1000 &bridge(user/1001)" # 回拨
fs_cli可以连接到其他机器上的FreeSWITCH,用户主目录编辑配置文件.fs_cli_conf
[server1]
host => 192.168.1.10
port => 8021
password => secret_password
debug => 7
[server2]
host => 192.168.1.11
port => 8021
password => secret_password
debug => 0
配置好,可以这样使用:
$ fs_cli server1
$ fs_cli server2
fs_cli有几个特殊命令,以”/”开头。这些命令不直接发送到FreeSWITCH,而是先由fs_cli处理。
4.5 呼叫
4.5.1 发起呼叫
使用originate
命令发起一次呼叫。
freeswitch> originate user/1000 &echo
呼叫1000,1000接听后,将听到回声。
4.5.2 呼叫字符串
“user/1000”称为呼叫字符串。
假设alice的UA地址为192.168.4.4:5090,已向FreeSWITCH注册。
freeswitch> sofia status profile internal reg
可以看到alice的注册信息。
使用originate命令呼叫user/alice这个呼叫字符串时,会找到Cantact地址sip:alice@192.168.4.4:5090
并向其发送INVITE请求。
4.6 API与App
FreeSWITCH的命令不仅可以在控制台上使用,也可以在各种嵌入式脚本、Event Socket或HTTP RPC上使用,
所有命令都遵循一个抽象的接口,因而这些命令又称为API Commands。
echo则是一个常用的应用程序(Application,App),它的作用是控制一个Channel的一端。
alice是一端,另一端是echo。这种通话称为“单腿通话(one-legged connection)”。
可以将电话“挂起”,park便是实现这个功能。
hold比较友好,等待同时播放音乐。
freeswitch> originate user/alice &hold
播放特定的声音
freeswitch> originate user/alice &playback(/root/welcome.wav)
或直接录音
freeswitch> originate user/alice &record(/tmp/voice_of_alice.wav)
大多数情况下,FreeSWITCH都是作为一个B2BUA来桥接两个UA进行通话的。在alice接听电话后,bridge程序可以在启动一个UA呼叫bob
freeswitch> originate user/alice &brige(user/bob)
另一种方式
originate user/alice &park
originate user/bob &park
show channels
uuid_bridge <alice_uuid><bob_uuid>
分别呼叫alice和bob,然后通过uuid_bridge命令将两个Channel桥接起来
两条命令(API):originate和uuid_bridge
几个程序(App):echo、park和bridge
**简单来说,一个App是一个程序(Application),它作为一个Channel一端与另一端的UA进行通信,相当于它工作在Channel内部;
而一个API则是独立于一个Channel之外的,它只能通过找到Channel的UUID来控制一个Channel(如果需要的话),相当于一个第三者。**
这就是API和App最本质的区别。
- 大部分API都是在mod_commands模块中加载的。
- App则在mod_dptools中。
4.7 API命名帮助
使用help可以列出所有命令的帮助信息。
freeswitch> help
第5章 FreeSWITCH架构
5.1 总体架构
总的来说,FreeSWITCH由一个稳定的核心(Core)以及一些外围模块组成。
FreeSWITCH内部使用线程模型来处理并发请求,每个连接都在单独的线程中进行处理,不同的线程间通过Mutex互斥访问共享资源,并
通过消息和异步事件等方式进行通信。
FreeSWITCH的核心非常短小精悍。绝大多数应用层的功能都在外围模块中实现。外围模块通过核心提供的Public API与核心进行通信,
而核心则通过回调(或称钩子)机制执行外围模块中的代码。
5.1.1 核心
FreeSWITCH的核心是Core,它包含了关键的数据结构和复杂的代码、状态机、数据库等,这些代码只出现在核心中,并保持了最大限度
的抽象和重用。外围模块只能通过核心代码提供的公共应用程序接口调用核心的功能。
1.数据库(DB)
FreeSWITCH的核心除了使用内部队列、哈希表存储数据外,也使用外部的关系型数据库存储数据。
2.公共应用程序接口(Public API)
核心层实现了一些Public API。这些Public API可以被外围的模块调用。
3.接口(Interface)
提供了很多抽象的接口,具体实现一般由外围的模块负责,核心层通过回调(钩子)方式调用具体的实现代码或函数。
4.事件(Event)
内部也使用消息和事件机制进行进程间和模块间通信。
5.1.2 接口实现
接口都是抽象的,其中只有少量在核心中有具体实现(如PCM编码解码实现),大部分最终由外部实现。
- 终点(Endpoint)。
- 拨号计划(Dialplan)。
- 聊天计划(Chatplan)。
- 应用程序(Application,APP)。
- 命令接口(FSAPI)。
- XML接口(XML Interface)。
- 编解码器(Codec)。
- 语音识别及语音合成(ASR/TTS)。
- 格式、文件接口(Format、File Interface)。
- 日志(Logger)。
- 定时器(Timer)。
- 嵌入式语言(Embeded Language)。
- 事件套接字(Event Socket)。
5.2 目录结构
目录 | 说明 |
---|---|
bin | 可执行程序 |
db | 系统数据库(sqlite),将呼叫信息存放到数据库中,这样在查询时就无须对核心数据结构进行加锁了 |
htdocs | HTTP Server根目录 |
lib | 库文件 |
mod | 可加载模块 |
run | 运行目录,存放FreeSWITCH运行时PID |
sounds | 声音文件,使用playback()时默认的寻找路径 |
grammer | 语法,用于ASR |
include | 头文件 |
recordings | 录音,使用record()时默认的存放路径 |
scripts | 嵌入式语言写的脚本,如使用lua()、luarun()、jsrun等默认寻找的路劲 |
storage | 语音留言(Voicemail)的录音 |
conf | 配置文件 |
5.3配置文件
在系统装载时,XML解析器会将所有的XML文件组织在一起,并读入内存,组成一个大的XML文档(Document),称为XML注册表。
5.3.1 freeswitch.xml
freeswitch.xml是所有XML文件的黏合剂。
5.3.2 vars.xml
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"/>
实际使用中,可以使用global_getvar或API命令来查看这些变量的值。
freeswitch> global_getvar sound_prefix
freeswitch> global_getvar local_ip_v4
5.3.3 autoload_configs目录
autoload_config目录下的各种配置文件会在系统启动时装入。一般来说都是块级的配置文件,每个模块对应一个。
5.3.4 其他
- dialplan目录:该目录定义了XML拨号计划。
- ivr_menues目录:该目录下存放了默认的一些IVR菜单例子。
- directory目录:作为注册服务器时,用于配置本地用户,配置信息称为用户目录。
5.4 XML用户目录
SIP并不要求一定要注册才能可以打电话,但是通话前的用户认证参数仍需要在用户目录中进行配置。
5.5 呼叫相关概念
5.5.1 来去话、Session、Channel与Call
Bob到FreeSWITCH的通话称为来话,FreeSWITCH作为一个B2BUA再去呼叫Alice时,称为去话。
无论来话还是却话,都会启动一个Session,控制着整个呼叫,直到结束。每个Session都控制着一个Channel。
在逻辑上组成一个通话,称为Call。
5.5.2 回铃音与Early Media
A-交换机a-交换机b-B
为了在A端能听到B端特殊的回铃音,回铃音只能由B端交换机发送。这些回铃音称为Early Media。
理论上将,B接听电话后交换机b可以一直不向交换机a发送应答消息,而是将真正的话音数据伪装成Early Media,实现“免费通话”。
5.5.3 全局变量与局部变量
- 全局变量 $${var}
- 局部变量 ${var}
第6章 拨号计划
拨号计划主要作用就是对电话进行路由,决定和影响通话的流程。
6.1 XMLDialplan
可以是静态配置的,也可以使用动态配置方式从其他服务器或脚本中动态获取。
6.1.1 配置文件的结构
拨号计划由多个Context组成。每个Context中有多个Extension。Context就是多个Extension的逻辑集合,
它相当于一个分组。一个Context中的Extension与其他Context中的Extension在逻辑上是隔离的。
6.1.2 默认的配置文件简介
系统默认提供的配置文件包含三个Context,分别是default、feature和public。
- default:默认的Dialplan,一般来说注册用户都可以通过它来打电话。
- public:一般用于接收外来呼叫。
6.1.3 正则表达式
使用与Perl兼容的正则表达式匹配算法。
6.1.4 通道变量
每一次呼叫都由一条或多条“腿”(Call Leg)组成,其中的一条腿又称为一个Channel,每一个Channel都有很多属性,
用于标识Channel的状态、性能等,这些属性称为Channel Variable(通道变量)。
6.1.5 测试条件
最简单的测试条件
<condition field="destination_number" expression="^1234$">
<condition field="network_addr" expression="^192\.168\.7\.7$">
Dialplan中的测试条件
变量 | 说明 |
---|---|
context | Dialplan当前的Context |
rdnis | 被转移的号码 |
destination_number | 被叫号码 |
diaplan | Dialplan模块的名字,如XML、YAML、inline、asterisk、enum等 |
caller_id_name | 主叫(来电显示)的名称 |
caller_id_number | 主叫号码 |
ani | 主叫的自动识别 |
aniii | 主叫类型,如投币电话 |
uuid | 本Channel的唯一标志 |
source | 呼叫源,来自哪一个FreeSWITCH模块 |
chan_name | Channel名字 |
network_addr | 主叫ip地址 |
year | 当前的年,0~9999 |
yday | 一年中的第几天,1~366 |
mon | 月,1~12 |
mday | 日,1~31 |
week | 一年中的第几周,1~53 |
mweek | 本月中的第几周,1~6 |
wday | 一周中的第几天,1~7 |
hour | 小时,0~23 |
minute | 分,0~59 |
minute-of-day | 一天中的第几分钟,(1~1440) |
接受用户在用户目录中设置的变量,但要注意必须使用${}对变量进行引用。
<condition field="${toll_allow}" expression="international">
测试条件不可嵌套,但可迭加。构成“逻辑与”关系。
break参数可以使condition构成其他关系。
- on-false。在第一次匹配失败时停止。
- on-true。在第一次匹配成功时停止。
- always。不管是否匹配,都停止。
- never。不管是否匹配,都继续。
6.1.6 动作与反动作
除使用condition的break机制来完成复杂的条件以外,你还可以使用“反动作”来达到类似的目的。
6.1.7 工作机制深入剖析
new->init->routing<->execute->hangup->reporting->destory
ROUNTING和EXECUTE是属于两个不同的阶段,只有ROUTING完毕后才会进行EXECUTE阶段的操作。
6.1.8 内联执行
在Hunting阶段,如果发现带有inline的Action,会直接执行它,而不用等到EXECUT阶段。
<action inline="true" application="set" data="greeting=no-greeting.wav" />
inline会打乱执行顺序,所以使用不当可能会产生非预期的结果。
6.1.9 实例解析
1.Local_Extension
<extension name="Local_Extension">
<condition field="destination_number" expression="^(10[01][0-9])$">
<!-- many actions,此处省略 -->
</condition>
</extension>
1000呼叫1001时,匹配的结果会放入变量 1中, 1 中 , 1=1001。
省略的“many actions”里面的内容:
<action application="set" data="dialed_extension=$1"/>
<action application="export" data="dialed_extension=$1"/>
set是将变量设置在当前Channel上,及a-leg。
export是将变量设置在b-leg上,还设置了一个特殊的值。
上面第二行相当于:
<action application="set" data="dialed_extension=$1"/>
<action application="set" data="export_vars=dialed_extension"/>
接着:
<action application="bind_meta_app" data="1 b s execute_extension::dx XML features"/>
<action application="bind_meta_app" data="2 b s record_session::$${recordings_dir}/${caller_id_number}.${strftime{%Y-%m-%d-%H-%M-%S}}.wav"/>
<action application="bind_meta_app" data="3 b s execute_extension::cf XML features"/>
<action application="bind_meta_app" data="4 b s execute_extension::att_xfer XML features"/>
bind_meta_app的作用是在该Channel上绑定DTMF(Dual Tone Multi Frequency(双音多频))。上面分别绑定了1、2、3、4四个按钮,都绑定在了b-leg上。
接着设置回铃音:
<action application="set" data="ringback=${us-ring}"/>
如果发生呼叫转移,听到回铃音:
<action application="set" data="transfer_ringback=$${hold_music}"/>
设置呼叫超时变量:
<action application="set" data="call_timeout=30"/>
<action application="set" data="hangup_after_bridge=true" />
<action application="set" data="continue_on_fail=true" />
<action application="hash" data="insert/${domain_name}-call_return/${dialed_extension}/${caller_id_number}"/>
<action application="hash" data="insert/${domain_name}-last_dial_ext/${dialed_extension}/${uuid}"/>
<action application="hash" data="insert/${domain_name}-last_dial_ext/${called_party_callgroup}/${uuid}"/>
<action application="hash" data="insert/${domain_name}-last_dial_ext/global/${uuid}"/>
最后一句:向 domainname−lastdialext这个hash表中插入一个global键,值是 d o m a i n n a m e − l a s t d i a l e x t 这 个 h a s h 表 中 插 入 一 个 g l o b a l 键 , 值 是 {uuid}。
set是将变量设置在Channel上,以通道变量形式存在,而hash保存到内存的哈希表数据结构中。
设置通道变量:
<action application="set" data="called_party_callgroup=${user_data(${dialed_extension}@${domain_name} var callgroup)}"/>
哈希表中插入数据:
<action application="hash" data="insert/${domain_name}-last_dial/${called_party_callgroup}/${uuid}"/>
终于到了一个干实事的地方:
<action application="bridge" data="{sip_invite_domain=$${domain}}user/${dialed_extension}@${domain_name}"/>
呼叫字符串翻译出来就是:
{sip_invite_domain=192.168.7.2}user/1001@192.168.2
“{}”里是设置通道变量。等价于:
<action application="export" value="nolocal:sip_invite_domain=192.168.7.2"/>
<action application="bridge" value="user/1001@192.168.7.2"/>
路由完成,接下来可能有几种情况:
- 被叫应答
- 被叫忙
- 被叫无应答
- 被叫拒绝
- 其他情况…
bridge一直阻塞,1000挂机,Dialplan没有必要执行了,产生计费信息,并销毁a-leg。
1001挂机,a-leg依然存在。
通过给continue_on_fail不同的值,决定在什么情况下继续。
<action application="set" data="continue_on_fail=USER_BUSY,NO_ANSWER"/>
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="voicemail" data="default ${domain_name} ${dialed_extension}"/>
暂停1秒,然后转到1001的语音信箱。
2.回声和延迟回声
<extension name="echo">
<condition field="destination_number" expression="^9196$">
<action application="answer"/>
<action application="echo"/>
</condition>
</extension>
<extension name="delay_echo">
<condition field="destination_number" expression="^9196$">
<action application="answer"/>
<action application="delay_echo" data="5000"/>
</condition>
</extension>
3.会议
<extension name="nb_conferences">
<condition field="destination_number" expression="^(30\d{2})$">
<action application="answer" data=""/>
<action application="conference" data="$1-${domain_name}@default"/>
</condition>
</extension>
30开头的4位数字呼叫,会进入电话会议。
4.将通话的双发转入会议
<action application="bind_meta_app" data="3 b s execute_extension::cf XML features"/>
1000呼叫1001,1001摘机与1000通话。1001通过按“*3”这个DTMF按键触发execute_extension动作。
<extension name="cf">
<condition field="destination_number" expression="^cf$">
<action application="answer"/>
<action application="transfer" data="-both 30${dialed_extension:2} XML default"/>
</condition>
</extension>
transfer一行等价于:
<action application="transfer" data="-both 3001 XML default"/>
-both表示将两条腿分别转到3001这个extension上。
6.2 inline Dialplan
inline Dialplan称为内联拨号计划。
语法格式:
app1:arg1,app2:arg2,app3:arg3
originate user/1000 echo inline
originate user/1000 answer,echo inline
6.3 其他Dialplan
查看系统支持多少Dialplan
show dialplan
6.4 常用的Dialplan App
FreeSWITCH中有超过140个App,常用的有:
(1)set
设置一个通道变量。
(2)echo
回声。
(3)info
日志打印全部通道变量。
(4)answer
用于应答一路呼叫。
(5)bridge
负责桥接另一条腿。
(6)playback
playback用于给Channel放音。
(7)sleep
设置可以等待/暂停的一段时间。
(8)ring_ready
在SIP中给对方回180消息,通知对方可以振铃了。
(9)pre_answer
在SIP中给对方回复183消息,后续的playbakck之类的动作作为早期媒体发送给对方。
(10)read
用于实现播放声音并且等待接收DTMF按键。
(11)play_and_get_digits
与read类似,更高级。
6.5 在Dialplan中使用API命令
API调用一般是通过set来执行的:
<action application="set" data="api_result=${status()}"/>
<action application="set" data="api_result=${version()}"/>
<action application="set" data="api_result=${strftime()}"/>
<action application="set" data="api_result=${expr(1+1)}"/>
6.6 深入理解通道变量以及相关操作
给变量赋值:
<action application="set" data="my_var=my_value"/>
export可以对a-leg和b-leg同时赋值(即使此时b-leg不存在):
<action application="export" data="my_var=my_value"/>
export可以通过nolcal参数将变量限制仅复制到b-leg上:
<action application="export" data="nolocal:my_var=my_value"/>
a-leg上的一些值复制到b-leg上:
<action application="export" data="var1=$var1"/>
<action application="export" data="var2=$var2"/>
<action application="export" data="var3=$var3"/>
等价于:
<action application="set" data="export_vars=var1,var2,var3"/>
取消Variable定义只需对它赋一个特殊值–”undef“或使用unset App
<action application="set" data="var1=_undef_"/>
<action application="unset" data="var1"/>
截取Variable值
语法:${var:位置:长度}
第7章 SIP协议
7.1 SIP协议基础
会话初始协议(Session Initiation Protocal)是一个控制发起、修改和终结交互式多媒体会话的信令协议。
7.1.1 HTTP与SIP协议基础
SIP是一个基于文本的协议,与HTTP和SMTP类似。
HTTP:
GET /index.html HTTP/1.1
SIP:
INVITE sip:seven@freeswitch.org.cn SIP/2.0
7.1.2 SIP基础概念和相关元素
SIP是一个对等协议,类似P2P。
在SIP网络中,Alice和Bob都称为用户代理(User Agent,UA)。UA是在SIP网络中发起或响应SIP处理的逻辑实体。
UA是有状态的。UA有两种:一种是UAC(UA Client),发起SIP请求的一方;另一种是UAS(UA Server),接受并
发送响应的一方。一般来说,UA都会实现上述两种功能。
还有一种特殊的UA称为背靠背代理(Back-to-Back UA,B2BUA)。FreeSWITCH就是一个典型的B2BUA。
边界会话控制器(Session Border Controller,SBC)。主要位于一堆SIP服务器的边界,用于隐藏内部服务器的
拓扑结构、抵御外来攻击等。
7.1.3 SIP协议的基本方法和头域简介
SIP的6种基本方法
基本方法 | 说明 |
---|---|
REGISTER | 注册联系信息 |
INVITE | 初始化一个会话,可以理解为发起一个呼叫 |
ASK | 对INVITE消息的最终响应 |
CNACEL | 取消一个等待处理或正在处理的请求 |
BYE | 终止一个电话 |
OPTIONS | 查询和服务器能力,也可以用作ping测试 |
SIP还定义了一些扩展方法,如SUBSCRIBE、NOTIFY、MESSAGE、REFER、INFO等。
SIP必须包含的头域
名称 | 描述 |
---|---|
Call-ID | 用于区分不同会话的唯一标志 |
CSeq | 顺序号,用于在同一会话中区分事务 |
From | 说明请求来源 |
To | 说明请求接受方 |
Max-Forwards | 限制跳跃点数和最大转发次数 |
Via | 描述请求消息经过的路径 |
7.2 SIP注册
注册流程
Alice向FreeSWITCH发起注册(REGISTER)请求,FreeSWITCH返回401消息对Alice发起Challenge(挑战),Alice将自己的用户名密码信息
与收到的Challenge信息进行计算,并将计算结果以加密的形式附加到下一个REGISTER请求上,重新发起注册,FreeSWITCH收到后对本地数
据库中保存的Alice的信息使用同样的算法进行计算和加密,并将其与Alice发过来的计算结果想比较。如果计算结果匹配,则认证通过,
Alice便可以正常注册。
7.3 SIP呼叫流程
7.3.1 UA间直接呼叫
状态码由三位数字组成,与HTTP类似:
- 1xx:响应为临时状态。
- 2xx:请求已被成功收到、理解和接受。
- 3xx:重定向。
- 4xx:请求失败,客户端或网络引起。
- 5xx:服务器内部错误。
- 6xx:全局性错误。
7.3.2 通过B2BUA呼叫
7.4 深入理解SIP
7.4.1 SIP URI
sip:Alice@192.168.1.20
192.168.1.9是FreeSWITCH服务器,Bob和Alice在另外机器上,Bob呼叫Alice,Bob使用使用服务器地址,
FreeSWITCH接到请求后,查找本地数据库,找到Alice实际地址,建立呼叫。
7.4.2 SDP和SOA
SIP负责建立和释放会话,一般来说,会话包含相关的媒体,如视频和音频。媒体数据是由SDP(Session Description Protocol,
会话描述协议)描述的。
SDP一般不单独使用,它与SIP配合使用时会放在SIP协议正文(Body)中。
媒体流的协商过程称为SOA(Service Offer and Answer,协议/应答)。
7.4.3 3PCC
3PCC(Third Party Call Control,第三方电话呼叫控制)指得是由第三方控制者(Controller)在另外两者之间建立的一个会话,
由控制者负责会话双方的媒体协商。
在3PCC中可能没有SDP。
7.4.4 SIP承载
HTTP是用TCP承载的,而SIP则支持TCP和UDP承载。常用的SIP都是用UDP承载的。
需要对SIP加密的情况,可以使用TLS。TLS是基于TCP的。
第8章 媒体
8.1 媒体与媒体处理
8.1.1 音频编码
从模拟信号变成数字信号的过程称为模数转换(Analog Digital Conver,AD)。AD转换要经过采样、量化、编码三个过程。
1.PCM编码
使用PCM方式对原始声音信号进行采样、量化后得到线性编码,然后再进行压缩,这种编码方式称为PCM编码。PCM的两种压缩
方式A率和μ率对应的编码名称分别为PCMA和PCMU。
2.FreeSWITCH支持的其他语言编码
FreeSWITCH支持非常丰富的语音编码。
3.FreeSWITCH中与编码相关的主要命令
控制台使用show codec
命令,可以查看FreeSWITCH支持的编码类型。
8.1.2 媒体工作机理和相关配置
1.工作机理
在基于SIP的通信中,媒体数据是在RTP流中传输的。
RTP包使用与SIP不同的UDP端口传送,因而在实际传输前需要先通过SIP信令与对方“协商”好往哪个端口传送。
RTP数据一般只使用UDP承载。
2.相关配置
SIP Profile支持的媒体列表是在vars.xml文件中配置的。
<X-PRE-PROCESS cmd="set" data="global_codec_prefs=G722,PCMU,PCMA,GSM" />
<X-PRE-PROCESS cmd="set" data="outound_codec_prefs=PCMU,PCMA,GSM" />
8.2 媒体协商
8.2.1 协商过程
打一个电话,如果客户端与服务端提供的编码没有交集,FreeSWITCH会返回SIP 488消息。
SIP采用Offer/Answer(请求/应答)机制来协商。请求发起的一方提供自己的编码列表,被请求的一方比较自己支持的媒体列表最终选择一种编码,
以应答方式通知请求者,然后就可以使用兼容的编码进行通信了。
8.2.2 SDP以及在编码协商中的作用
媒体类型是由SDP消息描述的。
8.2.3 协商时机与策略
协商可分为早协商和晚协商。当呼叫到达一个SIP Profile时,即某端收到INVITE请求而未到达路由阶段时,就先行协商,称为早协商。而等到路由
阶段,到达拨号阶段再进行协商的,称为晚协商。
系统默认为晚协商。
FreeSWITCH支持如下协商策略:generous、greedy和scrooge。
- generous:优先考虑客户端。
- greedy:优先考虑服务端的编码。
- scrooge:除了greedy还强制使用自己的采样率。
8.3 其他媒体相关的问题
8.3.1 RTP和RTCP
在完成SIP及SDP协商后,真正的语音数据是在RTP协议中传送的。
RTP协议的全称是Real-time Transport Protocol,即及时传输协议。
实时传输控制协议(Real-time Transfer Control Protocol或 RTP Control Protocol,RTCP)是实时传输协议的一个姐妹协议。
RTCP为RTP流媒体提供信道外的控制,本省不传输数据。
8.3.2 转码
FreeSWITCH是一个B2BUA,因而在桥接两条腿时,如果两条腿分别使用不同的编码,则需要
经过一个转码过程分别转换成对方需要的编码。
需要转码时,会将收到的音频数据转换成一直中间格式,称为L16。
8.3.3 透传、媒体绕过与媒体代理
透传:不经过转码的情况下,将从一方收到的流媒体原样传送给另一方。
媒体绕过:真正的媒体流使用点到点传输,根本不经过FreeSWITCH。
媒体代理:对RTP数据不在进行任何处理发给另一方,只改变SDP中的“c=”部分。
8.3.4 Media Bug
为了解决监听和录音问题,FreeSWITCH在媒体流路径上放了一个Media Bug。相当于水管上的一个三通。
8.3.5 视频
FreeSWITCH还不支持视频编码解码,所有的视频流都是透传的。
8.3.6 排错
Log、装包工具、uuid_debug_media。
第9章 SIP模块
9.1 基本概念
- Sofia-SIP
- Endpoint
- mod_sofia
- SIP Profile
- Gateway
- 本地SIP用户
- 来话和去话
- 中继来话或中继去话
9.2 Sofia配置文件
Sofia的配置文件是conf/autoload_configs/sofia.conf.xml
,不过一般不修改,大部分的配置参数
实际上述文件中使用下面的预处理指令装入conf/sip_profiles
目录中的XML中的配置。
Sofia支持多个Profile,每个Profile相当于一个SIP UA。
inernal和external最大的区别就是一个运行在5060端口,另一个运行在5080端口上。
9.2.1 Profile配置文件
Profile中具有大量的配置参数,这些参数与具体的部署方式和呼叫流程有关。
9.2.2 Profile的几个重要参数
Sofia的Profile有很多可配置参数,它们可以影响某一Profile所代表的SIP UA的行为。
inbound-bypass-media用于设置入局呼叫是否启用“媒体绕过(Bypass Media)”模式
<param name="inbound-bypass-media" value="true"/>
9.2.3 external.xml
internal.xml与external.xml区别是internal使用的是5060端口,external使用的是5080端口。客户端往
5060端口发消息需要鉴权。而5080不需要。
9.2.4 Gateway
FreeSWITCH需要通过外部网关向外打电话,而这个外部网关就称为Gateway。
<gateways>
<X-PRE-PROCESS cmd="include" data="external/*.xml"/>
</gateways>
<gateway name="gwl">
<param name="realm" value="SIP服务器地址"/>
<param name="username" value="SIP用户名"/>
<param name="password" value="密码"/>
</gateway>
9.3 常用命令
mod_sofia提供了一个API命令–sofia。
9.3.1 状态相关命令
- 列出某个Profile的状态
freeswitch> sofia status profile internal
- 列出某个Profile上所有已注册用户。
freeswitch> sofia status profile internal reg
- 过滤某些符合条件的用户
freeswitch> sofia status profile internal reg 1000
- 列出某个特定用户
freeswitch> sofia status profile internal user 1000
- 列出网关状态
freeswitch> sofia status gateway gwl
9.3.2 Profile相关命令
Profile相关的命令都是针对Profile进行的操作。
freeswitch> sofia profile internal start # 启动
freeswitch> sofia profile internal stop # 停止
freeswitch> sofia profile internal restart # 重启
重读sofia的配置(不是所有配置参数都能生效)
freeswitch> sofia profile internal rescan
9.3.3 SIP Capture
FreeSWITCH内置了Homer Capture Agent用于SIP抓包。
使用Capture功能前,需要在sofia.conf.xml中配置Capture Node的地址。
<param name="capture-server" value="udp:192.168.0.100:6060"/>
9.3.4 global相关
打开和关闭全局SIP消息跟踪
freeswitch> sofia global siptrace on
freeswitch> sofia global siptrace off
打开和关闭全局SIP捕获(Homer方式抓包):
freeswitch> sofia global capture on
freeswitch> sofia global capture off
9.3.5 debug相关
更低级别调试器
freeswitch> sofia loglevel all 9
9.3.6 其他命令
- sofia_username_of。返回注册用户的username。
- sofia_contact。返回注册用户的联系地址。
- sofia_count_reg。计算有多少客户端注册了。
- sofia_dig。返回其他服务器地址和端口。
- sofia_presence_data。显示Presence数据。
9.3.7 其他
修改Profile参数需要重启,能不重启就不重启,但IP地址相关的参数和端口,一般需要重启。
9.4 NAT穿越
适当地解决在NAT网络环境下的内、外网通信问题,就称为NAT穿越。
9.4.1 NAT的种类
NAT有三种类型:静态NAT(Static NAT)、动态NAT(Pooled NAT)和网络地址端口转换
(Network Address Port Translation,NAPT)。
NAPT有四种类型
(1)Full Cone NAT(全锥型NAT)
内部主机向外打一个洞,外网的任何主机都可以利用这个洞与它通信。
(2)Restricted Cone NAT(限制锥型NAT)
内部主机向外某一外部主机打一个洞后,只有该外部主机才能利用这个洞。
(3)Port Restricted Cone NAT(端口限制锥型NAT)
内部主机向外部主机上某一程序(一个端口)打了一个洞,只有该程序可以利用这个洞。
(4)Symmetric NAT(对称型NAT)
对称型NAT相当于对同一内部主机联系不同外部主机时都需要打不同的洞。
9.4.2 FreeSWITCH的拓扑结构
FreeSWITCH一般有三种拓扑结构。
客户端A–NAT–Internet–FreeSWITCH–外部网关
客户端A–FreeSWITCH–NAT–Internet–外部网关
客户端A–FreeSWITCH–NAT–Internet–外部网关(其中Internet有分支 客户端B–Internet–NAT–客户端C )
9.4.3 NAT是怎样影响SIP/RTP通信的
解决NAT问题通常2种思路:
- 如果FreeSWITCH足够聪明,那么它会记住外网地址。
- 可以从客户端解决。靠STUN服务解决。
9.4.4 NAT的穿越方法
解决NAT穿越问题前,先做如下准备:
- 了解你的网络环境和拓扑结构。
- 禁用路由器的ALG(Application Level Gateway)。
第10章 基本技能
10.1 调试与排错
10.1.1 解决问题的一般方法和流程
发现问题、定位问题、分析问题、解决问题。
- 核实问题的现象。
- 问题能否重现。
10.1.2 查看日志
分断调试,查看日志。
10.2 使用外部工具包
10.2.1 tcpdump
tcpdump是经典的抓包工具。
# tcpdump -np -s 0 -A -vvv eth0 port 5060
10.2.2 tshark
tshark是Wireshark的命令行版。使用方法与tcpdump类似。
10.2.3 ngrep
ngrep也是一个非常好用的抓包工具(类似与经典的UNIX命令行工具grep)。
# ngrep -p -q -W byline port 5060
10.2.4 pcapsipdump
pcapsipdump能将不同通话IP包存到不同的文件里,有大量通话的时候比较好用。
pcapsipdump -i eth0 -d /tmp/sipdump/
10.3 使用Wireshark抓包并分析呼叫
10.3.1 使用Wireshark抓包
图形界面的抓包工具Wireshark。
10.3.2 使用Wireshark对抓包进行分析
- 分析SIP包
- 分析RTP包
10.4 originate命令实例解析
_USAGE:<call url><exten>|&<application_name>(app_sec)[<dialplan>][<context>[cid_name][cid_num][<timeout_sec>]]
10.4.1 使用格式和参数
freeswitch> originate user/1000 &echo
10.4.2 转入Dialplan
freeswitch> originate user/1000 1001 XML public
10.4.3 更改主叫号码
主叫名称(cid_name,Caller ID Name)和主叫号码(cid_number,Caller ID Number)
freeswitch> originate user/1000 &echo XML default 'Seven Du' 7777
10.4.4 处理呼叫超时
最后一个参数是超时的秒数。
freeswitch> originate sofia/internal/1000@192.168.100.100 &ehco XML default 'Seven Du' 7777 10
10.4.5 防止命令阻塞
解决阻塞:
- 使用bgapi。
- 开启另外一个fs_cli客户端。
freeswitch> bgapi originate user/1000 &echo
10.4.6 使用通道变量
通道变量可以影响呼叫行为。
freeswitch> originate {originate_call_id_name='Seven Du',origination_caller_id_number=7777}user/1000 &echo
10.4.7 Early Media对呼叫的影响
有些Early Media对我们没有意义,如我们主动外呼的应用,可以指定ignore_earlly_media变量,忽略对方返回的
Early Media。
10.4.8 bridge也使用originate
freeswitch> originate user/1000 &bridge(user/1000)
10.4.9 brige中的Early Media
freeswitch> originate {transfer_ringback=local_stream://moh}user/1000 &bridge(user/1001)
10.4.10 bridge中的主叫号码
freeswitch> originate {originate_caller_id_number=7777}user/1000 &echo
10.5 呼叫是怎样工作的
SIP发送请求到5060端口->UAS对INVITE进行鉴权->路由->找到1001实际位置->作为UCA给1001发送请求
10.6 FreeSWITCH图形用户界面简介
开发FreeSWITCH的GUI有两种方法:
- 通过图形界面,修改FreeSWITCH的XML配置文件,并调用reloadxml或其他重启指令。
- 使用xml_curl接口,提供一个HTTP服务器动态的向FreeSWITCH提供XML。
10.6.1 FusionPBX
FusionPBX是使用PHP开发的FreeSWITCH GUI。通过将数据储存在数据库中,并修改本地XML配置文件。
10.6.2 blue.box
2600Hz团队开发的一款开源GUI产品。
10.6.3 FreeSWITCH Portal
freeswitch> load_mod_xml_rpc
第11章 基本功能与实现
11.1 批量创建用户
- 手工复制和替换。
# sed -e "s/1000/1020" 1000.xml > 1020.xml
- 使用
script/perl
中的add_user脚本
11.2 用FreeSWITCH实现IVR
IVR(Interactive Voice Response,交互式语音响应)
11.2.1 最简单的菜单
IVR系统默认的配置文件为conf/autoload_config/ivr.conf.xml
。
真正的菜单配置信息放到一对“”标签中。
11.2.2 默认IVR简介
<entry action="menu-exec-app" digits="1" param="bridge sofia/$${domain}/888@conference.freeswitch.org"/>
<entry action="menu-exec-app" digits="2" param="transfer 9196 XML default"/>
<entry action="menu-exec-app" digits="3" param="transfer 9664 XML default"/>
<entry action="menu-exec-app" digits="4" param="transfer 9191 XML default"/>
<entry action="menu-exec-app" digits="5" param="transfer 1234*256 enum"/>
<entry action="menu-exec-app" digits="6" param="demo_ivr_submenu"/>
11.3 按时间进行路由
<extension name="time_base_ivr">
<condition wday="2-6" hour="8:30-17:30">
<action application="ivr" data="ivr_day"/>
<anti-anction application="ivr" data="ivr_night"/>
</condition>
</extension>
11.4 配置中文语音提示
11.4.1 最简单的实现方案
默认声音文件存放在sounds目录下面,英文。
最简单的方式就是将语音包直接替换成中午语音包。
11.4.2 使用sound prefix
使用sound_prefix变量定义声音文件的具体路径
<X-PRE-PROCESS cmd="set" data="sound_prefix=$${sounds_dir}/en/us/callie"/>
11.4.3 使用Phrase
1.认识Phrase
为了屏蔽各种不同语言提示的差异性,FreeSWITCH实现了Phrase(短语)框架。
2.中文支持Phrase配置
中文与英文的配置大同小异,将英文复制一份,并在此基础上进行修改。
3.“说”中文
可以通过一些预先录制的声音文件“说”出一些常用的词语组合。
11.4.4 使用中文语音提示
准备就绪后,再Dialplan中指定language或default_language通道变量。
11.5 录音
11.5.1 单腿录音
originate user/1000 &record(/tmp/welcome.wav)
<extension name="record">
<condition field="destination_number" expression="^rec(.*)$">
<action application="answer"/>
<action application="playback" data="tone_stream://%(100,1000,800)"/>
<action application="record" data="/tmp/$1.wav"/>
</condition>
</extension>
11.5.2 对两条腿的通话进行录音
uuid_record <channel_uuid> start /tmp/record.wav
该录音文件包含两个声道。
可以使用sox命令进行混音:
$ sox record.wav -c 1 record-1.wav
在Dialplan中,可以通过record_session达到类似的效果:
<extension name="record">
<condition field="destination_number" expression="^(100[0-9])$">
<action application="record_session" data="/tmp/record-$1.wav"/>
<action application="bridge" data="user/$1"/>
</condition>
</extension>
record_session是一个APP,非阻塞。
11.5.3 立体声
通过事先将RECORD_STEREO通道变量设置为true可以在录音时直接录成立体声。
11.5.4 录音相关的通道变量
- RECORD_HANGUP_ON_ERROR
- RECORD_WRITE_ONLY
- RECORD_READ_ONLY
- RECORD_STEREO
- RECORD_STEREO_SWAP
- RECORD_ANSWER_REQ
- RECORD_BRIDGE_REQ
- RECORD_APPEND
- record_sample_rate
- enable_file_write_buffering
- RECORD_MIN_SEC
- RECORD_INITIAL_TIMEOUT_MS
- RECORD_FINAL_TIMEOUT_MS
- RECORD_SILENCE_THRESHOLD
11.5.5 原生格式
为了最大限度地节省系统资源,可以将声音录制成原生(Native)格式。
freeswitch> originate user/1000 &record(/tmp/test)
会将录音录成/tmp/test.PCMU
可以使用sox软件中的play命令播放
play -e u-law -r 8000 -t raw test-in.PCMU
11.6 放音
11.6.1 playback的参数
1.声音文件
大部分声音文件的支持都在mod_sndfile模块中实现的。典型的如WAV、AU、AIFF、VOX等。
2.local_stream
local_stream是在mod_local_stream中实现的。
3.silence_stream
silence_stream是一个静音流。
<action application="playback" data="silence_stream://2000,1400"/>
1400为舒适噪音的参数值。
4.tone_stream
tone_stream是一个铃流,它在mod_tone_stream模块中实现。
我国的回铃音信号为450Hz的信号音,1秒通,4秒断。
<action application="playback" data="tone_stream://%(1000,4000,450)"/>
5.file_string
可以将多个文件串联起来,放在同一个playback命令中播放。
<action application="playback" data="file_string:///tmp/file1.wav!tmp/file2.wav!/tmp/file3.wav"/>
11.6.2 循环播放
不断播放test.wav直至挂机的实现如下:
<action application="endless_playback" data="temp/test.wav"/>
11.6.3 Say
<action application="say" data="en number iterated 1234"/>
11.7 TTS
TTS(Text To Speech)是将文本转换成语音的一项技术,因而又称为语音合成(Synthesis)。
11.7.1 使用mod_flite
mod_file是基于Flite语音合成引擎的一个TTS模块。
originate user/1000 &speak('flite|kal|Hello,Welcome to FreeSWITCH')
11.7.2 mod_tts_commandline
可以使用命令来执行TTS功能。mod_tts_commandline模块可以调用这些命令,生成一个文件,进而
播放这个声音文件,从而达到其他TTS软件执行TTS功能的目的。
11.7.3 MRCP
MRCP(Media Resource Control Protocl)是一个支持访问网络上的媒体资源的协议。
它的典型应用就是TTS和ASR(自动语音识别)。
11.7.4 Google Translate
Google Translate(谷歌翻译)
11.8 在呼叫失败的情况下向主叫用户播放语音提示
11.8.1 实现方法
<action application="bridge" data="user/${dialed_extension}@${domain_name}"/>
<action application="answer"/>
<action application="sleep" data="1000"/>
<action application="bridge" data="loopback/app=voicemail:default ${domain_name} ${dialed_extension}"/>
11.8.2 进阶
- 使用Lua脚本
使用if..then..else之类的逻辑选择播放声音,其他一律播放同一个文件。
- 使用Dialplan配置
11.8.3 使用TTS
使用Phrase Macro功能实现各种提示
<include>
<macro name="USER_BUSY">
...
</macro>
<macro name="USER_NOT_REGISTERED">
...
</macro>
</include>
11.8.4 原理
在被叫失败后播放我们上面指定的提示音或TTS是有一个前提的,在Dialplan的第一个bridge要有以下两行
<action application="set" data="hangup_after_bridge=true"/>
<action application="set" data="continue_on_fail=true"/>
11.9 实现呼叫前转业务
通过拨打一个特定功能码登记预转移到的电话号码,以后所有呼叫都会转移到该号码上。
第12章 高级功能与配置实例
12.1 使用mod_fifo实现简单呼叫队列
ACD(Auto Call Distribution,自动电话分配)
12.1.1 呼叫停泊与取回
在电话分配中,一般用停泊与取回的方式进行电话搭接。
fifo是一个“生产者–消费者”模型,即来话(Caller)相当于生产者(Producer),坐席(Agent)
则称为消费者(Consumer),它对来话进行服务相当于“消费”生产者生产的内容。
12.1.2 配置座席
1.静态座席的配置
mod_fifo的配置文件是conf/autoload_configs/fifo.conf.xml
。
Dialplan将来路电话路由到我们配置的fifo。
2.动态座席的配置
mod_fifo提供了一个fifo_member命令可以动态增加和删除座席。
# 3.offhook座席
offhook(摘机)座席,这种座席会事先呼入队列并等待。
12.1.3 fifo
1.相关的通信变量
许多相关的通道变量可以改变它的行为。有效的使用这些变量,往往能配置出比较实用的功能。
2.相关事件
当fifo相关状态发生变化时,会产生一些Subclass为fifo::info的CUSTOM事件。
12.2 使用mod_callcenter实现呼叫中心应用
mod_callcenter采用一种基于积分(score)策略的排队算法。
12.2.1 mod_callcenter模块简介
1. mod_callcenter模块的安装
# make mod_callcenter-install
freeswitch> load mod_callcenter
2.涉及的基本概念
- 队列
- 座席
- 策略
- 座席状态
- States
- 座席类型
- 梯队
12.2.2 坐席配置与管理
1.静态座席配置
默认配置文件是conf/autoload_configs/callcenter.conf.xml
。
2.动态管理队列和座席
mod_callcenter提供了一个callcenter_config的API命令,用于管理与该模块相关的资源。
3.offhook座席
mod_callcenter也支持offhook座席。
12.3 数据库
FreeSWITCH内部使用关系型数据库记录一些实时的数据。
12.3.1 默认数据库中有什么?
1.核心数据库
默认使用SQLite嵌入式数据库。
2.Sofia数据库
mod_sofia模块中每一个Profile都使用一个单独的数据库。
3.其他数据库
其他模块也有自己的数据库。
12.3.2 ODBC
SQLite在并发量特别大的情况下会是一个瓶颈。
- 1.增加ODBC数据库支持
在编译前安装unixODBC的开发包,并安装相关的数据驱动。
- 2.MySQL
安装MyODBC。
- 3.PostgreSQL
- 4.测试ODBC连接
- 5.使用ODBC
12.3.3 使用数据库原生客户端直接连接数据库
FreeSWITCH内部对PostgreSQL原生支持。
12.4 视频通话
12.4.1 配置视频通话
如果需要支持视频呼叫,只需要在配置文件中增加相关的视频编解码就可以了。
12.4.2 视频录音与回放
FreeSWITCH中实现了一个简单的mod_fsv模块,提供录像及回放支持。
12.4.3 视频转码
通过相应的视频库或硬件的DSP芯片,也可以在FreeSWITCH中提供视频的转码。
12.5 多人电话会议
12.5.1 音频会议
- 使用DTMF按键进行控制
- 配置Dialplan将电话路由到会议
- 使用API命令控制会议
- 配置文件
12.5.2 视频会议
- 普通视频会议
- 多画面融屏
- 视频监控
- RFC4579
12.6 话单
12.6.1 CSV格式的话单
mod_cdr_csv模块可以记录CSV格式的话单。
12.6.2 直接将话单写入数据库
通过mod_cdr_csv模块可以直接在FreeSWITCH中将话单写入PostgreSQL数据库。
12.6.3 使用HTTP服务器接收话单
支持将话单写入远程的HTTP服务器。
12.7 计费
mod_nibblebill是一个预付费的计费模块。
第13章 FreeSWITCH与FreeSWITCH对接
13.1在同一主机上启动多个FreeSWITCH实例
启动多个不同端口FreeSWITCH实例。
13.2FreeSWITCH与FreeSWITCH对接
- 双击对接
- 汇接
- 双归属
- 长途局
- ACL
13.3FreeSWITCH作为PBX
- 普通的PBX设置
- DID
- 使用PBX上的网关呼出
第14章 FreeSWITCH与其他设备或系统对接
14.1使用Doubango客户端连接
Doubango是一个不错的开源框架,跟电信业务走得比较近。
14.2对接IMS
如果要通过互联网与运营商的IMS对接,就需要通过SBC及层层防火墙。可以将SBC设备和IMS看成
SIP转PSTN的“大网关”。
- 网关配置
- 通过IMS呼出
- 通过IMS呼入
- 其他问题
14.3连接模拟话机和模拟中继线
- FXS和FXO
- 拓扑结构
- 使用潮流网关连接模拟话机
- 使用迅时网关连接模拟话机和模拟中继线
14.4通过E1线路与其他系统对接
- 配置FS1
- 配置E1网关配置
- 配置FS2
- 对接其他厂家的E1网关
14.5对接Asterisk
- 从FreeSWITCH呼叫Asterisk
- 从Asterisk呼叫FreeSWITCH
14.6使用H.323协议对接
H.323是比较古老的VoIP协议,然而现在还是有很多设备支持该协议。
第15章 其他技巧与实例
15.1 转接和代接
来电转接和代接是企业PBX中常用的功能。来电转接分为盲转和协商转。
代接一般用于工位上没有人其他工位上的人代为接听的场景。
15.2 共享线路呈现
共享线路呈现(Shared Lines Appearence,SLA)也是企业应用中非常有用的功能。
模拟话机中没有,只有SIP话机才能实现该功能。可以在自己话机上监视其他话机状态。
15.3 使用组播功能做网络广播
实现该业务模式最经济的方式就是使用组播(Multicast,或称多播)。组播只想向组播
地址发送一个RTP流,而监听该组播地址的所有主机就能收到。
15.4 DTMF
DTMF(Double Tone Multiple Frequency,双音多频)是一种通话过程中的号码传输方式,
特别是在IVR类应用中,一般的电话菜单都是通过案件控制的。
- 带内DTMF
- RFC2833
- SIP INFO
15.5 号码连选
运营商一般不提供SIP对开中继的方式,而是开发单个的接入号码。
- 注册到运营商服务器。
- 通过单个号码呼出。
- 使用随机数做号码连选。
- 使用mod_distributor进行连选。
15.6 收发传真
连接TMD传真机最简单的方式是使用一个模拟转SIP的网关,将它变成SIP后在FreeSWITCH中收发
传真就变得容易了。
15.7 多租户
多租户就是在一个系统中(或更简单点,一台FreeSWITCH服务器上),支持多个彼此相互独立的
PBX应用,这些不同的PBX中可能有相同的分机号,而不会产生冲突。
15.8 使用loopback
考虑在用originate外呼的时候也使用Dialplan。使用一个新的Endpoint,称为loopback。
15.9 在Web浏览器中打电话
- Flash
- WebRTC
- JsSIP
- sipML5
15.10 HA
HA(High Availability)即高可用(可靠)性。
15.11 集群及分布式部署
HP(High Performance),即高性能。
- 大规模基群总体结构
- 负载均衡配置实例
15.12 压力测试
- 参数和指标
- 呼叫测试
- 注册测试
- 编码测试
- 测试结果
15.13 生产环境下的稳定性和安全性
- 稳定性
- 安全性
第16章 嵌入式脚本
FreeSWITCH支持使用嵌入式的脚本语言控制呼叫流程。
16.1 FreeSWITCH中的嵌入式脚本
可支持:
- Lua
- JavaScript
- Python
- Perl
- Java
16.2 Lua
Lua语法优雅,小巧。
16.3 其他脚本语言
- JavaScript
- Python
第17章 嵌入式及HTTP开发
- 用Lua脚本写一个小程序
- 用Lua实现IVR
- 在会议中呼出
- 一个在FreeSWITCH中外呼的脚本
- 使用Lua脚本通过多个网关循环外呼
- 在FreeSWITCH中执行长期运行的嵌入式脚本
- 使用Lua提供XML Binding
- 语音识别
- 使用mod_xml_curl提供动态用户管理
- 使用mod_xml_cdr模块处理话单
第18章 Event Socket
与嵌入式语言不通,通过Event Socket方式,可以使用运行在FreeSWITCH外部的
程序控制FreeSWITCH。
FreeSWITCH使用SWIG来支持多语言。
18.1 架构
- 外连模式
- 内连模式
18.2 Event Socket协议
- 外连
- 内连
- Event Socket命令详解
18.3 Event Socket库
- Event Socket示例
- ESL函数说明
18.4 事件
- 事件的学习方法
- 常用事件简介
第19章 使用ESL开发
ESL是一个客户端,它主要对FreeSWITCH进行逻辑控制。