אות לפרסום של ספק

פרסום: כאשר גלוי

כשמכשיר הספק ניתן לגילוי BR/EDR (כלומר, במצב התאמה), הוא יפרסם נתוני מזהה של מודל התאמה מהירה באמצעות BLE, ולא תתבצע רוטציה של כתובת ה-BLE.

מרווח זמן לפרסום: כאשר גלוי

המרווח בין הפרסומות לא יכול להיות גדול מ-100 אלפיות שנייה (10 הרץ). קצב מהיר מאפשר למחפש למצוא במהירות את הספק, גם כשהוא סורק במצב של הספק נמוך.

מטען ייעודי (payload) של פרסום: נתוני מזהה המודל להתאמה מהירה

המודעה תכיל את סוג הנתונים של נתוני השירות, לדוגמה, סעיף 1.11. ה-UUID יהיה ה-UUID של השירות להתאמה מהירה של 0xFE2C. נתוני השירות יכללו את הפרטים הבאים:

8 תווים סוג הנתונים תיאור ערך
0-2 uint24 מזהה מודל 24-ביט משתנה

פרסום: כאשר לא ניתן לגלות

כשהמכשיר לא גלוי (כלומר, לא במצב התאמה), המכשיר של הספק יפרסם את נתוני החשבון בהתאמה מהירה, בהתאם להנחיות הבאות.

פרסום נתוני החשבון מאפשר למחפשים שנמצאים בקרבת מקום לזהות מתי ספק שייך לחשבון שלהם ולהתחיל את ההתאמה בלי לאלץ את הספק לחזור למצב ההתאמה תחילה, וזו אחת מהסיבות הנפוצות לתלונות של משתמשים. המשתמשים יוכלו להתעלם מהשידור, למקרה שהם לא ימתינו להתאמה עם הספק או שהשידור לא יהיה רלוונטי (לדוגמה, אם הם כבר הותאמו עם הספק). מי שמחפש יכול גם לסנן באופן אוטומטי שידורים לא תקינים, למשל כשנתוני החשבון מוגדרים בצורה שגויה.

מרווח זמן לפרסום: כאשר לא גלוי

מרווח הזמן בין פרסומות לא יכול להיות יותר מ-250 אלפיות השנייה (4Hz).

מטען ייעודי (payload) של פרסום: נתוני חשבון בהתאמה מהירה

המודעה תכיל את סוג הנתונים של נתוני השירות, Ibid., סעיף 1.11. ה-UUID יהיה ה-UUID של השירות להתאמה מהירה של 0xFE2C. נתוני השירות יכללו את הפרטים הבאים:

8 תווים סוג הנתונים תיאור ערך
0 uint8 גרסה ודגלים
0bVVVVFFFF
  • V = גרסה
  • F = דגלים
0x00
(שמור לשימוש עתידי)
1 – משתנה נתוני מפתח של החשבון משתנה
או 0x00 אם רשימת מפתחות החשבון ריקה

הנתונים העיקריים של החשבון כוללים:

8 תווים סוג הנתונים תיאור ערך
0 uint8 אורך וסוג השדה
0bLLLLTTTT
  • L = אורך מסנן מפתח החשבון בבייטים
  • T = סוג
0bLLLL0,000
  • אורך = 0bLLLL = משתנה
  • סוג = 0b0000 (הצגת אינדיקציה בממשק המשתמש) או 0b0010 (הסתרת אינדיקציה בממשק המשתמש), מסנן מפתח החשבון
1 – s מסנן מפתח חשבון משתנה
s + 1 uint8 אורך וסוג השדה
0bLLLLTTTT
  • L = אורך בבייטים
  • T = סוג
0b00100001
  • אורך = 0b0010 = 2
  • type = 0b0001, מלח
s + 2 - s + 3 uint16 Salt משתנה

מסנן מפתח חשבון

מסנן מפתחות החשבון שפורסם מאפשר למחפש לבדוק במהירות אם ייתכן שלספק יש מפתח חשבון מסוים (עם הסתברות חיובית כוזבת ונמוכה, בממוצע הרבה פחות מ-0.5%), לפני אינטראקציות נוספות. שמחפש יכול להתחבר באופן אוטומטי ולנסות להתחיל את התהליך באופן אוטומטי כשהוא מזהה מסנן שמשודר עם סוג 0, כלומר הצגת אינדיקציה בממשק המשתמש, שמכיל פוטנציאל לאחד ממפתחות החשבון שלו, וכך לצמצם עוד יותר את שיעור התוצאות החיוביות השגויות. במצבים מסוימים, יכול להיות שהספק ירצה לזהות על ידי המחפש בזמן שהוא לא מוכן להתאמה. דוגמה אחת לכך היא שכאשר אוזניות נצמדות לנרתיק, אנחנו רוצים להפסיק להציג את הודעת ההתאמה הבאה, כי האוזניות עשויות לדחות את ההתאמה.

מסנן המפתח של החשבון הוא מסנן Bloom באורך משתנה, שנוצר באופן הבא:

  1. הערך n מציין את מספר מפתחות החשבון (n >= 1) ברשימת מפתחות החשבון הקבועה.
  2. הקיצור s, גודל המסנן בבייטים, ייקטע (1.2*n + 3). לדוגמה, אם מפתח אחד מופיע באופן קבוע, s = 4 בייטים.
    uint8_t s = (((uint8_t)(( float )1.2 * n)) + 3);
  3. מפעילים את המסנן F כמערך של s בייטים, שכל אחד מהם מוגדר ל-0.
    uint8_t F[s] = {0};
  4. לכל מפתח חשבון K ברשימת מפתחות החשבון הקבועה:
    א. הפונקציה V יכולה להיות משורשר(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;
          ... }
    

    ב. מתבצעת גיבוב V באמצעות SHA256, וכך מתקבל ערך של 32 בייטים H = {H0, ..., H31}.

    uint8_t H[32] = {0};
    SHA256_hash_function(V, H);
    

    ג. מחלקים את 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);
         }
    

    ד. לכל Xi:
    i. ממקמים את M כך: Xi מודולו את מספר הביטים במסנן, (s * 8).
    2. צריך לחשב את הבייטים בערך F באינדקס (M / 8), מעוגל כלפי מטה.
    3. בתוך הבייט, מגדירים את הביט באינדקס (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 בתור השדה 'מסנן מפתח חשבון'. שימו לב שאין 'סופיות' לערך הזה, מכיוון שאין בייטים משמעותיים יותר או פחות – אל תשנו את סדר הבייטים.

שדה מלח

ה-salt הוא ערך אקראי שמצורף למפתחות של החשבונות כשיוצרים את מסנן הפריחה. צריך ליצור מחדש את ה-salt בכל פעם ש-RPA מתעדכן עבור הספק, כדי למנוע מעקב אחר סבב כתובות.

כדי ליצור את מסנן מפתח החשבון באמצעות ה-salt:

  1. יוצרים קובץ S אקראי בגודל 2 בייטים. שימו לב שאין 'סופיות' לערך הזה, כי אין בייטים משמעותיים יותר או פחות – לא לשנות את סדר הבייטים.
  2. משתמשים ב-S של 2 בייטים בתור ה-Salt.
  3. בנתוני החשבון בהתאמה מהירה שמתפרסמים, כוללים את המסנן שנוצר בשדה Account Key Filter (מסנן מפתחות החשבון) ואת S בשדה Salt.