供應商廣告信號

廣告:發生曝光時

如果供應商裝置在 BR/EDR 可偵測到時 (也就是處於配對模式),就會在 BLE 上通告快速配對模型 ID 資料,且 BLE 位址不會旋轉。

廣告間隔:曝光可見時

廣告之間的間隔不得超過 100 毫秒 (10Hz)。快速速率可讓搜尋器快速找到供應器,即使在低耗電模式下進行掃描也一樣。

廣告酬載:快速配對模型 ID 資料

廣告應包含服務資料資料類型 ibid。§ 1.11. UUID 應為 0xFE2C 的快速配對服務 UUID。服務資料應包含下列項目:

八位元 資料類型 說明
0 到 2 年 uint24 24 位元模型 ID 因人而異

廣告:不可供偵測時

當偵測不到 (也就是未處於配對模式) 時,供應商裝置應遵循下列準則宣傳快速配對帳戶資料。

透過廣告帳戶資料,附近的搜尋器可以辨識出供應商屬於其帳戶,並且不必先強制供應商重新進入配對模式 (這是使用者申訴的常見原因)。尋找者將提供機會,讓使用者在未等候與供應商配對,或廣播不相關 (例如,如果已配對) 的情況下忽略此廣播。此外,系統也會自動篩除明顯品質不佳的廣播訊息,例如帳戶資料設定錯誤時。

廣告間隔:不可供偵測時

廣告之間的間隔不得超過 250 毫秒 (4Hz)。

廣告酬載:快速配對帳戶資料

廣告應包含服務資料資料類型 Ibid。§ 1.11. UUID 應為 0xFE2C 的快速配對服務 UUID。服務資料應包含下列項目:

八位元 資料類型 說明
0 uint8 版本和旗標
0bVVVFFFF
  • V = 版本
  • F = 旗標
0x00
(保留供日後使用)
1 - 各不相同 帳戶金鑰資料 varies
0x00 (如果帳戶金鑰清單空白)

帳戶金鑰資料包含:

八位元 資料類型 說明
0 uint8 欄位長度並輸入
0bLLLLTTT
  • L = 帳戶金鑰篩選器的長度 (以位元組為單位)
  • T = 類型
0bLL0000
  • long = 0bLLLL = 各不相同
  • type = 0b0000 (顯示 UI 指示) 或 0b0010 (隱藏 UI 指示)、帳戶金鑰篩選器
1 至 帳戶金鑰篩選器 因人而異
s + 1 鍵 uint8 欄位長度並輸入
0bLLLLTTT
  • L = 長度 (以位元組為單位)
  • T = 類型
0b00100001
  • 長度 = 0b0010 = 2
  • 類型 = 0b0001,Salt
s + 2 - S + 3 uint16 Salt 因人而異

帳戶金鑰篩選器

通告帳戶金鑰篩選器可讓 Seeker 在進一步互動之前,快速檢查供應商是否具備特定帳戶金鑰 (偽陽性機率偏低,平均遠低於 0.5%)。如果搜尋器看到類型為 0 的篩選器正在廣播,可能會自動連線並嘗試啟動程序;即顯示 UI 指示,可能包含其中一個帳戶鍵,以便進一步降低誤判率。在某些情況下,搜尋器可能會希望在未準備好配對的情況下能夠辨識供應器。其中一個例子是,當耳機變回保護殼時,我們會想要停止顯示後續的配對通知,因為耳機可能會拒絕配對通知。

「帳戶金鑰篩選器」是變數長度的 Bloom 篩選器,結構如下:

  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」除以大端至的八個 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. 讓 MXi 修改篩選器中的位元數 (s * 8)。
    ii. 在索引 (M / 8) 處取得 F 中的位元組,無條件捨去至整數。
    iii. 在位元組中,將索引位置 (M % 8) 設為 1。
    iv. 換句話說:

        // 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」篩選器做為「帳戶金鑰篩選器」欄位。 請注意,這個值沒有「終止性」,因為位元組沒有增或較少,因此不要變更位元組順序。

鹽欄位

鹽是隨機值,會在建立 Bloom 篩選器時附加至帳戶鍵。每次為供應商更新 RPA 時,都應該重新產生這個鹽,以免跨位址輪替進行追蹤。

如何使用鹽產生帳戶金鑰篩選器:

  1. 產生隨機的 2 位元組 S。請注意,這個值沒有「結束程度」,因為沒有更多或更低重要的位元組,因此不要變更位元組順序。
  2. 使用 2 位元組 S 做為鹽。
  3. 在通告的快速配對帳戶資料中,將產生的篩選器新增至「帳戶金鑰篩選器」欄位,並在「鹽」欄位加入 S