您当前的位置是:  首页 > 资讯 > 国内 >
 首页 > 资讯 > 国内 >

完整SIP/SDP媒体协商概论-SDP协商模式详解-会话管理全解

2020-03-19 10:20:57   作者:james.zhu   来源:Asterisk开源派   评论:0  点击:


  笔者在前面的章节重点讨论了answerer中answer消息的构建,针对发起方对answer消息中单播和多播环境处理进行了讨论说明。除了前面章节中针对应答方生成answer的讨论以外,本章节还将继续介绍关于SDP的会话管理(修改会话描述参数),指示能力的讨论和一个交互模式的示例,关于early offer和later offer的详解以及later offer可能出现的问题。
  7、关于会话管理讨论
  前面的章节包括上一次笔者发布的文章中,笔者分别讨论了offer和answer双方的消息生成。这里,笔者将讨论会话的修改。修改会话是常见的业务场景,通过修改会话实现另外一个新的流程。在会话的某个点上,任何会话参与方都可以发出一个新的offer来修改会话的属性参数。会话修改是offer/answer交互模式的基本操作,它的处理流程其实和我们前面讨论的流程完全一致,通过某些流程修改现存会话的某些参数。offer可能和以前的相同,也可能和以前的不同。当讨论修改会话时,我们需要涉及上一个或者前面的SDP,上一个SDP提供了其他的会话参数基础,这些参数可能已经在offer或者answer消息中存在。现在,笔者先说明一下修改会话的一些基本框架和前提条件。如果offer相同,answer可能和从answerer获得的上一个SDP中的相同,也可能answer不同。如果已提供的SDP和前面的SDP不同,一些特定的限制需要注意。关于这些限定,笔者在后续部分讨论。理论上说,几乎所有的会话属性都可以修改。例如,可以增加一个媒体流,可以删除现存媒体流,可以修改现存媒体流参数。当发起一个offer,此offer修改需要修改会话时,除了origin域值其版本号必须在前面的SDP版本号基础上增加一位数以外,新SDP中的"o="行必须等同于前面的SDP中的"o="行。如果在新SDP中,origin域值不能增加的话,此SDP必须等同于同一origin值域的SDP。answerer应答方必须准备接收offer,此offer包含一个无改变origin值域版本的SDP。根据笔者在前面应答方生成answer的流程,虽然answerer接收了这样的一个offer,然而,answerer仍然必须生成一个有效的answer消息(此answer消息可能和以前SDP相同不同,也可能不同)。如果已提供的SDP和前面的SDP不同的话,这个新的SDP必须有一个媒体流和前面的SDP媒体流中的匹配。换句话说,如果前面的SDP有四个"m="行,那么在新的SDP中必须至少有四个"m="行。前面SDP中的媒体流排序(从最顶端计数)关系必须匹配新的SDP中的媒体流排序(从最顶端计数)关系。为什么需要这样的匹配关系呢?其实,这样的匹配关系是非常必要的,answerer应答方决定新的SDP中某个媒体流可以对应前面SDP中的那个媒体流,然后可以绑定SDP媒体流的具体的匹配关系,否则,修改会话就会出现数据混乱。因为为了满足以上的这些要求,我们看到,媒体流中的"m="行从来不会减少,“m=”行数保持不变或者增加。另外,从前面SDP中删除的媒体流一定不能从新SDP中移除,不过,这些媒体的属性不能出现在新的SDP中。
  通过Offer/Answer 交互模式修改会话描述
  新的媒体流可以通过添加一个新的媒体描述来实现,它可以添加到当前媒体描述的下面,也可以重新使用旧的媒体流的空间来重新激活新的媒体流。注意,这里,旧的媒体流通过端口设置为零以后已经被关闭。如果新的媒体流使用旧媒体流空间的话,新媒体描述需要替换掉旧的媒体描述,但是新媒体描述应该在SDP中和其他媒体描述位置不变。新媒体描述必须出现在已存在媒体描述的下面(这是一个格式规则)。当answerer应答方收到的SDP中所包含的媒体描述比offerer发起方发送的媒体描述多时,或者收到的SDP中包含媒体流,此媒体流占用的以前旧媒体流空间的话(端口为零),应答方就知道这里增加了一个新的媒体流。当然,新增加的媒体流也可以通过answer消息,在answer重构媒体描述接受或者拒绝这个新的媒体流。关于应答发生成answer的流程,读者需要参考前面的章节。
  除了在会话中增加媒体流以外,媒体流当然也可以被从会话中移除。如果要移除媒体流的话,需要创建一个新的SDP,在新的SDP中对需要移除的媒体流端口设置为零,这样就移除了媒体流。媒体描述可以忽略以前出现的所有描述,仅保留单个媒体格式。所有在offer消息中出现被标识为关闭的媒体流(端口设置为零)也必须在anwer标识这些媒体流,并且关闭端口。反之,answer也必须针对offer做同样的处理流程。在这种情况下,RTP和RTPC的传输流程也会停止退出,释放任何和这些媒体关联的资源,例如占用的电脑麦克风,摄像头资源也会关闭。
  除了增加媒体流,删除媒体流以外,本章节开始时,笔者说过,几乎所有的会话中的媒体流属性参数都可以修改。现在,我们主要介绍一下修改地址,端口,传输方式,媒体格式,媒体类型,属性,以及单播媒体等待状态处理。
  媒体的端口号是可以被修改的。笔者将讨论offerer和answerer两个方向的端口修改。如果要修改媒体的端口号,发起方offerer需要创建一个新的会话描述,在新会话描述中的“m=”行包含一个端口号,此端口号必须和前面相应媒体SDP中的会话描述中的端口号不同。如果仅修改端口号,那么其他的媒体描述应该保持不变状态。因为offerer修改了端口以后,还没有收到任何answer消息之前,所以,只要offerer发送了offer以后,offerer发起方必须准备接收旧端口发送过来的媒体和新端口发送过来的媒体。直到收到了answer消息,媒体流从新端口抵达,offerer发起方才能退出旧端口的侦听。简单来说,在使用新端口的媒体抵达之前,发起方不应该退出旧端口的侦听,否则,可能出现传输的媒体丢失的问题。需要特别注意到是,这里存在一个新旧端口切换的过渡阶段,可能一些应用场景中的已接收到媒体流。这里的已接收到媒体可能已经被存放在了一个系统的存储节点上,如果有一个缓冲区的处理列表的话,接收方用户终端会继续侦听旧端口来的这个媒体流,直到从新端口接收到的媒体流存放在优先级最高的空间,这样,接收方终端才会退出旧端口的媒体侦听,真正开始侦听新端口的媒体。
  前面,笔者讨论了offerer发起方的端口修改,现在开始讨论answerer的端口修改。在answer中相应的媒体流可以和前面answerer发送的SDP中的媒体流相同也可能不同。如果应答发接受了一个已更新的媒体流,应答方应该使用新的端口马上开始发送此更新的媒体流数据。如果应答方从前面的SDP的端口改变了发送端口,只要answer消息发送后,answerer应答方必须准备同时从新端口和旧端口接收媒体流数据。关于新端口和旧端口的侦听退出和offerer的思路完全相同,笔者这里不再重复。以上我们讨论的是answerer接受了offer的更新媒体。如果answerer应答方拒绝了offer的媒体流,offerer发起方收到拒绝消息后,offerer会停止前面准备接收媒体的端口。
  改变媒体发送地址的处理方式和改变端口的处理方式相同,区别在于其连接属性“c=”需要更新,端口没有修改。媒体传输方式也可以修改,处理方式和端口的处理方式是相同的,传输方式修改,其端口不能修改。
  除了会话中修改地址,端口和传输方式以外,会话管理的另外一个功能就是修改媒体格式。在会话中支持的媒体列表中的任何一个媒体格式都可以被修改。如果需要修改媒体格式的话,offer需要创建一个媒体描述,在这个新的媒体描述中,"m="行的媒体格式列表和此媒体流前面SDP中的不同。在新的会话描述中,此媒体列表可以增加新的媒体格式,也可以删除出现在前面SDP中的媒体格式。具体到RTP的使用中,在此媒体流中,会话期间的这个匹配关联关系一定不能被修改,具体来说,这个绑定关联关系是从一个指定的动态payload类型匹配到一个指定的编码,它们两者之间绑定关系在此会话生命周期内是不能修改的。例如,如果Bob端生成了一个offer消息,此offer消息中标识了编码格式G.711绑定到了一个动态的payload 类型号46,在此会话期间,在此媒体流中,无论是offer或者answer,这个46 payload 类型号码一定是表示G.711编码格式。但是,多个payload 类型号映射到同一编码格式的这种情况也是可以接受的。因此,一个已更新的offer消息中可以使用其他payload 类型号码来映射G.711编码,例如,也可以在更新的offer中使用payload type是72来映射G.711编码。
  Asterisk-18中编码协商处理流程示例
  显而易见,为了保证SDP信令交互和媒体流之间的同步,在一个会话期间,动态payload号类型和编码的映射关系必须维持一个固定状态。我们在前面的章节介绍过在answer中相应的媒体流构建,构建的过程也可能导致修改媒体格式。同样的,只要应答方发送answer应答消息,answerer应答方必须开始使用某种媒体格式发送媒体流,这种媒体格式出现在answer消息中,也出现在了其offer消息中,answerer应该使用offer中优先级最高的推荐媒体格式(此媒体格式也出现answer中的媒体格式)。即使某种媒体格式出现在前面的SDP中,如果此媒体格式没有出现在offer中的话,answerer一定不能使用这种媒体格式。反之亦然,offerer发起方收到answer后,它发送媒体时必须使用answer中优先级最高的媒体格式。即使某种媒体格式在前面的SDP中出现过,但是在本answer中没有出现的话,offerer发起方一定不能使用此媒体格式。当终端agent停止使用某种媒体格式时(这种媒体格式不在offer或answer消息中),它仍然需要在将来一定时间内准备使用此媒体格式接收媒体。这里,agent仍然需要做一个状态处理。它自己本身如何知道何时停止使用某种媒体格式接收媒体流呢?它需要一些必要的技巧来处理,使得agent变得“聪明”一点,它可以判断对端是否停止使用旧媒体格式。第一种处理技巧,agent可以修改端口来修改媒体格式。当媒体抵达新端口后,agent知道对端peer已经停止使用旧媒体格式发送媒体流,agent也能停止使用此媒体格式接收媒体流。这种处理方式的好处是不依赖于媒体格式,但是,如果涉及了加密处理的话,修改端口要求原来预留的资源也要做出改变,原来安全加密的密钥需要重新签发。接下来,我们讨论第二种处理技巧,当一个媒体格式被弃用时,agent使用一组全新的payload动态类型来映射所有的编码。agent收到媒体时,它使用了新payload类型中的其中一种格式的话,agent知道对端已经停止使用就媒体格式发送媒体流。和第一种方式相比,这种方式不会影响预留资源和加密处理,但是需要增加额外的空间重新创建新payload 类型号。最后一种方式是使用定时器。当agent收到一个从对端peer发送过来的SDP,agent设置一个定时器。当定时器被触发后,agent就停止使用旧的媒体格式来接收媒体流。定时器设置为一分钟的超时设置是完全没有问题的。在一些使用环境中,agent也可以不用考虑是否继续使用旧媒体格式接收媒体流。因此,agent也无需过多干预。如果agent拒绝了offer的媒体流,对端也收到拒绝消息后也会停止准备使用任何新媒体格式发送媒体流。第三种方式相对比较适用于简单的环境中,通过定时器超时来处理媒体格式的修改响应。
  除了前面我们讨论的一些媒体描述参数可以修改以外,媒体类型(语音,视频,数据等)也可以进行修改。对流媒体来说,媒体类型也可以通过一定的处理方式来修改。一般的推荐方式是,如果传输的逻辑数据是一样的,如果修改媒体类型的话,可以通过不同的媒体格式来实现。以前比较常见的示例是传真部署中的场景,基于VBD(Voiceband Data)的传真和模拟传真信号的媒体类型修改。在当媒体流修改为不同的媒体类型。Voiceband Data和传统传真是分离的两种类型,它们可以在路由器,网关和IPPBX之间进行类型修改支持传真功能。如果需要修改媒体类型的话,offerer方使用一个新的媒体类型创建一个新的媒体描述,替代掉前面SDP中需要修改的媒体类型。在answer中相应的媒体流需要遵从笔者前面讨论的answer消息中构建流程。假设媒体流被接受的话,只要answerer应答方收到了offer以后,它应该开始通过新的媒体类型和格式发送媒体流。收到answer消息后,发起方offerer必须准备使用旧媒体类型和新媒体类型接收媒体流,新媒体类型的媒体流抵达后,新类型媒体上升到播放缓冲区顶部,开始正式使用最新媒体类型。
  修改会话中的特征属性也需要通过offer/answer来修改。在媒体描述中其他的属性也可以通过一个offer消息或answer消息来更新。一般情况下,如果agent收到了一个已修改参数的SDP,agent必须使用新的参数属性发送媒体。
  在以上所有的会话描述修改中,我们没有涉及到一个非常普遍使用的应用场景。这个使用场景就是呼叫等待功能。笔者再花费一点时间来进一步和大家说明如何在呼叫等待状态中处理单播媒体流。如果在呼叫中,一方(例如,A)把另外一方(例如,B)的呼叫执行了电话驻留,让另外一方处于呼叫等待状态(需要暂时停止发送一个或者多个单广播媒体流)。这时,呼叫方A会对另一方B发送一个offer消息,offer消息中包含了一个更新的SDP。如果前面被停靠的媒体是一个被标记为sendrecv的媒体流,现在,这个流媒体将会被替换成标记为sendonly的媒体流。
  如果前面被停靠的媒体是一个被标记为recvonly的媒体流,现在,这个流媒体将会被替换成标记为inactive的媒体流。这样的处理方式表示在每个方向停靠的呼叫等待媒体可以独立分别标识。等待状态的媒体流都是各自独立的。在等待状态的媒体的offer消息的接收方不应该自动返回一个针对此等待状态的answer消息。一个对所有等待状态的媒体的SDP看作是已接受的SDP(held SDP)。当answerer对已接受的SDP响应SDP时,某些第三方的呼叫控制方案中,已接受的SDP不能正常工作。比较典型的应用场景是,当终端agent摁 "Hold" 按键时,agent端将会在SDP中对所有的流媒体生成一个offer消息,此offer消息表示一个sendonly指向,并且agent自己也执行本地静音,agent也没有对远端发送媒体和播放媒体。还有很多的应用遵从RFC 2543(不再使用),从规范规定通过连接地址设置为0.0.0.0来驻留呼叫。这种规范方式其实已不再推荐为一种停靠方式,并且也不能支持IPv6,它不能支持RTCP对媒体流的报表监控。但是这种处理方式在初始offer时会非常有用。在发起时间,当发起方offerer知道它想使用的具体的一组媒体流和它们的格式,但是此时还不知道接地址和端口,这种处理方式就满足了初始offer的需求。Agent必须有一个支持能力来接收SDP,此SDP中的连接地址为0.0.0.0,关闭对RTP语音包数据或者RTCP报表数据的发送。关于呼叫等待的完整的流程介绍,读者可以参考笔者历史文档:
  最常用的18个SIP呼叫业务流程详解-1-呼叫保持
  8、指示能力讨论
  在agent发送offer之前,如果知道offer中的媒体格式可以被远端answerer 应答方接受的话,那将对agent有很大的帮助。SIP协议具有查询能力,可以对对端进行基本的能力查询。在SIP响应中的SDP可以用来指示对端的媒体支持能力。读者可以查阅RFC 3261-11获得关于查询能力的介绍。这里,我们讨论如何实现类似SDP的构建。可能一些读者知道,其实,SDP没有办法指示此消息来说明为了实现能力指示的目的,SDP只能进行一些简单的能力查询。它真正的的能力指示是由更高级的协议层内容完成,SDP的基本能力指示的媒体承载能力是非常有限的。SDP本身不能表达允许参数值范围,也不能通过offer/answer本身实现并行处理。SDP的这个局限性可能在未来的规范中得以支持。
  使用一个结构化的SDP表示媒体能力支持,其创建过程是这样的。当然,首先,此SDP必须是一个有效的SDP结构,另外,它可以忽略"e=" 和 "p=" 行(前面讨论已提及)。“t=”必须等于“0 0”。agent所支持的每个媒体类型必须有相应的媒体类型的描述。在origin域中的会话ID是唯一的,唯一的会话ID用来支持每个已构建的SDP指示其媒体能力。端口必须设置为零,但是连接地址可以是随意的。如果一个SDP解析为offer或answer消息的话,使用端口为零的设置手段可以保证一个已经构建好的SDP不会引起媒体流创建,因为此已格式化的SDP仅针对其支持能力,并且端口设置为零。"m="行表示传输的媒体类型。对于agent支持的媒体类型中的每个媒体格式来说,"m="行应该有一个媒体格式列表。在RTP使用方面,如果使用了动态payload类型的话,rtmp属性必须出现在SDP中,它用来绑定媒体类型和具体的媒体格式。注意,在SDP中没有办法指示媒体限定,例如一种编码可以支持的并发媒体流数量等。
  9、交互示例和其他延伸讨论
  在前面的几个章节包括现在我们正在讨论的章节中,笔者完整介绍了基本的语法概要,offer/answer各自生成消息的流程,还介绍了如何对会话中的媒体描述进行管理。为了保证offer/answer交互模式规范的标准化,笔者在前面的所有章节中没有涉及太多规范以外的内容。此部分的内容中,笔者结合几个实例来具体说明offer/answer的交互示例,终端/网关产品中关于媒体协商的示例,还有关于早期offer和后期offer的区别等延伸讨论。说明,因为篇幅有限,在示例中,我们仅列出一般正常的交互方式,不涉及非常特别的或具体每个特殊场景的环境和参数讨论。
  首先读者可以了解一个最简单的offer/answer交互模式的处理流程,示例中仍然是经典的Alice/Bob举例。这里,假设Alice在offer中已经包含了以下的媒体描述,描述中一个双向的语音媒体,两个双向的视频媒体,其中视频媒体使用了H.261(payload类型是31)和MPEG(payload类型是32)。这里,offer的SDP是这样的:
  v=0
  o=alice 2890844526 2890844526 IN IP4 host.anywhere.com
  s=
  c=IN IP4 host.anywhere.com
  t=0 0
  m=audio 49170 RTP/AVP 0
  a=rtpmap:0 PCMU/8000
  m=video 51372 RTP/AVP 31
  a=rtpmap:31 H261/90000
  m=video 53000 RTP/AVP 32
  a=rtpmap:32 MPV/90000
  Alice呼叫了Bob,但是,Bob不想接收或发送第一个视频媒体流,因此Bob返回了一个answer消息:
  v=0
  o=bob 2890844730 2890844730 IN IP4 host.example.com
  s=
  c=IN IP4 host.example.com
  t=0 0
  m=audio 49920 RTP/AVP 0
  a=rtpmap:0 PCMU/8000
  m=video 0 RTP/AVP 31
  m=video 53000 RTP/AVP 32
  a=rtpmap:32 MPV/90000
  在每个时间点,Bob想决定修改他的语音媒体流接收端口(从49920修改到65422),同时,他还要增加一个额外的媒体流,此媒体流标识为receive指向状态,使用的payload 类型支持event(例如DTMF,传真等)。关于event的介绍,读者可以参考RFC4734-2。Bob会生成这样的offer消息返回到Alice:
  v=0
  o=bob 2890844730 2890844731 IN IP4 host.example.com
  s=
  c=IN IP4 host.example.com
  t=0 0
  m=audio 65422 RTP/AVP 0  // 修改了端口
  a=rtpmap:0 PCMU/8000
  m=video 0 RTP/AVP 31
  m=video 53000 RTP/AVP 32
  a=rtpmap:32 MPV/90000
  m=audio 51434 RTP/AVP 110
  a=rtpmap:110 telephone-events/8000
  a=recvonly  // 增加的指向
  假设Alice接受了额外的媒体流支持请求,Alice生成以下answer:
  v=0
  o=alice 2890844526 2890844527 IN IP4 host.anywhere.com
  s=
  c=IN IP4 host.anywhere.com
  t=0 0
  m=audio 49170 RTP/AVP 0
  a=rtpmap:0 PCMU/8000
  m=video 0 RTP/AVP 31
  a=rtpmap:31 H261/90000
  m=video 53000 RTP/AVP 32
  a=rtpmap:32 MPV/90000
  m=audio 53122 RTP/AVP 110
  a=rtpmap:110 telephone-events/8000
  a=sendonly
  通过几次交互以后,完成双方会话管理。以上交互流程实际上是Alice对Bob呼叫时的一个会话修改的流程,具体的协商响应和回复需要参考笔者前面介绍的内容。
  多选一”One of N Codec“是编码协商中比较常见的场景。现在,很多物理SIP话机已经非常普及,SIP话机的DSP支持了多种编码的压缩。
  资源来自于互联网
  有时,编码一旦被选定以后,编码不能轻易被修改。以下这个示例演示了通过初始化的offer/answer交互创建会话的流程,然后马上通过第二个offer选择编码组锁定需要的编码。从Alice发送到Bob的初始offer中指示单媒体流可使用三种编码,这三种编码都是DSP中支持的编码。因为Alice还没有收到媒体流,编码锁定以后才能发送媒体流,因此,这里的媒体流标识为inactive状态:
  v=0
  o=alice 2890844526 2890844526 IN IP4 host.anywhere.com
  s=
  c=IN IP4 host.anywhere.com
  t=0 0
  m=audio 62986 RTP/AVP 0 4 18
  a=rtpmap:0 PCMU/8000
  a=rtpmap:4 G723/8000
  a=rtpmap:18 G729/8000
  a=inactive
  Bob端可以支持动态切换编码格式,可以从PCMU和G.723编码。因此,Bob返回一个answer消息,包含的编码如下:
  v=0
  o=bob 2890844730 2890844731 IN IP4 host.example.com
  s=
  c=IN IP4 host.example.com
  t=0 0
  m=audio 54344 RTP/AVP 0 4
  a=rtpmap:0 PCMU/8000
  a=rtpmap:4 G723/8000
  a=inactive
  Alice收到Bob的answer以后,从收到的两种编码中选择了其中一种编码G.723,通过一个更新的offer消息,并且标识其媒体流的媒体指向是sendrecv状态。
  v=0
  o=alice 2890844526 2890844527 IN IP4 host.anywhere.com
  s=
  c=IN IP4 host.anywhere.com
  t=0 0
  m=audio 62986 RTP/AVP 4
  a=rtpmap:4 G723/8000
  a=sendrecv
  Bob收到更新的offer以后,接受其编码G.723, 发送answer给Alice。
  v=0
  o=bob 2890844730 2890844732 IN IP4 host.example.com
  s=
  c=IN IP4 host.example.com
  t=0 0
  m=audio 54344 RTP/AVP 4
  a=rtpmap:4 G723/8000
  a=sendrecv
  如果Bob这里只能支持N选一(one-of-N codecs)的编码方式的话,Bob将会从offer中提供的编码中选择其中一个可用编码,然后把选择的编码通过answer发送到对端。这种情况下,Alice将会重新发起一个re-INVITE请求启用此最后协商的编码来传输媒体流。以上笔者介绍的是在第一次初始化offer中使用了"a=inactive"。对于在第一次交互中使用"a=inactive"指向的方式来说,另外一种处理方式是Alice可以列出所有的编码,只要她从Bob收到媒体流以后,然后马上生成一个更新的offer消息,在更新的offer中锁定一种刚才从Bob收到的媒体格式,使用其锁定的编码格式来传输媒体流。当然,如果Bob这里只能支持N选一(one-of-N codecs)的编码方式的话,他的answer中将会包含一种编码格式,这种情况下,Alice也不需要发起一个re-INVITE请求锁定编码。当然,如果双方的编码协商不能成功的话,需要在B2BUA上进行编码转换的处理。关于编码转换的问题,笔者在历史文档中有深入的讨论,这里不再重复。读者可以参考:
  编码转换处理
  以上是一个关于带物理DSP的SIP话机简单编码协商流程。除了SIP终端之间的协商以外,我们在生产环境中还会看到网关产品的编码协商处理的使用场景。现在,我们通过一个语音网关的编码协商的示例来说明编码协商是如何进行的。再次说明,这里的示例仅是某个厂家的网关的简单示例(多个“m=”行支持),可能和其他厂家的处理机制在细节上有所差别,但是原理基本上都是一致的(遵从RFC 3264规范)。示例中,网关通过offer/answer交互模式,通过第一个“m=”行和端口设置(m=0)接受了所需要的媒体格式,拒绝了不能支持的媒体。注意,这里的编码优先级不会影响offer中编码的选择,仅影响answer中编码选择方式。
  图例来自于互联网
  语音呼叫环境中,SIP INVITE进入到网关以后的offer和网关返回的answer消息对比:
Default Codec = G.711 ulaw

m=audio 38400 RTP/AVP 0

m=audio 49500 RTP/AVP 8

m=audio 6000 RTP/AVP 0 // 接受

m=audio 0 RTP/AVP 8 // 拒绝

  offer中提供了两种编码的支持,但是网关发送到answer接受了payload type为0的媒体格式(在answer中是第一个编码),拒绝了payload是8的媒体,设置其端口为0。
  1. 黄金法则:
  2. Early offer= SDP in INVITE而 Late offer= SDP in ACK
  除了以上协商的策略以外,可能还有一个需要问题需要读者要注意,那就是呼叫流程中“early offer”和“late offer”的问题,因为在B2BUA中涉及了编码协商的机制和编码转换的问题,它们会影响到编码协商的最终结果。最早的SIP应用场景中很多是使用early offer模式,但是随着网络架构和网络环境越来越复杂,更多的性能优化需要调整编码能力或者带宽/QoS等业务要求,所以,在SIP网络中使用later offer的场景也逐渐多了。一些读者可能没有注意这两个概念的不同或比较迷惑这两个概念。首先,讨论简单说明一下什么是“early offer”和“late/delayed offer”。其实,这两个概念也没有太难理解的地方,顾名思义,early offer就是在INVITE请求中包含SDP消息,later offer就是在后续的ACK中包含SDP消息。例如,如果一个UAC发起一个INVITE请求,并且在INVITE(offer消息)做包括了SDP消息,SDP消息中指示了UAC所支持的媒体格式,例如通常使用的G.711和G.723等编码。请求的接收方收到SDP消息后解析编码,然后根据所支持的编码决定接收方UAS使用何种编码来进行媒体传输。注意,UAC(被呼叫方)首先看到的是UAS(呼叫方)在SDP中的编码。这种情况下,相当于UAC已经把可以选择的编码提供给了被呼叫方,被呼叫方没有什么选择的余地,它只能根据UAS提供的编码进行选择。所以,其实在early offer中,UAS具有更多的自主权,而UAC只能从编码中被动选择需要的编码。当然,其优点是UAS降低了编码编码处理的的复杂度。
  early offer 示例(INVITE包含SDP)
  前面笔者讨论了early offer,呼叫方首先提供了一种选择权让对方来选择。和early offer相反的是later offer。从字面意思也可以看到,early或later仅是一个offer SDP的时间问题。Later offer更多的offer消息的选择权则是由被呼叫方晚一点提供。呼叫方在INVITE呼叫请求发送时,没有包含SDP消息,同时双方也进行正常的INVITE流程处理,被呼叫方返回一个临时响应,例如,发送 180振铃(但是,被呼叫方此时还没有准备好或意识到使用何种编码)或者183(带SDP,下面讨论此问题),紧接着发送 200 ok(带SDP消息,这时开始发送offer消息/later offer)。呼叫方收到 200 ok 以后,结合其offer中的SDP消息,然后返回ACK(包含SDP消息体)。实际上,呼叫方最终决定使用何种编码。
  later offer(ACK中包含)
  在later offer中的场景中,有两个比较重要的问题可能会影响呼叫。有时,发送了200 ok最终响应的设备会马上发送媒体流,此时对端可能还没有收到 200 ok(包括SDP),它们之间的会话也根本没有创建,因此可能出现语音丢失的问题,语音丢失的长度可能完全取决于双方最后协商的时间。所以,有时我们经常遇到,通话开始的前几秒可能双方都听不到对方的声音,或者播放IVR时,IVR语音的前几秒语音丢失。另外一个问题就是在被呼叫方发送临时响应时,它没有发送180 振铃,但是有时发送的是183(带SDP),这样的临时响应携带了媒体。因为此时此刻,没有协商流程还没有完成也没有协商成功,呼叫方的媒体端口或者地址还没有开启,因此,SDP中携带的媒体流可能就会在中途丢失,例如,听不到回铃音,彩铃或者其他的语音业务播放的媒体。这些问题可能需要经过一些B2BUA的处理(在Asterisk或者FreeSWITCH都针对两种offer有相关的具体配置。),有时需要PRACK的支持,在媒体服务器端针对性地进行设置(增加progress 处理,等待,或者answer处理等)或者在其呼叫路径中增加一个SBC来处理later offer带来的这些问题。
  参考资料:
  https://tools.ietf.org/id/draft-ietf-mmusic-ice-sip-sdp-14.html
  https://tools.ietf.org/html/draft-ietf-rmcat-cc-codec-interactions-00
  https://www.swisscom.ch/content/dam/swisscom/en/about/company/network/all-ip/documents
  https://freeswitch.org/confluence/display/FREESWITCH/Codec+Negotiation
  https://lists.cs.columbia.edu/pipermail/sip-implementors/2018-December/031167.html
  在接下来的章节中,笔者将继续讨论SDP offer/answer交互模式中NAT处理以及ICE。
 
  关注微信公众号:asterisk-cn,获得有价值的Asterisk行业分享
  Asterisk freepbx FreeSBC技术文档: www.freepbx.org.cn
  融合通信/IPPBX商业解决方案:www.hiastar.com
  如何使用FreeSBC,qq技术分享群:334023047, www.freesbc.cn

【免责声明】本文仅代表作者本人观点,与CTI论坛无关。CTI论坛对文中陈述、观点判断保持中立,不对所包含内容的准确性、可靠性或完整性提供任何明示或暗示的保证。请读者仅作参考,并请自行承担全部责任。

专题

CTI论坛会员企业