プロバイダの広告シグナル

広告: 目に留まりやすいタイミング

プロバイダ デバイスが BR/EDR で検出可能(つまりペア設定モード)の場合、BLE を介してファスト ペアリング モデル ID データをアドバタイズしなければならず、BLE アドレスはローテーションされません。

広告間隔: 見つかりやすさ

広告の間隔は 100 ミリ秒(10 Hz)以下とします。高速モードでは、低電力モードでスキャンする場合であっても、シーカーがプロバイダをすばやく見つけることができます。

広告ペイロード: ファスト ペアリング モデル 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(UI の表示を表示)または 0b0010(UI の表示を非表示)、アカウント キー フィルタ
1 ~s アカウント キー フィルタ 場合によって異なる
S+1 uint8 フィールドの長さと型
0bLLLLTTTT
  • L = バイト単位の長さ
  • T = 型
0b00100001
  • 長さ = 0b0010 = 2
  • タイプ = 0b0001、Salt
S+2 ~S+3 uint16 Salt 場合によって異なる

アカウント キー フィルタ

アドバタイズされたアカウント キー フィルタにより、シーカーは、さらなるインタラクションの前に、プロバイダが特定のアカウントキー(偽陽性率が低く平均 0.5% 未満)を持っているかどうかをすばやく確認できます。シーカーはタイプ 0 のフィルタがブロードキャストされているとき、自動的に接続してプロシージャの開始を試みることができます。つまり、偽陽性率をさらに減らすために、いずれかのアカウント キーを含む可能性がある UI 表示を示しています。場合によっては、ペアリングの準備ができていないときに、プロバイダがシーカーに認識されたい場合があります。たとえば、イヤフォンをケースに戻すときは、ヘッドセットでペア設定が拒否される可能性があるため、後続のペア設定通知の表示は停止します。

アカウントキー フィルタは、次のように作成された可変長の Bloom フィルタです。

  1. 永続化されたアカウントキー リストにあるアカウント キーの数を n とします(n >= 1)。
  2. フィルタのサイズ(バイト単位) を (1.2×n + 3) だけ切り捨てます。たとえば、1 個の鍵が永続化されている場合、s = 4 バイトです。
    uint8_t s = (((uint8_t)(( float )1.2 * n)) + 3);
  3. フィルタ F を 0 に設定した s バイトの配列として初期化します。
    uint8_t F[s] = {0};
  4. 永続アカウントキーリストのアカウント キー K ごとに、次の操作を行います。
    a. V を連結します(Kソルト)。

    // 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. フィルタのビット数を mi
    で割ります(s * 8)。
    ii. インデックス F のバイトを切り捨て(M / 8)に切り捨てます。
    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 を含めます。 この値には「エンディアン」はありません。意味のあるバイトが多すぎたり少なくなったりするため、バイト順を変更しないでください。

ソルト フィールド

ソルトは、ブルーム フィルタを作成する際にアカウント キーに追加されるランダムな値です。このソルトは、プロバイダが RPA を更新するたびに再生成し、アドレスのローテーション全体でトラッキングされないようにする必要があります。

ソルトを使用してアカウント キーフィルタを生成するには:

  1. 2 バイトの S をランダムに生成します。この値には「意味」の有無は関係ありません。バイトの増減はないため、バイト順を変更しないでください。
  2. 2 バイトの S をソルトとして使用します。
  3. アドバタイズされたファスト ペアリング アカウント データの [Account Key Filter] フィールドには生成されたフィルタを、[Salt] フィールドには S を含めます。