在 VoLTE/VoNR 网络里,当你拨出一个电话、收到一条 RCS 消息、或者被叫号码是空号触发呼叫转移时,真正"决定这个 SIP 请求要不要送给某个应用服务器(AS)去执行业务逻辑"的,既不是 UE,也不是某个写死的路由表,而是一份驻留在 HSS 里、按用户维度开通的小小的 XML 规则集——iFC(Initial Filter Criteria,初始过滤准则)。
iFC 的本质是一组条件表达式:当某个 SIP 初始请求到达 S-CSCF 时,S-CSCF 把请求的各个字段(方法名、会话方向、SIP 头、SDP 内容等)代入这组表达式,命中则按优先级顺序把请求逐个转发到对应的 AS,AS 处理(可能改写、可能拦截、可能放行)后再回到 S-CSCF 继续走下一条规则。这套机制定义在 3GPP TS 23.218《IP Multimedia (IM) Session Handling; IM Call Model》,其 XML 编码与 Cx 下发定义在 TS 29.228,S-CSCF 的具体 SIP 行为在 TS 24.229,ISC 接口规范是 TS 29.165。
设计它的核心意图有三点,理解了这三点就理解了整个机制的"为什么":
iFC 是用户 Service Profile(业务配置) 的一部分,常驻 HSS。它在 IMS 注册阶段被下载到 S-CSCF,这是理解整个机制的前置条件。
sequenceDiagram
autonumber
participant UE
participant P_CSCF as P-CSCF
participant I_CSCF as I-CSCF
participant HSS
participant S_CSCF as S-CSCF
UE->>P_CSCF: REGISTER
P_CSCF->>I_CSCF: REGISTER
I_CSCF->>HSS: UAR (User-Authorization-Request)
HSS-->>I_CSCF: UAA (能力向量, 推荐 S-CSCF)
I_CSCF->>S_CSCF: REGISTER (选定 S-CSCF)
S_CSCF->>HSS: MAR (Multimedia-Auth-Request, 取鉴权向量)
HSS-->>S_CSCF: MAA
Note over S_CSCF: 鉴权通过后, S-CSCF 请求业务配置
S_CSCF->>HSS: SAR (Server-Assignment-Request, SERVER_NAME)
HSS-->>S_CSCF: SAA (User-Data AVP 内含 3GPP-IMS-Data, 含 iFC XML)
Note over S_CSCF: 缓存 iFC, 标记用户 Registered
S_CSCF-->>I_CSCF: 200 OK
I_CSCF-->>P_CSCF: 200 OK (Service-Route)
P_CSCF-->>UE: 200 OK
关键在于 SAR(Server-Assignment-Request)/ SAA(Server-Assignment-Answer) 这对 Diameter 命令(TS 29.229)。SAA 的 User-Data AVP 中承载 3GPP-IMS-Data,其 XML 结构(TS 29.228 定义)大致为:
<IMSSubscription>
<PrivateID> ... </PrivateID>
<ServiceProfile>
<PublicIdentity> ... </PublicIdentity> <!-- 可多个 -->
<InitialFilterCriteria> ... </InitialFilterCriteria> <!-- 可多个 iFC -->
<CoreNetworkServiceAuthorization> ... </CoreNetworkServiceAuthorization>
</ServiceProfile>
</IMSSubscription>
TS 23.218 §5.2.3 明确规定:S-CSCF 应向 HSS 请求适用于该用户的相关 iFC 集合(已注册、未注册,或两者);如果 S-CSCF 已持有一份"仍有效"的 iFC(例如来自上一次请求),则不必重新请求。这正是 S-CSCF 在每次呼叫时不必查 HSS、直接用本地缓存 iFC 评估的依据——这是 IMS 性能设计的关键一环。当 HSS 侧 iFC 发生变更,会通过 PPR(Push-Profile-Request) 主动推送给 S-CSCF 更新缓存。
一条 iFC 的 XML 骨架如下,理解这张图就理解了"规则怎么写":
graph TD
IFC["InitialFilterCriteria"] --> P["Priority <越小越优先>"]
IFC --> TP["TriggerPoint 触发点"]
IFC --> AS["ApplicationServer 目标AS"]
IFC --> PP["ProfilePartIndicator<br/>0=HPLMN 1=VPLMN"]
TP --> CNF["ConditionTypeCNF<br/>true=合取范式 false=析取范式"]
TP --> SPT["SPT / Group (1..N)"]
SPT --> NEG["ConditionNegated 取反"]
SPT --> M["Method SIP方法"]
SPT --> SC["SessionCase 会话方向"]
SPT --> RURI["RequestURI"]
SPT --> RT["RegistrationType"]
SPT --> SH["SIPHeader (Header/Content)"]
SPT --> SD["SessionDescription SDP行"]
AS --> SN["ServerName AS的SIP URI"]
AS --> DH["DefaultHandling 默认处理"]
AS --> SI["ServiceInfo 透传给AS"]
AS --> IRR["IncludeRegisterRequest/Response"]
| 元素 | 作用 | 典型取值 / 说明 |
|---|---|---|
Priority |
多条 iFC 之间的执行先后 | 整数,值越小优先级越高;S-CSCF 按升序逐条评估 |
TriggerPoint |
触发条件,由 SPT 的布尔表达式构成 | 可为空(即"无条件触发",常用于全量业务 AS) |
ConditionTypeCNF |
表达式形态 | true=CNF(组间 AND、组内 OR);false=DNF(组间 OR、组内 AND) |
ServicePointTrigger (SPT) |
单个匹配条件 | 方法/方向/头/SDP/注册类型/Request-URI |
ConditionNegated |
该 SPT 取反 | 布尔,构造"不等于/不存在"类条件 |
ApplicationServer/ServerName |
命中后转发的 AS | 形如 sip:as1.ims.mnc<MNC>.mcc<MCC>.3gppnetwork.org |
DefaultHandling |
AS 不可达时的兜底 | 0=Session Continued(继续后续 iFC);1=Session Terminated(终止会话) |
ProfilePartIndicator |
归属/拜访区分 | 0=HPLMN 专用、1=VPLMN 专用(漫游场景下区分归属网/拜访网业务) |
IncludeRegisterRequest/Response |
是否把 REGISTER 请求/响应转发给 AS | 用于需要感知注册事件的 AS |
SessionCase 取值(TS 29.228)| 取值 | 含义 | 典型用途 |
|---|---|---|
0 |
Originating(主叫,已注册) | 主叫补充业务:号码显示控制、缩位拨号、限呼 |
1 |
Terminating Registered(被叫,已注册) | 被叫彩铃、防骚扰、视频彩铃 |
2 |
Terminating Unregistered(被叫,未注册) | 呼叫前转 CFU、语音信箱(用户离线时仍触发 AS) |
3 |
Originating Unregistered(主叫,未注册) | 特殊紧急/匿名主叫业务 |
4 |
Originating CDIV(呼叫转移后的主叫段) | 前转链路中作为"新主叫"的二次触发,避免循环/重复计费 |
实战要点:
SessionCase=2(被叫未注册)是设计前转、语音信箱的关键。当被叫 UE 未注册或不可达,I-CSCF/LIR 仍能定位到为该用户服务的 S-CSCF(HSS 记录了上次注册的 S-CSCF 名),S-CSCF 用"未注册 iFC"把 INVITE 送到 CFU/语音邮箱 AS——这就是"关机也能前转"的协议基础。
RegistrationType(0=初始注册、1=重注册、2=去注册)则让 AS 能在用户上线/下线时被触发,配合 IncludeRegisterRequest/Response 实现注册事件类业务。
理解 iFC 必须理解 S-CSCF 收到一个 SIP 请求后逐条评估的过程。注意一个常被忽略的铁律:iFC 只对"初始请求"(initial request,即建立对话框或处于对话之外的第一个请求)生效;对话内的后续请求(re-INVITE、BYE、PRACK、UPDATE)不再重新评估 iFC,而是沿对话框建立时确定的 Route 集转发。这是为了性能与一致性——业务逻辑在会话建立时已"凝固"进路由。
stateDiagram-v2
[*] --> Recv: 收到初始请求(INVITE等)
Recv --> DecideUser: 确定 served user<br/>主叫=P-Asserted-Identity<br/>被叫=Request-URI
DecideUser --> DecideCase: 判定 SessionCase(0~4)
DecideCase --> Sort: 按Priority升序取iFC集
Sort --> PickNext
PickNext --> EvalTP: 评估当前iFC的TriggerPoint(SPT布尔式)
EvalTP --> ToAS: TP命中=true → ISC转发到AS
EvalTP --> PickNext: TP=false → 下一条iFC
ToAS --> ASBack: AS返回请求(可能改写)
ASBack --> PickNext: 用(可能改写的)请求继续
ToAS --> Unreach: AS不可达/超时
Unreach --> Continue: DefaultHandling=0 继续
Unreach --> Reject: DefaultHandling=1 终止
Continue --> PickNext
PickNext --> Forward: iFC遍历完 → 按路由转发下一跳
Forward --> [*]
Reject --> [*]
这里有几个细节决定了 iFC 行为的正确性:
P-Asserted-Identity(注册时 P-CSCF 校验过)作为 served user;被叫方向,取 Request-URI 的 tel:/sip: URI。判定错了 served user,会用错用户的 iFC 集,这是排错高频点。P-Served-User(RFC 5502),携带 session-case 与 registration-state 参数,让 AS 知道"这是主叫还是被叫、用户是否已注册",避免 AS 再自行猜测。SessionCase=4(Originating CDIV)重新走 iFC,标识"这是前转产生的",防止前转死循环与重复触发计费。下面是一次典型 MO(主叫)呼叫、S-CSCF 命中两条 iFC、依次触发两个 AS(如限呼 AS + SCC-AS)的完整信令流,重点看 ISC 接口两侧的报文与 IE:
sequenceDiagram
autonumber
participant UE
participant P_CSCF as P-CSCF
participant I_CSCF as I-CSCF
participant S_CSCF as S-CSCF
participant AS1 as AS1(限呼)
participant AS2 as AS2(SCC-AS)
participant T as 终呼侧/BGCF/MGCF
UE->>P_CSCF: INVITE(SDP offer)
P_CSCF->>I_CSCF: INVITE(Route: orig)
Note over I_CSCF: 主叫侧可选直接按Service-Route转发到S-CSCF
I_CSCF->>S_CSCF: INVITE
Note over S_CSCF: served user=P-Asserted-Identity<br/>SessionCase=0(Originating)
Note over S_CSCF: iFC#1(Prio=1) TP=(Method=INVITE AND SC=0) 命中
S_CSCF->>AS1: INVITE(ISC, 改Request-URI为AS1,<br/>加 P-Served-User; sc=orig)
AS1-->>S_CSCF: INVITE(放行, Record-Route追加AS1)
Note over S_CSCF: iFC#2(Prio=2) TP命中
S_CSCF->>AS2: INVITE(ISC, 加 P-Served-User)
AS2-->>S_CSCF: INVITE(SCC锚定, 改SDP/URI)
Note over S_CSCF: iFC遍历完, 按最终Request-URI路由
S_CSCF->>T: INVITE(终呼方向)
T-->>S_CSCF: 100 Trying
T-->>S_S: 183 Session Progress
S_CSCF-->>UE: 183(经AS2/AS1/P-CSCF, Via/Record-Route逐跳)
逐消息关键 IE 解析:
Request-URI 被改写为 AS1 的 SIP URI(让 SIP 栈把请求送到 AS1);Via(S-CSCF 自身),保证响应能逐跳返回;P-Served-User: <sip:user@...>;sescase=orig;regstate=reg,告知 AS 主叫且已注册;Route / Record-Route 链,AS1 在 Record-Route 追加自己,确保后续 BYE/200 也经过它。Request-URI/路由信息,进入 iFC#2 评估。Request-URI(可能已被 AS 改写)和 Route 转发到下一跳(对端 I-CSCF / BGCF / MGCF)。Via 与 Record-Route 逐跳返回,AS1/AS2 因此能"看见"整个会话的建立与释放,这是补充业务能感知应答、计费 AS 能精准起计费点的基础。| 设计点 | 机制体现 | 解决了什么问题 |
|---|---|---|
| 只评估初始请求 | iFC 不作用于对话内请求 | 避免每个 re-INVITE/BYE 都重新查 iFC,性能可控;业务逻辑一次凝固 |
| 触发点用布尔表达式 | TriggerPoint + ConditionTypeCNF | 用一套 XML 表达"主叫且方法=INVITE且 SDP 含 video"等复杂条件,无需 S-CSCF 写死 |
| Priority 严格排序 | 整数优先级,升序执行 | 确定业务叠加顺序(如限呼优先于计费,计费优先于锚定) |
| DefaultHandling 兜底 | 0 继续 / 1 终止 | AS 宕机时网络行为可预测,避免业务"静默失效" |
| 区分 Registered/Unregistered iFC | SessionCase + 两套 Service Profile | 关机前转、语音信箱等"用户不在"业务可触发 |
| iFC 缓存 + PPR 推送 | SAR/SAA 下载,PPR 更新 | 会话期零 HSS 查询,又保证规则实时一致 |
| served user 明确化 | P-Asserted-Identity / Request-URI / P-Served-User | 主被叫用对 iFC 集,避免误触发 |
如何抓包确认 iFC 是否触发:
CMD: SAR / SAA,展开 User-Data AVP,Wireshark 可解析出内嵌的 3GPP-IMS-Data XML,直接看到该用户开了几条 iFC、每条 Priority/TriggerPoint/ApplicationServer。这是判断"用户到底配没配业务"的金标准。INVITE,看 Request-URI 是否指向某 AS、是否带 P-Served-User,以及 Via/Record-Route 是否有 S-CSCF 与 AS 的累积。同一呼叫在 S-CSCF 上看到"收到→转发给 AS→AS 回来→再转发"的多段 INVITE,就是 iFC 生效的明证。高频故障点:
Service Profile 未绑定 Public Identity → SAA 里 iFC 为空 → S-CSCF 不触发任何 AS。表现:补充业务全失效,但呼叫能正常接通。DefaultHandling=1 的 iFC,AS 宕机时整通会话直接失败(如全部主叫打不出);需评估该 AS 是否值得"硬依赖",多数场景应配 0。值得强调的是:iFC 机制在 5G VoNR 中原样复用。VoNR 的语音仍由 IMS CN 提供,5GC(AMF/SMF/UPF)只负责建立到 P-CSCF 的 IMS 信令/媒体 PDU 会话(QCI=5/1/2)。业务触发逻辑——主叫/被叫、补充业务、彩铃、防骚扰——依旧由 S-CSCF 评估 iFC、经 ISC 触发 AS 完成。即便 IMS 走向虚拟化(vIMS)乃至未来基于 SBA 的拆分,iFC 这套"用户数据驱动的声明式触发规则"模型因为足够解耦、足够灵活,至今(含 R19)未被颠覆。掌握 iFC,就掌握了 IMS 业务编排的"配方法则"。
Q1:iFC 与 CAMEL 触发(gsmSCF)有什么本质区别? A:CAMEL 是电路域/传统智能网的 DP(检测点)触发机制,依赖 CAP 信令与 SSP,规则固化在 SCP,扩展受限;iFC 是基于 SIP/IMS 的声明式 XML 规则,规则随用户数据下发到 S-CSCF、按 SPT 灵活匹配、业务实现完全在 AS,天然适配 IP 多媒体与互联网式业务叠加。
Q2:为什么对话内的 re-INVITE 不再触发 iFC? A:会话建立时的初始请求已把 Route 集与 Record-Route 链"固化",AS 通过 Record-Route 留在路径上,对话内请求沿该路径转发即可感知;重新评估 iFC 既无必要也会破坏业务一致性并显著增加 S-CSCF 负担。
Q3:一条 iFC 的 TriggerPoint 为空意味着什么? A:意味着"无条件触发",凡该用户所有匹配其(隐式或显式)SessionCase 的初始请求都会转发给对应 AS。常用于全量计费、合规监听类必须感知所有会话的 AS。
Q4:用户关机后还能呼叫前转,iFC 是怎么起作用的?
A:HSS 记录了用户最后注册的 S-CSCF;被叫不可达时 I-CSCF/LIR 仍定位到该 S-CSCF,S-CSCF 用 SessionCase=2(Terminating Unregistered)的 iFC 集,把 INVITE 触发到 CFU/语音邮箱 AS,由 AS 改写目标后重新发起前转。
Q5:iFC 修改后如何让在线的 S-CSCF 生效? A:HSS 通过 PPR(Push-Profile-Request) 主动推送更新后的 User-Data(含新 iFC)给 S-CSCF,S-CSCF 替换缓存。若 PPR 未送达,需触发用户重注册或手动同步。
本文由「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 等场景全覆盖。
