首页 › ims › VoNR会话Precondition信令拆解

5G核心网N2切换NGAP信令全链拆解

(注:以下为今日 ims 子域文章,已避开前序主题)


VoNR主叫会话建立的Precondition机制与资源预留全链拆解

一、为什么VoNR呼叫要"先占资源,再振铃"

在固网VoIP里,INVITE发出、对端摘机、200 OK回来,媒体通就通了——这是一个"乐观"模型。但在移动网络里,这套模型会直接杀死语音质量:如果直到对端摘机才开始申请无线承载(Radio Bearer)和核心网专用QoS流,那么主叫用户在接通瞬间会听到严重的前向截断(clipping),因为承载建立需要数十到上百毫秒,而此时被叫已经开始说话了。

为此,3GPP在IMS(TS 23.228)与MTSI(TS 26.114)中强制引入了一套资源预留前置条件机制(Precondition),其核心契约是:

被叫UE在确认主叫侧已经为本次会话预留好足够的双向QoS资源之前,不得向用户振铃;主叫UE在被叫侧资源就绪之前,不得认为会话已成功建立。

这把"建立承载"从"接通后的事后补救"前置成了"振铃前的前置条件"。VoNR(Voice over NR)与VoLTE在SIP/IMS层面共用同一套Precondition框架(RFC 3312 + RFC 4032 + RFC 3311 UPDATE + RFC 3262 100rel),差异只在于底层承载从EPC的专有承载变成了5GC的专用QoS Flow(5QI=1)。本文聚焦3GPP R18 TS 23.228 §5.3.2.2a(发起方)/§5.3.1.2a(终结方)所定义的、带Precondition的完整主叫会话建立流程,逐信令拆解。

二、Precondition框架:写在SDP里的"资源契约"

RFC 3312定义了一套用SDP属性描述资源状态的语法,3GPP在TS 24.229 §6.1.3与TS 26.114里对其做了约束(限定为qos类型、mandatory强度、必须sendrecv)。三个关键属性构成契约的三要素:

SDP属性 含义 典型取值
a=des:qos 期望状态(Desired)——本方要求最终达到的资源水平 local/remote × mandatory × send/recv/sendrecv
a=cur:qos 当前状态(Current)——此刻资源实际是否就绪 none 或 sendrecv(已预留)
a=conf:qos 确认请求(Confirmation)——请求对端在其remote侧就绪时通知我 remote sendrecv

其中local指"我到我的接入网关这段",remote指"对方到对方接入网关这段"。一次完整的VoNR呼叫,a=des基本恒为local mandatory sendrecv + remote mandatory sendrecv;变化的只是a=cur——它从none一步步演进到sendrecv。会话能否振铃,取决于双方cur是否都已满足des。

这就引出了Precondition机制最精妙的设计——会话需要两次SDP Offer/Answer交换:第一次协商编解码与QoS能力(约定des),第二次确认资源真的预留成功(更新cur)。

三、完整信令时序图

sequenceDiagram
    autonumber
    participant UEa as 主叫UE
    participant PCSCFa as P-CSCF(主叫)
    participant SCSCF as S-CSCF
    participant ICSCF as I-CSCF
    participant PCSCFb as P-CSCF(被叫)
    participant UEb as 被叫UE
    participant PCF as PCF(Rx)
    participant SMF as SMF(N4)

    Note over UEa,SMF: 第一阶段:SDP能力协商(约定 des 契约)
    UEa->>PCSCFa: INVITE (SDP Offer#1)<br/>a=des:qos local/remote mandatory sendrecv<br/>a=cur:qos local none
    PCSCFa->>PCF: Rx:AAR/授权(QoS=5QI1, GBR)
    PCF->>SMF: Npcf_SMPolicyControl_Update
    SMF->>PCSCFa: (专载建立中,并行)
    PCSCFa->>SCSCF: INVITE (转发)
    SCSCF->>ICSCF: INVITE
    ICSCF->>PCSCFb: INVITE
    PCSCFb->>UEb: INVITE

    Note over UEa,UEb: 第二阶段:被叫回送183(第一次Answer)
    UEb->>PCSCFb: 183 Session Progress (SDP Answer#1)<br/>Require:100rel, RSeq<br/>a=des:qos local/remote mandatory sendrecv<br/>a=cur:qos local none
    PCSCFb->>PCF: Rx:AAR(触发被叫专载)
    Note over UEb: 被叫UE本地资源预留完成
    PCSCFb->>UEb: (专载建立回调)
    Note over UEa: 主叫UE本地资源预留完成
    UEa->>PCSCFa: PRACK (确认183可靠传输)

    Note over UEa,UEb: 第三阶段:资源预留确认(第二次O/A,用UPDATE)
    UEa->>PCSCFa: UPDATE (SDP Offer#2)<br/>a=cur:qos local sendrecv<br/>a=conf:qos remote sendrecv
    PCSCFa->>PCSCFb: UPDATE (转发)
    PCSCFb->>UEb: UPDATE
    UEb->>PCSCFb: 200 OK(UPDATE) (SDP Answer#2)<br/>a=cur:qos local/remote sendrecv
    PCSCFb->>PCSCFa: 200 OK(UPDATE)
    PCSCFa->>UEa: 200 OK(UPDATE)

    Note over UEa,UEb: 第四阶段:振铃→应答→确认
    UEb->>UEa: 180 Ringing (双方cur均满足,开始振铃)
    UEb->>UEa: 200 OK (INVITE)
    UEa->>UEb: ACK
    Note over UEa,UEb: 双向RTP语音媒体开始

这张图把"两次SDP交换 + 两段Rx/N4专载建立 + UPDATE确认"全部串起来了。下面逐条拆解每条消息里的关键IE。

四、逐消息IE深度解析

1. INVITE(主叫→P-CSCF,SDP Offer #1)

这是会话的起点,也是契约的"要约"。关键字段:

INVITE sip:[email protected] SIP/2.0
Require: precondition, 100rel
Supported: 100rel, precondition, timer, replaces
P-Preferred-Identity: <sip:[email protected]>
P-Access-Network-Info: 3GPP-5G; utran-cell-id-3gpp=46000...
Content-Type: application/sdp

v=0
o=- 2890844526 2890844526 IN IP6 2001:db8::1
m=audio 5004 RTP/AVP 109 108 96    ← EVS/AMR-WB/AMR-NB编解码列表
a=rtpmap:109 EVS/...
a=fmtp:109 br=13.2; bw=nb-wb;...
a=sendrecv
a=des:qos mandatory local sendrecv   ← 期望:主叫本地必须保证双向
a=des:qos mandatory remote sendrecv  ← 期望:被叫侧也必须保证
a=cur:qos local none                 ← 现状:主叫本地资源尚未预留
a=cur:qos remote none

关键IE解读: - Require: precondition——强制要求对端支持Precondition,否则直接拒绝。这是把"先占资源"变成硬性约束的开关。 - m=audio ... RTP/AVP 109 108 96——Offer的编解码优先级列表。VoNR中通常把EVS(109)放在最前,AMR-WB(108)次之,AMR-NB(96)兜底,体现5G对EVS编解码的偏好(TS 26.441)。 - a=des:qos mandatory local/remote sendrecv——把契约写死:双方都必须为sendrecv方向预留mandatory强度的QoS。 - a=cur:qos local none——明确告诉对端:"我现在还没预留,你别急着振铃。"

设计意图:Offer里同时声明"我要什么(des)"和"我有什么(cur)",让被叫一次性知道目标态和起点态,避免后续误解。

2. 183 Session Progress(被叫→主叫,SDP Answer #1)

被叫UE收到INVITE后,不会立即振铃,而是先回一个带SDP Answer的临时响应:

SIP/2.0 183 Session Progress
Require: 100rel
RSeq: 1001                          ← 100rel可靠传输序列号
Content-Type: application/sdp

m=audio 5006 RTP/AVP 108 96         ← 选定AMR-WB(被叫不支持/未配EVS时的回退)
a=des:qos mandatory local sendrecv
a=des:qos mandatory remote sendrecv
a=cur:qos local none                ← 被叫本地也尚未预留

为什么用183而不是200 OK:因为此时双方cur都还是none,Precondition未满足,会话还不算成功,只能给临时响应。

3. Rx→N4:从SIP信令到专用QoS Flow

这是VoNR区别于纯固网SIP的最关键一段。P-CSCF收到带SDP的INVITE/183后,必须把QoS需求翻译成5GC能理解的PCC规则:

flowchart TD
    A["P-CSCF解析SDP<br/>提取媒体带宽/G.711/EVS比特率"] --> B["Rx:AAR<br/>Npcf_PolicyAuthorization_Create<br/>(Media-Component, 5QI=1, GBR)"]
    B --> C["PCF安装PCC规则<br/>授权GBR带宽"]
    C --> D["Npcf_SMPolicyControl_UpdateNotify"]
    D --> E["SMF发起N4 Session<br/>Modification Request(UPF)"]
    E --> F["SMF→AMF: N1N2MessageTransfer<br/>N2 SM信息(5QI=1, GBR)"]
    F --> G["AMF→gNB: PDU Session<br/>Resource Setup/Modify"]
    G --> H["专用QoS Flow建立<br/>UE↔UPF"]
    H -.回调.-> A

参数映射要点(TS 23.503 §5.2.2、§6.1.3.15): - 媒体类型→5QI:会话语音媒体映射为 5QI=1(GBR,时延预算100ms,丢包率10⁻²);IMS信令本身走5QI=5。 - SDP带宽→GBR:EVS的b=AS:或a=fmtp中的比特率,加上RTP/UDP/IP头开销,换算为上行/下行GBR(典型语音约几十kbps)。 - P-CSCF的Rx授权是异步的:P-CSCF发出AAR后并不阻塞信令,专载建立与后续SIP消息并行进行。这也是为什么UPDATE要等到本地预留完成后才发——它在等专载回调。

4. UPDATE(主叫→被叫,SDP Offer #2)

主叫UE收到183后,开始本地资源预留(与5GC建立专用QoS Flow并行)。一旦本地预留完成,主叫发UPDATE通知被叫:

UPDATE sip:... SIP/2.0
Content-Type: application/sdp

m=audio 5004 RTP/AVP 109           ← m行不变,只动cur
a=cur:qos local sendrecv            ← 本地主叫侧资源已就绪!
a=des:qos mandatory local sendrecv
a=des:qos mandatory remote sendrecv
a=conf:qos remote sendrecv          ← 请求:你那边就绪后务必通知我

为什么是UPDATE而不是re-INVITE:会话此时还处于早期对话(early dialog)阶段——INVITE事务尚未完成(还没收到200 OK),RFC不允许在INVITE事务期间发起re-INVITE。RFC 3311定义的UPDATE正是为"早期对话中重协商SDP"而生,它不影响目标号码,只刷新媒体参数。

5. 200 OK (UPDATE)(被叫→主叫,SDP Answer #2)

被叫收到UPDATE后,如果它本地资源也已预留好(专载已建立),回送:

a=cur:qos local sendrecv
a=cur:qos remote sendrecv            ← 被叫也声明remote(主叫侧)就绪

此刻,双方的des(mandatory sendrecv)与cur在local+remote四个维度全部对齐,Precondition满足。注意:因为被叫在主叫UPDATE里看到了a=conf:qos remote sendrecv,所以即便被叫先于主叫完成预留,它也会通过200 OK(UPDATE)把a=cur remote sendrecv带回去,履行conf契约。

6. 180 Ringing → 200 OK → ACK

Precondition满足后,被叫才振铃(180),用户摘机后回200 OK,主叫回ACK,会话正式进入确认态,RTP双向媒体才开始流动。整个过程的时序保证了接通瞬间承载已就绪,没有前向截断。

五、Precondition状态机

从UE视角看,一次主叫会话的资源状态在四个状态间迁移:

stateDiagram-v2
    [*] --> Idle
    Idle --> OfferSent: 发送INVITE<br/>(des约定, cur=none)
    OfferSent --> Negotiating: 收到183(Answer)<br/>触发本地预留+Rx专载
    Negotiating --> LocalReady: 本地cur=sendrecv<br/>发送UPDATE
    LocalReady --> BothReady: 收到200 OK(UPDATE)<br/>对端cur=sendrecv
    BothReady --> Ringing: Precondition满足<br/>允许振铃
    Ringing --> Confirmed: 200 OK/ACK
    Confirmed --> [*]
    Negotiating --> Failed: 专载建立失败/超时<br/>a=cur无法达sendrecv
    Failed --> [*]: 拆除会话

六、Precondition与其他方案对比

维度 带Precondition(VoNR/VoLTE标准) 不带Precondition(固网VoIP) 不带Precondition+事后建承载
振铃时机 双向资源就绪后 收到INVITE即可 收到INVITE即可
接通时前向截断 无 无(但QoS无保证) 严重(承载滞后)
信令开销 大(两次O/A+UPDATE+PRACK) 小 小
呼叫建立时延 略高(多了专载等待) 低 低但质量差
适用场景 移动网(无线资源受限、需GBR保证) 有QoS保证的固网 不推荐

七、抓包实战:如何识别这条流程

用Wireshark/TShark(配合pcap-analyzer技能)抓IMS UE的SIP信令,按以下方式定位:

  1. 过滤INVITE及其响应链:sip.Method == "INVITE" or sip.CSeq.method == "INVITE",展开SDP,确认是否存在a=des:qos与a=cur:qos。
  2. 确认100rel启用:在183里查找Require: 100rel和RSeq头;若缺失,说明对端不支持可靠临时响应,会导致SDP Answer丢失风险。
  3. 追踪UPDATE:sip.Method == "UPDATE",检查其SDP中a=cur:qos local是否从none变为sendrecv——这是资源预留成功的判据。
  4. 关联N4:在SIP INVITE与183之间,应能在UPF侧看到PFCP Session Modification Request,其中Create QER/Create FAR携带5QI=1、GBR速率。若SIP信令走完了但N4无对应修改,专载未建,呼叫必失败。
  5. 时间戳核对:180 Ringing必须晚于最后一个200 OK(UPDATE)。若180早于UPDATE完成,属异常。

常见故障点与排错:

现象 根因 排查方向
INVITE后无183,直接488/Not Acceptable 编解码协商失败(如主叫只给EVS,被叫不支持且未回退) 核对m行与a=rtpmap/fmtp;检查EVS能力集
183后无UPDATE,呼叫挂死 专载建立失败或本地资源预留超时 查Rx AAR是否被PCF拒;查N4/N2是否成功;UE是否上报QoS Flow失败
UPDATE发出后无200 OK(UPDATE) 被叫侧资源预留卡住 查被叫P-CSCF的Rx授权与被叫专载状态
183收到但主叫不回PRACK 100rel未启用或RSeq异常 检查183的Require:100rel与RSeq合法性
摘机后语音单通/质差 5QI=1误配为非GBR,或GBR带宽不足 核对PCC规则中5QI与GBR值
## 常见问题

Q1:为什么VoNR需要两次SDP Offer/Answer交换,而普通SIP呼叫只需一次? A:因为Precondition把"资源是否就绪"作为会话成立的条件,而资源预留是INVITE之后才发生的。第一次O/A(INVITE/183)用于约定"期望什么(des)"和"选定编解码",第二次O/A(UPDATE/200 OK)用于确认"资源真的预留好了(cur=sendrecv)"。一次O/A无法同时表达"约定目标"和"确认达成"两个时点。

Q2:UPDATE和re-INVITE有什么区别?为什么这里只能用UPDATE? A:re-INVITE用于已建立(confirmed)对话的会话重协商;UPDATE(RFC 3311)专用于早期对话(early dialog),即INVITE已发但尚未收到200 OK期间。Precondition确认发生在摘机之前,会话还在早期对话态,此时发re-INVITE是非法的,只能用UPDATE。

Q3:如果专载建立失败,会话会怎样? A:受影响UE的a=cur无法达到sendrecv,Precondition不满足。按TS 23.228,UE会在定时器超时后发送CANCEL或BYE释放会话,用户表现为"无法接通"。这是Precondition机制保护质量的体现——宁可不接通,也不建立质量无法保证的通话。

Q4:183为什么必须用PRACK可靠确认? A:183携带SDP Answer,是会话能力协商的结论,丢包会导致主叫无法继续资源预留。RFC 3262的100rel机制通过RSeq+PRACK保证这条临时响应可靠送达。

参考来源

  1. 3GPP TS 23.228 V18.x — IP Multimedia Subsystem (IMS) — §5.3.1.2a/§5.3.2.2a 发起与终结会话的Precondition流程
  2. 3GPP TS 24.229 V18.8.0 — IMS CC — §6.1.3 SDP处理、§L.3.1.4 终结UE Precondition处理
  3. RFC 3312 — Integration of Resource Management and SIP — Precondition框架(des/cur/conf)
  4. RFC 3311 — The SIP UPDATE Method — 早期对话SDP重协商
  5. ShareTechnote — IMS Precondition — Precondition机制图解与消息示例

本文由「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学通信知识星球海报-扫码加入