蓝星际SIP协议栈和媒体库

开源的协议栈很多了,为什么我要写一个新的协议栈呢?

开源协议栈复杂,效率低下。因为他们试图面面俱到,有的协议栈还试图兼容或转换H323。总之,开源协议栈没有一个简单的。

在我看来,要搞明白一个开源协议栈内部的构造并加以灵活应用,并不比我从底层开发一个新的适应性强调协议栈来的容易。

再说,我喜欢自造车轮,SIP协议文本我研读了不下20遍,也写过简单的SIP转发服务器和注册服务器,有一定基础。

相对来说,SS7的ISUP编解码更复杂些,在这上面做过很多应用。

另外,有几个客户急需,希望我的平台能立即支持。

开发协议栈(和媒体库)并反复测试直到它非常稳定,花了我将近1个月的时间,很久没有这么高强度的编码了,经常在深夜解决程序Bug的时候还要对付蚊虫,它是深圳一种更为常见的Bug。


我设计SIP协议栈(包括媒体库)的目标如下:

0、简单

实现一定要简单,这样才能稳健。

API接口也要简单,这要感谢前面和GregCheng的合作,他对SIP技术还有业界有精到的见解,他定义了一个合理的API界面。

1、和蓝星际平台无缝结合

蓝星际Koodoo语言的可编程能力超强,结合后就实现了SIP的动态可编程能力。

这很重要,现在运营商都进入IMS商用部署阶段了,他们对SIP进行了诸多扩展,“可编程的SIP”是个吸引人的目标,灵活性是很重要的。

2、大容量的并发性

比如单机1000-2000线,实际应用能到480路并发就可以,相当于单机16E1,够大了。

大容量并发的瓶颈在媒体处理。

好在现在服务器的性能都很好了,当然,必须要有优良的结构设计。

3、稳定性

系统的应用,是成为运营商IMS上的一个AS(带媒体功能的应用服务器),或者IP呼叫中心的软交换部件,或者是个可编程的信令或媒体网关,

总之是个需长期稳健运行的服务器。

(经过一段时间应用测试,目前可以说相当稳定了)

4、功能

首先要合乎标准,如SIP的标准,RTP的标准,DTMF的常用标准等。不一定实现标准的全部,但最主要的部分要实现(至少要和其他系统能够互联互通)。

通话要清晰,通话质量优先(带宽不重要了)。

支持多帐号注册,自动维护注册状态。

双方通话或多方会议。

文件播放或录制,可对会议进行放音或录制。


取舍决策:

1、仅考虑windows环境

windows服务器现在已经很稳定了,但可维护性比Linux强的多。

当然,我采用C/C++实现,要移植到别的系统,不难。

2、先实现IpV4和UDP

传输层是独立的模块。IpV6,TCP,没问题,有需要的时候我增加模块即可。

注:最新版本已经支持TCP和UDP。

3、先实现G711A编码

G711A即A率8000采样的单声道PCM编码,我国电话网上的标准就是这个编码。

首先,语音质量最好。其次,因为和电话网接口一致,省去转换的麻烦。另外,编码简单,在会议混音是占用CPU最少,能够做到大容量并发。

缺点,占更多的带宽,仅声音有效载荷部分每个通道就要占用64K的带宽。

这个决策基于这个前提:网络带宽按摩尔定律增长,带宽越来越不是问题,通话质量比带宽更重要。

注:最新版本已经支持G.711U,G.729A,GSM,iLBC等多种编码。

视频等暂不支持。

4、DTMF

仅实现RTP的101载荷,和Xlite等是一样的。

按照RFC2833标准实现。

5、需要支持会议

某些呼叫中心应用,多方通话是常见的。

6、支持某些语音卡

支持三汇的全部系列语音卡,因为他们有实时的IP录放音接口。

这样可以构造及其简单和低成本的IP呼叫中心或媒体网关。

7、RTP采用JrtpLib开源库

这个库是C++实现的,接口简单,很好。

8、不考虑实现为客户端协议栈

或者说,不优先考虑。

注:目前已经发放客户端版本lSIP.exe。


SIP协议栈实现:

1、概念(基本上和RFC3261一致)

消息 - SIP原始消息,包括请求消息和应答消息

字段 - SIP字段头域

对话 - 标识一次呼叫

事务 - 对话内的一个小来回,比如Invite事务或Bye事务

TU - 会话用户

简化起见,每个TU最多只能进行一个对话,对于服务器而言一个通道就是一个TU,因此可能有几千个预先创建好的TU对象

会话 - 一般是指接通后进行的媒体会话

2、实现

传输层 (负责消息的收发。收到的消息并不解析直接放到缓冲队列)

消息缓冲层(队列)

事务层 (构造事务或处理事务状态机)

TU层

驱动层 (对消息解析然后匹配到对话或事务)

API层 (C语言接口,供应用层调用)


媒体库实现:

Channel对象 - 媒体通道,里面一般包含rtp对象; 外部通道,则提供接口给语音卡层面连接

Rtp对象 - 负责进行媒体流的收发

收发器 - 比如rtp发送器,rtp接收器,文件播放play(是个接收器,从文件接收数据),文件录音rec(是个发送器,将混音后的数据发送到文件)

线程池 - 通过配置线程池的大小,可以优化性能。

Session对象 - 会话可以连接多个通道,即相当于通道加入到会话,可以以只听方式加入。会话对象类似于多人会话的会议室。

驱动层

API层 (C语言接口,供应用层调用)

如何实现高性能:

1、多线程

2、简单的并行算法

3、简单的对象之间的接口


小试牛刀,最近的两个应用:

1、外呼营销中心

为了节省费用并控制显号,他们和一外地voip运营商合作,该voip运营商提供数个sip帐号。

传统办法:用XLite软电话手工呼叫,需要很多帐号,而且不方便系统控制(如录音和业务管理)。

采用蓝星际系统:

座席 --> 蓝星际系统(SIP协议栈)--> Voip运营商

系统集中分配号码,控制呼叫,并对每个通话进行录音。操作和使用习惯就和他们原先基于E1的外呼营销系统一样。

蓝星际系统是个纯软件,安装在一个windows2003的4核服务器上。

属于呼叫密集型应用,60多个座席不通呼叫,每次通话都进行录制,录制格式为A率8000采样的wav文件(后台会自动压缩为Mp3存储)。

通话声音很清晰。

2、WebCall

客户是经营增值业务的。

他们的企业客户通过Web集成的页面,进行WebCall,进行两方的会话或多方的会议。

普通手机、固话号码和SIP分机可以一起进行通话或会议。

企业客户业务系统通过WebService方式调用我们开发的WebCall接口。

蓝星际平台SIP for三汇卡,采用4E1三汇语音卡。

操作系统windows2003 server。


鸣谢:Greg Cheng, Steven Shen


bluesen 2011.07.20 于深圳