公用信道技术在VoIP中的应用

时间:2022-10-26 12:04:26

公用信道技术在VoIP中的应用

摘要:随着 Internet 的发展,VoIP获得了广泛应用。目前的VoIP有多种协议,但是传统VoIP服务器只能够支持单一的协议,不同VoIP协议的互通问题始终是VoIP发展中的核心问题。本文基于公用信道思想,介绍了一种使用多协议的VoIP技术。

关键词:VoIP;公用信道;服务器

中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)24-1185-04

在VoIP通信过程中,服务器要为每个客户端创建一个信道来维持与其通信。这种用于和客户端保持通信的信道称为协议信道。如图1所示,传统的VoIP服务器都是由上层控制模块来直接控制协议信道,由于上层控制模块和底层协议信道相关,无法实现对不同类型协议信道的控制,因此传统VoIP服务器只能够支持单一的协议。如果能够设计出可同时支持多种协议的服务器,那么它就可以对各种协议进行处理和转换,从而解决不同VoIP协议的互通问题。

1 公用信道的思想

为了解决分布异构问题,人们提出了中间件的概念。中间件是位于平台(硬件和操作系统)和具体应用之间的通用服务,这些服务具有标准的程序接口和协议。中间件能够屏蔽操作系统和网络协议的差异,为应用程序提供多种通讯机制,并提供相应的平台以满足不同领域的需要。因此,中间件为应用程序提供了一个相对稳定的高层应用环境。这里借鉴了中间件的思想,在底层协议信道和上层控制模块之间添加一类特殊的信道,称为公用信道。图2描述了增加公用信道以后服务器控制协议信道的方式。通过公用信道将上层控制模块和底层协议信道相分离。公用信道提供了一系列的接口,上层控制模块只需通过这些接口就可以控制公用信道,从而达到管理和控制整个会话过程的目的,而不必关注底层协议信道具体使用的是哪种VoIP协议。

2 公用信道接口

2.1 会话模型

不同VoIP协议虽然在信令、媒体传输方式上存在不同,但服务器建立会话的过程都大致分为以下几个阶段:

呼叫开始:当服务器收到客户端的呼叫请求后,建立主叫用户信道。然后查找被叫用户地址,创建与被叫用户通信的信道。

呼叫被叫:在主被叫信道建立之后,开始向被叫用户发送能够呼叫请求消息,并等待被叫用户应答。

通话:服务器收到被叫用户应答后,就开始转发主被叫用户的语音数据。

呼叫结束:当收到主叫或被叫用户的挂机请求后,服务器分别拆除主被叫信道,结束通话。

公用信道可以根据服务器建立会话的过程,抽象出一系列与会话相关(呼叫、应答、挂机)的接口,以便上层控制模块使用这些接口来管理和调度公用信道,从而控制整个会话过程。

2.2 接口的多态性

多态性提供了接口和实现的分离,也就是说把做什么和怎么做分开来。多态性不但能改善代码的接口,提高其可读性,而且能创建可扩展的程序。

由于公用信道位于各协议信道之上,公用信道的这些接口的实现是和底层协议信道相关的。根据底层VoIP协议的不同,这些接口的实现方法有很大的差别。因此可采用多态性的思想来设计公用信道接口。由公用信道中定义上层控制模块调用的接口,而这些接口的实现交给底层各协议信道来完成。

在会话过程中,控制模块只需调用这些接口来控制会话,程序会根据底层信道类型的不同,调用相应的函数,公用信道因此表现出不同的行为。这样公用信道就屏蔽了底层协议信道的差异性,从而解决了不同VoIP协议的互通问题。

这种方式还具有良好的扩展性。当需要增加对一种新协议的支持,只需在底层实现公用信道定义的这些接口,而不必对公用信道和上层控制模块做任何改动。

2.3 多态性的实现

由于公用信道接口在实现上的多态性,这里使用结构体com_channel_tech来封装公用信道的接口。该结构体中包含了很多函数指针,这些函数指针指向接口的具体实现。根据底层协议信道类型的不同,底层使用不同的函数来填充com_channel_tech中的各个字段以实现这些接口。当上层控制模块调用某一接口时,系统根据会根据com_channel_tech的具体类型(底层使用的协议)调用相应的函数。这样我们就屏蔽了底层协议信道的差异性,为上层控制模块的调用提供了统一的接口。上层只需调用这些接口,就可以实现对公用信道的统一管理和调度,而不必关注在底层采用的是哪种协议。

例如,当接收到SIP请求,创建公用信道时,上层控制模块只需直接调用com_request接口,从而间接调用结构体com_channel_tech中request函数指针所指的sip_request函数。而对于IAX协议,相应的函数就换成了iax_request函数。

3 协议映射

3.1 公用帧

为了便于上层控制模块管理会话,公用信道中只使用一种协议来传输信令和语音,这种协议称为公用协议。以公用协议格式封装的帧称为公用帧(COM帧)。从客户端发送到协议信道的各种协议帧,必须首先转换成COM帧后才能送入公用信道,然后由控制模块对其进一步处理。从公用信道发往客户端的COM帧,需要根据底层协议信道的类型,进行相应的帧格式转换后才能发送。

由于公用信道既要处理信令又要转发语音数据,所以COM帧分为信令帧和语音帧两种类型。信令帧主要用于控制会话的进程,而语音帧用于传输实际的语音数据。采用结构体com_frame来表示COM帧:

struct com_frame {

int frametype;

int subclass;

int datalen;

int samples;

void *data;

struct timeval delivery;

};

其中frametype字段用于说明COM帧的类型属于信令帧(COM_FRAME_CONTROL)还是语音帧(COM_FRAME_VOICE)。

对于信令帧,只有subclass字段有意义,该字段用于说明信令帧表示的具体控制信息。

对于语音帧,subclass字段代表该语音帧使用的编码格式;datalen表示语音帧长度;samples表示采样点数;delivery表示发送时间戳;指针data指向实际的语音数据。

3.2 信令帧的映射

底层信道的各种协议帧在送入公用信道之前需要转化成COM帧。从公用信道中出来的COM帧需要转化成协议信道能处理的帧。不同协议帧之间的转换过程称为协议映射。协议映射关系的制定是实现VoIP互通的前提和保证。

3.3 语音帧的映射

为了保证语音在转发时不会失真,COM帧在传输语音时必须包含以下信息:语音编码格式、语音数据长度、采样点数、发送时间戳以及实际的语音数据。因此,其它协议帧在转化成COM帧时,必须完成以上内容的转换。

1)IAX帧映射到COM帧:对于IAX协议,语音是通过Mini帧来传输的,在开始发送语音和固定时间间隔内发送Full帧来同步语音帧。由于Mini帧只包含16位的时间戳和语音数据,协议信道需要将先前从Full帧中获得的语音编码格式subclass和32位的时间戳记录下来。这样,语音数据的编码格式可以从对应的协议信道获得。语音数据长度可由Mini帧帧长减去帧头长度得出。采样点数是根据数据长度和编码格式计算得出。时间戳由Full帧的高16位和Mini帧的16位组合而成。原始语音数据直接存入到COM帧的data字段。IAX帧的其他信息与转发语音无关,均保存在协议信道之中。

2)RTP帧映射到COM帧:对于SIP协议的客户端,语音数据通常是通过RTP帧来传送的。从RTP帧转化成COM帧,时间戳可以直接从RTP帧头的timestamp字段取得,语音编码格式从PT字段中得到,语音数据长度可由帧长减去帧头长度计算得出,采样点数也是根据数据长度和编码格式计算得出,而原始的语音数据直接存入到相应字段。

4 语音传输方式

在呼叫建立之后,客户端开始语音通信。语音传输方式有两种:一种是P2P方式,另一种是服务器转发方式(Server Relay)。

4.1 P2P方式

P2P方式是指语音数据直接从一个客户端发送到另一个客户端。P2P传输方式具有降低网络时延、减轻服务器负荷等优点。但不是任何客户端之间都可以建立P2P连接的。除了通信双方需要知道彼此的地址外,P2P还要具备如下条件:

1)通信双方采用相同的信令和语音传输方式。也就是说客户端采用的是相同的VoIP协议。

2)如果通信的一方或双方的网络中存在NAT,语音数据要能够穿越对方的NAT。

3)通信双方要能够理解对方所发送的语音数据。也就是说,发送语音数据的编码格式要能够为对方所支持。

对于满足上述条件的会话,服务器在建立呼叫后会调用com_bridge函数,尝试为客户端之间建立P2P连接。如果建立P2P成功,服务器就释放与客户端通信的信道,由客户端之间直接进行语音通信。

4.2 服务器转发方式

对于不满足建立P2P条件的客户端之间的会话,需要由服务器转发双方的语音数据,也就是说客户端先将语音数据发送给服务器,由服务器转发到另一个客户端。根据会话类型的不同,服务器的转发方式又分为以下两种。

1)经过公用信道的转发

对于不同客户端的语音通信,语音数据需要进行协议类型、语音编码格式的转换,这些都是由公用信道负责完成的。因此,语音数据要送入公用信道处理。图3描述了SIP和IAX客户端进行语音通信的过程。下面以SIP客户端向IAX客户端发送语音通信为例,来说明语音数据的传输路径。SIP客户端的语音以RTP帧的形式发送到服务器的RTP信道中,被转换成COM帧后送入到所在的公用信道。公用信道将其发送给与IAX客户端对应的公用信道。然后调用相应的接口函数将COM帧转换成IAX帧后,发送至IAX客户端。

2)不经公用信道的转发

对于同类型客户端的通信,由于语音数据不需要进行协议、编码格式的转换,可以将其直接发送到对方的协议信道中。所以可以优化上面的传输路径。图4描述了IAX客户端之间进行语音通信的过程,一方的语音数据以Mini帧格式发送到服务器,然后由IAX信道直接将该Mini帧发送到对方的IAX信道。这样语音数据就不必经过双方的公用信道,也不需要对帧类型进行转换,因而提高了语音数据的传输效率,减少了时延。

5 公用信道的通信

5.1 收发COM帧

每个公用信道都维护着一个readq队列,该队列是由COM帧组成的。协议信道发给公用信道的COM帧都是先送入该队列中。当服务器监听到某个公用信道有COM帧时,调用接口函数com_read,从该公用信道的readq队列中读取COM帧进行处理。

对于要发送给客户端的COM帧,直接调用公用信道提供的接口函数com_write即可。该函数的实现是由底层完成的,根据底层协议信道类型的不同,先将COM帧转化成对应的协议帧,然后调用套接字函数sendto将其发往客户端。

5.2 IO多路转接

如前所述,会话建立后上层控制模块要同时管理和控制主被叫两个公用信道,监听主被叫信道的readq队列是否有COM帧到来。如果采用传统的IO阻塞技术,那么线程就可能长时间阻塞在一个信道上,而另一个信道虽然有很多数据却不能得到及时处理。在这种情况下,我们使用IO多路转接技术来同时监听多个信道。

所谓IO多路转接技术,是先构造一张有关描述符(公用信道)的列表,然后调用poll函数,同时监听这些信道,直到这些信道中的一个已准备好进行IO(有数据发生)时,该函数立即返回。在返回时,它会告诉进程哪个信道有数据发生。poll函数的定义如下:

#include

int poll(struct pollfd fdarray[],nfds_t nfds,int timeout);

参数:fdarray 数组中的每一个元素对应一个描述符(公用信道)

nfds描述符的个数

timeout 监听(等待)时间

返回值:准备就绪的描述符,若超时则返回0,若出错返回-1

5.3 管道机制

COM帧是由底层的发送线程送至公用信道的readq队列中,而监听公用信道是由上层控制模块的线程来完成的。由于发送COM帧和监听COM帧是由服务器的不同线程控制,因此需要建立管道机制来解决线程间的通信问题。

在每个公用信道创建的时候,定义了一个alterpipe[2]的数组,用于建立通知管道。其中alterpipe[0]对应于管道的读端口,alterpipe[1]作为管道的写端口。在开始呼叫后,服务器会调用poll函数来监听公用信道的读端口alterpipe[0]。

当有数据送入到readq队列,底层发送线程控制该信道对应管道的写端口alterpipe[1]向读端口alterpipe[0]发送一个通知信号(通常是一个字符)。当读端口接收到该信号后,poll函数就立即返回,并告诉系统哪个信道有数据请求处理。服务器就从该信道对应的readq队列中读取出COM帧。这个过程可由图5来描述。

6 互通实例

下面就以IAX与SIP互通为例,说明互通过程中协议的映射过程。这里以SIP客户端发起呼叫和先挂机为例,呼叫的具体流程如图6所示,图中省略了一些次要消息的交互过程。

6.1 呼叫建立

主叫方SIP协议信道收到呼叫请求后,立即建立主叫公用信道。并分析被叫号码,根据被叫客户端的类型,建立相应的被叫公用信道以及到被叫客户端的协议信道。这样,双方就可以开始建立呼叫。SIP客户端呼叫IAX客户端的信令过程描述如图5所示:

1)SIP客户端向服务器的SIP信道发送INVITE消息;2)SIP信道收到INVITE消息,立即创建主叫公用信道,并向SIP客户端发送100 Trying消息,确认收到呼叫请求,服务器正在处理中;3)SIP信道将INVITE消息翻译成COM_CONTROL_INVITE消息,并发送到主叫公用信道中;4)当公用信道收到该消息后,立即创建一个新线程,接入到上层控制模块,分析被叫号码,查找被叫地址,并根据被叫客户端类型分别创建被叫公用信道和被叫IAX信道,以便与IAX客户端通信;5)被叫公用信道将COM_CONTROL_INVITE消息转换成NEW消息发送给IAX信道;6)IAX信道将该消息发送给IAX客户端;7)IAX客户端发送ACCEPT消息确认建立连接;8)IAX客户端发送RINGING消息,表示其正在振铃中;9)IAX信道将RINGING消息转化成COM_CONTROL_RINGING消息,发送给被叫公用信道;10)被叫公用信道将该消息转发给主叫公用信道;11)主叫公用信道将COM_CONTROL_RINGING消息翻译成180 Ringing消息,发送给SIP信道;12)SIP信道将该消息发送给SIP客户端;13)IAX客户端发送ANSWER,表示被叫端已经应答。ANSWER消息按与Ringing消息类似传送过程转化成200 OK消息发送给SIP客户端。呼叫建立完成,双方开始语音通信。

6.2 语音转发

SIP协议采用的是RTP传输语数据音,而且收发语音的端口不同于SIP协议端口(2N,2N+1,N为随机整数);IAX是信令和语音是共享端口的,使用Mini帧传输语音。同前面的信令映射方法类似,语音帧也需要经过RTP/Mini帧 COM帧 Mini/RTP帧的转化过程。

6.3 呼叫释放

呼叫结束的过程如图6所示:28)SIP客户端向服务器的SIP信道发送BYE消息,请求结束会话;29)SIP信道收到BYE消息,立即向SIP客户端发送ACK消息,确认收到结束;30)SIP信道将BYE消息翻译成COM_CONTROL_HANGUP消息,并发送给主叫公用信道中;31)主叫公用信道将COM_CONTROL_HANGUP消息发送给被叫公用信道,并释放主叫公用信道和SIP信道;32)被叫公用信道向IAX信道发送HANGUP消息;33)IAX信道向IAX客户端发送HANGUP消息;34)IAX客户端向IAX信道发送ACK消息,表示已收到释放请求。服务器释放被叫公用信道和IAX信道。

参考文献:

[1] 张登银,孙精科.VoIP技术分析与系统设计[M].北京:人民邮电出版社,2003.

[2] Abbasi T, Prasad S, Seddigh N., Lambadaris I. A Comparative study of the SIP and IAX VoIP protocols.Electrical and Computer Engineering,2005.Canadian Conference on1-4 May 2005 Page(s):179-183.

[3] 糜正琨.IP网络电话技术[M].北京:人民邮电出版社,2000.

[4] Mahler P.VoIP Telephony with Asterisk[M].2004.

[5] 黄鹰,朱木成,李晖.软交换IP信令互通的研究与实现[J].光通信研究,2006(5):22-24.

上一篇:智能客户端技术在当前高校教务管理系统中的应... 下一篇:实例分析关系模式的规范化与反规范化