SIP - offer/answer 规范


SDP 与 SIP 的使用在 SDP 提供答案 RFC 3264 中给出。SIP 中的默认消息正文类型是 application/sdp

  • 主叫方列出他们愿意在 SDP 中接收的媒体功能,通常是在 INVITE 或 ACK 中。

  • 被叫方在对 INVITE 的 200 OK 响应中列出其媒体功能。

SDP 的典型 SIP 使用包括以下字段:版本、来源、主题、时间、连接以及一个或多个媒体和属性。

  • 主题和时间字段不被 SIP 使用,但包含在内是为了兼容性。

  • 在SDP标准中,主题字段为必填字段,必须至少包含一个字符,如果没有主题,建议使用s=-。

  • 时间字段通常设置为 t = 00。SIP 使用连接、媒体和属性字段在 UA 之间建立会话。

  • 源字段在 SIP 中的使用有限。

  • 会话 ID 通常在整个 SIP 会话中保持不变。

  • 每次 SDP 更改时,版本都会递增。 如果发送的SDP与之前发送的SDP没有变化,则版本保持不变。

  • 由于要使用的媒体会话类型和编解码器是连接协商的一部分,因此 SIP 可以使用 SDP 来指定多种替代媒体类型,并有选择地接受或拒绝这些媒体类型。

offer/answer 规范 RFC 3264 建议每个媒体字段使用包含 a = rtpmap: 的属性。 通过将 SDP 响应中相应媒体字段的端口号设置为零来拒绝媒体流。

示例

在以下示例中,呼叫者 Tesla 希望使用初始 INVITE 中携带的 SDP 中的两个可能的音频编解码器和一个视频编解码器来建立音频和视频呼叫 −

v = 0 
o = John 0844526 2890844526 IN IP4 172.22.1.102  
s = - 
c = IN IP4 172.22.1.102 
t = 0 0 
m = audio 6000 RTP/AVP 97 98 
a = rtpmap:97 AMR/16000/1 
a = rtpmap:98 AMR-WB/8000/1 
m = video 49172 RTP/AVP 32 
a = rtpmap:32 MPV/90000 

编解码器由 RTP/AVP 配置文件编号 97、98 引用。

被叫方 Marry 应答呼叫,为第一个媒体字段选择第二个编解码器,并拒绝第二个媒体字段,只需要 AMR 会话。

v = 0 
o = Marry 2890844526 2890844526 IN IP4 172.22.1.110 
s = - 
c = IN IP4 200.201.202.203 
t = 0 0 
m = audio 60000 RTP/AVP 8 
a = rtpmap:97 AMR/16000 
m = video 0 RTP/AVP 32 

如果这个纯音频呼叫不可接受,那么 Tom 会发送一个 ACK,然后发送一个 BYE 来取消呼叫。 否则,将建立音频会话并交换 RTP 数据包。

如本示例所示,除非维持媒体字段的数量和顺序,否则呼叫方将无法确定被叫方正在接受和拒绝哪些媒体会话。

以下部分总结了 offer/answer 规范。

生成要约的规则

SDP 要约必须包含所有必需的 SDP 字段(包括 v=、o=、s=、c= 和 t=)。 这些是 SDP 中的必填字段。

它通常包含媒体字段 (m=),但并非必须如此。 媒体行包含按优先顺序列出的所有编解码器。 唯一的例外是,如果端点支持大量编解码器,则应列出最有可能被接受或最首选的编解码器。 不同的媒体类型包括音频、视频、文本、MSRP、BFCP 等。

生成answer的规则

对要约的 SDP 答复必须根据以下规则构建 −

  • answer必须具有与answer相同的 m= 行数和相同的顺序。

  • 可以通过将端口号设置为 0 来拒绝单个媒体流。

  • 通过发送非零端口号来接受流。

  • 每种媒体类型列出的有效负载必须是优惠中列出的有效负载的子集。

  • 对于动态负载,不需要在每个方向使用相同的动态负载编号。 通常,仅选择一个有效负载。

修改会话的规则

任何一方都可以发起另一个提议/应答交换来修改会话。 修改会话时,必须遵循以下规则 −

  • 原始 (o=) 行版本号必须与最后发送的版本号相同,这表明此 SDP 与之前的交换相同,或者可以加 1, 这表明必须解析新的SDP。

  • offer必须包含所有现有媒体线路,并且必须按相同顺序发送。

  • 可以将其他媒体流添加到m=行列表的末尾。

  • 可以通过将端口号设置为 0 来删除现有媒体流。该媒体线路必须保留在 SDP 以及该会话的所有未来 offer/answer 交换中。

呼叫保持

通话中的一方可以暂时让另一方保持呼叫。 这是通过发送一个 INVITE 来完成的,该 INVITE 的 SDP 与原始 INVITE 的 SDP 相同,但存在 a = sendonly 属性。

通过发送另一个带有 a = sendrecv 属性的 INVITE 来再次激活呼叫。 下图显示了呼叫保持的呼叫流程。

呼叫保持