提供商广告信号

广告:在可以发现时

当提供程序设备处于 BR/EDR 可检测状态(即处于配对模式)时, 应通过 BLE 通告快速配对模型 ID 数据,BLE 地址不得 旋转。

广告间隔:在可检测到时

广告之间的间隔不应超过 100 毫秒 (10Hz)。答 快速查找提供程序可快速找到该提供商,即使在扫描过程中扫描 低功耗模式。

广告载荷:快速配对模型 ID 数据

广告应包含服务数据数据类型(同上)。第 1.11 条。通过 UUID 应为 0xFE2C 的快速配对服务 UUID。服务数据应 包含以下内容:

八位字节 数据类型 说明
0-2 uint24 24 位模型 ID 因人而异

广告:无法被用户发现时

当不可检测到时(即未处于配对模式),提供程序设备应 宣传快速配对账号数据。

通过宣传账号数据,附近的探索者可以识别提供商 并开始配对,而不必强制 首先重新进入配对模式,这是导致 投诉。探索者将为用户提供忽略机会 或者不等待与提供商配对或 与广播无关(例如,如果广播已配对)。 搜寻者还将自动滤除明显不佳的广播,例如 当账号数据配置有误时。

广告间隔:在无法被检测到时

广告之间的时间间隔不应超过 250 毫秒 (4Hz)。

广告载荷:快速配对账号数据

广告应包含服务数据数据类型(同上)。第 1.11 条。通过 UUID 应为 0xFE2C 的快速配对服务 UUID。服务数据应 包含以下内容:

八位字节 数据类型 说明
0 uint8 版本和标记
0bVVVVFFFF
  • V = 版本
  • F = 标志
0x00
(预留供日后使用)
1 - 视具体情况而定 账号密钥数据 如果账号密钥列表为空,则不固定
0x00

账号密钥数据包含:

八位字节 数据类型 说明
0 uint8 字段长度和类型
0bLLLLTTTT
  • L = 账号密钥过滤器的长度(以字节为单位)
  • T = 类型
0bLLLL0000
  • 长度 = 0bLLLL = 各异
  • type = 0b0000(显示界面指示)或 0b0010(隐藏界面指示),账号密钥过滤器
1 - 账号密钥过滤器 因人而异
S + 1 uint8 字段长度和类型
0bLLLLTTTT
  • L = 长度(字节)
  • T = 类型
0b00100001
  • 长度 = 0b0010 = 2
  • type = 0b0001、Salt
s + 2 - s + 3 uint16 Salt 因人而异

账号密钥过滤器

查找者可以通过所通告的账号密钥过滤器快速检查 提供商可能拥有某个账号密钥(误报率较低) 平均远低于 0.5%)。通过 探寻器可能会在发现并自动连接时尝试启动程序 一个正在广播的过滤器,类型为 0,即显示界面指示, 从而降低错误发生率 积极。在某些情况下,提供商可能希望系统 同时尚未准备好配对。例如,如果将耳机放入 我们想停止显示后续的配对通知 因为耳机可能会拒绝该配对。

账号密钥过滤条件是可变长度的 泛光过滤器构造为 如下:

  1. n 是保留的 n >= 1 账号密钥列表
  2. s(以字节为单位的过滤器大小)将 (1.2*n + 3) 截断。对于 例如,如果保留了 1 个键,则 s = 4 个字节。
    uint8_t s = (((uint8_t)(( float )1.2 * n)) + 3);
  3. 将过滤器 F 初始化为 s 字节数组,每个字节数组都设置为 0。
    uint8_t F[s] = {0};
  4. 对于持久保留的账号密钥列表中的每个账号密钥 K
    a.让 V 为 concat(K, Salt)。

    // In the sample code, the size of salt is 2 bytes.
    #define SALT_SIZE 2
    
    uint8_t V[FASTPAIR_ACCOUNT_KEY_SIZE + SALT_SIZE];
    for (uint8_t keyIndex = 0; keyIndex < n; keyIndex++)
      {
         // concat (K, Salt)
          fastpair_get_account_key_by_index(keyIndex, V);
    
          uint8_t randomSalt = (uint8_t)rand();
          V[FASTPAIR_ACCOUNT_KEY_SIZE] = randomSalt;
          ... }
    

    b. 使用 SHA256 哈希 V,获得 32 字节的值 H = {H0, ..., H31}。

    uint8_t H[32] = {0};
    SHA256_hash_function(V, H);
    

    c. 将 H 除以 8 个 4 字节的无符号整数(采用大端字节序), X = {X0, ..., X7},其中 X0 = 0xH0H1H2H3

         uint32_t X[8];
         for (index = 0; index < 8; index++)
         {
            X[index] = (((uint32_t)(H[index * 4])) << 24) |
                        (((uint32_t)(H[index * 4 + 1])) << 16) |
                        (((uint32_t)(H[index * 4 + 2])) << 8) |
                        (((uint32_t)(H[index * 4 + 3])) << 0);
         }
    

    d. 对于每个 Xi
    i.让 M 为过滤器中位数的 Xi 模数, (s * 8)。
    ii.获取 F 中位于索引 (M / 8) 处的字节,向下舍入。
    iii.在该字节中,将索引 (M % 8) 处的位设置为 1。
    四、也就是说:

        // M = Xi % (s * 8)
        // F[M/8] = F[M/8] | (1 << (M % 8))
        for (index = 0; index < 8; index++)
        {
            uint32_t M    = X[index] % (s * 8);
            F[M / 8] = F[M / 8] | (1 << (M % 8));
        }
    

在广告数据中添加过滤条件 F 作为“账号密钥过滤条件”字段。 请注意,不存在“字节序”该值没有增加或减少 有效字节,请勿更改字节顺序。

盐田

盐是构建 繁花盛放过滤器。每次更新 RPA 后,都应重新生成此盐 Provider 以避免跨地址轮替进行跟踪。

要使用盐生成账号密钥过滤器,请执行以下操作:

  1. 生成一个 2 字节的随机 S。请注意,不存在“字节序”至此 因此请勿改变该字节 订单。
  2. 使用 2 字节 S 作为盐。
  3. 在所宣传的快速配对账号数据中,将生成的过滤条件添加到 Account Key Filter 字段,而“Salt”字段中的 S