在 SIP(RFC 3261)的原始设计中,1xx 类临时响应(如 100 Trying、180 Ringing、183 Session Progress)是不可靠传输的——发送方不保证对方收到,对方也不需要确认。这在普通 VoIP 场景下可以接受,但在 3GPP IMS / VoNR 语音业务中会引发严重问题:
180 Ringing 一旦丢包,主叫 UI 不会显示"正在响铃",用户体验断裂;183 携带的 SDP 中,一旦 183 丢失,主叫将无法启动专用承载建立,会话死锁;RFC 3312 定义的 precondition 机制要求双方在 curr:qos / des:qos 状态变化时互相通知,这些通知必须可靠送达。为此,RFC 3262 引入了 100rel(Reliability of Provisional Responses)扩展,把指定的临时响应升级为"必须被确认"的可靠消息,并用一个新的 SIP 方法 PRACK(Provisional ACKnowledgement)来完成确认。3GPP 在 TS 24.229(IP multimedia call control protocol based on SIP/SDP; Stage 3)和 GSMA IR.92/IR.94(VoLTE/ViLTE profile)中强制要求 IMS UE 必须支持 precondition 与 100rel 这两个 option tag。
本文聚焦被叫侧(Terminating)的会话建立链路,拆解从 INVITE 抵达到 200 OK(INVITE) 期间,100rel/PRACK 如何与 precondition 状态机、以及 5GC 专用 QoS flow 建立进行时序耦合。本文不重复已覆盖的"主叫预条件与资源预留"主题,而是从被叫视角切入这个机制。
下图是被叫侧(MT UE)视角的完整信令流,覆盖 SIP 对话与 5GC 专用 QoS flow 建立的联动。注意 183 与 180 都携带 Require: 100rel,因此每一条都必须有对应的 PRACK 确认。
sequenceDiagram
autonumber
participant MO as 主叫UE (MO)
participant PCF as PCF (Policy)
participant SCSCF as S-CSCF (被叫归属)
participant PCCSCF as 被叫P-CSCF
participant MT as 被叫UE (MT)
participant SMF as SMF/gNB
Note over MO,SMF: 阶段一:会话建立与媒体协商(临时响应可靠化)
MO->>SCSCF: INVITE (SDP offer, Require:precondition, Supported:100rel)
Note right of MO: a=curr:qos local none<br/>a=curr:qos remote none<br/>a=des:qos mandatory local sendrecv<br/>a=des:qos mandatory remote sendrecv
SCSCF->>PCCSCF: INVITE (转发,查询iFC触发被叫业务)
PCCSCF->>MT: INVITE (Gm接口)
MT-->>PCCSCF: 100 Trying
MT->>PCCSCF: 183 Session Progress (SDP answer, Require:100rel, Require:precondition, RSeq:1)
Note over PCCSCF,SMF: 阶段二:被叫侧专用QoS flow建立触发
PCCSCF->>PCF: N5 PolicyAuth Create (媒体组件=audio,5QI=1授权)
PCF->>SMF: AM Policy/SM Policy Update (QoS决策)
SMF->>MT: N2/N4 建立专用QoS flow (5QI=1语音)
Note right of MT: 本端专用承载建立完成<br/>local precondition 即将满足
Note over MO,MT: 阶段三:可靠性握手(100rel)
PCCSCF->>MO: 183 Session Progress (透传)
MO->>PCCSCF: PRACK (RAck:1 CSeq) 确认收到183
PCCSCF->>MT: PRACK
MT-->>PCCSCF: 200 OK (for PRACK)
Note over MO,MT: 阶段四:precondition收敛(MO发UPDATE确认双方就绪)
MO->>PCCSCF: UPDATE (a=curr:qos local sendrecv 主叫资源就绪)
PCCSCF->>MT: UPDATE
Note right of MT: MT本端资源也已就绪<br/>双方local均sendrecv
MT-->>PCCSCF: 200 OK (UPDATE)<br/>a=curr:qos local sendrecv<br/>a=curr:qos remote sendrecv
PCCSCF->>MO: 200 OK (UPDATE)
Note over MO,MT: 阶段五:振铃(可靠)与摘机
MT->>PCCSCF: 180 Ringing (Require:100rel, RSeq:2)
PCCSCF->>MO: 180 Ringing
MO->>PCCSCF: PRACK (RAck:2 CSeq)
PCCSCF->>MT: PRACK
MT-->>PCCSCF: 200 OK (for PRACK)
MT->>PCCSCF: 200 OK (INVITE) 摘机
PCCSCF->>MO: 200 OK (INVITE)
MO->>PCCSCF: ACK (三次握手完成,媒体面打通)
100rel 的本质是为临时响应建立一套与 INVITE/200/ACK 三次握手类似的确认机制,只是套在 1xx 上。
可靠性靠两个新增的 SIP header 实现:
RAck: <RSeq值> <CSeq值> <Method>,与被确认的临时响应严格对应。被叫只有收到携带正确 RAck 的 PRACK,才会停止重传该临时响应(RFC 3262 规定重传间隔按 T1=500ms 起步、指数退避,直到 64×T1≈32s)。
flowchart TD
A["被叫发出 183<br/>RSeq:1<br/>Require:100rel"] --> B{主叫是否回PRACK<br/>RAck:1 CSeq?}
B -- "未收到(超时T1=500ms)" --> A
B -- "收到正确RAck" --> C["停止重传183<br/>该临时响应已可靠送达"]
A -. "携带SDP时<br/>PRACK可回带SDP answer" .-> D["完成媒体协商"]
C --> E["可继续后续UPDATE/180流程"]
style A fill:#e3f2fd,stroke:#1565c0
style C fill:#c8e6c9,stroke:#2e7d32
理解 100rel 还需区分两个 header 的语义(TS 24.229 §5.1.2A、RFC 3262 §3):
Supported: 100rel ——"我支持可靠临时响应,但不是必须用"。多出现在主叫 INVITE 中,是能力声明。Require: 100rel ——"这条响应必须被 PRACK 确认,否则对话无法继续"。多出现在被叫 183/180 中。被叫在 183 中带 Require: 100rel,意味着这条携带关键 SDP 的响应不收到 PRACK 誓不罢休(按 T1 指数退避重传至超时)。这就是"可靠"二字的全部含义。
可靠临时响应解决的是"消息送达",而 precondition(RFC 3312)解决的是"资源就绪后才允许振铃/摘机"。这是被叫侧会话建立的真正难点。
precondition 用三个 SDP 媒体级属性描述资源状态(RFC 3312 §3,ShareTechnote 抓取原文确认语法):
| 属性 | 含义 | 语法示例 |
|---|---|---|
a=curr:qos |
当前实际达到的 QoS 状态 | a=curr:qos local none |
a=des:qos |
期望达到的 QoS 状态(含强度标签) | a=des:qos mandatory local sendrecv |
a=conf:qos |
确认状态(要求对端确认达到) | a=conf:qos remote sendrecv |
其中:
mandatory(强制,不满足则不进入下一阶段)/ optional / nonenone / send / recv / sendrecv(双向)local(本端)/ remote(对端)从被叫视角,会话经历的 precondition 状态收敛过程如下(注意 local 指本端 MT 自己的资源,remote 指主叫 MO 的资源):
stateDiagram-v2
[*] --> S0: 收到INVITE<br/>curr local/remote=none
S0 --> S1: 本端专用QoS flow(5QI=1)建立<br/>curr local=sendrecv
S1 --> S2: 收到MO的UPDATE<br/>确认对端curr remote=sendrecv
S2 --> S3: 回200 OK(UPDATE)<br/>双方local均满足des:mandatory sendrecv
S3 --> S4: 发180 Ringing(可靠)
S4 --> [*]: 摘机 200 OK(INVITE)
note right of S0
评估条件: curr>=des?
none < send < recv < sendrecv
end note
note right of S3
仅当双方curr都≥des:mandatory
才允许振铃,避免"振铃但无声"
end note
ShareTechnote 原文明确点出 precondition 的设计动机:
"Precondition is used to prevent the call from alerting the far end before the media path is likely to work."
也就是避免"被叫振铃、用户摘机后却无法通话"的尴尬场景。在 IMS 中,SIP 信令、无线承载、IP 策略、媒体资源这四件事并非同步完成。如果没有 precondition,可能出现振铃早于专用承载建立——用户摘机瞬间媒体面还没通,导致前几百毫秒无声或呼叫失败。
precondition 强制把时序钉死:专用 QoS flow 建立完成(curr 满足)→ 才允许 180 振铃 → 才允许摘机。这正是为何 UPDATE 必须在专用承载建立后才发送(ShareTechnote 原文:"UPDATE would be sent out after Dedicated EPS Bearer Setup")。
这是 VoNR 区别于纯 SIP VoIP 的核心——临时响应不只是 SIP 事件,更是 5GC 建承载的触发器。
被叫侧 P-CSCF 收到带 SDP 的 183(或先于 UE 的 INVITE)后,会从 SDP 中提取媒体信息(编解码、IP 五元组、带宽),作为应用功能 AF 向 PCF 发起策略授权请求:
Npcf_PolicyAuthorization 服务,TS 29.514),SBI over HTTP/2;AAR,TS 29.214),VoNR 网络在融合部署时仍可能走 Rx 语义。P-CSCF 在请求中携带媒体组件描述(media-component、flow-description、flow-status=ENABLED、max-requested-bandwidth-dl/ul)。PCF 据此生成 QoS 决策,通过 Npcf_SMPolicyControl(N7)下发给 SMF,SMF 再经 N4(PFCP)控制 UPF、经 N2 通知 gNB,为被叫 UE 建立专用 QoS flow。
VoNR 语音媒体通常采用 5QI=1(conversational voice,GBR,默认 ARP 优先级高):
| 参数 | 典型值 | 来源 |
|---|---|---|
| 5QI | 1(GBR) | TS 23.501 §5.7.4 标准化 5QI |
| ARP Priority Level | 1~3(高优先级,可抢占) | TS 23.501 §5.7.2 |
| GFBR (UL/DL) | AMR-WB 23.85k 约 32~64 kbps | TS 23.501 §5.7.4 |
| Notification Control | 开启(QoS 通知控制) | 触发 5GC 反馈承载状态 |
当被叫 UE 的专用 QoS flow 建立完成,UE 本地感知到 curr:qos local 由 none 跃迁为 sendrecv——这就是上一节状态图中 S0→S1 的触发点。SIP 信令与承载建立在这里完成握手耦合:承载没建好,precondition 不满足,被叫就绝不会振铃。
| 消息 | 方向(MT视角) | 关键 IE | 作用 |
|---|---|---|---|
| INVITE | 收(MO→MT) | Require: precondition、Supported: 100rel、SDP offer(curr:qos none、des:qos mandatory sendrecv) |
声明需要 precondition 与支持可靠响应 |
| 183 | 发(MT→MO) | Require: 100rel、Require: precondition、RSeq: 1、SDP answer |
可靠送达媒体协商结果,要求 PRACK |
| PRACK | 收(MO→MT) | RAck: 1 <CSeq> |
确认 183 已收,停止重传 |
| 200 OK(PRACK) | 发(MT→MO) | (可选 SDP) | 完成 183 的可靠性握手 |
| UPDATE | 收(MO→MT) | curr:qos local sendrecv |
主告知名端资源就绪 |
| 200 OK(UPDATE) | 发(MT→MO) | curr:qos local sendrecv、curr:qos remote sendrecv |
确认双方 precondition 收敛 |
| 180 Ringing | 发(MT→MO) | Require: 100rel、RSeq: 2 |
可靠振铃通知 |
| 200 OK(INVITE) | 发(MT→MO) | final SDP answer | 摘机,会话最终建立 |
| ACK | 收(MO→MT) | — | 三次握手完成,打通 RTP 媒体面 |
flowchart TB
MSG["SIP/2.0 183 Session Progress"]
MSG --> H1["Status-Line: 183"]
MSG --> H2["Via / From / To / Call-ID / CSeq<br/>对话标识(与INVITE一致)"]
MSG --> H3["Require: 100rel<br/>该响应必须被PRACK确认"]
MSG --> H4["Require: precondition<br/>本会话强制QoS预条件"]
MSG --> H5["RSeq: 1<br/>可靠响应序列号(首个)"]
MSG --> H6["P-Asserted-Identity<br/>主叫号码"]
MSG --> H7["Content-Type: application/sdp"]
MSG --> SDP["SDP body"]
SDP --> M1["m=audio <port> RTP/AVP 96 97<br/>媒体行,AMR/EVS payload"]
SDP --> M2["a=rtpmap / a=fmtp<br/>编解码参数"]
SDP --> M3["a=curr:qos local none<br/>a=curr:qos remote none"]
SDP --> M4["a=des:qos mandatory local sendrecv<br/>a=des:qos mandatory remote sendrecv"]
style H3 fill:#fff3e0,stroke:#e65100
style H5 fill:#fff3e0,stroke:#e65100
style M3 fill:#fce4ec,stroke:#880e4f
style M4 fill:#fce4ec,stroke:#880e4f
| 维度 | 不可靠临时响应(原始SIP) | 可靠临时响应(100rel/PRACK) |
|---|---|---|
| 送达保证 | 无,丢失即丢 | 有,按T1指数退避重传至确认 |
| 携带 SDP | 不可靠,丢失导致协商失败 | 可靠,PRACK 可回带 answer |
| 适用场景 | 普通 VoIP、纯状态通知 | IMS/VoNR 媒体协商、precondition |
| 3GPP 要求 | 不满足业务 | TS 24.229 / IR.92 强制 |
| 维度 | 早期协商(183带SDP) | 后期协商(200 OK带SDP) |
|---|---|---|
| 协商时机 | 振铃前 | 摘机后 |
| 资源预留 | 提前启动(与振铃并行) | 滞后(摘机后才建承载) |
| 摘机即通 | ✅ 是 | ❌ 否,有静默 |
| VoNR 采用 | ✅ 推荐 | ❌ 不符合 IR.92 |
用 Wireshark(或 tshark)过滤 sip,关键判据:
Supported: 或 Require: 是否含 precondition、100rel option tag;Require: 100rel 与 RSeq,并解码 SDP 中的 a=curr:qos / a=des:qos;RAck 的值是否等于对应 183 的 RSeq(如 RAck: 1 对应 RSeq: 1);PolicyAuthorization Create,确认专用 QoS flow 是否被授权;| 故障现象 | 根因 | 排查方向 |
|---|---|---|
| 183 重复出现/超时 | 主叫未回 PRACK 或 RAck 不匹配 |
检查 PRACK 的 RAck 是否=183 的 RSeq;确认主叫是否支持 100rel |
| 呼叫卡在 183,不振铃 | precondition 不满足,专用承载未建立 | 查 N5/N7:PCF 是否下发授权?查 N2/N4:5QI=1 专用 flow 是否建成? |
| UPDATE 缺失 | 主叫本地资源未就绪(主叫侧承载失败) | 先确认主叫侧专用承载建立,再检查 UPDATE 是否被发送 |
| 摘机后无声/掉话 | precondition 收敛但媒体面五元体不一致 | 比对 SDP 中 RTP 端口与实际 PFCP 规则、UPF 转发表项 |
| INVITE→183 时延过大(>800ms) | N5 策略授权或 SMF 建承载慢 | 定位 PCF/SMF 处理时延,检查 N7/N4 信令时延分段 |
现网经验:
INVITE→183分段时延超过 800ms 会导致用户投诉率显著上升(CSDN 现网优化案例数据),需重点优化 N5 策略授权与 SMF 专用 flow 建立速度。
Q1:被叫侧的 183 和 180 Ringing 都必须可靠吗?
A:在 IR.92/VoNR 严格 profile 下,携带 SDP 或承载 precondition 状态的临时响应必须可靠(Require: 100rel)。180 Ringing 因为决定主叫 UI 的振铃显示,丢失会导致体验断裂,通常也被配置为可靠。但严格按 RFC 3262,只有携带 RSeq 且被 Require: 100rel 标记的才需要 PRACK。
Q2:PRACK 自己需要被确认吗?会不会无限套娃?
A:不会。PRACK 是一个正常请求,被叫回 200 OK (for PRACK) 作为最终响应,到此结束。RFC 3262 明确规定可靠性握手只覆盖一层临时响应,PRACK 的 200 OK 不再触发新的可靠性机制。
Q3:被叫侧 precondition 的 local 和 remote 到底指谁?
A:从每个端自己的视角看,local 指本端(自己)的资源状态,remote 指对端的资源状态。被叫 MT 的 curr:qos remote sendrecv 表示"主叫 MO 的资源已就绪"。双方各自维护本地视角,通过 UPDATE / 200 OK(UPDATE) 交换 remote 信息达成收敛。
Q4:如果 5G 网络迟迟建不好专用 QoS flow,会发生什么?
A:被叫 curr:qos local 一直停在 none,precondition 永远不满足。此时要么 183 一直重传直至超时(32s 后释放),要么主叫的 UPDATE 拿不到 200 OK 也超时。最终表现为呼叫建立失败,而非"振铃但无声"——这正是 precondition 的保护价值。
Q5:VoNR 与 VoLTE 在这个机制上有什么区别? A:SIP/precondition/100rel 机制完全一致(都基于 TS 24.229 + RFC 3262/3312)。差异仅在承载层:VoNR 用 5GC 的 N5/N7/N4/N2 建 5QI=1 专用 QoS flow,VoLTE 用 EPC 的 Rx/Gx +专用 EPS 承载。P-CSCF 需根据接入域选择走 SBI(N5)还是 Diameter(Rx)。
本文由「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 等场景全覆盖。
