建立 CPID

GTAF 在与 DPA 通信时使用用户密钥来识别订阅者。有权访问用户的 MSISDN 的应用可将其用作 user_key。另一方面,无权访问 MSISDN 的应用需要建立运营商计划标识符 (CPID),而无需发现用户的 MSISDN。接下来,我们将介绍 CPID 建立机制。

CPID 通话流程

图 2:建立 CPID 的调用流程。

  1. UE 中的 Google 应用使用 Google 内部 API 从 GTAF 检索 CPID 端点的网址。系统会使用客户端的公共 IP 地址和有效 SIM 卡的 MCC+MNC 识别运营商。对于 MVNO,Google 将使用 SPNGID1 来确定 MVNO
  2. 客户端向 CPID 端点发出 HTTP GET 请求。运营商可以支持通过 HTTPS 发送请求。
  3. 运营商可以使用其深度数据包检测功能来识别请求,并将用户的电话号码作为 HTTP 标头注入该请求。
  4. CPID 端点接收请求,构建 CPID,并将 CPID 返回到 UE,并带有存留时间 (TTL),后者指示 UE 可使用此 CPID 的时长。

运营商也可以在 CPID 端点网址中使用 IP 地址而非域名。这些 IP 地址可以位于专用地址空间中,但必须可供运营商网络内的 Google 客户端访问。

在初始配置过程中,运营商应向 Google 提供以下信息:

  1. 应用为获取 CPID 而需联系的 CPID_网址。必须提供一个 CPID_网址,但运营商可以提供多个网址以提高可用性。
  2. 运营商拥有的 IP 前缀列表,以及运营商希望映射到所提供的 CPID_网址 的移动设备国家/地区代码 (MCC) 和移动网络代码 (MNC)。如果运营商使用 SPN 或 GID1 来区分其网络中的 MVNO,则运营商也应提供此信息。Google 将使用此信息将客户端与相应的 CPID 端点进行匹配,如图 2 的第 1 步所示。

请求的格式如下: GET CPID_URL 出于旧版原因,CPID 端点应该能够支持如下请求:

GET CPID_URL?app={app_id}

CPID 端点在生成 CPID 时可以忽略 {app_id} 网址参数。但是,它必须能够处理包含该参数的请求。

向 CPID 端点发出的请求可以包含 Accept-Language 标头。如果包含该标头,在 DPA 使用 Mobile Data Plan Sharing API 发送的更新中,人类可读的字符串必须使用 CPID 请求中提供的设置。

每次客户端发出 GET CPID_网址 请求时,都必须接收新的 CPID。如果 CPID 创建成功,CPID 端点必须返回 200 OK 响应。响应正文必须包含 CPIDResponse 的实例。

{
    "cpid": "<CPID_string>",
    "ttlSeconds": 2592000
}

即使订阅者之后请求了其他 CPID,返回的 CPID 也必须在 ttlSeconds 秒内有效。为了获得最佳用户体验,Google 建议您将 TTL 值设为 30 天(但至少为 14 天)。在后续调用 DPA 时,GTAF 会根据 RFC2396 对 CPID 进行编码。

生成 CPID

CPID 端点创建 CPID 的推荐方法是:

CPID_string = Base64(AES(MSISDN + TimeStamp + language, secret))

CPID 端点会将客户端在 Accept-Language 标头中发送的语言 MSISDN 和高分辨率时间戳串联起来,然后使用 secret 密钥通过 AES 将其加密。时间戳应与 CPID 的到期时间相对应。加密的输出内容采用 Base64 编码格式。此外,在网址中使用 CPID 时,必须对其进行网址编码,以处理 Base64 中使用的特殊字符 (/+=)。尤其是当 GTAF 调用 DPA 或 DPA 调用移动流量套餐共享 API 时,CPID 必须经过网址编码。

实现特定的 CPID 端点可能并非易事,具体取决于特定运营商的情况。经常遇到的一项特定挑战是在 CPID 端点上访问 MSISDN。我们很乐意分享吸取经验教训的教训。如果您遇到任何问题,请与我们联系。

CPID 存储

使用上述机制生成的 CPID 无需存储到数据库中。处理 DPA 调用的相关信息可以来自 CPID。

  1. 当 DPA 收到针对计划状态或提议的 GTAF 调用时,可以通过解密 CPID 并提取 MSISDN 来派生 MSISDN。
  2. 可以解密 CPID,然后推导出到期时间时间戳,从而得出 CPID 的到期时间。

可用性和容量要求

如果客户端无法检索 CPID,则无法从 Mobile Data Plan API 访问任何信息。因此,运营商应采取必要的措施来确保 CPID 端点的可用性。这些措施包括拥有多个 CPID 端点和 DPI 函数实例,并使这两个函数具有物理、站点和网络冗余,并确保系统资源和容量充足。此外,CPID 端点以及注入标头的 DPI 函数必须有足够的容量来处理请求 CPID 的所有 Google 客户端的负载。CPID 端点可以在 ttlSeconds 字段中使用较大的值来降低其生成 CPID 的频率。

错误案例

如果发生错误,CPID 端点必须返回 HTTP 错误,且响应正文必须包含 ErrorResponse 的实例。良好的错误消息会包含有助于调试错误原因的信息。例如,如果 CPID 过期(包括 CPID 生成和到期时间),这将有助于我们确认 CPID 端点是否按预期运行。

{
    "errorMessage": "<error message>",
    "cause": "USER_ROAMING"
}

CPID 端点必须根据具体情况返回以下内容:

  1. 如果某个 CPID 不属于任何用户(例如,用户属于另一个运营商,但正通过此 roid 漫游),或者尚未选择与 Google 共享数据计划信息,那么该 CPID 必须向 USER_ROAM、USER_OPT_OUT 和 INELIGI 提供这类用户信息(用户 ID 为 403)
  2. 如果收到的 CPID 请求包含无效的电话号码,则 CPID 端点必须返回 HTTP 400 以及 INVALID_NUMBER 错误原因。
  3. 如果对 CPID 端点的请求格式有误,CPID 端点必须返回 HTTP 400,并作为错误原因返回 ERROR_CAUSE_UNSPECIFIED。
  4. 对于其他错误原因,可以使用任何兼容的 HTTP 错误代码。具体而言,HTTP 500 是导致 CPID 端点出现任何内部故障的合适错误原因。