跳到主要内容

OmniRoam

OmniRoam 是 Omnitouch 为漫游运营商提供的全面批发收入管理解决方案。它处理漫游数据 CDR(通话详细记录)的完整生命周期,从数据摄取到计费评级,再到 TAP3 文件生成和报告。

目录

概述

OmniRoam 处理来自移动网络运营商的漫游 CDR,使用 OmniCharge 计费引擎进行评级,生成符合 GSMA 标准的 TAP3 文件用于计费,并提供全面的监控和报告能力。

OmniTAP Architecture 1

CDR 导入和评级过程

TAP3 导出过程

操作指南

运行 TAP3 导出

# Export for specific partner
python3 export_TAP3.py VZW_Live

# Interactive mode (prompts for partner)
python3 export_TAP3.py

导出过程:

  1. 查询过去 30 天的 CDR(GSMA 要求)
  2. 过滤掉标记为已处理的 CDR
  3. 排除结束时间少于 1 小时的 CDR(防止不完整会话)
  4. 按漫游合作伙伴分组 CDR
  5. 为每个合作伙伴生成 TAP3 文件
  6. 在数据库中将 CDR 标记为已处理
  7. 增加序列计数器
  8. 将指标推送到 InfluxDB

监控与报告

OmniRoam 将实时指标推送到 InfluxDB 进行监控和分析。

收集的指标

原始 CDR 指标 在 CDR 导入和评级过程中推送:

  • operator: 漫游合作伙伴标识符
  • input_file: 源 CSV 文件名
  • apn: 接入点名称(数据服务标识符)
  • cellId: 基站标识符
  • imsi: 用户身份
  • tac: 跟踪区域代码
  • sGWAddress: 服务网关 IP 地址
  • pGWAddress: PDN 网关 IP 地址
  • chargeableUnits: 使用的总字节数
  • chargedUnits: 计算的费用

TAP 导出指标 在 TAP3 文件生成过程中推送:

  • operator: 漫游合作伙伴标识符
  • filename: 生成的 TAP3 文件名
  • totalcharge: TAP3 文件中的总费用
  • totalconsumed: TAP3 文件中的总字节数
  • cdr_count: TAP3 文件中的 CDR 数量

仪表板查询

用于监控的示例 InfluxDB 查询:

按运营商收入

SELECT sum("totalcharge")
FROM "tap_cdr"
WHERE time > now() - 30d
GROUP BY "operator"

按 TAC 数据使用

SELECT sum("chargeableUnits")
FROM "raw_cdr"
WHERE time > now() - 7d
GROUP BY "tac"

按小时 CDR 量

SELECT count("chargeableUnits")
FROM "raw_cdr"
WHERE time > now() - 24h
GROUP BY time(1h)

按 APN 收入

SELECT sum("chargedUnits")
FROM "raw_cdr"
WHERE time > now() - 7d
GROUP BY "apn"

Grafana 集成

使用这些指标创建 Grafana 仪表板,用于:

  • 实时收入监控
  • 流量模式分析
  • 合作伙伴绩效跟踪
  • 网络资源利用率
  • 异常检测
  • 计费对账

故障排除

OmniTAP Architecture 3

CDR 导入问题

检查日志 /tmp/import_CDR_Logger_Marben_*.log

常见问题:

  • 无效的 IMSI 格式
  • 缺少必填字段
  • 时区转换错误
  • 重复的计费 ID

TAP3 导出问题

检查日志 /tmp/tap3_export_*.log

常见问题:

  • 最近 30 天内没有 CDR
  • 缺少 TAC 配置
  • 无效的序列号
  • 数据库连接错误

OmniCharge 计费错误

查看 OmniCharge 日志以查找:

  • 缺少费率计划
  • 找不到账户
  • 无效的使用值
  • 货币转换错误

InfluxDB 连接问题

验证:

  • InfluxDB URL 可达
  • 有效的身份验证令牌
  • 存在存储桶
  • 网络连接

支持与维护

日志位置

  • CDR 导入: /tmp/import_CDR_Logger_Marben_*.log
  • TAP 导出: /tmp/tap3_export_*.log

关键配置文件

  • config.yaml - 主要配置(合作伙伴费率、网络设置、InfluxDB 连接)
  • counters.yaml - TAP3 文件序列计数器

定期维护任务

  1. 监控序列计数器 - 确保它们不超过 99999
  2. 归档旧的 TAP 文件 - 移动超过保留期的文件
  3. 监控 InfluxDB 磁盘使用 - 配置保留策略
  4. 审查费率配置 - 当合作伙伴费率变化时更新
  5. 备份配置文件 - config.yaml 和 counters.yaml
  6. 监控 CDR 积压 - 确保及时处理

系统架构

高层架构

CDR 导入过程

OmniRoam 使用两阶段导入过程,使用缓存作为临时聚合层,将部分 CDR 记录组装成完整的可计费 CDR。

理解部分 CDR

移动网络元素(S-GW/P-GW)不会为数据会话生成单个 CDR。相反,它们在会话生命周期中生成 多个部分 CDR 记录

  • 开始记录:在数据会话开始时生成
  • 更新记录:在会话期间定期生成(例如,每 15 分钟或每 100 MB 数据使用)
  • 停止记录:在会话结束时生成

每个部分记录包含增量使用数据。为了准确计费,OmniRoam 必须:

  1. 识别 哪些部分记录属于同一数据会话
  2. 聚合 所有部分记录的使用数据
  3. 计算 总会话持续时间
  4. 组装 一个完整的 CDR,表示整个会话

为什么使用缓存进行 CDR 聚合?

缓存作为高性能的临时存储区域,部分 CDR 在会话完成之前会在此累积。缓存提供:

  • 快速键值查找 - 立即找到会话的现有部分 CDR
  • 内存存储 - 实时聚合的高速读写操作
  • 原子操作 - 安全的并发更新来自多个导入过程
  • 持久性 - CDR 在聚合窗口期间即使系统重启也能存活

两阶段导入架构

阶段 1:CSV 解析和部分 CDR 聚合

第一阶段持续读取来自 S-GW 网络元素的 CSV 文件,并在缓存中聚合部分 CDR。

如何识别和匹配部分 CDR

OmniRoam 必须确定哪些部分记录属于同一数据会话。每个会话通过一个复合 会话 ID 唯一标识,该 ID 由以下组成:

  • 计费 ID:来自网络元素的唯一会话标识符
  • IMSI:用户身份(移动号码标识符)
  • 日期:服务网络时区的会话日期
  • P-GW IP 地址:处理会话的网关
  • TAC:跟踪区域代码(基站位置)
  • QCI:服务质量类别

这种组合确保来自同一数据会话的所有部分记录被分组在一起,即使多个文件的到达顺序不同。

如何聚合部分 CDR

当 CSV 解析器处理每个部分 CDR 时:

  1. 从 CDR 字段生成会话 ID
  2. 检查缓存 以查看此会话是否已存在
  3. 如果会话存在于缓存中
    • 检索累积的 CDR 数据
    • 验证此文件是否未被处理过(防止重复)
    • 添加新的使用数据:传入字节 + 传出字节
    • 使用最早和最新的时间戳更新会话持续时间
    • 保存关于此部分记录的元数据以供审计
    • 将更新的 CDR 保存回缓存
  4. 如果是新会话
    • 在缓存中创建新的 CDR 条目
    • 初始化使用计数器和会��元数据
    • 记录第一个部分记录的时间戳

审计跟踪和元数据

每个对 CDR 有贡献的部分记录都通过全面的元数据进行跟踪:

  • 源文件名:包含此部分记录的 CSV 文件
  • 时间戳:网络元素生成此记录的时间
  • 处理时间:OmniRoam 接收和处理它的时间
  • 使用贡献:此部分增加了多少数据(传入/传出字节)
  • 事件类型:这是开始、更新还是停止记录
  • 服务网络时区:用于准确的时间戳转换

为什么元数据对会计至关重要:

这个审计跟踪允许 OmniRoam 追踪单个费用在每个处理阶段的端到端过程,这对于:

  • 争议解决:当合作伙伴质疑费用时,运营商可以准确显示哪些源文件对此做出了贡献
  • 收入对账:验证所有可计费使用是否被捕获,没有遗漏或重复
  • 合规性:证明对计费记录的适当处理以供审计
  • 调试:通过追踪完整数据流迅速识别 CDR 聚合过程中的问题
  • 财务准确性:确保每一美元的收费都可以追溯到特定的网络事件

会话持续时间计算

总会话持续时间通过查找以下内容计算:

  • 所有部分记录中的最早时间戳(会话开始)
  • 所有部分记录中的最新时间戳(会话结束)
  • 持续时间 = 最新 - 最早

对于仅存在更新记录的会话(缺少开始/停止),持续时间默认为 24 小时。

阶段 2:CDR 组装和评级

第二阶段定期扫描缓存以查找已完成的会话,组装最终 CDR,并提交给 OmniCharge 进行评级。

如何从缓存中选择完整的 CDR

CDR 组装过程持续运行,检查缓存中存储的所有会话:

  1. 扫描缓存 以查找所有累积的 CDR 会话
  2. 每次处理 1,000 个会话 的批次
  3. 对于每个会话
    • 从会话 ID 中提取会话日期
    • 如果太旧则跳过(> 30 天):从缓存中删除(防止过时数据积累)
    • 如果太新则跳过(< 24 小时):保留在缓存中以等待更多部分记录到达
    • 加载完整的 CDR,包含所有累积的数据

24 小时等待期

为什么 OmniRoam 在评级 CDR 之前等待 24 小时?

  • 部分记录的到达顺序不一致:网络拥塞可能会延迟 CSV 文件的交付数小时
  • 会话跨越午夜:在 11:50 PM 开始的会话会生成两个不同日期的文件。相同的计费 ID 可能跨越多天,部分记录的日期不同
  • 更新记录延迟到达:定期更新记录可能在会话结束后很久才到达
  • 异步文件生成:不同的网络元素在不同的时间表上导出文件
  • 长时间运行的会话:数据会话可能持续数小时或数天,更新记录可能会在整个过程中逐渐到达

通过等待 24 小时,OmniRoam 确保所有部分记录都已到达,并且 CDR 在计费之前确实完整。

CDR 验证和丰富

在评级之前,每个组装的 CDR 都要经过验证和丰富:

  1. 验证完整性

    • 检查是否存在开始/停止记录
    • 如果仅存在更新记录,则将持续时间设置为 24 小时(默认)
  2. 丢弃无效 CDR

    • 删除零使用会话(没有可计费活动)
  3. 计算最终使用

    • 汇总所有传入和传出字节
    • 应用合作伙伴特定的四舍五入规则(例如,向上舍入到最近的 1 KB)
  4. 丰富位置信息

    • 将 TAC(跟踪区域代码)映射到服务网络位置
    • 添加时区信息以确保时间戳准确
    • 添加地理位置描述
  5. 提交给 OmniCharge

    • 将完整的、丰富的 CDR 提交进行评级
    • 收回计算的费用
  6. 存储和清理

    • 将评级后的 CDR 保存到数据库
    • 将指标推送到 InfluxDB 进行报告
    • 从缓存中删除已处理的 CDR

CDR 数据结构

每个聚合的 CDR 包含:

  • 用户信息:IMSI、MSISDN、IMEI
  • 网络信息:服务网关(S-GW)、PDN 网关(P-GW)、基站 ID、TAC(跟踪区域代码)
  • 会话详情:开始/结束时间戳、持续时间、APN(接入点名称)
  • 使用数据:传入/传出数据量、总可计费单位
  • 位置信息:服务 BID(网络 ID)、地理位置
  • QoS 信息:QCI(服务质量类别标识符)

数据处理规则

使用四舍五入

CDR 根据合作伙伴特定配置中的 config.yaml 进行四舍五入:

partners:
Example_Live:
round_up_to: 1024 # Round usage to nearest 1KB

系统:

  1. 计算总使用量:dataVolumeIncoming + dataVolumeOutgoing
  2. 向上舍入到配置的单位(例如,1024 字节)
  3. 保留原始值以供审计

基于 TAC 的本地化

系统根据 TAC(跟踪区域代码)确定服务网络位置:

config:
tac_config:
Global:
tac_list: ['1101', '10000', '10100']
servingBid: 72473
servingLocationDescription: 'Smallville USA'
timezone: 'America/Smallville'

这使得:

  • 时间戳的正确时区转换
  • 地理位置的分配
  • 服务网络的识别

OmniCharge 计费引擎

OmniRoam 将 CDR 发送到 OmniCharge,这是一个强大的计费引擎,根据可配置的费率计划计算费用。

OmniTAP Architecture 2

计费过程

费率配置

费率在配置文件中按漫游合作伙伴进行配置:

partners:
Example_Live:
imsi_prefixes:
- 99901
rates:
unit_price: 0.000476800 # Price per unit
unit_bytes: 1024 # Unit size in bytes
batch_info:
sender: AUSIE
recipient: AAA00
accountingInfo:
localCurrency: 'USD'
tapCurrency: 'USD'
roundingAction: 'Simple'
tapDecimalPlaces: 5

IMSI 前缀匹配

OmniRoam 使用 IMSI 前缀匹配和最长匹配优先逻辑 将 CDR 匹配到漫游合作伙伴。这使得运营商能够为测试 SIM 创建特定配置,同时保持生产流量的一般配置。

前缀匹配的工作原理

在对 CDR 进行计费时,OmniRoam:

  1. 从 CDR 中提取 IMSI(例如,310410123456789
  2. 按顺序评估所有合作伙伴配置
  3. 找到最长的匹配前缀
  4. 应用该合作伙伴的费率和配置

示例:测试 SIM 配置

此功能对于 TADIG/IREG 测试特别有用,其中测试 SIM 需要不同的处理:

partners:
Demo_Test:
imsi_prefixes:
- 0010112345123 # Test SIM range (9-digit prefix)
rates:
unit_price: 0.0 # No charge for test traffic
batch_info:
sender: AUSIE
recipient: AAA00TEST

Demo_Production:
imsi_prefixes:
- 001011 # Production range (6-digit prefix)
rates:
unit_price: 0.000476800
batch_info:
sender: AUSIE
recipient: AAA00

匹配行为:

  • IMSI 00101123451234 → 匹配 Demo_Test(9 位前缀更长)
  • IMSI 00101023456789 → 匹配 Demo_Production(6 位前缀)

这确保测试流量进入测试 TAP 文件,使用测试 TADIG 代码,而生产流量正常计费,使用生产 TADIG 代码。

计费计算

对于每个 CDR:

  1. 匹配合作伙伴:通过 IMSI 前缀识别漫游合作伙伴
  2. 计算单位totalBytes / unit_bytes
  3. 应用费率units × unit_price = charge
  4. 应用四舍五入:根据 roundingAction(向上/向下/简单)进行四舍五入
  5. 转换为 TAP 单位:乘以 1000 以符合 TAP3 格式

示例:

使用量:52,428,800 字节(50 MB)
单位大小:1024 字节
单位:51,200
费率:每 1KB $0.000476800
费用:51,200 × $0.000476800 = $24.41
TAP 单位:24,410(24.41 × 1000)

基于 QCI 的呼叫类型分配

服务质量类别(QCI)映射到 TAP3 呼叫类型级别:

call_type_level:
qci_1: 20 # 对话(语音)
qci_2: 22 # 对话(视频)
qci_3: 23 # 实时游戏
qci_4: 24 # 缓冲流媒体
qci_5: 20 # IMS 信令
qci_6: 26 # 交互式(浏览)
qci_7: 27 # 交互式(游戏)
qci_8: 28 # 背景
qci_9: 29 # 背景(低优先级)
default: 20

TAP3 文件生成

在 CDR 被 OmniCharge 评级后,OmniRoam 生成符合 GSMA 标准的 TAP3 文件用于批发计费。

TAP3 导出流程

TAP3 文件结构

文件命名约定

TAP3 文件遵循 GSMA 命名标准:

<FileType><Sender><Recipient><SequenceNumber>

示例:
CDAUSIEAAA0000001 - 从 AUSIE 到 AAA00 的商业数据文件,序列 1
TDAUSIEAAA0000001 - 从 AUSIE 到 AAA00 的测试数据文件,序列 1

其中:

  • FileType: CD(商业)或 TD(测试)
  • Sender: 5 字符 TADIG 代码
  • Recipient: 5 字符 TADIG 代码
  • SequenceNumber: 5 位序列(来自 counters.yaml

配置指南

合作伙伴配置

config.yaml 中添加漫游合作伙伴:

partners:
ONS_Live:
imsi_prefixes: # 此合作伙伴的 IMSI 前缀列表
- 505057
accessPointNameOI: mnc057.mcc505.gprs
rates:
unit_price: 0.000476800 # 每单位价格(美元)
unit_bytes: 1024 # 每单位的字节数
batch_info:
sender: AUSIE # 您的 TADIG 代码
recipient: AAA00 # 合作伙伴 TADIG 代码
specificationVersionNumber: 3
releaseVersionNumber: 12
accountingInfo:
localCurrency: 'USD'
tapCurrency: 'USD'
roundingAction: 'Simple' # 向上/向下/简单
tapDecimalPlaces: 5
round_up_to: 1024 # 将使用量四舍五入到最近的 N 字节
call_type_level: # QCI 到呼叫类型级别的映射
qci_1: 20
qci_2: 22
default: 20

序列计数器配置

counters.yaml 中初始化序列计数器:

AAA00:
CD: 1 # 商业数据序列
TD: 1 # 测试数据序列
AAA01:
CD: 1
TD: 1

序列在��个生成的 TAP 文件中自动递增。

网络配置

配置 TAC 到位置的映射:

config:
tac_config:
LocationName:
tac_list: ['1101', '10000']
servingBid: 72473
servingLocationDescription: 'Network Location'
timezone: 'America/New_York'

InfluxDB 配置

config.yaml 中配置 InfluxDB 连接:

config:
influx_db:
influxDbUrl: 'http://10.3.0.135:8086'
influxDbOrg: 'omnitouch'
influxDbBucket: 'Omnicharge_TAP3'
influxDbToken: 'your-token-here'

输出路径

配置文件输出位置:

config:
tap_output_path: '/etc/pytap3/OutputFiles'
tap_human_readable_output_path: '/etc/pytap3/OutputFiles_Human'
tap_in_path: '/home/user/TAP_In/'

架构决策

为什么选择 OmniCharge?

OmniCharge 提供:

  • 强大的计费引擎,具有灵活的费率计划
  • 实时计费能力
  • CDR 去重
  • 全面的审计跟踪
  • 基于 API 的集成

为什么选择 InfluxDB?

优势:

  • 针对 CDR 指标优化的时间序列
  • 高写入吞吐量
  • 具有压缩的高效存储
  • 内置降采样
  • 原生 Grafana 集成

工作流程摘要


OmniRoam - 由 Omnitouch 提供的专业漫游收入管理。