简介:面向IMS计费学习与工程实践者的中文版3GPP TS 32.260规范(V17.3.0),聚焦IP多媒体子系统计费管理,适合从事核心网计费、运营商支撑系统开发及通信标准研究的技术人员,用于理解在线与离线计费架构、计费数据记录与Diameter接口等关键机制。资源包共1个PDF文件,约2.65MB,为规范正文的中文译本,涵盖前言、范围、参考文献、定义符号与缩写、架构注意事项、计费原理等章节,并展开高级IMS架构、离线与在线计费架构及融合计费架构的说明。已有196人学习,可作为对照英文原版精读的辅助材料。读者可从中系统掌握CDR生成、计费触发点、OCS与OFS分工、计费策略规则功能及Gx等接口协议,理清从2G到4G多制式下计费环节的标准脉络,为计费系统设计、联调排错与标准条款查阅提供直接参考。
1. IMS 计费:为什么一通电话的账单,在挂断之前就已经算完了
很多人以为计费是“事后算账”——通话结束,话单落地,后台批价出账。但在 IMS 域里,这个直觉是错的。真正决定一通 VoLTE 电话能不能接通、能打多久、什么时候被强制拆线的,往往不是核心网的信令处理能力,而是计费系统在会话建立那一刻给出的“额度”。3GPP TS 32.260 这份规范,讲的就是这套机制:IMS 计费如何把一次 SIP 会话拆成可计量的信用单位,又如何在离线、在线、融合三种模式下保证同一通电话不被重复计费、也不被漏计。搞懂它,你才能理解为什么一个看似简单的200 OK背后,可能已经完成了一次 Diameter 信用控制交互。这份中文版行标把 17.3.0 版本的架构、触发条件、消息流和错误场景都落到了具体章节,是啃 IMS 计费底层机制时绕不开的原料。
2. 计费架构的分层:离线、在线与融合到底差在哪
2.1 三种架构不是三套系统,而是三种信任模型
规范第 4 章把 IMS 计费架构拆成高级架构、离线计费架构、在线计费架构和融合计费架构四块。表面看是四张图,底层其实是三种信任模型的选择。离线计费假设“先服务、后结算”,网元只管把计费数据记下来,通过 Rf 参考点送到 CDF(计费数据功能),再由 CGF(计费网关功能)落成 CDR。在线计费则假设“先授权、后服务”,网元在会话建立或中期更新时必须先向 OCS 要额度,拿到配额才放行媒体。融合计费是两者的折中:同一个会话可以同时走在线和离线两条路径,但计费标识必须一致,否则对账时会出现两套互不相认的话单。
这里的关键设计动机是:IMS 的业务触发点太多,S-CSCF、AS、IBCF、ATCF 都可能产生计费事件。如果每个网元各自为政,运营商收到的就是一堆无法关联的碎片。规范用 ICID(IMS 计费标识符)把同一会话在不同网元产生的计费数据串起来,这个标识在 SIP 消息里随会话传递,离线侧靠它做 CDR 关联,在线侧靠它做配额归并。常见的实现思路是:S-CSCF 在收到首个 INVITE 时生成 ICID,写入 P-Charging-Vector 头域,后续所有涉及该会话的网元都从这个头域里取,而不是自己重新生成。
2.2 参考点与基于服务接口的并存:Rf 为什么没有退场
规范 5.2.1.1 讲参考点 Rf 的规格,5.2.1.2 讲基于服务的 Nchf 接口。这两者并存不是历史包袱,而是部署形态差异。Rf 是 Diameter 时代的点对点接口,网元配置好 CDF 地址后直接发 ACR(计费请求),适合传统电信机房里的静态组网。Nchf 是 SBA 架构下的服务化接口,走 HTTP/2,支持服务发现和负载均衡,适合云化部署。规范没有强制二选一,而是让网元根据自身支持的接口能力选择路径。
从机制上看,两者的计费语义是对齐的:ACR 里的Service-Information和 Nchf 里的ChargingDataRequest承载的是同一套 IMS 计费信息,包括会话标识、用户标识、媒体成分、时间戳和触发原因。差异在于传输层:Rf 用 Diameter 的 AVP 编码,Nchf 用 JSON/Protobuf 序列化。我一般会这么理解:Rf 是“我知道 CDF 在哪,直接敲门”,Nchf 是“我先问服务注册中心,再按返回的地址发请求”。前者简单但僵化,后者灵活但多一跳发现开销。
提示:规范里 Rf 和 Nchf 的计费信息模型是同一套,迁移时重点核对 AVP 到 JSON 字段的映射,而不是重写业务逻辑。
2.3 融合计费的真正难点:一次会话两条账,怎么保证不打架
融合计费架构(4.4 节)允许同一会话同时产生在线配额消耗和离线 CDR。难点不在“同时记两笔”,而在“两笔账能对上”。规范的做法是让在线和离线共享同一个 ICID 和同一个计费会话标识,并且在在线侧的中期更新里携带已用量,离线侧的 CDR 里也记录对应的时间窗口。这样后台对账时,可以用 ICID 加时间窗口把在线扣费和离线话单匹配起来。
如果实现时偷懒,在线侧用一套会话 ID、离线侧用另一套,对账就会变成血泪经验:同一通电话在线扣了 60 秒,离线话单记了 75 秒,差额找不到出处。规范在 5.1.2.2 和 5.1.2.2A 里专门定义了 IMS 计费标识符和相关 ICID,就是为了堵这个口子。常见的实现思路是:网元在会话建立时只生成一次 ICID,在线和离线两条路径都引用它,任何一侧的中期更新都不重新生成。
3. 计费触发与信用控制:额度是怎么被“要”出来的
3.1 触发条件不是拍脑袋,而是挂在 SIP 状态机上
规范 5.1.4 定义触发条件,5.2.2 展开消息流。IMS 计费的触发点不是独立定时器,而是挂在 SIP 会话状态机的关键迁移上:会话建立(INVITE 到 200 OK)、中期程序(re-INVITE 或 UPDATE)、会话释放(BYE)。在线计费下,这些点对应信用控制请求:建立时申请初始配额,中期时申请增量配额并上报已用量,释放时上报最终用量并退还剩余配额。
为什么挂在 SIP 状态机上?因为计费必须和媒体实际可用性强绑定。如果计费触发和 SIP 信令脱节,就会出现“信令已通、媒体未通却开始扣费”或者“媒体已断、计费还在跑”的翻车场景。规范把触发条件写成“SIP 事务成功完成”而不是“收到某条消息”,就是为了让计费动作跟随会话的真实生命周期。
3.2 在线计费的信用控制循环:一个伪代码看清配额申请
下面这段伪代码按规范 5.2.2.1.1 和 5.2.2.1.3 的语义,模拟 S-CSCF 在在线计费下的信用控制循环。它不是规范原文,而是把消息流里的关键判断抽出来,方便看清“申请—使用—上报—再申请”的闭环。
# 模拟 IMS 在线计费信用控制循环(语义对齐 TS 32.260 5.2.2) def handle_session(sip_session, ocs_client): # 会话建立:申请初始配额,携带 ICID 和请求的单元数 initial_request = build_ccr( session_id=sip_session.icid, subscriber=sip_session.user, requested_units=60, # 请求 60 秒额度 trigger="SESSION_START" ) grant = ocs_client.send(initial_request) if grant.granted_units == 0: # 配额为零:规范要求拒绝会话,不能先放行再补授权 sip_session.reject(reason="INSUFFICIENT_CREDIT") return sip_session.start_media(grant.granted_units) # 中期程序:用量接近阈值时申请增量,同时上报已用量 while sip_session.active: if sip_session.used_units >= grant.threshold: update_request = build_ccr( session_id=sip_session.icid, used_units=sip_session.used_units, requested_units=60, trigger="MID_SESSION" ) grant = ocs_client.send(update_request) if grant.granted_units == 0: # 增量配额为零:规范要求终止会话 sip_session.terminate(reason="CREDIT_EXHAUSTED") break sip_session.extend_quota(grant.granted_units) # 会话释放:上报最终用量,退还未使用配额 final_request = build_ccr( session_id=sip_session.icid, used_units=sip_session.used_units, trigger="SESSION_END" ) ocs_client.send(final_request)这段逻辑里有两个容易踩坑的参数:requested_units和threshold。前者是向 OCS 要多少额度,后者是已用量达到多少时触发中期申请。规范没有规定具体数值,而是留给运营商策略配置。常见的实现思路是 threshold 设为 granted_units 的 80% 左右,留出申请往返的余量,避免额度用尽时增量请求还没回来导致会话被误杀。trigger字段则决定 OCS 侧走哪条计费规则,SESSION_START、MID_SESSION、SESSION_END 对应不同的批价逻辑,写错会导致话单归类错误。
3.3 离线计费的 ACR 事件:为什么释放时还要再发一次
离线计费虽然不控制额度,但消息流并不简单。规范 5.2.2.1.4 的会话释放流程里,网元在 BYE 之后仍要发一次 ACR,携带最终用量和会话时长。原因是离线计费的 CDR 需要闭合:建立时的 ACR 只记录了开始时间和初始媒体描述,释放时的 ACR 才补上结束时间和实际用量。如果只发建立不发释放,CDF 侧会留下一条没有结束标记的半开话单,后台批价时要么丢弃要么按异常处理。
这里的设计取舍是:离线计费允许“先记后补”,但补的时机必须紧跟会话释放,不能拖到定时器超时。规范在 5.2.2.2 的错误场景里专门提到,如果释放 ACR 发送失败,网元需要重试,重试仍失败则本地缓存并在链路恢复后补发。常见的实现思路是给 ACR 加一个本地持久化队列,按 ICID 去重,避免重试导致重复话单。
4. 多网元计费关联:ICID 与接入网标识怎么串起整条链路
4.1 ICID 的生成与传递:谁生成、谁透传、谁不能改
规范 5.1.2.2 明确 ICID 由发起会话的网元生成,写入 P-Charging-Vector 头域,后续网元透传。这里的关键约束是“透传不改”:中间网元可以读取 ICID 用于自己的计费记录,但不能重新生成或覆盖。原因是 ICID 是跨网元关联的唯一锚点,一旦被改,S-CSCF 的话单和 AS 的话单就对不上。
实际部署里,这个约束经常被打破。某类 AS 在作为 B2BUA 时,如果实现不规范,可能会把收到的 INVITE 拆成两个独立会话,各自生成 ICID,结果一次通话在计费系统里变成两条互不相关的记录。规范 5.1.7 专门讲了“来自作为 B2BUA 的 AS/ATCF 的单一计费会话”,要求这类网元在拆分信令时保持计费会话的唯一性。常见的实现思路是:B2BUA 在内部维护入向和出向的映射表,两个方向共用同一个 ICID,只在 CDR 里用不同的功能实体标识区分。
4.2 接入网计费标识与运营商间标识:跨域对账的钥匙
5.1.2.3 的接入网计费标识和 5.1.2.4 的运营商间标识,解决的是“同一用户在不同网络接入时,话单怎么归集”的问题。接入网计费标识由接入网侧生成,随 SIP 消息带入 IMS 域,用于把 IMS 话单和接入网话单关联起来。运营商间标识则用于跨运营商结算,当会话经过 IBCF 转接时,双方用这个标识核对流量归属。
这两个标识的设计动机是:IMS 计费不能只看 IMS 域内的网元,用户的实际接入方式(比如通过某种无线接入)会影响成本分摊。如果只记 IMS 侧的话单,跨运营商结算时就缺少接入侧的凭证。规范把它们放进 P-Charging-Vector,就是为了让计费信息随信令走,而不是靠后台文件交换。
4.3 功能实体标识列表:一张话单里为什么有多个网元名字
5.1.2.8 定义了功能实体标识列表,允许一条计费记录里携带多个参与网元的标识。这看起来是冗余,实际是排障刚需。当一通电话出现计费争议时,后台需要知道这条话单经过了哪些网元:S-CSCF 记了会话建立,AS 记了业务触发,IBCF 记了转接。如果只记一个网元名,排障时就得靠时间戳猜路径,效率极低。
常见的实现思路是:每个网元在写计费记录时,把自己的功能实体标识追加到列表里,而不是覆盖前一个。列表的顺序反映信令经过的顺序,后台可以据此还原会话路径。这个字段在规范里不算显眼,但在实际对账和故障定位时,往往是黑匣子里的关键线索。
5. 避坑与排查:IMS 计费落地时最容易翻车的几个点
5.1 现象:在线会话建立成功但媒体不通,计费却已开始扣费
原因:网元在收到 OCS 的配额授权后,先启动了计费计时器,再等待媒体协商完成。如果媒体协商失败(比如 SDP 协商不成功),计费侧已经按授权额度开始消耗,但用户实际没有通话。规范 5.1.3 的 SDP 处理要求计费信息与媒体描述对齐,但实现时容易把“授权成功”等同于“媒体可用”。
解决:把计费启动点挂在媒体通道确认之后,而不是配额授权之后。在线计费下,配额授权只代表“可以放行”,不代表“已经放行”。如果媒体协商失败,应立即发终止请求退还配额,而不是等会话超时。
5.2 现象:同一通电话在离线话单里出现两条记录,时长各算一半
原因:B2BUA 类网元把入向和出向当成两个独立会话,各自生成 ICID 并各自发 ACR。CDF 侧收到两条不同 ICID 的记录,无法合并。规范 5.1.7 要求单一计费会话,但实现时如果 B2BUA 的内部映射表没把两个方向绑到同一个 ICID,就会翻车。
解决:在 B2BUA 内部建立入向会话 ID 到出向会话 ID 的映射,两个方向共用发起侧生成的 ICID。CDR 里用功能实体标识区分方向,而不是用 ICID 区分。
5.3 现象:中期更新时 OCS 返回配额为零,会话被拆线,但用户还有余额
原因:中期 CCR 里上报的used_units超过了实际用量,或者requested_units填得过大,OCS 按策略判定额度不足。规范 5.2.2.1.3 的中期程序要求上报已用量,但“已用量”的统计口径如果和 OCS 侧不一致(比如一边按秒、一边按分钟),就会出现误判。
解决:统一计量单位和取整规则,在会话建立时的首次 CCR 里就明确单位。中期上报的已用量应该是“自上次上报以来的增量”,而不是“会话累计总量”,除非 OCS 侧明确要求累计值。这个口径要在网元和 OCS 的对接文档里写死,不能靠猜。
5.4 现象:会话释放的 ACR 丢失,后台出现半开话单
原因:BYE 之后网元立即释放了会话上下文,ACR 发送失败后没有重试机会。规范 5.2.2.2 的错误场景要求重试,但实现时如果 ACR 发送是异步的且没有持久化,进程重启或链路抖动就会丢。
解决:ACR 发送前先落本地持久化队列,按 ICID 去重,发送成功后再删除。重试策略要有上限和退避,避免链路恢复后瞬间冲击 CDF。半开话单的排查方法是按 ICID 查建立和释放两条记录,缺释放的那条就是丢失点。
5.5 现象:跨运营商结算时双方话单对不上,差额找不到出处
原因:运营商间标识没有随信令正确传递,或者 IBCF 在转接时重新生成了标识。规范 5.1.2.4 要求该标识在运营商间保持稳定,但转接网元如果把它当成“本网标识”处理,就会破坏对账锚点。
解决:IBCF 在转接时透传运营商间标识,不重新生成。结算对账时以该标识加时间窗口为键,而不是以 ICID 为键,因为 ICID 在跨网场景下可能被不同运营商各自解释。对不上的差额先查标识传递链路,再查时间窗口是否对齐。
6. 设计取舍:为什么规范把“关联”看得比“精确”更重
翻完这份规范,最值得琢磨的不是某个消息流的细节,而是它在“精确计费”和“可关联计费”之间的取舍。IMS 域里,一次会话可能经过 S-CSCF、多个 AS、IBCF、ATCF,每个网元都有自己的时钟、自己的会话视图、自己的失败重试逻辑。如果追求单点精确,每个网元都独立算一份账,后台合并时必然打架。规范的选择是:先保证所有网元用同一套标识(ICID、接入网计费标识、运营商间标识)把记录串起来,再在这个基础上做批价和對账。精确性让位于可关联性,因为不可关联的精确记录在跨网元场景下等于不可用。
这个取舍在在线计费里体现得更明显。规范没有规定配额单元的具体数值,也没有规定中期更新的触发阈值,而是把这些留给运营商策略。它只强制一件事:配额申请和用量上报必须携带同一个计费会话标识。这意味着不同运营商可以有不同的额度策略,但跨网结算时仍然能对上账。我一般会这么理解:规范管的是“账本怎么装订”,不管“每页写多少”。
验证这套机制是否落地正确,最直接的方法不是读代码,而是抓一次真实会话的完整信令,按 ICID 把各网元的计费记录拉出来,看建立、中期、释放三个点是否闭合,看在线和离线两条路径的用量是否在容差内一致。如果对不上,先查标识传递,再查时间窗口,最后才查批价规则。这个顺序能省掉大量无效排查。
从那以后我每次接触 IMS 计费相关的实现,都强制先画一张 ICID 流转图,把每个网元在哪个环节读、哪个环节写标清楚,再去看代码里的计费触发点。这张图对不上的地方,往往就是后面话单对不上的地方。希望帮到你。
本文还有配套的精品资源,点击获取