供應商廣告信號
廣告:可搜尋時
當「供應商」裝置可透過 BR/EDR 探索 (即處於配對模式) 時,應透過 BLE 播送快速配對型號 ID 資料,且 BLE 位址不得輪替。
廣告間隔:可探索時
廣告間隔不得超過 100 毫秒 (10 Hz)。如果掃描速度較快,即使「搜尋者」處於低功耗模式,也能快速找到「供應者」。
廣告酬載:快速配對模型 ID 資料
廣告應包含服務資料資料類型,同上,§ 1.11. UUID 應為 0xFE2C 的快速配對服務 UUID。服務資料應包含下列資訊:
| 八位元 | 資料類型 | 說明 | 值 |
|---|---|---|---|
| 0-2 | uint24 |
24 位元模型 ID | 因人而異 |
LE Audio Sharing Advertising 酬載:快速配對模型 ID 資料和 FP 功能對應
服務資料應包含下列資訊:
| 八位元 | 資料類型 | 說明 | 值 |
|---|---|---|---|
| 0 | uint8 |
版本和旗標 0bVVVVFFFF
|
0x00 |
| 1 | uint8 |
欄位長度和類型 0bLLLLTTTT
|
0bLLLL0111
|
| 2 - s | 模型 ID | 因人而異 | |
| s + 1 | uint8 |
欄位長度和類型 0bLLLLTTTT
|
0bLLLL1000
|
| s + 2 | uint8 |
FP 功能對應表 | 因人而異 |
FP 功能對應表
FP 功能地圖是點陣圖,代表供應商支援的 FP 功能。點陣圖的第一個位元組定義如下:
| 點陣圖 | 說明 |
|---|---|
| 0bRRRRRRSO | R - 保留位元,目前會遭到搜尋器忽略,應設為 0。 S - FP LE Audio Sharing 支援 (啟用時設為 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。
廣告:無法搜尋時
如果無法探索 (即不在配對模式),供應商裝置應使用下列指南宣傳快速配對帳戶資料。
廣告宣傳帳戶資料後,附近的 Seeker 就能辨識供應商是否屬於自己的帳戶,並啟動配對程序,不必先將供應商強制返回配對模式,這也是使用者常見的抱怨原因。如果使用者不想等待與供應商配對,或廣播與他們無關 (例如已配對),搜尋者會提供忽略這項廣播的機會。系統也會自動篩除明顯不佳的廣播,例如帳戶資料設定錯誤時。
廣告間隔:無法搜尋時
廣告間隔不得超過 250 毫秒 (4 Hz)。
廣告酬載:快速配對帳戶資料
廣告應包含「服務資料」資料類型,同上,§ 1.11. UUID 應為 0xFE2C 的快速配對服務 UUID。服務資料應包含下列資訊:
| 八位元 | 資料類型 | 說明 | 值 |
|---|---|---|---|
| 0 | uint8 |
版本和旗標 0bVVVVFFFF
|
0x00(預留供日後使用) |
| 1 - 因人而異 | 帳戶金鑰資料 | 因人而異 |
帳戶金鑰資料包含:
| 八位元 | 資料類型 | 說明 | 值 |
|---|---|---|---|
| 0 | uint8 |
欄位長度和類型 0bLLLLTTTT
|
0bLLLL0000
|
| 1 - s | 帳戶金鑰篩選器 | 因人而異 | |
| s + 1 | uint8 |
欄位長度和類型 0bLLLLTTTT
|
0b00100001
|
| s + 2 - s + 3 | uint16 |
Salt | 因人而異 |
帳戶金鑰篩選器
廣告宣傳的帳戶金鑰篩選器可讓搜尋者快速檢查供應商是否可能擁有特定帳戶金鑰 (誤判機率很低,平均遠低於 0.5%),再進行後續互動。當 Seeker 看到以類型 0 播送的篩選器 (即顯示 UI 指示) 時,可能會自動連線並嘗試啟動程序,因為這類篩選器可能含有 Seeker 的其中一個帳戶金鑰,進一步降低誤判率。在某些情況下,供應商可能希望在尚未準備好配對時,獲得搜尋者認可。舉例來說,如果將耳機放回充電盒,我們希望停止顯示後續的配對通知,因為耳機可能會拒絕配對。
帳戶金鑰篩選器是可變長度的 Bloom 篩選器,建構方式如下:
- 假設 n 是持續性「帳戶金鑰清單」中的帳戶金鑰數量 (n >= 1)。
- 假設 s 是篩選器的大小 (以位元組為單位),則 s 為 (1.2*n + 3) 截斷。舉例來說,如果保留 1 個金鑰,s = 4 個位元組。
uint8_t s = (((uint8_t)(( float )1.2 * n)) + 3); - 將篩選器 F 初始化為 s 位元組的陣列,每個位元組都設為 0。
uint8_t F[s] = {0}; 針對持續性「帳戶金鑰」清單中的每個帳戶金鑰 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. 設 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 設為「帳戶金鑰篩選器」欄位。 請注意,這個值沒有「位元組順序」,因為沒有更多或更少的有效位元組,請勿變更位元組順序。
鹽田
鹽值是建構 Bloom 篩選器時附加至帳戶金鑰的隨機值。每次更新供應商的 RPA 時,都應重新產生這個鹽,避免在地址輪替時遭到追蹤。
如要使用鹽產生帳戶金鑰篩選器,請按照下列步驟操作:
- 產生隨機 2 位元組的 S。請注意,這個值沒有「位元組順序」,因為沒有更重要或不重要的位元組,請勿變更位元組順序。
- 使用 2 位元組的 S 做為 Salt。
- 在放送的「快速配對」帳戶資料中,將產生的篩選器納入「帳戶金鑰篩選器」欄位,並將 S 納入「鹽」欄位。