プロバイダ広告シグナル

広告: 検出可能

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

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

広告間の間隔は 100 ms(10 Hz)以下にする必要があります。レートが速いため、低電力モードでスキャンしている場合でも、シーカーはプロバイダをすばやく見つけることができます。

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

アドバタイズメントには、同項の Service Data データ型が含まれる。§ 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 - さまざま アカウント キーデータ 異なる

アカウントキーデータには、次の情報が含まれます。

オクテット データ型 説明
0 uint8 フィールドの長さとタイプ
0bLLLLTTTT
  • L = アカウントキー フィルタの長さ(バイト単位)
  • T = タイプ
0bLLLL0000
  • length = 0bLLLL = 可変
  • type = 0b0000(UI の表示)または 0b0010(UI の非表示)、アカウントキー フィルタ
1 - アカウント キー フィルタ 変動あり
s + 1 uint8 フィールドの長さとタイプ
0bLLLLTTTT
  • L = 長さ(バイト単位)
  • T = タイプ
0b00100001
  • length = 0b0010 = 2
  • type = 0b0001、Salt
s + 2 - s + 3 uint16 Salt 変動あり

アカウント キー フィルタ

広告掲載されたアカウントキー フィルタを使用すると、シーカーは、さらにやり取りを進める前に、プロバイダが特定のアカウントキーを所有しているかどうかをすばやく確認できます(誤検出の確率は低く、平均で 0.5% 未満です)。誤検出率をさらに低減するために、Seeker は、アカウント キーのいずれかが含まれている可能性のあるタイプ 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. フィルタ Fs バイトの配列として初期化し、それぞれを 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. インデックス(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 バイトの S を Salt として使用します。
  3. アドバタイズされたファスト ペアリング アカウント データで、生成されたフィルタを [アカウント キー フィルタ] フィールドに、[Salt] フィールドに S を含めます。