プロバイダ広告シグナル

広告: 検索可能な場合

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

アドバタイズ間隔: 検出可能な場合

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

アドバタイズ ペイロード: Fast Pair モデル ID データ

アドバタイズメントには、サービスデータ データ型が含まれます(前掲)。§ 1.11. UUID は、0xFE2C のファスト ペアリング サービス UUID とします。サービスデータには、次のものが含まれます。

オクテット データ型 説明 値
0~2 uint24 24 ビットモデル ID varies

LE Audio 共有アドバタイジング ペイロード: ファスト ペアリング モデル ID データと FP ケーパビリティ マップ

サービスデータには、次の情報が含まれます。

オクテット データ型 説明 値
0 uint8 バージョンとフラグ
0bVVVVFFFF
  • V = バージョン
  • F = flags
0x00
1 uint8 フィールドの長さとタイプ
0bLLLLTTTT
  • L = モデル ID の長さ(バイト単位)
  • T = type
0bLLLL0111
  • length = 0bLLLL = 可変
  • type = 0b0111、モデル ID
2 - s モデル ID varies
s + 1 uint8 フィールドの長さとタイプ
0bLLLLTTTT
  • L = 長さ(バイト単位)
  • T = type
0bLLLL1000
s + 2 uint8 FP 機能マップ varies
FP 機能マップ

FP Capability Map は、プロバイダがサポートする FP 機能を表現するビットマップです。ビットマップの最初のバイトは次のように定義されます。

ビットマップ 説明
0bRRRRRRSO R - 予約ビット。現時点ではシーカーによって無視され、0 に設定されます。
S - FP LE Audio 共有のサポート(有効な場合は 1、無効な場合は 0 に設定)。
O - Out of Box(OOB)ビット。デバイスが工場出荷時の状態の場合は 1 に設定。

プロバイダが FP LE Audio Sharing 仕様(つまり、一時的なペア設定、LE Audio Sharing 広告ペイロード、ヒアラブル制御バージョン 2 をサポート)をサポートしている場合、FP LE Audio Sharing サポートビットを 1 に設定します。それ以外の場合は、0 に設定します。

プロバイダが FP シーカーとペア設定されておらず、工場出荷時の状態(プロバイダに FP アカウント キーがない)の場合は、OOB ビットを 1 に設定します。それ以外の場合は、0 に設定します。

広告: 検出できない場合

検出可能でない場合(ペア設定モードでない場合)、プロバイダ デバイスは次のガイドラインに沿ってファスト ペアリング アカウント データをアドバタイズしなければなりません。

アカウント データをアドバタイズすることで、近くのシーカーはプロバイダが自分のアカウントに属していることを認識し、プロバイダをペア設定モードに戻すことなくペア設定を開始できます。これは、ユーザーの不満の一般的な原因です。シーカーは、プロバイダとのペア設定を待たない場合や、ブロードキャストが関連しない場合(すでにペア設定済みの場合など)に、ユーザーがこのブロードキャストを無視できるようにします。また、アカウント データが誤って設定されている場合など、明らかに不適切なブロードキャストは自動的に除外されます。

アドバタイズ間隔: 検出可能でない場合

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

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

広告には、サービスデータのデータ型を含めるものとします(前掲書)。§ 1.11. UUID は、0xFE2C のファスト ペアリング サービス UUID とします。サービスデータには、次のものが含まれます。

オクテット データ型 説明 値
0 uint8 バージョンとフラグ
0bVVVVFFFF
  • V = バージョン
  • F = flags
0x00
(将来の使用のために予約済み)
1 - varies アカウントのキーデータ varies

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

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

アカウント キーフィルタ

広告されたアカウントキー フィルタにより、シーカーは、プロバイダが特定のアカウントキーを所有している可能性があるかどうかを、さらなるやり取りの前にすばやく確認できます(偽陽性の確率は低く、平均して 0.5% を大幅に下回ります)。シーカーは、タイプ 0 のフィルタ(UI インジケータを表示するフィルタ)がブロードキャストされていることを検知すると、自動的に接続して手順の開始を試み、誤検出率をさらに低減します。状況によっては、プロバイダはペア設定の準備ができていない状態でシーカーに認識されることを望むことがあります。たとえば、イヤホンがケースに戻されたときに、ヘッドセットでペア設定が拒否される可能性があるため、後続のペア設定通知の表示を停止します。

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

  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 に設定します。
    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. アドバタイズされるファスト ペアリング アカウント データで、生成されたフィルタを Account Key Filter フィールドに、S を Salt フィールドに含めます。