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

広告: 見つけやすい場合

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

広告掲載の間隔: 検出可能な場合

アドバタイズメントの間隔は 100 ms(10 Hz)以下にしてください。高速レートを使用することで、シーカーは省電力モードでスキャンしている場合でも、プロバイダをすばやく見つけることができます。

広告ペイロード: ファスト ペアリング モデル ID データ

広告には、上記の「サービスデータ」データタイプを含めるものとします。第 1.11 条UUID は 0xFE2C のファスト ペアリング サービス UUID です。サービスデータには以下を含める必要があります。

オクテット データの種類 説明
0~2 uint24 24 ビットのモデル ID 場合によって異なる

広告: 見つけられない場合

検出できない場合(つまり、ペア設定モードでない場合)、プロバイダ デバイスは、次のガイドラインを使用して、ファスト ペアリング アカウント データをアドバタイズするものとします。

アカウント データをアドバタイズすることで、近くのシーカーはプロバイダがアカウントに属していることを認識し、最初にプロバイダを強制的にペア設定モードに戻すことなく、ペア設定を開始できます。これは、ユーザーからの苦情の一般的な原因です。シーカーは、ユーザーがプロバイダとのペア設定を待っていない場合、またはブロードキャストが重要でない場合(すでにペア設定されている場合など)に、このブロードキャストを無視できる機会を提供します。また、シーカーは明らかに不正なブロードキャストを自動的に除外します(アカウント データが正しく構成されていない場合など)。

広告掲載の間隔: 検出できない場合

アドバタイズメントの間隔は 250 ミリ秒(4 Hz)以下にする必要があります。

広告ペイロード: ファスト ペアリング アカウント データ

広告には、サービスデータデータタイプ(上記を参照)を含むものとします。第 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+1 uint8 フィールドの長さと型
0bLLLLTTTT
  • L = 長さ(バイト単位)
  • T = 型
0b00100001
  • 長さ = 0b0010 = 2
  • type = 0b0001、Salt
S+2 ~S+3 uint16 Salt 場合によって異なる

アカウント キー フィルタ

公表されているアカウントキーフィルタにより、シーカーはプロバイダが特定のアカウントキーを持っている可能性があるかどうかを素早く確認できます(偽陽性率は低く、平均で 0.5% を大きく下回る確率です)。シーカーは、誤検出の割合をさらに低減するために、タイプ 0 のブロードキャスト(UI 表示を示す)を見たときに自動的に接続し、手順を開始することがあります。状況によっては、ペア設定の準備ができていないときに、プロバイダがシーカーに認識されたいと考える場合があります。一例として、イヤフォンがケースに戻されたら、ヘッドセットによってペア設定が拒否される可能性があるため、後続のペア設定通知の表示を停止したい場合があります。

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

  1. 保持されるアカウントキーリストのアカウントキーの数(n >= 1)を n とします。
  2. フィルタのサイズ(バイト単位)である s が (1.2*n + 3) 切り捨てられます。たとえば、1 つのキーが永続化する場合、s = 4 バイトになります。
    uint8_t s = (((uint8_t)(( float )1.2 * n)) + 3);
  3. フィルタ Fs バイトの配列として初期化し、それぞれを 0 に設定します。
    uint8_t F[s] = {0};
  4. 保存されているアカウントキーのリストにあるアカウントキー K ごとに、次の操作を行います。
    a. V を連結(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 を、X = {X0, ..., X7} の 4 バイトの符号なし整数に 8 つ除算します(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 がフィルタ内のビット数(s × 8)をモジュロした Xi であるとします。
    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 を含めます。 この値には「エンディアン」はありません。重要なバイトは増減しないため、バイト順序を変更しないでください。

塩田

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

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

  1. ランダムな 2 バイトの S を生成します。この値には「エンディアン」はありません。2 つの重要なバイトはないため、バイト順序は変更しないでください。
  2. ソルトとして 2 バイトの S を使用します。
  3. アドバタイズされたファスト ペアリング アカウント データの、[アカウント キー フィルタ] フィールドに生成されたフィルタを、[ソルト] フィールドに S を追加します。