XCAP 应用服务器 - 使用和架构文档
目录
执行摘要
此 XCAP (XML 配置访问协议) 应用服务器为电信网络提供 IMS (IP 多媒体子系统) 附加服务管理。它使用户能够通过标准化的 XML 文档管理呼叫转移、呼叫限制和来电显示设置。
主要特点:
- 符合 3GPP 标准:实现 ETSI TS 183 063 的 IMS 附加服务
- HSS 集成:基于 REST API 与家庭用户服务器的通信
- BSF 准备就绪:通用引导架构 (GBA) 认证框架
- 多服务:呼叫转移、呼叫限制(来电/去电)、来电显示控制
- 高可用性:在多个 HSS 对等体之间进行负载均衡
- Web UI:用户���助管理门户
XCAP 在 3GPP 网络中的应用
什么是 XCAP?
XCAP (XML 配置访问协议) 是由 IETF (RFC 4825) 定义的标准化基于 HTTP 的协议,并被 3GPP 采用,用于管理 IMS 网络中的用户配置数据。它允许移动设备和应用程序创建、读取、更新和删除存储在网络服务器上的 XML 文档。
在 3GPP IMS 架构中的角色
XCAP 服务类别
XCAP 服务���管理三类 IMS 附加服务:
-
通信转移(呼叫转移)
- 无条件(CFU)
- 忙(CFB)
- 无应答(CFNA)
- 不可达(CFNRc)
- 未注册(CFNReg)
-
通信限制(呼叫阻止)
- 来电:所有呼叫、国际呼叫、除本国外的国际呼叫、漫游时
- 去电:所有呼叫、国际呼叫、除本国外的国际呼叫、漫游时
-
身份展示服务
- 发起身份展示(OIP) - 显示来电显示
- 发起身份展示限制(OIR) - 隐藏来电显示
3GPP 标准合规性
| 标准 | 标题 | 相关性 |
|---|---|---|
| ETSI TS 183 063 | 基于 IMS 的 PSTN/ISDN 模拟服务 | simservs XML 模式的主要规范 |
| 3GPP TS 24.623 | 可扩展标记语言 (XML) 配置访问协议 (XCAP) 通过 Ut | XCAP 接口规范 |
| 3GPP TS 24.238 | 基于会话发起协议 (SIP) 的用户配置 | 用户配置管理 |
| 3GPP TS 33.220 | 通用认证架构 (GAA) | BSF/GBA 认证框架 |
| RFC 4825 | 可扩展标记语言 (XML) 配置访问协议 (XCAP) | 基础 XCAP 协议定义 |
| RFC 4745 | 通用策略:表达隐私偏好的文档格式 | 用于规则条件的 XML 命名空间 |
系统架构
高级组件视图
数据流架构
组件职责
| 组件 | 目的 | 端口/协议 |
|---|---|---|
| XCAP 服务器 | 主要应用服务器,REST API 端点 | 5000/HTTP |
| XML 处理器 | XML 文档转换和操作 | N/A |
| HSS 客户端 | 通过 REST API 检索/更新用户数据 | 8080/HTTP |
| 模板引擎 | 从用户数据生成 XCAP XML | N/A |
| BSF 认证 | 可选的 GBA 摘要认证 | N/A |
| Web UI | 用户自助门户 | 5000/HTTP |
HSS 集成
HSS 通信模式
XCAP 服务器充当 XCAP 客户端与 HSS 之间的 无状态代理。它不维护用户数据的本地存储,而是针对每个请求查询 HSS。
HSS REST API 端点
1. 通过 MSISDN 检索用户
GET /ims_subscriber/ims_subscriber_msisdn/{msisdn}
Host: 10.4.2.140:8080
响应:
{
"ims_subscriber_id": 12345,
"imsi": "505570000012345",
"msisdn": "15551234567",
"xcap_profile": "<ss:communication-diversion>...</ss:communication-diversion>",
"scscf": "sip:scscf1.ims.example.com:6060",
"scscf_peer": "scscf1.ims.example.com",
"scscf_realm": "ims.example.com"
}
2. 更新用户配置
PATCH /ims_subscriber/{ims_subscriber_id}
Host: 10.4.2.140:8080
Content-Type: application/json
{
"xcap_profile": "<ss:communication-diversion xmlns:ss=\"http://uri.etsi.org/ngn/params/xml/simservs/xcap\" active=\"true\">...</ss:communication-diversion>"
}
响应:
{
"Status": "success",
"ims_subscriber_id": 12345
}
3. PCRF 用户查找(基于 IP)
GET /pcrf/subscriber_routing/{ip_address}
Host: 10.4.2.140:8080
目的: 从 UE IP 地址解析用户身份以便访问 Web UI。
响应:
{
"subscriber_id": 67890,
"ip_address": "100.64.4.16",
"apn": "ims"
}
4. 获取基本用户信息
GET /subscriber/{subscriber_id}
Host: 10.4.2.140:8080
响应:
{
"subscriber_id": 67890,
"imsi": "505570000012345",
"msisdn": "15551234567"
}
5. 通过 IMSI 获取 IMS 用户
GET /ims_subscriber/ims_subscriber_imsi/{imsi}
Host: 10.4.2.140:8080
响应: 与端点 #1 相同结构
HSS 负载均衡
特征:
- 无状态:每个请求可以发送到任何 HSS 对等体
- 随机分配:在可用对等体之间进行负载均衡
- 数据库同步:HSS 对等体共享一个公共后端数据库
- 无粘性会话:没有客户端亲和性或会话持久性
为什么选择 REST 而不是 Diameter?
传统的 3GPP 网络使用 Diameter Sh 接口进行 XCAP↔HSS 通信。此实现使用 REST API 以简化操作:
| 方面 | Diameter Sh(传统) | REST API(此实现��� |
|---|---|---|
| 协议 | Diameter (RFC 6733) | HTTP/JSON |
| 复杂性 | 高 - 需要 Diameter 栈 | 低 - 标准 HTTP 库 |
| 消息格式 | AVP(属性-值对)二进制 | JSON(可读性强) |
| 端口 | 3868 (SCTP/TCP) | 8080 (HTTP) |
| 用例 | 运营商级电信网络 | 云原生、API 优先的部署 |
| 集成 | 需要 FreeDiameter, OpenDiameter | 标准 REST 客户端 (requests) |
| 认证 | TLS/Diameter 安全 | API 令牌, OAuth(未来) |
REST 方法的优势:
- 更容易与现代 DevOps 工具集成
- 更简单的调试(curl, Postman)
- 兼容云原生架构
- 降低基础设施复杂性
- 开发者友好
BSF 认证
通用引导架构 (GBA)
GBA 是一个 3GPP 认证框架 (TS 33.220),它通过从 UMTS/LTE 认证基础设施派生的共享密钥实现 UE 与网络服务之间的相互认证。
BSF 实现状态
服务器提供灵活的认证选项,当需要时可完全支持 BSF/GBA。
配置:
# config.yaml
bsf_support: False
认证挑战:
当启用 BSF 认证时,服务器会发出 HTTP 401 未授权,内容为:
WWW-Authenticate: Digest realm="3GPP-bootstrapping@xcap.ims.example.com",
qop="auth-int",
nonce="<random-32-chars>",
opaque="<random-32-chars>",
algorithm="MD5",
domain="/"
摘要认证参数
当启用 BSF 认证时,服务器会用以下参数挑战客户端:
| 参数 | 值 | 目的 |
|---|---|---|
| realm | 3GPP-bootstrapping@xcap.ims.example.com | 认证域 |
| qop | auth-int | 保护质量:带有完整性保护的认证 |
| algorithm | MD5 | 摘要计算的哈希算法 |
| nonce | 32 字符随机字符串 | 服务器挑战以防止重放攻击 |
| opaque | 32 字符随机字符串 | 服务器特定数据,客户端返回时不变 |
| domain | / | 凭证有效的 URI 空间 |
认证架构
XCAP 服务器提供多种认证机制,以适应不同的部署场景:
1. 通过 PCRF 的 UE IP 基于认证(推荐)
XCAP 服务器可以通过验证其 UE IP 地址与 HSS/PCRF 中的活动会话进行用户认证。这提供了安全的、会话感知的认证,而无需 GBA 基础设施。
工作原理:
优势:
- 会话感知:只有具有活动数据会话的认证 UE 才能访问 XCAP
- 无共享密钥:不需要预共享密钥或密码
- 自动注销:当 UE 从网络中分离时,IP 会话终止
- 漫游支持:在本地和访问网络之间工作(如果 PCRF 可访问)
- NAT 安全:��接验证 UE IP,而不是客户端侧头信息
安全属性:
- 源 IP 验证:TCP 连接的源 IP 在建立连接时无法伪造
- PCRF 授权:只有具有活动、授权 PDP/PDN 上下文的 UE 才有 IP 地址
- 实时验证:每个请求查询当前 PCRF 状态
- 用户绑定:每个请求都验证 IP 到用户的映射
配置:
# config.yaml
ue_subnets:
- '100.64.0.0/22' # UE CGNAT 范围 1
- '100.64.4.0/22' # UE CGNAT 范围 2
- '100.64.24.0/24' # UE 测试范围
# 通过 HSS API 进行 PCRF 查找
hss_peers:
- '10.4.2.140:8080' # HSS 具有 PCRF 端点
- '10.4.2.141:8080'
PCRF API 端点:
GET /pcrf/subscriber_routing/{ue_ip_address}
Host: hss-server:8080
响应:
{
"subscriber_id": 12345,
"ip_address": "100.64.4.16",
"apn": "ims",
"session_start": "2026-01-07T10:30:00Z",
"rat_type": "EUTRAN"
}
验证流程:
- 从 HTTP 请求 TCP 连接中提取源 IP
- 验证 IP 是否在配置的
ue_subnets范围内 - 查询 PCRF:
GET /pcrf/subscriber_routing/{source_ip} - 如果活动会话存在,PCRF 返回
subscriber_id - 检索用户详细信息:
GET /subscriber/{subscriber_id} - 获取 IMSI,然后查询:
GET /ims_subscriber/ims_subscriber_imsi/{imsi} - 将 XCAP URL 中的 MSISDN 与 PCRF 解析的 MSISDN 进行比较
- 如果匹配:认证通过 ✓
用例:
- Web 自助服务:UE 通过移动数据连接,自动通过 IP 进行认证
- 移动应用:智能手机上的原生 XCAP 客户端
- 企业:具有固定 UE IP 分配的 CPE 设备
2. IP 子网白名单(受信网络)
对于受信的应用服务器和测试环境:
# config.yaml
as_allowed_ips:
- '10.4.3.60' # SIP 应用服务器
- '10.4.3.61' # 测试服务器
用例:
- SIP 应用服务器在呼叫处理期间检索用户配置
- 内部网络管理工具
- 开发/测试环境
3. SIP URI 到 MSISDN 解析
服务器从 XCAP URL 本身提取用户身份:
/simservs.ngn.etsi.org/users/sip:+15551234567@ims.example.com/simservs.xml
└─────────┬─────────┘
MSISDN: 15551234567
服务器解析 SIP URI 以提取 E.164 电话号码 (MSISDN)。
4. X-3GPP-Intended-Identity 头
服务器支持用于身份断言的标准 3GPP 头:
GET /simservs.xml HTTP/1.1
Host: xcap.ims.example.com
X-3GPP-Intended-Identity: sip:+15551234567@ims.example.com
此头允许客户端明确指定请求的目标用户身份。
启用 BSF 认证
要在生产中启用 GBA 认证:
- 部署 BSF 服务器:实现 3GPP TS 33.220 引导服务器
- 配置 Diameter Zh:通过 Diameter 将 BSF 连接到 HSS
- 更新 config.yaml:
bsf_support: True
bsf_url: "http://bsf-server:8090" - 实现 NAF-Key 检索:添加 BSF API 调用以获取 Ks_NAF 进行验证
- 添加摘要验证逻辑:使用共享密钥验证客户端响应
XCAP 文档类型
Simservs 根文档结构
所有 XCAP 文档都包裹在 simservs 根元素中:
<?xml version="1.0" encoding="UTF-8"?>
<simservs xmlns="http://uri.etsi.org/ngn/params/xml/simservs/xcap"
xmlns:cp="urn:ietf:params:xml:ns:common-policy">
<!-- 身份展示服务 -->
<originating-identity-presentation active="true"/>
<originating-identity-presentation-restriction active="true">
<default-behaviour>presentation-not-restricted</default-behaviour>
</originating-identity-presentation-restriction>
<!-- 呼叫转移(通信转移) -->
<communication-diversion active="true">
<NoReplyTimer>20</NoReplyTimer>
<cp:ruleset>
<!-- 呼叫转移规则 -->
</cp:ruleset>
</communication-diversion>
<!-- 呼叫限制 -->
<incoming-communication-barring active="false">
<cp:ruleset>
<!-- 来电限制规则 -->
</cp:ruleset>
</incoming-communication-barring>
<outgoing-communication-barring active="false">
<cp:ruleset>
<!-- 去电限制规则 -->
</cp:ruleset>
</outgoing-communication-barring>
</simservs>
文档类型详细信息
1. 通信转移(呼叫转移)
目的: 根据条件将来电重定向到替代目的地
XCAP URL 模式:
/simservs.ngn.etsi.org/users/{sip_uri}/simservs.xml/~~/simservs/communication-diversion
规则类型:
| 规则 ID | 条件 | 描述 |
|---|---|---|
| cfa | (无) | 呼叫转移无条件 - 立即转移所有呼叫 |
| cfb | 忙 | 呼叫转移忙 - 当线路忙时转移 |
| cfna | 无应答 | 呼叫转移无应答 - 在 NoReplyTimer 超时后转移 |
| cfnrc | 不可达 | 呼叫转移不可达 - 当设备离线时转移 |
| cfnreg | 未注册 | 呼叫转移未注册 - 当未注册到 IMS 时转移 |
XML 结构:
<ss:communication-diversion xmlns:ss="http://uri.etsi.org/ngn/params/xml/simservs/xcap"
active="true">
<ss:NoReplyTimer>20</ss:NoReplyTimer>
<cp:ruleset xmlns:cp="urn:ietf:params:xml:ns:common-policy">
<!-- 无条件转移 -->
<cp:rule id="cfa">
<cp:conditions></cp:conditions>
<cp:actions>
<ss:forward-to>
<ss:target>tel:+15559999999</ss:target>
<ss:notify-caller>false</ss:notify-caller>
</ss:forward-to>
</cp:actions>
</cp:rule>
<!-- 忙时转移 -->
<cp:rule id="cfb">
<cp:conditions>
<ss:busy/>
</cp:conditions>
<cp:actions>
<ss:forward-to>
<ss:target>tel:+15558888888</ss:target>
<ss:notify-caller>false</ss:notify-caller>
</ss:forward-to>
</cp:actions>
</cp:rule>
</cp:ruleset>
</ss:communication-diversion>
2. 来电通信限制
目的: 阻止来自特定类别的来电
XCAP URL 模式:
/simservs.ngn.etsi.org/users/{sip_uri}/simservs.xml/~~/simservs/incoming-communication-barring
规则类型:
| 规则 ID | 条件 | 描述 |
|---|---|---|
| all | (无) | 阻止所有来电 |
| international | 国际 | 阻止来自国际号码的呼叫 |
| international-exHC | 国际-除本国 | 阻止来自国际呼叫���除了本国 |
| roaming | 漫游 | 阻止漫游时的来电 |
XML 结构:
<ss:incoming-communication-barring xmlns:ss="http://uri.etsi.org/ngn/params/xml/simservs/xcap"
active="true">
<cp:ruleset xmlns:cp="urn:ietf:params:xml:ns:common-policy">
<cp:rule id="international">
<cp:conditions>
<ss:international/>
</cp:conditions>
<cp:actions>
<ss:allow>false</ss:allow>
</cp:actions>
</cp:rule>
<cp:rule id="roaming">
<cp:conditions>
<ss:roaming/>
</cp:conditions>
<cp:actions>
<ss:allow>false</ss:allow>
</cp:actions>
</cp:rule>
</cp:ruleset>
</ss:incoming-communication-barring>
3. 去电通信限制
目的: 限制拨打特定目的地的去电
XCAP URL 模式:
/simservs.ngn.etsi.org/users/{sip_uri}/simservs.xml/~~/simservs/outgoing-communication-barring
规则类型: 与来电限制相同
XML 结构:
<ss:outgoing-communication-barring xmlns:ss="http://uri.etsi.org/ngn/params/xml/simservs/xcap"
active="false">
<cp:ruleset xmlns:cp="urn:ietf:params:xml:ns:common-policy">
<cp:rule id="international">
<cp:conditions>
<ss:international/>
</cp:conditions>
<cp:actions>
<ss:allow>false</ss:allow>
</cp:actions>
</cp:rule>
</cp:ruleset>
</ss:outgoing-communication-barring>
4. 发起身份展示限制(来电显示)
目的: 控制来电显示是否向被叫方展示
XCAP URL 模式:
/simservs.ngn.etsi.org/users/{sip_uri}/simservs.xml/~~/simservs/originating-identity-presentation-restriction
XML 结构:
<ss:originating-identity-presentation-restriction active="true">
<ss:default-behaviour>presentation-restricted</ss:default-behaviour>
</ss:originating-identity-presentation-restriction>
选项:
presentation-restricted- 隐藏来电显示(匿名)presentation-not-restricted- 显示来电显示(正常)
呼叫流程图
呼叫转移配置流程
Web UI 自助服务流程
呼叫限制执行流程
BSF GBA 认证流程(启用时)
示例 XCAP 文档
完整的 Simservs 文档(去标识化)
<?xml version="1.0" encoding="UTF-8"?>
<simservs xmlns="http://uri.etsi.org/ngn/params/xml/simservs/xcap"
xmlns:cp="urn:ietf:params:xml:ns:common-policy"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<!-- 来电显示服务 -->
<originating-identity-presentation active="true"/>
<originating-identity-presentation-restriction active="true">
<default-behaviour>presentation-not-restricted</default-behaviour>
</originating-identity-presentation-restriction>
<!-- 呼叫转移配置 -->
<communication-diversion active="true">
<NoReplyTimer>20</NoReplyTimer>
<cp:ruleset>
<!-- 无条件转移(禁用) -->
<cp:rule id="cfa">
<cp:conditions></cp:conditions>
<cp:actions>
<forward-to>
<target>tel:+15556666666</target>
<notify-caller>false</notify-caller>
</forward-to>
</cp:actions>
</cp:rule>
<!-- 忙时转移(启用) -->
<cp:rule id="cfb">
<cp:conditions>
<busy/>
</cp:conditions>
<cp:actions>
<forward-to>
<target>tel:+15557777777</target>
<notify-caller>false</notify-caller>
</forward-to>
</cp:actions>
</cp:rule>
<!-- 无应答转移(启用) -->
<cp:rule id="cfna">
<cp:conditions>
<no-answer/>
</cp:conditions>
<cp:actions>
<forward-to>
<target>tel:+15558888888</target>
<notify-caller>false</notify-caller>
</forward-to>
</cp:actions>
</cp:rule>
<!-- 不可达转移(启用) -->
<cp:rule id="cfnrc">
<cp:conditions>
<not-reachable/>
</cp:conditions>
<cp:actions>
<forward-to>
<target>tel:+15559999999</target>
<notify-caller>false</notify-caller>
</forward-to>
</cp:actions>
</cp:rule>
<!-- 未注册转移(启用) -->
<cp:rule id="cfnreg">
<cp:conditions>
<not-registered/>
</cp:conditions>
<cp:actions>
<forward-to>
<target>tel:+15559999999</target>
<notify-caller>false</notify-caller>
</forward-to>
</cp:actions>
</cp:rule>
</cp:ruleset>
</communication-diversion>
<!-- 来电限制 -->
<incoming-communication-barring active="false">
<cp:ruleset>
<!-- 阻止所有来电(禁用) -->
<cp:rule id="all">
<cp:conditions></cp:conditions>
<cp:actions>
<allow>false</allow>
</cp:actions>
</cp:rule>
<!-- 阻止国际来电(禁用) -->
<cp:rule id="international">
<cp:conditions>
<international/>
</cp:conditions>
<cp:actions>
<allow>false</allow>
</cp:actions>
</cp:rule>
<!-- 阻止国际(除本国)来电(禁用) -->
<cp:rule id="international-exHC">
<cp:conditions>
<international-exHC/>
</cp:conditions>
<cp:actions>
<allow>false</allow>
</cp:actions>
</cp:rule>
<!-- 阻止漫游来电(禁用) -->
<cp:rule id="roaming">
<cp:conditions>
<roaming/>
</cp:conditions>
<cp:actions>
<allow>false</allow>
</cp:actions>
</cp:rule>
</cp:ruleset>
</incoming-communication-barring>
<!-- 去电限制 -->
<outgoing-communication-barring active="false">
<cp:ruleset>
<!-- 阻止所有去电(禁用) -->
<cp:rule id="all">
<cp:conditions></cp:conditions>
<cp:actions>
<allow>false</allow>
</cp:actions>
</cp:rule>
<!-- 阻止国际去电(禁用) -->
<cp:rule id="international">
<cp:conditions>
<international/>
</cp:conditions>
<cp:actions>
<allow>false</allow>
</cp:actions>
</cp:rule>
<!-- 阻止国际(除本国)去电(禁用) -->
<cp:rule id="international-exHC">
<cp:conditions>
<international-exHC/>
</cp:conditions>
<cp:actions>
<allow>false</allow>
</cp:actions>
</cp:rule>
<!-- 阻止漫游去电(禁用) -->
<cp:rule id="roaming">
<cp:conditions>
<roaming/>
</cp:conditions>
<cp:actions>
<allow>false</allow>
</cp:actions>
</cp:rule>
</cp:ruleset>
</outgoing-communication-barring>
</simservs>
用户数据 YAML(HSS 存储格式)
这是存储在 HSS xcap_profile 字段中的内部表示:
NoReplyTimer: 20
call_forwarding:
cfa:
enabled: false
target: tel:+15556666666
cfb:
condition: busy
enabled: true
target: tel:+15557777777
cfna:
condition: no-answer
enabled: true
target: tel:+15558888888
cfnrc:
condition: not-reachable
enabled: true
target: tel:+15559999999
cfnreg:
condition: not-registered
enabled: true
target: tel:+15559999999
call_barring_incoming:
all:
allow: false
international:
allow: false
condition: international
international-exHC:
allow: false
condition: international-exHC
roaming:
allow: false
condition: roaming
call_barring_outgoing:
all:
allow: false
international:
allow: false
condition: international
international-exHC:
allow: false
condition: international-exHC
roaming:
allow: false
condition: roaming
示例 XCAP PUT 请求(启用 CFB)
请求:
PUT /simservs.ngn.etsi.org/users/sip:+15551234567@ims.example.com/simservs.xml/~~/simservs/communication-diversion/cp:ruleset/cfb HTTP/1.1
Host: xcap.ims.example.com:5000
Content-Type: application/xcap-el+xml
Content-Length: 342
<?xml version="1.0" encoding="UTF-8"?>
<cp:rule id="cfb" xmlns:cp="urn:ietf:params:xml:ns:common-policy"
xmlns:ss="http://uri.etsi.org/ngn/params/xml/simservs/xcap">
<cp:conditions>
<ss:busy/>
</cp:conditions>
<cp:actions>
<ss:forward-to>
<ss:target>tel:+15557777777</ss:target>
<ss:notify-caller>false</ss:notify-caller>
</ss:forward-to>
</cp:actions>
</cp:rule>
响应:
HTTP/1.1 200 OK
Content-Type: application/xcap-el+xml
ETag: "eti87"
Content-Length: 0
示例 XCAP GET 请求(检索所有 CF 规则)
请求:
GET /simservs.ngn.etsi.org/users/sip:+15551234567@ims.example.com/simservs.xml/~~/simservs/communication-diversion HTTP/1.1
Host: xcap.ims.example.com:5000
Accept: application/xcap-el+xml
响应:
HTTP/1.1 200 OK
Content-Type: application/xcap-el+xml
ETag: "eti87"
Content-Length: 1456
<?xml version="1.0" encoding="UTF-8"?>
<ss:communication-diversion xmlns:ss="http://uri.etsi.org/ngn/params/xml/simservs/xcap"
xmlns:cp="urn:ietf:params:xml:ns:common-policy"
active="true">
<ss:NoReplyTimer>20</ss:NoReplyTimer>
<cp:ruleset>
<cp:rule id="cfa">
<cp:conditions></cp:conditions>
<cp:actions>
<ss:forward-to>
<ss:target>tel:+15556666666</ss:target>
<ss:notify-caller>false</ss:notify-caller>
</ss:forward-to>
</cp:actions>
</cp:rule>
<cp:rule id="cfb">
<cp:conditions>
<ss:busy/>
</cp:conditions>
<cp:actions>
<ss:forward-to>
<ss:target>tel:+15557777777</ss:target>
<ss:notify-caller>false</ss:notify-caller>
</ss:forward-to>
</cp:actions>
</cp:rule>
<!-- 其他规则省略以节省空间 -->
</cp:ruleset>
</ss:communication-diversion>
示例部分更新(更改 NoReplyTimer)
请求:
PUT /simservs.ngn.etsi.org/users/sip:+15551234567@ims.example.com/simservs.xml/~~/simservs/communication-diversion/NoReplyTimer HTTP/1.1
Host: xcap.ims.example.com:5000
Content-Type: application/xcap-el+xml
Content-Length: 87
<?xml version="1.0" encoding="UTF-8"?>
<ss:NoReplyTimer xmlns:ss="http://uri.etsi.org/ngn/params/xml/simservs/xcap">30</ss:NoReplyTimer>
响应:
HTTP/1.1 200 OK
Content-Type: application/xcap-el+xml
ETag: "eti87"
配置指南
config.yaml 参考
# HSS 后端服务器(负载均衡)
hss_peers:
- '10.4.2.140:8080' # opt-se2-hss01
- '10.4.2.141:8080' # opt-se2-hss02
# OCS(在线计费系统) - 当前未使用
ocs_peers:
- '10.4.2.140'
- '10.4.2.141'
# BSF/GBA 认证开关
bsf_support: False # 设置为 True 以进行生产 GBA
# IMS 域配置
ims_domain: 'ims.example.com'
diameter_realm: 'example.com'
# XML 命名空间前缀开关
ss_prefix: True # 在生成的 XML 中包含 'ss:' 前缀
# 允许的 UE IP 范围(用于基于 IP 的认证)
ue_subnets:
- '100.64.0.0/22' # CGNAT 范围 1
- '100.64.4.0/22' # CGNAT 范围 2
- '100.64.24.0/24' # CGNAT 范围 3
# 受信的应用服务器 IP
as_allowed_ips:
- '10.4.3.60' # opt-se2-as01
# 单元测试配置
unit_test_data:
source_ip: "100.64.4.16"
base_url: "http://localhost:5000"
msisdn: "15551234567" # 测试用户 MSISDN
Web 自助服务门户
对于不原生支持 XCAP 的用户设备,服务器提供基于 Web 的自助服务门户。用户可以直接从移动设备浏览到 XCAP 服务器,通过直观的 HTML 界面管理他们的设置。
访问方法:
用户只需在智能手机上打开 Web 浏览器并导航到 XCAP 服务器 URL:
http://xcap.ims.example.com:5000/
自动认证:
当从连接到运营商网络的移动设备访问时���认证会通过 UE IP 验证自动发生:
- 用户的设备已经有一个活动的数据会话(PDP/PDN 上下文)
- XCAP 服务器从 HTTP 连接中提取源 IP
- 服务器查询 HSS PCRF 以解析 IP → 用户身份
- 用户自动登录 - 无需用户名/密码
- Web UI 显示当前的呼叫转移、呼叫限制和来电显示设置
特点:
- 呼叫转移管理:启用/禁用转移规则,设置目的号码
- 呼叫限制控制:配置来电和去电限制
- 无应答计时器:调整无应答时的超时
- 实时更新:更改立即反映在用户配置中
- 移动优化:适应智能手机浏览器的响应式设计
用例:
- 传统设备:没有原生 XCAP 客户端支持的智能手机
- iOS 设备:在设置应用中未暴露 XCAP 设置的 iPhone
- Android 变种:没有运营商特定 XCAP 集成的 Android 版本
- 用户偏好:更喜欢 Web 界面而不是设备设置菜单的用户
- 快速访问:在旅行或漫游时进行临时更改
示例工作流程:
这消除了对专门的 XCAP 客户端软件的需求,并通过标准 Web 浏览器提供了通用访问。
API 参考
基础 URL 结构
http(s)://xcap.ims.example.com:5000/simservs.ngn.etsi.org/users/{sip_uri}/simservs.xml[/~~/selector]
组件:
- 根:
simservs.ngn.etsi.org(AUID - 应用唯一 ID) - XUI:
users/{sip_uri}(XCAP 用户标识符) - 文档:
simservs.xml - 节点选择器:
/~~/simservs/communication-diversion/...(基于 XPath)
端点参考表
| 操作 | 方法 | XCAP URL | 描述 |
|---|---|---|---|
| 获取所有服务 | GET | /users/{sip}/simservs.xml | 检索完整的 simservs 文档 |
| 获取 CF 规则 | GET | /users/{sip}/simservs.xml/~~/simservs/communication-diversion | 获取所有呼叫转移规则 |
| 获取特定 CF 规则 | GET | /users/{sip}/simservs.xml/~~/simservs/communication-diversion/cp:ruleset/{rule_id} | 获取单个 CF 规则(cfa, cfb 等) |
| 更新 CF 规则 | PUT | /users/{sip}/simservs.xml/~~/simservs/communication-diversion/cp:ruleset/{rule_id} | 更新呼叫转移规则 |
| 更新 CF 条件 | PUT | /users/{sip}/simservs.xml/~~/simservs/communication-diversion/cp:ruleset/{rule_id}/{element} | 更新规则元素(目标、条件) |
| 设置 NoReplyTimer | PUT | /users/{sip}/simservs.xml/~~/simservs/communication-diversion/NoReplyTimer | 更改无应答超时 |
| 获取来电显示 | GET | /users/{sip}/simservs.xml/~~/simservs/originating-identity-presentation-restriction | 获取来电显示限制设置 |
| 获取来电 CB | GET | /users/{sip}/simservs.xml/~~/simservs/incoming-communication-barring/cp:ruleset/{rule_id} | 获取来电限制规则 |
| 更新来电 CB | PUT | /users/{sip}/simservs.xml/~~/simservs/incoming-communication-barring/cp:ruleset/{rule_id} | 更新来电限制规则 |
| 获取去电 CB | GET | /users/{sip}/simservs.xml/~~/simservs/outgoing-communication-barring/cp:ruleset/{rule_id} | 获取去电限制规则 |
| 更新去电 CB | PUT | /users/{sip}/simservs.xml/~~/simservs/outgoing-communication-barring/cp:ruleset/{rule_id} | 更新去电限制规则 |
HTTP 头
请求头
Content-Type: application/xcap-el+xml
Accept: application/xcap-el+xml
X-3GPP-Intended-Identity: sip:+15551234567@ims.example.com
响应头
Content-Type: application/xcap-el+xml
ETag: "eti87"
错误响应
| HTTP 代码 | 含义 | 描述 |
|---|---|---|
| 200 OK | 成功 | 操作成功完成 |
| 401 Unauthorized | 需要认证 | BSF/GBA 认证挑战(如果启用) |
| 404 Not Found | 资源未找到 | 用户或文档不存在 |
| 409 Conflict | 冲突 | 文档版本不匹配(ETag 冲突) |
| 500 Internal Server Error | 服务器错误 | HSS 通信失败或处理错误 |
Web UI 端点
| 端点 | 方法 | 目的 |
|---|---|---|
/ | GET | 用户信息页面(基于 IP 查找) |
/call_forwarding | GET | 显示呼叫转移管理表单 |
/call_forwarding | POST | 通过 Web UI 更新呼叫转移规则 |
/api | GET | Swagger UI 文档 |
日志格式
2026-01-07 10:15:32,456 12345 {/var/log/XCAP.log:123} INFO GetSubscriberData called for MSISDN: 15551234567
字段: 时间戳,进程 ID��文件位置,日志级别,消息
性能考虑
- 无状态设计: XCAP 服务器不维护会话状态
- 负载分配: 每个请求随机选择 HSS 对等体
- 模板缓存: 文档模板在启动时加载一次
- XML 处理: 内存解析和格式化
- 数据库查询: 每个 GET 一个 HSS 查询,两个 PUT(读-修改-写)
结论
此 XCAP 应用服务器提供了一个生产就绪的 3GPP IMS 附加服务管理实现。主要亮点:
优势:
- 完全符合 ETSI/3GPP XCAP 标准
- 基于 REST API 的 HSS 集成,适用于云原生部署
- 多种认证选项,包括 BSF/GBA 和 UE IP 基于验证
- 基于 Web 的自助服务门户,适用于通用设备兼容性
- 高可用性,负载均衡的 HSS 对等体
部署场景:
- 移动网络运营商(MNO)和移动虚拟网络运营商(MVNO)
- 企业 IMS 部署
- VoLTE/VoWiFi 服务平台
- 云原生电信基础设施
- 私有 LTE/5G 网络
参考文献
3GPP 和 ETSI 规范
| 规范 | 标题 | 描述 | URL |
|---|---|---|---|
| ETSI TS 183 063 | 电信和互联网融合服务与协议的高级网络 (TISPAN); 基于 IMS 的 PSTN/ISDN 模拟服务 | 定义 IMS 附加服务的 simservs XML 模式的主要规范 | ETSI Portal |
| 3GPP TS 24.623 | 可扩展标记语言 (XML) 配置访问协议 (XCAP) 通过 Ut 接口用于操作附加服务 | 定义 UE 与应用服务器之间的 XCAP Ut 接口规范 | 3GPP Portal |
| 3GPP TS 24.238 | 基于会话发起协议 (SIP) 的用户配置;第 3 阶段 | 指定 IMS 中用户配置管理的基于 SIP 的机制 | 3GPP Portal |
| 3GPP TS 33.220 | 通用认证架构 (GAA);通用引导架构 (GBA) | 定义 BSF 和 GBA 框架以引导安全凭证 | 3GPP Portal |
| 3GPP TS 24.229 | 基于会话发起协议 (SIP) 和会话描述协议 (SDP) 的 IP 多媒体呼叫控制协议;第 3 阶段 | 核心 IMS 呼叫控制规范,包括服务触发器和附加服务执行 | 3GPP Portal |
| 3GPP TS 29.228 | IP 多媒体 (IM) 子系统 Cx 和 Dx 接口;信令流程和消息内容 | 定义 S-CSCF 与 HSS 之间的 Diameter Cx/Dx 接口(与用户配置检索相关) | 3GPP Portal |
| 3GPP TS 29.328 | IP 多媒体 (IM) 子系统 Sh 接口;信令流程和消息内容 | 定义 AS 与 HSS 之间的 Diameter Sh 接口以访问用户数据 | 3GPP Portal |
IETF RFCs
| RFC | 标题 | 描述 | URL |
|---|---|---|---|
| RFC 4825 | 可扩展标记语言 (XML) 配置访问协议 (XCAP) | 定义基于 HTTP 的 XML 文档操作的基础 XCAP 协议规范 | IETF Datatracker |
| RFC 4745 | 通用策略:表达隐私偏好的文档格式 | 定义用于 XCAP 文档中规则条件的通用策略 XML 命名空间 | IETF Datatracker |
| RFC 2617 | HTTP 认证:基本和摘要访问认证 | 定义在 BSF/GBA 挑战中使用的摘要认证机制 | IETF Datatracker |
| RFC 3261 | SIP:会话发起协议 | 核心 SIP 规范,是 IMS 架构的基础 | IETF Datatracker |
| RFC 6733 | Diameter 基础协议 | 定义传统 Sh/Cx 接口中使用的 Diameter 协议(背景上下文) | IETF Datatracker |
相关标准
| 标准 | 组织 | 标题 | 相关性 |
|---|---|---|---|
| OMA-TS-XDM_Core-V2_1 | 开放移动联盟 | XML 文档管理 (XDM) 规范 | 定义 OMA 上下文中 XCAP 文档管理的 XDM 架构 |
| ISO/IEC 19757-2 | ISO/IEC | 文档模式定义语言 (DSDL) — 第 2 部分:基于常规语法的验证 — RELAX NG | 用于 XCAP 文档的 XML 模式验证 |
| ITU-T E.164 | ITU-T | 国际公共电信编号计划 | 定义在 tel: URI 中使用的全球电话号码格式 |