<!-- title: VoNR呼叫建立前提机制解读 -->
<!-- domain: ims -->

# VoNR呼叫建立全流程深度解读：SIP INVITE与QoS Precondition机制的标准化设计

## 1. 为什么VoNR呼叫建立是最复杂的SIP流程

在5G SA网络上，VoNR（Voice over New Radio）呼叫建立信令是所有3GPP信令流程中交互轮次最多、跨层耦合最深的流程之一。它不是简单的“INVITE→200 OK”，而是**SIP信令层（TS 24.229）与5G QoS资源预留层（TS 23.501/23.502）的强同步过程**。核心矛盾在于：IMS要求“振铃之前资源必须预留完成”，否则会出现被叫用户接听后因无线资源不足而掉话——这就是所谓“幽灵振铃（ghost ring）”问题。

IETF RFC 3312（业内俗称"manyfolks"文档）在其引言中精准描述了这个鸡生蛋问题：资源预留需要从对端获取IP地址、端口和会话参数（即需要先完成SDP offer/answer交互），而常规的offer/answer交互又会导致话机振铃。precondition（前提条件）机制正是为了打破这个死锁而设计的。

本文以2026年最新的Rel-18版本规范为基线，逐条解析VoNR呼叫建立中的每个信令消息、每个关键Information Element，并给出完整的信令时序图与排错方法。

## 2. 规范依据：3GPP与IETF的分工

VoNR呼叫建立横跨两套标准体系，理解分工是阅读规范的前提：

| 层面 | 规范 | 职责 |
|------|------|------|
| IMS会话控制 Stage 2 | 3GPP TS 23.228（Rel-18 V18.10.0） | IMS架构、S-CSCF/P-CSCF行为、QoS授权框架 |
| IMS会话控制 Stage 3 | 3GPP TS 24.229（Rel-18 V18.7.0） | UE/IMS节点级SIP消息流程、必选/可选头域 |
| SIP方法扩展 | RFC 3311 | UPDATE方法：在早期对话中更新会话参数 |
| 资源管理集成 | RFC 3312 | precondition框架：a=curr/a=des/a=conf属性 |
| 可靠临时响应 | RFC 3262 | 100rel机制、PRACK方法、RSeq/RAck头 |
| 5G QoS框架 | TS 23.501 Clause 5.7 / TS 23.502 | QoS Flow建立、5QI=1 GBR语音承载 |
| 运营商落地 | GSMA NG.126（VoNR IMS Profile） | 对TS 24.229特性做必选/可选裁剪 |

需要注意的设计事实是：**precondition机制并非3GPP发明**，它源自IETF。3GPP只是在TS 24.229中强制要求IMS终端支持它——这正是VoIP电话上很少见到100rel/UPDATE而在手机上必须存在的原因。

## 3. 核心机制：RFC 3312定义的三个SDP属性

RFC 3312在每个媒体流上定义了三个新的媒体级SDP属性，全部以`a=`开头：

| 属性 | 语法 | 语义 |
|------|------|------|
| `a=curr` | `a=curr:qos <status-type> <direction-tag>` | 当前资源预留状态 |
| `a=des` | `a=des:qos <strength-tag> <status-type> <direction-tag>` | 期望达到的状态（即前提条件本身） |
| `a=conf` | `a=conf:qos <status-type> <direction-tag>` | 确认请求：当对端该方向资源预留完成时，必须立即发起新offer |

三个属性各自携带的标签构成了完整的约束体系：

**strength-tag（强度标签）**——五个值有严格的强弱排序：`none` < `optional` < `mandatory`，另有`failure`和`unknown`仅用于拒绝场景。关键规则（RFC 3312 Section 5.2）：**应答方可以升级（upgrade）强度但绝不能降级**。例如主叫给`optional`，被叫可以改成`mandatory`；反之非法。这保证了会话双方对“资源是否必须预留”形成单调收敛的共识。

**status-type（状态类型）**——`e2e`（端到端）与`local`/`remote`（分段式，segmented）。分段式状态把资源预留拆成“各自接入网”两段分别描述。在蜂窝网络中，接入网资源预留由UE和RAN/核心网完成，IMS核心完全无法感知，因此**VoNR实践中普遍采用分段式（local/remote）状态**，`e2e`主要用于IntServ/RSVP这类真正的端到端资源协议场景。

**direction-tag（方向标签）**——`send`/`recv`/`sendrecv`/`none`，且**应答方向必须反转**（RFC 3312 Table 4）：offer中的`send`在answer中写作`recv`，`local`与`remote`互换。这是抓包分析中最容易犯的错误——直接拿主叫SDP的curr行去对比被叫SDP的curr行，会得出完全错误的结论。

一个典型的VoNR主叫INVITE中的SDP offer（片段）：

```text
m=audio 49170 RTP/AVP 103 9 0 8
c=IN IP4 10.0.0.1
a=curr:qos local none
a=curr:qos remote none
a=des:qos mandatory local sendrecv
a=des:qos mandatory remote sendrecv
a=rtpmap:103 AMR-WB/16000
a=fmtp:103 octet-align=0
```

这四行a=前缀的含义：双向（sendrecv）的本地与远端资源预留都是`mandatory`——在双向资源全部到位之前，**被叫终端禁止振铃**。

## 4. 完整信令时序图

```text
sequenceDiagram
    autonumber
    participant UEo as 主叫UE
    participant Go as 主叫gNB
    participant PCFo as PCF/SMF/UPF
    participant IMSo as 主叫P-CSCF/S-CSCF
    parameter IMSt as 被叫S-CSCF/P-CSCF
    participant UEt as 被叫UE
    participant Gt as 被叫gNB

    UEo->>IMSo: INVITE (SDP offer1, Require: precondition,<br/>Supported: 100rel, Allow: UPDATE)
    IMSo->>IMSt: INVITE (透传)
    IMSt->>UEt: INVITE (SDP offer1)

    Note over UEt: 挂起会话建立<br/>不振铃，开始本地资源预留
    UEt->>IMSt: 183 Session Progress<br/>(SDP answer1, Require: 100rel, a=conf:qos)
    IMSt->>IMSo: 183 (Require: 100rel)
    IMSo->>UEo: 183 (SDP answer1)
    UEo->>IMSo: PRACK (RAck: RSeq/CSeq)
    IMSo->>IMSt: PRACK
    IMSt->>UEt: PRACK
    UEt->>IMSt: 200 OK (PRACK)
    IMSt->>IMSo: 200 OK
    IMSo->>UEo: 200 OK (PRACK)

    rect rgb(230, 240, 255)
        Note over UEo,Gt: 主叫侧异步资源预留（与SIP信令并行）
        PCFo->>PCFo: P-CSCF经Rx接口请求PCF<br/>触发SMF建立5QI=1 GBR QoS Flow
        PCFo->>Go: PDU Session Modification
        Go->>UEo: RRC Reconfiguration<br/>(建立语音专用DRB)
        UEo->>Go: RRC Reconfiguration Complete
    end

    rect rgb(230, 255, 230)
        Note over UEt,Gt: 被叫侧异步资源预留
        UEt->>Gt: 触发被叫侧5QI=1 QoS Flow建立
        Gt->>UEt: RRC Reconfiguration Complete
    end

    Note over UEo: 主叫本地资源就绪<br/>a=curr:qos local sendrecv
    UEo->>IMSo: UPDATE (SDP offer2, curr更新)
    IMSo->>IMSt: UPDATE
    IMSt->>UEt: UPDATE
    Note over UEt: local+remote均达mandatory→<br/>前提条件全部满足→恢复会话建立
    UEt->>IMSt: 200 OK (UPDATE, SDP answer2)
    IMSt->>IMSo: 200 OK
    IMSo->>UEo: 200 OK (UPDATE)

    UEt->>IMSt: 180 Ringing (开始振铃)
    IMSt->>IMSo: 180
    IMSo->>UEo: 180 (回铃音经专用QoS Flow传主叫)
    UEo->>IMSo: PRACK
    IMSo->>UEo: 200 OK (PRACK)

    UEt->>IMSt: 200 OK (INVITE, 接听)
    IMSt->>IMSo: 200 OK
    IMSo->>UEo: 200 OK (INVITE)
    UEo->>IMSo: ACK
    IMSo->>UEt: ACK
    Note over UEo,UEt: 双向语音RTP流经5QI=1 QoS Flow承载
```

**这张图最重要的信息是时序约束**：180 Ringing严格位于UPDATE交换完成之后。这不是工程惯例，而是规范的强制要求——RFC 3312 Section 6规定：收到带precondition offer的UAS“在所有mandatory前提条件满足前不应（SHOULD NOT）alert用户”。

## 5. SDP Offer/Answer链的逐步演进

整个呼叫建立过程中，同一媒体流经历了两轮offer/answer，curr状态随之单调推进：

```mermaid
flowchart TD
    A["INVITE (offer1)<br/>curr: local none / remote none<br/>des: mandatory local sendrecv<br/>des: mandatory remote sendrecv"] --> B["183 (answer1)<br/>curr: local none / remote none<br/>des: 不降级, 保持mandatory<br/>conf: 请求对端预留完成后发UPDATE"]
    B --> C["主叫收到183后 + 被叫发出183后<br/>双方并行启动接入网资源预留"]
    C --> D["UPDATE (offer2)<br/>curr: local sendrecv / remote none<br/>主叫侧本地预留完成"]
    D --> E["200 OK (answer2)<br/>curr: local sendrecv / remote sendrecv<br/>被叫侧也完成(以被叫视角反转)"]
    E --> F{"所有mandatory前提<br/>条件是否满足?"}
    F -->|是| G["被叫UE振铃 → 180 Ringing<br/>→ 200 OK (INVITE) → ACK"]
    F -->|否, 超时| H["会话保持挂起<br/>最终580 Precondition Failure<br/>或主叫侧超时取消"]
```

每一步的设计意图值得逐一拆解：

**为什么183必须用100rel可靠传输？** 因为183携带了SDP answer，主叫UE必须确认它收到。RFC 3312 Section 11明确规定：在SDP中使用precondition的UA**必须**支持PRACK和UPDATE方法，因此**必须**在Supported头中包含`100rel`选项标签。TS 24.229据此要求IMS终端在Supported中列出`100rel`、在Allow中列出`UPDATE`。这也是手机IMS注册时REGISTER消息Allow列表比普通SIP电话长得多的原因。

**为什么用UPDATE而不是re-INVITE来上报curr更新？** 这是RFC 3311的立规之本。INVITE方法同时影响两件东西：会话（媒体参数）和对话（dialog状态）。在初始INVITE尚无最终响应的早期对话中发re-INVITE，会导致对话状态机混乱。RFC 3311原文的定义是："UPDATE allows a client to update parameters of a session but has no impact on the state of a dialog"——它像re-INVITE一样可以携带SDP offer，但**不改变对话状态**，且可以在初始INVITE完成之前发送。这正是precondition状态上报需要的能力。而200 OK (INVITE)和ACK都不带SDP，因为最终协商已在UPDATE轮完成——这是识别“标准precondition流程”抓包的最简特征。

**PRACK的RAck如何关联1xx？** 每个可靠的临时响应带一个递增的RSeq值（RFC 3262），PRACK中的`RAck: <RSeq> <CSeq> INVITE`同时引用RSeq和被响应消息的CSeq号，精确对应到具体哪一个1xx。一个呼叫中会出现**两次PRACK**（一次针对183、一次针对180），抓包时以RAck中的数字区分。

## 6. Precondition状态机视角

把单个媒体流抽象为状态机，可以更清楚地看到会话建立为何被“挂起/恢复”：

```mermaid
stateDiagram-v2
    [*] --> Idle : INVITE发出<br/>curr均为none
    Idle --> ReservationInProgress : 收到/发出answer<br/>双方开始资源预留
    ReservationInProgress --> LocalMet : 本地接入网预留完成<br/>(5QI=1 QoS Flow建立)
    LocalMet --> PeerMet : UPDATE上报curr<br/>对端资源也确认完成
    PeerMet --> SessionResumed : mandatory条件全满足<br/>→ 振铃(180)
    SessionResumed --> Established : 200 OK + ACK
    LocalMet --> Failure : 预留失败/超时
    ReservationInProgress --> Failure : 网络拒绝
    Failure --> Terminated : 580 Precondition Failure<br/>或CANCEL/BYE
    Established --> [*]
```

状态推进的信令触发点非常明确：Idle→LocalMet由**RRC层**事件触发（QoS Flow建立的RRC Reconfiguration Complete），LocalMet→PeerMet由**SIP层UPDATE**触发，PeerMet→SessionResumed是**本地判定**（RFC 3312：当本地状态表中所有strength-tag为mandatory的行的Current字段全为yes时恢复会话建立）。理解“两个协议层的握手点在哪”是排错的关键。

## 7. 实战：抓包识别与故障定位

**Wireshark识别标准precondition呼叫**：

```text
# 提取带precondition的INVITE
sip.Request-Line contains "INVITE" && sip.msg_hdr contains "precondition"
# 提取UPDATE交互
sip.Request-Line contains "UPDATE"
# 校验可靠临时响应
sip.msg_hdr contains "100rel"
# 查看资源状态推进
sip contains "a=curr:qos"
```

一条健康的VoNR呼叫抓包应呈现严格的节拍：INVITE→183(100rel)→PRACK→200→UPDATE→200→180→200 OK→ACK，且200 OK (INVITE)无SDP。如果时间戳间隔出现在“PRACK 200 OK”与“UPDATE”之间超过数秒，说明瓶颈在**接入网资源预留**而非IMS信令。

**常见故障点与排错路径**：

| 现象 | 典型根因 | 定位方法 |
|------|---------|---------|
| 收到183但无PRACK | 主叫UE不支持100rel收到420，或 Require: precondition被对端拒绝 | 检查420 Bad Extension响应；核对终端的Supported头 |
| UPDATE长时间不出现 | 5QI=1专用QoS Flow建立失败：PCF策略未下发、gNB拒绝GBR承载 | 联合分析Npcf/Nsmf信令与RRC Reconfiguration，核对AMBR/5QI配置 |
| UPDATE收到491 Request Pending | RFC 3311规定的glare冲突：双方同时发UPDATE带offer | 规范行为：Call-ID拥有者随机等2.1~4秒重试，另一方等0~2秒 |
| UPDATE收到500+Retry-After | 收到了带offer的UPDATE但我方还有未应答的offer | 依据RFC 3311 Section 5.2，随机0~10秒后重试 |
| 580 Precondition Failure | 资源预留失败且strength为mandatory，应答方拒绝 | 580响应体SDP中会以`a=des:qos failure ...`标明失败的具体方向 |
| 振铃延迟明显偏长 | 被叫侧QoS Flow建立慢，或运营商将des强度配为双向mandatory而实际只需单向 | 对比 INVITE→180 的跨段时延拆分；检查PCF的precondition策略模板 |

## 8. VoNR与VoLTE在此流程上的异同

| 维度 | VoLTE (EPS) | VoNR (5GS) |
|------|-------------|------------|
| 专用承载 | EPS Dedicated Bearer，5QI=1 | 5G QoS Flow，5QI=1 GBR |
| 资源预留触发 | P-CSCF经Rx接口→PCRF→PCEF | P-CSCF经Rx接口（TS 29.514）→PCF→SMF（Npcf/Nsmf） |
| 空口确认 | RRC Connection Reconfiguration | RRC Reconfiguration，NAS层PDU Session Modification Command |
| SIP precondition流程 | TS 24.229，100rel/PRACK/UPDATE | 完全相同——SIP层不感知接入网制式 |
| 信令承载QoS | QCI=5默认承载 | 5QI=5，IMS DNN的PDU会话 |
| 关键差异 | — | EUTRA-NR双注册场景需保证呼叫期间不发生EPS回落（否则UPDATE中断、会话挂起超时） |

**SIP层完全复用**是这一机制最大的工程红利：VoNR没有为呼叫引入任何新的SIP语义，5G的变化全部发生在资源预留执行层（QoS Flow替代Dedicated Bearer）。理解了RFC 3312的机制，VoLTE到VoNR的呼叫流程知识可以零成本迁移。

## 常见问题

**Q: 183 Session Progress和180 Ringing的区别是什么？**
A: 功能上183用于携带SDP answer并启动precondition协商（通常带Require: 100rel），180表示被叫已振铃。在precondition流程中二者有严格的先后关系：只有所有mandatory前提条件满足后才能发180。另外180阶段主叫与被叫间可能开始传回铃音RTP流（early media），这需要`P-Early-Media`头授权。

**Q: UPDATE和re-INVITE都能改会话参数，为什么precondition上报只用UPDATE？**
A: re-INVITE不允许在初始INVITE获得最终响应之前发送（会破坏对话状态机），而curr状态更新恰恰发生在早期对话阶段。UPDATE（RFC 3311）专为此设计：可携带offer/answer、不影响对话状态、必须立即应答（不允许等待用户批准）。会话建立后的参数修改（如保持）才使用re-INVITE。

**Q: a=des里的mandatory和optional分别会导致什么行为？**
A: mandatory方向的资源未预留完成，被叫禁止振铃、会话禁止建立，最终失败会得到580 Precondition Failure；optional方向会尽力预留但不阻塞会话建立。answer方只能把强度升级（none→optional→mandatory）不能降级，这保证了双方对资源要求的共识只会收紧不会放松。

**Q: 抓包里为什么有一次PRACK对应183、一次对应180？它们能省掉吗？**
A: 不能省。每个携带SDP或需要可靠传输的1xx都必须被PRACK确认（RFC 3262），否则发送方会重发。通过PRACK中的RAck头（含RSeq和CSeq）区分确认的是哪个响应。如果INVITE的Supported里没有100rel，被叫退化为不可靠1xx流程，precondition将无法工作——TS 24.229要求IMS终端必须支持。

**Q: 为什么呼叫建立的时延瓶颈常常不在SIP而在RRC层？**
A: SIP消息本身走5QI=5信令承载，毫秒级即可穿越IMS核心；而mandatory precondition要求在UPDATE之前完成5QI=1 GBR QoS Flow的建立（涉及PCF策略决策、SMF与gNB的PDU Session Modification、RRC Reconfiguration等多轮交互）。因此分段测量INVITE→183→PRACK与PRACK→UPDATE的间隔，是定位呼叫时延问题的第一刀。

## 参考来源

1. [IETF RFC 3312 "Integration of Resource Management and SIP"](https://www.ietf.org/rfc/rfc3312.txt) — precondition框架：a=curr/a=des/a=conf属性定义、挂起/恢复规则、580状态码、端到端与分段式状态类型示例（Section 4、5、6、8、13）
2. [IETF RFC 3311 "The SIP UPDATE Method"](https://www.ietf.org/rfc/rfc3311.txt) — UPDATE方法定义、早期对话使用约束、491/500重试规则与随机定时器（Section 3、5、8）
3. [ETSI TS 124 229 V18.7.0](https://www.etsi.org/deliver/etsi_ts/124200_124299/124229/18.07.00_60/ts_124229v180700p.pdf) — 3GPP IMS会话控制Stage 3：主叫/被叫UE会话流程与Require: precondition、100rel、Allow: UPDATE的强制要求
4. [ETSI TS 123 228 V18.10.0](https://www.etsi.org/deliver/etsi_ts/123200_123299/123228/18.10.00_60/ts_123228v181000p.pdf) — IMS Stage 2：QoS授权与资源预留的架构层描述

---
> 本文由「51学通信」技术团队出品。51学通信由通信行业18年老兵**爱卫生**（微信ID: gprshome201101）维护，聚焦5G/6G核心网、3GPP标准解读、通信前沿技术深度分析。
> 出版作品有《5G核心网原理与实践》《IMS原理与实践》等4本通信专业书籍。知识星球「51学通信」提供深度技术答疑和行业洞察。

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
