3PCC全称Third Party Call Control,中文即第三方电话呼叫控制,指的是由第三方控制者在另外两者之间建立一个会话,由控制者负责会话双方的媒体协商。3PCC是一种非常灵活的会话控制方式。在PSTN网中,第三方呼叫控制通常用于会议、接线业务(接线员创建一个连接另外双方的呼叫)。同样,使用SIP协议也可以借助3PCC来完成PSTN网中的一些相关业务,例如点击拨号、通话过程中放音等等,而且实现起来非常方便。RFC3264中定义了一种提供/应答模式,使两个实体之间可以使用SDP的提供/应答(offer/answer)模式进行会话协商。
SIP消息可以携带SDP消息体。SDP(会话描述协议)是用来描述与媒体流相关的参数以及与会话相关的信息,其中包括对会话的描述以及媒体类型、数据发送到的端口、传输协议(例如RTP)以及媒体格式(例如RTP载荷格式)的描述。3PCC的实现关键就在于控制者如何在会话双方之间使用SDP消息协商即将建立的会话。
需要说明的是,下面的所有flow讲解都省略了中间的部分服务器应答,如Trying、Ringing等应答,因为这些应答不是3PCC流程所控制的关键点。且下面的说明都是依据带有标号顺序的SIP消息为核心。
根据SIP协议的整个协商处理机制,可以有下面四种方法实现3PCC(RFC 3725):
Flow 1:
(1)是Controller向A发送一个不带SDP的INVITE请求,不带SDP即前面所说的,没有Message Body部分;
(2)是A给Controller的200 OK应答,其中的offer指的是SDP消息,这其中描述与A有关媒体处理能力的相关数据,详见SDP协议;
(3)是Controller向B发送INVITE请求,这其中带有A的SDP相关描述;
(4)是B给Controller的200 OK应答,其中的answer指的是SDP消息,这其中描述与B有关的媒体处理能力的相关数据;
(5)是Controller对B的ACK应答,不含任何SDP信息,因为在前面的INVITE中已经有了
(6)是Controller对A的ACK应答,其中带有B的SDP相关信息,这其实就让媒体流在A和B之间传输了,而不用Controller去转发媒体流。
Flow1是最简单的一种3PCC控制方式,不需要Controller对SDP做控制,但是有个典型的缺点就是,当B不及时对Controller的INVITE请求做200 OK的应答,会导致A周期性的向Controller发送200 OK的消息,最终可能会导致A认为呼叫失败,而主动去挂断电话。
Flow 2:
(1)是Controller向A发送INVITE请求,该请求带一个bh SDP1。所谓的bh SDP1只是一个伪SDP描述,里面只有简单media、codec和connection信息,connection信息中的地址必须是0.0.0.0,port可以为不为0的任意数字,关于SDP的详细东西可以看RFC 4566;
(2)是A给Controller的200 OK应答,里面带有的SDP2是一个完整的SDP描述;
(3)是Controller向B发送的INVITE请求,和Flow 1中的(3)是完全一样的;
(4)是Controller对(2)的简单应答;
(5)是B给Controller的200 OK应答,里面带有与B相关的SDP描述;
(6)是Controller对(5)的简单应答;
(7)是Controller向A发起的re-invite请求,其中带有与B有关的SDP描述;
(8)是B针对(7)做的200 OK应答;
(9)是针对(8)做的简单应答。最终在A和B之间建立媒体流(当然这是理想状态,呵呵)
Flow 2的优点是所有的最终响应都可以被立即确认,不会因超时而导致呼叫失败。缺点也是显而易见的,Controller必须预先知道本次呼叫所要使用的媒体类型来创建初始的“黑洞”SDP描述,同时“黑洞”是一种扩展机制,不是所有的UA都支持,最后就是要假设(8)中带有的SDP2和(2)中的完全一致,才不至于产生无限循环的re-invite请求。因此,Flow 2只是在理论上可行,实际操作过程中强烈建议不要使用。
Flow 3:
(1)和(2)的说明可以参见Flow 1(1)和(2)中的说明;
(3)是Controller针对(2)的简单应答,这其中的SDP描述中关于connection部分全部被改为0.0.0.0,即所谓的“黑洞”SDP;
(4)和(5)的说明可以参见Flow 1中的(3)和(4)说明;
(6)是Controller向A发起的re-invite请求,其中的offer2’是根据offer1和offer2之间所存在的共同的媒体处理能力由Controller生成的,但是其中connection与offer2中的一致,这样才能保证流媒体在A和B之间传输;
(7)是A对re-invite的200 OK应答,其中的answer2’是根据offer2’做的重新调整,他与offer1已然不同;
(8)是Controller针对(5)做的ACK应答,其中带有answer2’所描述的SDP信息,这里只是为了区分A和B而写成answer2了;
(9)是Controller针对(8)做的简单ACK应答;
Flow 3的优点当然是,首先是所有的最终响应都能够被及时处理,不会产生超时和重传的问题;其次是Controller不需要预知本次会话的SDP媒体描述信息。
Flow 3相对来说要复杂一点,他需要Controller去处理两者的SDP描述信息,为他们找到交集,当然他们也有可能不存在交集而导致最终的呼叫失败。
Flow 4:
Flow 4是针对Flow 3做的一个变通,降低了复杂度,其实际的SIP消息处理过程与Flow 3完全一致。这里我只对几个关键点做一下说明。
在(1)中offer1 no media指的是SDP描述中不带m行,具体的含义参见SDP规范吧,:)
其余的过程与Flow 3中完全一致。
Flow 4相对于Flow 3的缺点是显而易见的,A中没有任何媒体描述,但是呼叫已经正常建立了。当从B得到的SDP描述时,发现A和B没有共同的媒体描述时,必须中断Controller与A和B之间的会话,但是这是A和B同Controller之间的会话已经正常建立了,A和B会因为听不到任何媒体流而感到奇怪。
综上所述,Flow 3是最为合适的控制流程。
注:理论往往会和现实有差距的,具体见我后面有关SIP Servlet中,我在实际的实现操作过程中遇到的问题吧,呵呵:)