<!-- title: VoNR主叫INVITE与precondition拆解 -->
<!-- domain: ims -->

# VoNR 主叫 SIP INVITE 会话建立与 SDP precondition 机制全链拆解

## 一、为什么 VoNR 呼叫不能"先振铃再建路"

VoNR（Voice over NR）的本质，是**把 IMS 域的 SIP/SDP 会话控制层完整地搬到 5G NR 之上**。从协议角度，VoNR 与 VoLTE 在 IMS 信令层面几乎完全同构——同样遵循 3GPP TS 23.228（IMS Stage 2）的会话建立流程、TS 24.229 的 SIP/SDP 编解码规则、TS 26.114 的 MTSI 媒体处理要求。真正的差异不在 SIP，而在底层承载：VoLTE 走 EPS 的专用承载（PCRF→PGW，Rx→Gx），VoNR 走 5G 的专用 QoS Flow（PCF→SMF→UPF，Rx→N7/N4），语音媒体用 5QI=1 的 GBR 承载。

语音是**会话型实时业务**，对端到端时延（PDB=100ms）和丢包极度敏感。这就引出一个根本性设计问题：如果允许 SIP 信令先把被叫"振铃→摘机"走完，再去网络里抢无线资源建承载，会出现两类灾难性故障——

1. **起呼即单向/断续**：被叫摘机瞬间，专用 GBR 承载尚未在空口（gNB）和核心网（UPF）建立完成，前几百毫秒的语音包丢失或走 best-effort，听感为"喂喂喂听不见"。
2. **抢占失败导致通话中断**：NR 空口在拥塞时执行**接纳控制（Admission Control）**，会拒绝 GBR 业务的 QoS Flow 建立。如果此时呼叫已经接通，就只能硬中断。

因此 3GPP/IMS 的设计哲学是：**把"会话协商"（SIP/SDP 协商编解码、IP/端口、QoS 需求）与"资源预留"（专用承载建立）解耦，并让前者"门控"后者**——只有当双方都成功预留了专用资源，被叫才允许振铃、主叫才允许应答。这套"门控"机制，就是 RFC 3312 定义的 **SDP precondition（前置条件）机制**，并被 TS 26.114（MTSI）规定为 VoLTE/VoNR 的默认强制行为（GSMA IR.92 / IR.93 profile）。

本文聚焦 TS 23.228 clause 5.2.2.1 的**移动主叫（MO, Mobile Originated）IMS 会话建立流程**，逐消息拆解 SIP INVITE 全链信令、SDP precondition 的 IE 结构与状态机、以及与 5G 专用 QoS Flow 的 Rx/N7 联动。

---

## 二、MO 会话建立完整信令时序

下面给出一次完整的 VoNR 主叫（UE-A）→ 被叫（UE-B）会话建立信令，覆盖 precondition 的"offer→answer→UPDATE 确认"三阶段。本流程对应 TS 23.228 §5.2.2.1（Origination）与 §5.2.2.2（Termination），precondition 的可靠性由 RFC 3262（100rel/PRACK）和 RFC 3311（UPDATE）共同保障。

```mermaid
sequenceDiagram
    autonumber
    participant A as UE-A (主叫)
    participant PA as P-CSCF-A
    participant SA as S-CSCF-A
    participant IB as I-CSCF-B
    participant SB as S-CSCF-B
    participant PB as P-CSCF-B
    participant B as UE-B (被叫)
    participant PCF as PCF/SMF (5G承载)

    A->>PA: INVITE (SDP offer, EVS, precond:none→des:mandatory)
    Note over PA,PCF: Rx AAR→PCF，发起主叫专用QoS Flow(5QI=1)预留
    PA->>SA: INVITE (Route含S-CSCF)
    SA->>IB: INVITE (按被叫域名查询)
    IB->>SB: INVITE (Cx LIR/LIA定位)
    SB->>PB: INVITE
    PB->>B: INVITE
    PA-->>A: 100 Trying (逐跳,抑制重传)
    Note over B,PCF: 被叫侧Rx→PCF发起QoS Flow预留
    B-->>A: 183 Session Progress (SDP answer, precond未满足, Require:100rel)
    A->>B: PRACK (对183可靠确认)
    B-->>A: 200 OK (PRACK)
    Note over A,PCF: 主叫专用承载建立完成→local precond达成
    A->>B: UPDATE (SDP: curr local sendrecv)
    Note over B,PCF: 被叫专用承载建立完成→remote precond达成
    B-->>A: 200 OK (UPDATE) (curr remote sendrecv→前置条件全部满足)
    B-->>A: 180 Ringing (Require:100rel)
    A->>B: PRACK (对180)
    B-->>A: 200 OK (PRACK)
    Note over B: 被叫摘机
    B-->>A: 200 OK (INVITE)
    A->>B: ACK
    Note over A,B: 双向媒体在5QI=1 GBR承载上建立
```

### 关键信令消息逐条解析

**① INVITE（初始 offer）**：UE-A 构造初始 SDP offer，包含：
- `m=audio` 行给出媒体端口与 RTP payload type 列表（首选 EVS，回退 telephone-event）；
- `a=rtpmap`/`a=fmtp` 描述 EVS 编解码能力集（TS 26.445）；
- 一组 precondition 属性：`a=curr:qos local none`、`a=curr:qos remote none`、`a=des:qos mandatory local sendrecv`、`a=des:qos mandatory remote sendrecv`、`a=conf:qos remote sendrecv`；
- Route 头：携带注册时通过 Service-Route 学到的 P-CSCF、S-CSCF 地址（`Route: <sip:pcscf.home.net;lr>`、`Route: <sip:orig@scscf.home.net;lr>`）。

**② 100 Trying**：**逐跳（hop-by-hop）临时响应**，仅用于抑制 INVITE 重传，**不携带 SDP，不端到端转发**。这点与 183/180 不同，是抓包定位时最易混淆之处。

**③ 183 Session Progress**：被叫 UE-B 回送 **SDP answer**，确认编解码（EVS）、确认 precondition 为 mandatory，但 `curr` 仍为 none（资源尚未预留）。由于含 `Require: 100rel`，183 必须被可靠传送。

**④⑤ PRACK / 200 OK(PRACK)**：RFC 3262 对 183 的可靠确认。PRACK 自身也可携带更新 SDP（用于能力二次协商），但 precondition 的"达成"更新通常走 UPDATE。

**⑥ UPDATE**：主叫侧专用承载建好后，UE-A 用 UPDATE 携带更新 SDP，把 `a=curr:qos local sendrecv` 置位，表示本端 QoS 已达成。UPDATE 是 RFC 3311 定义的、**在初始 INVITE 尚未 200 OK 之前**修改会话参数的唯一合法手段（re-INVITE 只能在 dialog 建立后使用）。

**⑦ 200 OK(UPDATE)**：被叫侧承载也建好后回送，`a=curr:qos remote sendrecv` 置位。至此 **local + remote 的 curr 全部 ≥ des，precondition 全部满足**。

**⑧ 180 Ringing**：前置条件满足后，被叫才振铃，并带 `Require: 100rel`。

**⑨ 200 OK(INVITE) + ACK**：被叫摘机，会话建立，双向语音在 5QI=1 GBR 承载上流通。

---

## 三、SDP precondition 的 IE 结构与状态机

precondition 机制的核心，是在 SDP 中嵌入三类属性，分别描述"当前状态""期望状态""确认请求"，由 RFC 3312 定义、TS 26.114 第 7 章对 MTSI 客户端给出强制要求。

### SDP precondition 属性字段表

| SDP 属性 | 含义 | 取值/示例 | 作用 |
|---|---|---|---|
| `a=curr:qos <dir> <status>` | 当前 QoS 状态 | `dir`=local/remote；`status`=none/send/recv/sendrecv | 标识本端或对端当前已达到的资源状态 |
| `a=des:qos <strength> <dir> <status>` | 期望 QoS 状态（目标） | `strength`=mandatory/optional；示例 `mandatory local sendrecv` | 定义为达成呼叫必须满足的目标，带强度标签 |
| `a=conf:qos <dir> <status>` | 确认请求 | `a=conf:qos remote sendrecv` | 请求对端在达成 precondition 时主动通知本端（触发 UPDATE） |
| precondition 类型 | QoS 类前置条件 | 默认 `qos`（IANA 注册，见 RFC 4032） | 区分资源类与其他类前置条件 |

### 初始 offer（INVITE）中的 SDP 片段

```text
m=audio 50000 RTP/AVP 100 101
a=rtpmap:100 EVS/16000
a=fmtp:100 br=5.9-24.4; bw=nb-wb; dt=0; header=full
a=rtpmap:101 telephone-event/8000
a=sendrecv
a=ptime:20
a=maxptime:240
b=AS:88
a=curr:qos local none
a=curr:qos remote none
a=des:qos mandatory local sendrecv
a=des:qos mandatory remote sendrecv
a=conf:qos remote sendrecv
```

主叫在 offer 中把 local/remote 的 curr 都置 none，desired 都设为 **mandatory sendrecv**，并通过 `a=conf:qos remote sendrecv` 请求"被叫一旦完成资源预留，立即通知我"——这正是触发被叫回送 UPDATE/200OK 的钩子。

### precondition 状态机（决定何时可振铃/应答）

```mermaid
flowchart TD
    S0[Offer/Answer交换完成<br/>curr local=none, remote=none] --> S1{各端并行预留专用承载}
    S1 --> S2[主叫侧承载建立<br/>curr local=sendrecv]
    S1 --> S3[被叫侧承载建立<br/>curr remote=sendrecv]
    S2 -->|UPDATE 携带 curr local=sendrecv| S4{curr≥des 全部满足?}
    S3 -->|200 OK UPDATE 携带 curr remote=sendrecv| S4
    S4 -- 否 --> S5[保持等待, 不振铃<br/>超时则失败]
    S4 -- 是 --> S6[前置条件达成<br/>允许 180 Ringing]
    S6 --> S7[被叫摘机 → 200 OK → ACK → 媒体流通]
```

判定规则可形式化为：**当且仅当对所有方向（local+remote）、所有流，`curr` 的状态集合 ⊇ `des` 要求的集合，且 mandatory 项全部达成，前置条件视为"满足"**。`optional` 强度的项即使未达成也允许放行。

---

## 四、与 5G 专用 QoS Flow 的 Rx/N7 联动

precondition 不是 SIP 层自说自话——它的 `curr` 状态由**真实存在的专用承载**支撑。在 VoNR 中，这个"真实资源"就是 5G 的 5QI=1 专用 QoS Flow，由 P-CSCF 通过 Rx 接口（TS 29.214）向 PCF 触发。

```mermaid
sequenceDiagram
    autonumber
    participant UE as UE
    participant PCSCF as P-CSCF
    participant PCF as PCF (Npcf)
    participant SMF as SMF
    participant UPF as UPF
    participant NB as gNB

    UE->>PCSCF: SIP INVITE (SDP含媒体描述+QoS需求)
    PCSCF->>PCF: Diameter AAR (Rx)<br/>Media-Component/Flow-Description/<br/>Media-Sub-Component, 5QI=1, MBR/GBR
    PCF->>SMF: 安装/更新PCC规则 (Npcf_SMPolicyControl, N7)
    SMF->>UPF: N4 会话修改 (安装包检测/QoS执行规则)
    SMF->>NB: PDU Session Resource Setup (N2)
    NB->>UE: RRC Reconfiguration + NAS QoS规则分配
    NB-->>SMF: PDU Session Resource Setup Response
    SMF-->>PCF: 承载建立结果
    PCF-->>PCSCF: RAR 通知资源已预留 (Rx)
    Note over PCSCF,UE: curr local/remote 可置 sendrecv<br/>→驱动 UPDATE 完成 precondition
```

关键 IE 与参数：

- **Rx AAR（AA-Request）**：P-CSCF 向 PCF 上报媒体组件描述，包含 `AF-Application-Identifier`（IMS 语音）、`Media-Type`（audio）、`Flow-Description`（IP 5 元组：源/目 IP、端口、协议 UDP）、`Codec-Data`（EVS）、`Requested-QoS`（5QI=1、上行/下行 MBR 与 GBR）。
- **PCC 规则下发**：PCF 决策后通过 N7 将 PCC 规则下发给 SMF，SMF 生成对应的 QoS Flow（QFI、ARP、GBR 参数）。
- **空口接纳**：SMF 经 N2 要求 gNB 建立 PDU Session Resource；gNB 执行**接纳控制**，若空口资源不足则**拒绝**——这一拒绝会沿 N7→Rx 上报回 P-CSCF，导致 `curr` 永远无法置位，precondition 无法满足，呼叫**干净失败**而非带病接通。

这就是 precondition 设计的根本收益：**让"资源不足"在振铃前暴露，而不是在通话中暴露**。

---

## 五、抓包识别与实战排错

### 抓包识别要点

| 关注点 | Wireshark 过滤/方法 | 判读依据 |
|---|---|---|
| INVITE 与状态码 | `sip.Method == "INVITE"`、`sip.Status-Code == 183` | 183 携带 SDP answer，100 Trying 不携带 |
| 编解码协商 | 展开 SDP `m=audio`、`a=rtpmap`、`a=fmtp` | 确认 EVS payload type 与能力集是否匹配 |
| precondition | 在 SDP 中搜 `curr:qos`/`des:qos`/`conf:qos` | mandatory + local/remote sendrecv 即 VoNR 标准画像 |
| 路由信息 | 查看 `Route`、`Via`、`Record-Route` 头 | 校验 P-CSCF/S-CSCF/I-CSCF 寻址是否符合注册期 Service-Route |
| 承载联动 | 抓 NGAP `PDU Session Resource Setup`、N4、或 Diameter AAR/RAR | 确认专用 QoS Flow 是否成功建立 |
| RTCP/AVPF | `sdp.media`、`a=tcap`/`a=pcfg`（SDP 能力协商 RFC 5939） | MTSI 使用 RTP/AVPF 做 RTCP 反馈 |

### 常见故障点与排错思路

1. **488 Not Acceptable Here**：编解码不匹配。主叫未 offer EVS、或 fmtp 能力集与被叫实现不兼容。检查 UE 是否声明 EVS（TS 26.441/26.445），以及是否误用 AMR-NB。
2. **183 后无 UPDATE、长时间无 180**：precondition 卡住。优先怀疑专用承载未建立——核查 PCF 是否收到 AAR、SMF 是否下发 QoS Flow、gNB 是否接纳（常见于**空口拥塞导致 GBR 接纳失败**）。
3. **180 先于 precondition 满足到达**：实现违反 IR.92/IR.93，precondition 未设为 mandatory。表现为起呼前几百毫秒单向/断续。
4. **UPDATE 超时（408）**：某一侧资源预留始终不完成。需定位是主叫侧（UE-A/PCF-A/SMF-A）还是被叫侧，结合 Rx 与 N2 信令交叉比对。
5. **分叉（Forking）乱序**：S-CSCF 将 INVITE 分叉到多个 UE，产生多个 183。需按 `Call-ID`+`From tag`+`To tag`（Dialog 标识）正确关联，避免 SDP answer 错配。
## 六、VoNR 与 VoLTE / 有无 precondition 对比

| 维度 | VoNR（5G IMS） | VoLTE（EPS IMS） | 无 precondition（best-effort） |
|---|---|---|---|
| IMS 信令规范 | TS 23.228 + TS 24.229（**相同**） | TS 23.228 + TS 24.229 | TS 23.228（可选） |
| 承载建立 | 5G QoS Flow, 5QI=1, PCF→SMF→UPF (Rx→N7/N4) | EPS 专用承载, QCI=1, PCRF→PGW (Rx→Gx) | 走默认 best-effort 承载 |
| 资源保障 | GBR，PDB 100ms | GBR，PDB 100ms | 无 GBR 保证 |
| 振铃门控 | 强制 mandatory precondition（IR.93） | 强制（IR.92） | 无门控，可能先振铃后建路 |
| 起呼体验 | 起呼即双向清晰 | 起呼即双向清晰 | 易出现"喂喂听不见" |

---

## 七、常见问题

**Q1：VoNR 和 VoLTE 在 IMS 信令上到底有什么区别？**
A：几乎无区别。两者都用 TS 23.228 的会话建立流程和 TS 24.229 的 SIP/SDP 规则，编解码都用 EVS。区别在承载：VoNR 用 5G 专用 QoS Flow（5QI=1）经 PCF/SMF/UPF，VoLTE 用 EPS 专用承载经 PCRF/PGW；媒体一个走 NR 空口，一个走 LTE 空口。

**Q2：183 为什么一定要 PRACK？**
A：183 携带 SDP answer，是后续资源预留与 precondition 协商的关键依据。若不可靠传送，183 丢失将使整个流程停滞。RFC 3262 的 100rel 机制（`Require: 100rel`）强制对端用 PRACK 确认，保证关键临时响应可靠到达。

**Q3：为什么用 UPDATE 而不是 re-INVITE？**
A：precondition 的状态更新发生在初始 INVITE **尚未被 200 OK/ACK 确认**之前。re-INVITE 只能在已建立的 dialog 中使用，此时根本不可用。RFC 3311 的 UPDATE 是早期会话内修改参数的唯一合法手段。

**Q4：空口无法接纳 GBR 承载时会怎样？**
A：gNB 接纳控制拒绝该 QoS Flow，经 SMF→PCF→Rx 上报至 P-CSCF，导致 `curr` 无法置位、precondition 无法满足，呼叫**干净失败**（如超时或 503），而非带病接通。这正是 precondition 的价值——把"资源不足"暴露在振铃之前。

**Q5：mandatory 和 optional precondition 的区别？**
A：mandatory（强制）：在 QoS 未预留前，被叫**不得**振铃、主叫**不得**应答，是 VoLTE/VoNR 默认配置；optional（可选）：尽力而为，呼叫照常推进，资源未就绪也不阻断。两者可混合使用，但对语音默认用 mandatory。

---

## 参考来源

1. [3GPP TS 23.228 — IP Multimedia Subsystem (IMS) Stage 2](https://www.3gpp.org/dynareport/23228.htm) — §5.2.2.1 移动主叫会话建立流程
2. [3GPP TS 24.229 — IP multimedia call control protocol based on SIP and SDP](https://www.3gpp.org/dynareport/24229.htm) — SIP/SDP 过程与 precondition 处理
3. [3GPP TS 26.114 — MTSI client specification](https://portal.3gpp.org/desktopmodules/Specifications/SpecificationDetails.aspx?specificationId=1404) — 媒体处理与 SDP precondition 强制要求
4. [RFC 3312 — Integration of Resource Management and SIP](https://www.rfc-editor.org/info/rfc3312/) — precondition 框架与 curr/des/conf 属性定义
5. [RFC 3262 — Reliability of Provisional Responses](https://www.rfc-editor.org/info/rfc3262/) — PRACK/100rel 机制
6. [RFC 3311 — The Session Initiation Protocol UPDATE Method](https://www.rfc-editor.org/info/rfc3311/) — UPDATE 方法定义
7. [3GPP TS 29.214 — Policy and Charging Control over Rx reference point](https://www.3gpp.org/dynareport/29214.htm) — P-CSCF↔PCF 的 AAR/RAR
8. [ShareTechnote — IMS SIP Precondition](https://www.sharetechnote.com/html/IMS_SIP_Precondition.html) — precondition 机制与信令示例图解
9. [TelecomTutorial — VoLTE SIP Call Flow MO & MT](https://www.telecomtutorial.info/post/volte-sip-call-flow-mobile-originating-mo-terminating-mt) — MO/MT 完整流程与 Route 头解析

---
> 本文由「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)
