Tín hiệu quảng cáo của nhà cung cấp
Quảng cáo: Khi có thể phát hiện
Khi thiết bị Nhà cung cấp có thể phát hiện được BR/EDR (tức là ở chế độ ghép nối), thiết bị đó sẽ quảng cáo Dữ liệu mã nhận dạng mô hình Ghép nối nhanh qua BLE và địa chỉ BLE sẽ không được xoay vòng.
Khoảng thời gian quảng cáo: Khi có thể phát hiện
Khoảng thời gian giữa các quảng cáo không được lớn hơn 100 mili giây (10 Hz). Tốc độ nhanh cho phép Trình tìm kiếm nhanh chóng tìm thấy Nhà cung cấp, ngay cả khi quét ở chế độ công suất thấp.
Tải trọng quảng cáo: Dữ liệu mã nhận dạng mô hình Ghép nối nhanh
Quảng cáo phải chứa kiểu dữ liệu Dữ liệu dịch vụ, ibid., § 1.11. UUID phải là UUID Dịch vụ Ghép nối nhanh của 0xFE2C. Dữ liệu dịch vụ phải chứa những thông tin sau:
| Octet | Loại dữ liệu | Mô tả | Giá trị |
|---|---|---|---|
| 0-2 | uint24 |
Mã mẫu 24 bit | tuỳ thuộc |
Tải trọng Quảng cáo chia sẻ âm thanh LE: Dữ liệu mã nhận dạng mô hình Fast Pair và Bản đồ chức năng FP
Dữ liệu dịch vụ phải chứa những thông tin sau:
| Octet | Loại dữ liệu | Mô tả | Giá trị |
|---|---|---|---|
| 0 | uint8 |
Phiên bản và cờ 0bVVVVFFFF
|
0x00 |
| 1 | uint8 |
Độ dài và loại trường 0bLLLLTTTT
|
0bLLLL0111
|
| 2 – s | Mã kiểu máy | tuỳ thuộc | |
| s + 1 | uint8 |
Độ dài và loại trường 0bLLLLTTTT
|
0bLLLL1000
|
| s + 2 | uint8 |
Bản đồ chức năng FP | tuỳ thuộc |
Bản đồ chức năng FP
FP Capability Map là một bitmap biểu thị những tính năng FP mà Nhà cung cấp hỗ trợ. Byte đầu tiên của bitmap được xác định như sau:
| Bitmap | Mô tả |
|---|---|
| 0bRRRRRRSO | R – Bit dành riêng, hiện tại sẽ bị trình tìm kiếm bỏ qua và phải được đặt thành 0. S – Hỗ trợ chia sẻ âm thanh năng lượng thấp FP (đặt thành 1 nếu được bật, nếu không thì đặt thành 0). O – Bit Out of Box (OOB), đặt thành 1 nếu thiết bị là thiết bị mới xuất xưởng. |
Nếu Nhà cung cấp hỗ trợ quy cách Chia sẻ âm thanh năng lượng thấp của FP (tức là hỗ trợ Ghép nối tạm thời, Tải trọng quảng cáo chia sẻ âm thanh năng lượng thấp và Phiên bản 2 của chế độ điều khiển thiết bị trợ thính), hãy đặt bit hỗ trợ Chia sẻ âm thanh năng lượng thấp của FP thành 1; nếu không, hãy đặt thành 0.
Nếu Nhà cung cấp chưa ghép nối với bất kỳ Người tìm kiếm FP nào và là thiết bị mới xuất xưởng (nghĩa là Nhà cung cấp không có khoá tài khoản FP), hãy đặt bit OOB thành 1; nếu không, hãy đặt bit này thành 0.
Quảng cáo: Khi không thể phát hiện
Khi không thể phát hiện (tức là không ở chế độ ghép nối), thiết bị Nhà cung cấp sẽ quảng cáo Dữ liệu tài khoản Ghép nối nhanh theo các nguyên tắc sau.
Việc quảng cáo dữ liệu tài khoản cho phép Người tìm kiếm ở gần nhận ra khi một nhà cung cấp thuộc về tài khoản của họ và bắt đầu ghép nối mà không cần phải buộc nhà cung cấp quay lại chế độ ghép nối trước. Đây là nguyên nhân thường gặp khiến người dùng phàn nàn. Người tìm kiếm sẽ cho phép người dùng bỏ qua thông báo này trong trường hợp họ không đợi ghép nối với nhà cung cấp hoặc thông báo không liên quan (ví dụ: nếu họ đã ghép nối). Seeker cũng sẽ tự động lọc bỏ những chương trình phát sóng rõ ràng là không phù hợp, chẳng hạn như khi dữ liệu tài khoản được định cấu hình sai.
Khoảng thời gian quảng cáo: Khi không thể phát hiện
Khoảng thời gian giữa các quảng cáo phải tối đa là 250 mili giây (4 Hz).
Tải trọng quảng cáo: Dữ liệu tài khoản Ghép nối nhanh
Quảng cáo phải chứa kiểu dữ liệu Dữ liệu dịch vụ, Ibid., § 1.11. UUID phải là UUID Dịch vụ Ghép nối nhanh của 0xFE2C. Dữ liệu dịch vụ phải chứa những thông tin sau:
| Octet | Loại dữ liệu | Mô tả | Giá trị |
|---|---|---|---|
| 0 | uint8 |
Phiên bản và cờ 0bVVVVFFFF
|
0x00(dành riêng để sử dụng trong tương lai) |
| 1 – tuỳ thuộc | Dữ liệu khoá tài khoản | tuỳ thuộc |
Dữ liệu khoá tài khoản chứa:
| Octet | Loại dữ liệu | Mô tả | Giá trị |
|---|---|---|---|
| 0 | uint8 |
Độ dài và loại trường 0bLLLLTTTT
|
0bLLLL0000
|
| 1 – s | Bộ lọc khoá tài khoản | tuỳ thuộc | |
| s + 1 | uint8 |
Độ dài và loại trường 0bLLLLTTTT
|
0b00100001
|
| s + 2 – s + 3 | uint16 |
Salt | tuỳ thuộc |
Bộ lọc khoá tài khoản
Bộ lọc khoá tài khoản được quảng cáo cho phép Người tìm kiếm nhanh chóng kiểm tra xem Nhà cung cấp có thể sở hữu một khoá tài khoản nhất định hay không (với xác suất dương tính giả thấp, trung bình thấp hơn 0,5% đáng kể) trước khi tương tác thêm. Seeker có thể tự động kết nối và cố gắng bắt đầu quy trình khi thấy một bộ lọc đang được truyền với loại 0, tức là cho thấy chỉ báo trên giao diện người dùng, có khả năng chứa một trong các khoá tài khoản của bộ lọc đó, để giảm hơn nữa tỷ lệ dương tính giả. Trong một số trường hợp, Nhà cung cấp có thể muốn được Người tìm kiếm nhận dạng khi chưa sẵn sàng ghép nối. Một ví dụ là khi người dùng đặt tai nghe trở lại hộp sạc, chúng ta muốn ngừng hiển thị thông báo ghép nối tiếp theo vì tai nghe có thể từ chối yêu cầu ghép nối đó.
Bộ lọc khoá tài khoản là một bộ lọc Bloom có độ dài thay đổi được tạo như sau:
- Giả sử n là số lượng khoá tài khoản (n >= 1) trong danh sách Khoá tài khoản được duy trì.
- Giả sử s là kích thước của bộ lọc tính bằng byte, được rút gọn thành (1, 2*n + 3). Ví dụ: nếu 1 khoá được duy trì, s = 4 byte.
uint8_t s = (((uint8_t)(( float )1.2 * n)) + 3); - Khởi tạo bộ lọc F dưới dạng một mảng gồm s byte, mỗi byte được đặt thành 0.
uint8_t F[s] = {0}; Đối với mỗi khoá tài khoản K trong Danh sách khoá tài khoản được duy trì:
a. Đặt V là 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. Băm V bằng SHA256, thu được giá trị 32 byte H = {H0, …, H31}.
uint8_t H[32] = {0}; SHA256_hash_function(V, H);c. Chia H thành 8 số nguyên không dấu 4 byte theo thứ tự từ lớn đến bé, X = {X0, …, X7}, trong đó 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. Đối với mỗi Xi:
i. Đặt M là Xi modulo số lượng bit trong bộ lọc, (s * 8).
ii. Lấy byte trong F tại chỉ mục (M / 8), làm tròn xuống.
iii. Trong byte, hãy đặt bit ở chỉ mục (M % 8) thành 1.
iv. Nói cách khác:// 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)); }
Thêm bộ lọc F làm trường Bộ lọc khoá tài khoản trong dữ liệu quảng cáo. Xin lưu ý rằng giá trị này không có "endianness" (thứ tự byte), vì không có byte nào quan trọng hơn hoặc ít quan trọng hơn – đừng thay đổi thứ tự byte.
Ruộng muối
Salt là một giá trị ngẫu nhiên được thêm vào các khoá tài khoản khi tạo bộ lọc bloom. Bạn nên tạo lại chuỗi ngẫu nhiên này mỗi khi RPA được cập nhật cho Nhà cung cấp để tránh việc theo dõi trên nhiều lần xoay vòng địa chỉ.
Cách tạo Bộ lọc khoá tài khoản bằng muối:
- Tạo một S gồm 2 byte ngẫu nhiên. Xin lưu ý rằng không có "endianness" cho giá trị này, vì không có byte nào quan trọng hơn hoặc ít quan trọng hơn – đừng thay đổi thứ tự byte.
- Dùng S gồm 2 byte làm Salt.
- Trong Dữ liệu tài khoản được quảng cáo của tính năng Ghép nối nhanh, hãy thêm bộ lọc đã tạo vào trường Bộ lọc khoá tài khoản và S vào trường Salt.