אות של פרסום של ספק
פרסום: מתי המודעות גלויות
כשמכשיר הספק גלוי ל-BR/EDR (כלומר, במצב התאמה), הוא צריך לפרסם נתונים של מזהה דגם של התאמה מהירה דרך BLE, ולא צריך לבצע רוטציה של כתובת ה-BLE.
מרווח הזמן לפרסום: כשהמודעות גלויות
המרווח בין המודעות לא יכול להיות ארוך מ-100 אלפיות השנייה (10Hz). קצב מהיר מאפשר למכשיר המחפש למצוא במהירות את הספק, גם כשהסריקה מתבצעת במצב צריכת אנרגיה נמוכה.
עומס נתונים בפרסום: נתוני מזהה הדגם של התאמה מהירה
המודעה צריכה לכלול את סוג הנתונים 'נתוני שירות', שם, 1.11. ה-UUID יהיה ה-UUID של שירות ההתאמה המהירה של 0xFE2C
. נתוני השירות צריכים לכלול את הפרטים הבאים:
אוקטט | סוג הנתונים | תיאור | ערך |
---|---|---|---|
0-2 | uint24 |
מזהה דגם של 24 סיביות | משתנה |
פרסום: כשהחשבון לא גלוי
כשהמכשיר של הספק לא גלוי (כלומר, לא במצב התאמה), הוא צריך לפרסם את נתוני החשבון של התאמה מהירה לפי ההנחיות הבאות.
פרסום נתוני החשבון מאפשר למחפשים בסביבה לזהות מתי ספק מסוים שייך לחשבון שלהם ולהתחיל את ההתאמה בלי שתצטרכו לאלץ את הספק לחזור למצב התאמה קודם, מה שגורם לעתים קרובות לתלונות של משתמשים. מודעות ה-Seeker יאפשרו למשתמשים להתעלם מהשידור הזה אם הם לא ממתינים להתאמה עם הספק או אם השידור לא רלוונטי (לדוגמה, אם הם כבר התאימו). המערכת תסנן באופן אוטומטי גם שידורים ברורים שהם לא טובים, למשל אם נתוני החשבון מוגדרים באופן שגוי.
מרווח הזמן להצגת מודעות: כשהסרטון לא גלוי
המרווח בין המודעות צריך להיות 250 אלפיות השנייה (4Hz) לכל היותר.
נתוני תשתית הפרסום: נתוני חשבון של התאמה מהירה
המודעה צריכה לכלול את סוג הנתונים Service Data, שם, § 1.11. ה-UUID יהיה ה-UUID של שירות ההתאמה המהירה של 0xFE2C
. נתוני השירות צריכים לכלול את הפרטים הבאים:
אוקטט | סוג הנתונים | תיאור | ערך |
---|---|---|---|
0 | uint8 |
גרסה ודגלים 0bVVVVFFFF
|
0x00 (שמור לשימוש עתידי) |
1 – משתנה | נתוני מפתח החשבון | משתנה |
נתוני מפתח החשבון מכילים את הפרטים הבאים:
אוקטט | סוג הנתונים | תיאור | ערך |
---|---|---|---|
0 | uint8 |
אורך השדה והסוג שלו 0bLLLLTTTT
|
0bLLLL0000
|
1 - s | מסנן של מפתח חשבון | משתנה | |
s + 1 | uint8 |
אורך השדה והסוג שלו 0bLLLLTTTT
|
0b00100001
|
s + 2 - s + 3 | uint16 |
Salt | משתנה |
מסנן של מפתח חשבון
הסינון של מפתח החשבון שפורסם מאפשר למחפש לבדוק במהירות אם לספק מסוים יש מפתח חשבון מסוים (עם הסתברות נמוכה לזיהוי שגוי של תוצאה חיובית, בממוצע פחות מ-0.5%), לפני אינטראקציות נוספות. כדי לצמצם עוד יותר את שיעור הזיהויים השגויים, החיפוש עשוי להתחבר באופן אוטומטי ולנסות להתחיל את התהליך כשהוא מזהה מסנן שמשודר עם סוג 0, כלומר עם אינדיקציה בממשק המשתמש, שעשוי להכיל אחד ממפתחות החשבון שלו. במקרים מסוימים, יכול להיות שהספק ירצה להימצא במצב שבו הוא מזוהה על ידי המכשיר המחפש, גם אם הוא לא מוכן להתאמה. דוגמה לכך היא כשהאוזניות מוחזרות למארז. אנחנו רוצים להפסיק להציג את ההתראה הבאה על ההתאמה, כי יכול להיות שהיא תידחה על ידי אוזניות ההשתלה.
מסנן מפתח החשבון הוא מסנן Bloom באורך משתנה שנוצר באופן הבא:
- נניח ש-n הוא מספר מפתחות החשבון (n >= 1) ברשימת מפתחות החשבון שנשמרה.
- נניח ש-s, הגודל של המסנן בבייטים, הוא (1.2*n + 3) חתוך. לדוגמה, אם מפתח אחד נשמר, הערך של s הוא 4 בייטים.
uint8_t s = (((uint8_t)(( float )1.2 * n)) + 3);
- מאתחלים את המסנן F כמערך של s בייטים, שכל אחד מהם מוגדר ל-0.
uint8_t F[s] = {0};
לכל מפתח חשבון K ברשימת מפתחות החשבון שנשמרה:
א. 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; ... }
ב. מבצעים גיבוב (hash) של V באמצעות SHA256, ומקבלים ערך של 32 בתים H = {H0, …, H31}.
uint8_t H[32] = {0}; SHA256_hash_function(V, H);
ג. מחלקים את H לשמונה מספרים שלמים לא חתומים באורך 4 בייטים בפורמט big-endian, 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); }
ד. לכל Xi:
i. M הוא Xi modulo מספר הביטים במסנן, (s * 8).
2. אחזור הבייט ב-F במדד (M / 8), מעוגל כלפי מטה.
3. בתוך הביתט, מגדירים את הבייט באינדקס (M % 8) לערך 1.
4. במילים אחרות:// 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 בתור השדה Account Key Filter (מסנן מפתח החשבון) בנתוני הפרסום. שימו לב שאין לערכים האלה 'סדר ביטים', כי אין בייט משמעותי יותר או פחות – אל תשנו את סדר הבייטים.
שדה מלח
המלח הוא ערך אקראי שמצורף למפתחות החשבון בזמן יצירת מסנן ה-Bloom. צריך ליצור מחדש את המלח הזה בכל פעם שמעדכנים את ה-RPA של הספק כדי למנוע מעקב במהלך רוטציית כתובות.
כדי ליצור את המסנן של מפתח החשבון באמצעות המלח:
- יוצרים S של 2 בייטים באופן אקראי. שימו לב שאין לערכים האלה 'endianness', כי אין בייט משמעותי יותר או פחות – אל תשנו את סדר הבייטים.
- משתמשים ב-S בן 2 בייטים בתור המלח.
- בנתוני החשבון של Fast Pair שמוצגים, צריך לכלול את המסנן שנוצר בשדה Account Key Filter ואת הערך S בשדה Salt.