ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

IMS计费行标中文版:离线/在线计费消息流与AVP字段核对实战

IMS计费行标中文版:离线/在线计费消息流与AVP字段核对实战 简介本资源为3GPP TS 32.260 IMS计费技术规范的中文版文档面向从事移动通信核心网计费系统研发、测试与运维的工程师以及需要理解IMS计费机制的通信专业学生与研究人员。规范围绕IP多媒体子系统IMS的计费管理展开涵盖GSM、UMTS、LTE等多制式场景重点讲解计费数据记录CDR、计费触发点、在线计费OCS、离线计费OFS、融合计费架构、计费策略与规则功能CPRF以及Diameter、Gx等接口协议并给出高级IMS架构、离线与在线计费架构的说明。资源包内含1个PDF文件大小约2.65MB为V17.3.02022-06版本目录包含前言、范围、参考文献、定义符号缩写、架构注意事项、计费原理等章节结构完整便于按模块查阅。目前已有195人学习下载适合作为IMS计费系统设计、协议对接与标准研读的参考材料建议结合英文原版对照学习以掌握技术细节。1. 一份把 IMS 计费讲透的中文行标到底能省下多少翻文档的时间做 IMS 计费对接的工程师大概都有过这种体验Diameter 的 CCR/CCA 抓包摆在面前字段名全认识但就是说不清某个 AVP 该不该填、填了之后离线计费节点会怎么处理。英文原版 TS 32.260 动辄几百页光目录就能翻到手酸更别说里面大量交叉引用和条件分支。这份《3GPP TS 32.260 IMS计费行标 中文版》对应的就是 3GPP TS 32.260 V17.3.02022-06技术规格主题是电信管理下的计费管理专门讲 IP 多媒体子系统IMS的计费。它覆盖了从架构、计费原则到离线/在线计费消息流的完整链路适合做 IMS 核心网计费、OCS/OFCS 对接、话单验证的从业者。你不需要把它当教科书从头读到尾而是当成一本可以按图索骥的字段字典和流程手册来用。2. 先搞清楚这份规范在计费链路里的位置IMS 计费架构与核心概念2.1 从 TS 32.260 的章节结构看它管什么拿到一份标准第一步不是逐字读而是看它的目录骨架判断哪些章节跟你手上的活直接相关。这份中文版的结构大致是前言、范围、参考文献、定义符号缩写、架构注意事项、计费原则、离线计费原理、在线计费原理以及后面大量的消息流场景。真正干活时高频翻的是第 4 章架构、第 5 章计费原则和第 5.2 节的离线计费消息流。第 4 章把 IMS 计费拆成三种架构离线计费、在线计费、融合计费。离线计费的核心思路是“先服务、后出单”网元把计费信息通过 Rf 参考点送到 CDFCDF 生成 CDR 再交给 CGF 做后续处理。在线计费则是“先授权、后服务”通过 Ro 参考点跟 OCS 交互OCS 实时返回配额配额用完就断。融合计费是把两者放在同一套体系里用 Nchf 基于服务的接口统一处理。这里有个容易混淆的点Rf 和 Ro 是参考点不是具体协议。它们上面跑的都是 Diameter但应用层消息不同。Rf 上跑的是 ACR/ACAAccounting Request/AnswerRo 上跑的是 CCR/CCACredit-Control Request/Answer。看消息流图时先确认走的是哪个参考点再去看对应的 AVP 列表能少走很多弯路。第 5 章计费原则里IMS 计费标识符ICID是整个关联逻辑的钥匙。一次 IMS 会话可能经过 P-CSCF、S-CSCF、AS 等多个网元每个网元都会产生计费事件ICID 就是把这些散落的话单串成一次完整会话的线索。规范里还定义了相关 ICID、接入网计费标识、运营商间标识符等这些字段在跨运营商结算场景里尤其关键。2.2 离线计费与在线计费的关键差异很多刚接触 IMS 计费的人会把离线和在线当成“两种收费方式”其实它们的差异远不止收钱时机。离线计费不控制服务使用网元只管记录和上报用户该打多久打多久事后出账单。在线计费则要在会话建立和中期都跟 OCS 要配额配额不足时网元必须执行终止或重定向。从实现角度看离线计费的消息流相对简单会话建立时发 ACR START会话中发 ACR INTERIM如果有中期事件会话结束时发 ACR STOP。每个 ACR 里带什么 AVP规范里按场景列得很细。在线计费就复杂得多CCR 要带 Requested-Service-Unit 或 Used-Service-UnitCCA 要带 Granted-Service-Unit还要处理配额耗尽、重授权、最终报告等状态机。一个实操建议如果你在做计费验证先把离线计费的 ACR 三种类型START/INTERIM/STOP的必选 AVP 列出来对照规范第 5.2 节的消息流逐个核对。离线计费跑通了再去看在线计费的 CCR/CCA 状态机理解成本会低很多。2.3 计费数据记录CDR与触发条件CDR 是离线计费的最终产物但规范里不会直接给你一个“CDR 字段大全”而是通过消息流和 AVP 定义来间接描述。CDF 收到 ACR 后根据触发条件和配置决定什么时候生成一条 CDR。触发条件包括会话建立、会话释放、中期事件比如媒体变更、补充业务触发等。这里有个血泪经验不同设备商对“中期事件”的判定标准不完全一致。规范里写了触发条件但具体到某个 AS 在什么时刻发 ACR INTERIM不同实现可能有差异。做对接测试时不要假设对方一定按你理解的时机发消息抓包看实际行为比读规范更可靠。规范给你的是“应该怎样”设备给你的是“实际怎样”两者对不上时先确认是配置问题还是实现差异。3. 把规范落到抓包和配置上离线计费消息流的实操拆解3.1 会话建立阶段的 ACR START 字段核对离线计费里会话建立对应 ACR START。这个 ACR 里必须带的 AVP 包括 Session-Id、Origin-Host、Origin-Realm、Destination-Realm、Accounting-Record-Type值设为 START_RECORD、Accounting-Record-Number、User-Name或 Subscription-Id、IMS-Information 等。IMS-Information 是个分组 AVP里面又嵌套了 Node-Role、Node-Functionality、User-Session-Id、Calling-Party-Address、Called-Party-Address、Time-Stamps 等。下面是一段用 Python 解析 Diameter ACR 抓包文本的示例把关键字段提取出来做核对。实际抓包工具导出的格式可能是 Wireshark 的文本或 JSON这里用简化的字典结构演示逻辑。# 解析 ACR START 消息中的关键 AVP用于跟规范第 5.2 节核对 acr_start { Session-Id: ims;1234567890;abcdef, Accounting-Record-Type: START_RECORD, Accounting-Record-Number: 0, User-Name: sip:userims.example.com, IMS-Information: { Node-Role: originating, Node-Functionality: S-CSCF, Calling-Party-Address: tel:8613800138000, Called-Party-Address: tel:8613900139000, Time-Stamps: { SIP-Request-Timestamp: 2024-06-01T10:00:00Z, SIP-Response-Timestamp: 2024-06-01T10:00:01Z }, IMS-Charging-Identifier: icid-value-001 } } # 必选字段检查清单缺一个都可能导致 CDF 拒绝或话单异常 required_fields [ Session-Id, Accounting-Record-Type, Accounting-Record-Number, User-Name, IMS-Information ] for field in required_fields: if field not in acr_start: print(f缺失必选字段: {field}) else: print(f字段 {field} 存在值类型: {type(acr_start[field]).__name__}) # 检查 IMS-Information 里的 ICID这是跨网元关联的关键 icid acr_start.get(IMS-Information, {}).get(IMS-Charging-Identifier) if icid: print(fICID: {icid}用于关联本次会话的所有计费事件) else: print(警告: 缺少 ICID跨网元话单可能无法关联)这段代码的逻辑很直白把抓包解析后的 ACR 当成字典先检查顶层必选字段再深入 IMS-Information 检查 ICID。参数说明上Accounting-Record-Type 必须是 START_RECORDNumber 从 0 开始递增。IMS-Information 里的 Node-Role 和 Node-Functionality 决定了这条话单是哪个网元产生的做多网元关联时这两个字段加上 ICID 基本就能定位。实际对接中CDF 对必选字段的校验严格程度取决于设备实现。有些设备缺了 User-Name 会直接拒绝有些会填默认值。规范里写了“shall include”但设备不一定完全照做。我的习惯是先按规范把必选字段列全抓包时逐个打勾缺的字段先怀疑自己解析漏了再怀疑对方没发。3.2 会话释放阶段的 ACR STOP 与话单生成会话释放对应 ACR STOPAccounting-Record-Type 设为 STOP_RECORD。这个 ACR 里除了 START 里的那些字段还要带 Accounting-Output-Octets、Accounting-Input-Octets、Accounting-Session-Time 等用量字段。如果是语音通话还要带 Cause-Code 或 SIP-Response-Code 来标识释放原因。这里有个容易翻车的点ACR STOP 里的 Accounting-Record-Number 必须是该会话中最后一个序号CDF 靠这个序号判断话单是否完整。如果中间丢了 ACR INTERIM序号不连续CDF 可能会生成不完整话单或者告警。做压力测试时故意丢几个 INTERIM 看 CDF 怎么处理能帮你摸清对方的容错边界。# 用 tshark 过滤 Diameter ACR STOP 消息快速定位会话释放话单 # 假设抓包文件是 ims_charging.pcap tshark -r ims_charging.pcap -Y diameter.cmd.code 271 diameter.Accounting-Record-Type 2 \ -T fields \ -e diameter.Session-Id \ -e diameter.Accounting-Record-Number \ -e diameter.IMS-Charging-Identifier \ -e diameter.Accounting-Session-Time \ -e diameter.Cause-Code # 参数说明 # diameter.cmd.code 271 表示 Accounting 命令ACR/ACA # Accounting-Record-Type 2 表示 STOP_RECORDSTART1, INTERIM2, STOP3具体值以实际解码为准 # 输出字段按会话 ID、记录号、ICID、会话时长、释放原因排列这条 tshark 命令的用途是把所有 ACR STOP 的关键字段拉成表格方便跟 CDF 生成的话单做比对。参数上Accounting-Record-Type 的数值在不同解码版本里可能有差异用tshark -G values可以查当前版本的枚举值。Cause-Code 是排查异常释放的重点正常释放和异常释放的 Cause-Code 不同话单里的释放原因字段直接影响计费结果。我一般会把这个命令的输出重定向到文件再跟 CDF 的话单做 diff。如果 Session-Id 对得上但 Accounting-Session-Time 差了几秒先看是网元计时精度问题还是 CDF 处理延迟。这种差异在跨设备对接时很常见规范不会告诉你具体容差是多少只能靠实测摸出来。3.3 中期事件与 ACR INTERIM 的触发时机ACR INTERIM 是离线计费里最容易被忽略的部分。很多场景下如果会话中没有触发中期事件整个会话就只有 START 和 STOP 两条 ACR。但一旦有媒体变更、补充业务触发、或者会话时长超过配置阈值就会产生 INTERIM。规范第 5.2 节列了多种中期程序包括会话修改、多方通话加入、AS 重定向等。每种场景下 INTERIM 里带的 AVP 不同。比如多方通话时IMS-Information 里会多出 Related-ICID 或者多个 Calling-Party-Address。做话单合并时这些字段决定了怎么把多条 CDR 拼成一次完整会话。一个实操技巧在测试环境里故意触发中期事件比如通话中切换媒体类型或者发起呼叫转移然后抓包看 INTERIM 的字段变化。对比规范里对应场景的 AVP 列表能快速建立“什么操作触发什么字段”的直觉。这比死记硬背规范条文有效得多。4. 避坑与排查IMS 计费对接中最容易翻车的五个点4.1 坑一ICID 不一致导致话单无法关联现象同一通电话P-CSCF 和 S-CSCF 都产生了话单但计费系统里显示成两通独立通话无法合并计费。原因ICID 在会话建立时由第一个产生计费事件的网元生成后续网元应该沿用同一个 ICID。但实际配置中如果网元没有正确从 SIP 头域或 Diameter 消息里提取 ICID就会各自生成新的 ICID。解决抓包确认 SIP 消息里的 P-Charging-Vector 头域是否携带了 icid-value以及 Diameter ACR 里的 IMS-Charging-Identifier 是否跟 SIP 头域一致。不一致的话检查网元的计费配置里 ICID 提取规则。规范里写了 ICID 的生成和传递规则但设备实现时可能因为版本差异有不同行为以抓包为准。4.2 坑二Accounting-Record-Number 跳号导致话单不完整现象CDF 生成的话单里缺少中间某段或者计费系统告警“记录号不连续”。原因ACR INTERIM 丢失或者网元在重传时没有正确递增 Accounting-Record-Number。Diameter 底层有重传机制但应用层记录号必须由网元自己维护。解决先确认是网络丢包还是网元没发。抓包看有没有对应的 ACR INTERIM如果有发送记录但 CDF 没收到查 Diameter 链路的重传和超时配置。如果网元根本没发检查中期事件的触发条件配置。规范里对记录号的要求是“每个后续记录递增 1”但重传场景下的行为规范没有细说这块只能靠设备文档和实测。4.3 坑三IMS-Information 里 Node-Role 填反现象话单里主叫和被叫的计费方向搞反导致结算金额算错。原因Node-Role 的取值是 originating 或 terminating取决于网元在会话中的角色。但某些场景下比如呼叫转移或第三方 AS 介入网元的角色可能跟直觉相反。解决不要靠猜抓 SIP 消息里的 From/To 头域和 Route 头域结合网元在 IMS 架构里的位置判断。规范第 5.2 节的消息流图里标注了每个场景下各网元的角色对照着看。如果还是不确定用测试呼叫跑一遍在话单里核对主被叫号码和 Node-Role 的对应关系。4.4 坑四离线计费 ACR 超时重传导致重复话单现象CDF 收到两条内容相同的 ACR STOP生成两条重复话单。原因网元发送 ACR 后没收到 ACA触发 Diameter 重传。如果 CDF 处理慢但最终回了 ACA网元可能已经重传了。CDF 如果没做去重就会生成重复话单。解决CDF 侧应该根据 Session-Id Accounting-Record-Number 做去重。网元侧的重传参数Tc 定时器需要跟 CDF 的处理能力匹配。规范里没有明确规定去重逻辑这是设备实现层面的问题。对接时先问清楚对方 CDF 的去重策略测试时故意制造超时场景验证。4.5 坑五在线计费配额耗尽后网元未终止服务现象用户余额不足OCS 返回配额为 0但通话没有中断产生了欠费。原因网元收到 CCA 后没有正确解析 Granted-Service-Unit或者配额耗尽后的终止逻辑没有触发。有些实现里配额耗尽只是停止计费但不断开服务。解决抓包看 CCA 里的 Granted-Service-Unit 和 Final-Unit-Indication。如果 OCS 返回了终止指示网元必须执行。测试时用余额不足的账户发起呼叫观察通话是否在配额耗尽后立即中断。规范第 5.3 节在线计费原理里对配额管理和终止流程有描述但具体行为取决于网元实现必须实测验证。5. 进阶用法用规范做话单验证和跨版本比对5.1 建立自己的 AVP 检查清单读规范最有效的方式不是从头翻而是带着问题去查。我一般会针对自己负责的场景从规范里抽出对应的 AVP 列表做成一个检查清单。比如离线计费会话建立场景清单里列上 Session-Id、Accounting-Record-Type、IMS-Information 下的所有必选子 AVP然后写个脚本从抓包里自动提取这些字段做核对。# 从解析后的 ACR 字典中按检查清单逐项核对 checklist { Session-Id: str, Accounting-Record-Type: str, Accounting-Record-Number: int, User-Name: str, IMS-Information.Node-Role: str, IMS-Information.Node-Functionality: str, IMS-Information.IMS-Charging-Identifier: str, IMS-Information.Calling-Party-Address: str, IMS-Information.Called-Party-Address: str } def check_acr(acr_dict, checklist): 按检查清单核对 ACR 字段返回缺失和类型不符的项 issues [] for path, expected_type in checklist.items(): keys path.split(.) value acr_dict for key in keys: if isinstance(value, dict) and key in value: value value[key] else: value None break if value is None: issues.append(f缺失: {path}) elif not isinstance(value, expected_type): issues.append(f类型不符: {path} 期望 {expected_type.__name__}实际 {type(value).__name__}) return issues # 假设 acr_start 是前面解析出来的字典 problems check_acr(acr_start, checklist) if problems: for p in problems: print(p) else: print(所有检查项通过)这个脚本的价值在于把规范条文变成可执行的检查逻辑。参数上checklist 的 key 用点号分隔嵌套路径value 是期望的类型。实际使用时把抓包解析后的字典传进去几秒钟就能定位缺失或类型异常的字段。比人工逐条核对快得多也不容易漏。5.2 跨版本比对V17.3.0 跟早期版本的差异排查3GPP 规范每个版本都会有修订V17.3.0 里可能新增了一些 AVP 或者修改了某些场景的消息流。如果你手上的设备是基于早期版本实现的对接时可能会遇到“规范里有但设备不支持”或者“设备发了但规范里没有”的情况。做跨版本比对时重点看第 5 章计费原则和第 5.2 节消息流的变化。新增的 AVP 通常在版本变更说明里有记录但中文版可能没有单独的变更记录章节需要对照英文原版的 Change History 部分。我的习惯是拿到新版本规范后先翻一遍目录看哪些章节号有变化再重点读变化章节。没有变化的部分沿用之前的理解就行。5.3 一个具体技巧用 ICID 串联全流程话单ICID 是 IMS 计费里最实用的关联字段。不管是离线还是在线不管经过多少个网元同一次会话的 ICID 应该保持一致。做全流程验证时我一般会按 ICID 把抓包里的所有计费消息拉出来按时间排序然后对照规范里的消息流图看每个节点该发什么消息、带什么字段。具体操作上用 tshark 按 ICID 过滤# 按 ICID 过滤所有计费消息按时间排序输出关键字段 tshark -r ims_charging.pcap -Y diameter.IMS-Charging-Identifier \icid-value-001\ \ -T fields \ -e frame.time_relative \ -e diameter.cmd.code \ -e diameter.Accounting-Record-Type \ -e diameter.Origin-Host \ -e diameter.Destination-Host \ -e diameter.IMS-Information.Node-Role \ | sort -n # 输出说明 # frame.time_relative 是相对抓包开始的时间用于看消息先后顺序 # cmd.code 区分 ACR(271) 和 CCR(272) # Origin-Host 和 Destination-Host 看消息从哪来到哪去 # Node-Role 确认网元角色这条命令的输出能让你一眼看出哪个网元先发消息、中间经过哪些节点、每个节点的角色是什么、消息类型对不对。如果某个节点该发 ACR 却没发或者 Node-Role 跟预期不符问题就定位到了。从那以后我每次做 IMS 计费对接都强制走一遍“ICID 串联 AVP 清单核对”的流程先确认关联字段一致再逐个核对必选 AVP最后才去看业务逻辑。这套流程帮我省掉了大量来回扯皮的时间。希望帮到你。本文还有配套的精品资源点击获取
返回列表