สัญญาณการโฆษณาของผู้ให้บริการ

การโฆษณา: เมื่อค้นพบได้

เมื่ออุปกรณ์ผู้ให้บริการสามารถค้นพบได้ผ่าน BR/EDR (นั่นคืออยู่ในโหมดการจับคู่) อุปกรณ์ดังกล่าวจะโฆษณาข้อมูลรหัสรุ่นการจับคู่ด่วนผ่าน BLE และจะไม่เปลี่ยนที่อยู่ BLE

ช่วงเวลาที่โฆษณาแสดง: เมื่อค้นพบได้

ช่วงเวลาระหว่างโฆษณาไม่ควรนานกว่า 100 มิลลิวินาที (10 Hz) อัตราการค้นหาที่รวดเร็วช่วยให้ผู้ค้นหาพบผู้ให้บริการได้อย่างรวดเร็ว แม้ขณะสแกนในโหมดพลังงานต่ำ

เพย์โหลดโฆษณา: ข้อมูลรหัสรุ่นการจับคู่ด่วน

โฆษณาต้องมีประเภทข้อมูล Service Data อ้างอิงจากที่เดียวกัน § 1.11. โดย UUID ดังกล่าวต้องเป็น UUID บริการการจับคู่ด่วนของ 0xFE2C ข้อมูลบริการต้องมีข้อมูลต่อไปนี้

อ็อกเท็ต ประเภทข้อมูล คำอธิบาย ค่า
0-2 uint24 รหัสรุ่น 24 บิต แตกต่างกัน

การโฆษณา: กรณีที่ค้นพบไม่ได้

เมื่อตรวจไม่พบ (ไม่ได้อยู่ในโหมดการจับคู่) อุปกรณ์ของผู้ให้บริการจะโฆษณาข้อมูลบัญชีการจับคู่ด่วนโดยใช้หลักเกณฑ์ต่อไปนี้

การโฆษณาข้อมูลบัญชีช่วยให้ผู้ค้นหาที่อยู่ใกล้เคียงทราบว่าผู้ให้บริการรายใดเป็นของบัญชีของตนและเริ่มการจับคู่ได้โดยไม่ต้องบังคับให้ผู้ให้บริการกลับไปอยู่ในโหมดการจับคู่ก่อน ซึ่งเป็นสาเหตุที่พบบ่อยของการร้องเรียนจากผู้ใช้ Seekers จะช่วยให้ผู้ใช้สามารถละเว้นการออกอากาศนี้ได้ในกรณีที่ผู้ใช้ไม่รอจับคู่กับผู้ให้บริการหรือในกรณีที่การออกอากาศไม่เกี่ยวข้อง (เช่น ผู้ใช้จับคู่ไปแล้ว) นอกจากนี้ Seeker จะกรองการออกอากาศที่ไม่ดีอย่างเห็นได้ชัดออกโดยอัตโนมัติด้วย เช่น เมื่อข้อมูลบัญชีได้รับการกําหนดค่าไม่ถูกต้อง

ช่วงเวลาที่โฆษณาทำงาน: เมื่อระบบไม่ค้นพบ

ช่วงเวลาระหว่างโฆษณาไม่ควรเกิน 250 มิลลิวินาที (4 Hz)

เพย์โหลดการโฆษณา: ข้อมูลบัญชีการจับคู่ด่วน

โฆษณาต้องมีประเภทข้อมูล Service Data อ้างอิงจาก Ibid. § 1.11. โดย UUID ดังกล่าวต้องเป็น UUID บริการการจับคู่ด่วนของ 0xFE2C ข้อมูลบริการต้องมีข้อมูลต่อไปนี้

อ็อกเท็ต ประเภทข้อมูล คำอธิบาย ค่า
0 uint8 เวอร์ชันและแฟล็ก
0bVVVVFFFF
  • V = เวอร์ชัน
  • F = Flag
0x00
(สงวนไว้สำหรับการใช้งานในอนาคต)
1 - แตกต่างกัน ข้อมูลคีย์บัญชี แตกต่างกัน

ข้อมูลคีย์บัญชีประกอบด้วยข้อมูลต่อไปนี้

อ็อกเท็ต ประเภทข้อมูล คำอธิบาย ค่า
0 uint8 ความยาวและประเภทฟิลด์
0bLLLLTTTT
  • L = ความยาวของตัวกรองคีย์บัญชีเป็นไบต์
  • T = ประเภท
0bLLLL0000
  • length = 0bLLLL = varies
  • type = 0b0000 (แสดงตัวบ่งชี้ UI) หรือ 0b0010 (ซ่อนตัวบ่งชี้ UI) ตัวกรองคีย์บัญชี
1 - วินาที ตัวกรองคีย์บัญชี แตกต่างกัน
s + 1 uint8 ความยาวและประเภทฟิลด์
0bLLLLTTTT
  • L = ความยาวเป็นไบต์
  • T = ประเภท
0b00100001
  • length = 0b0010 = 2
  • type = 0b0001, Salt
s + 2 - s + 3 uint16 Salt แตกต่างกัน

ตัวกรองคีย์บัญชี

ตัวกรองคีย์บัญชีที่โฆษณาช่วยให้ผู้ค้นหาตรวจสอบได้อย่างรวดเร็วว่าผู้ให้บริการอาจมีคีย์บัญชีบางรายการหรือไม่ (มีโอกาสเกิดผลบวกลวงต่ำ โดยเฉลี่ยน้อยกว่า 0.5%) ก่อนการโต้ตอบเพิ่มเติม ตัวค้นหาอาจเชื่อมต่อโดยอัตโนมัติและพยายามเริ่มกระบวนการเมื่อเห็นตัวกรองที่ออกอากาศด้วยประเภท 0 เช่น การแสดงตัวบ่งชี้ UI ที่อาจมีคีย์บัญชีรายการใดรายการหนึ่ง เพื่อลดอัตราผลบวกลวงต่อไป ในบางกรณี ผู้ให้บริการอาจต้องการให้อุปกรณ์ค้นหาจดจำตนในขณะที่ยังไม่พร้อมสำหรับการจับคู่ ตัวอย่างเช่น เมื่อใส่หูฟังกลับเข้าไปในเคส เราต้องการหยุดแสดงการแจ้งเตือนการจับคู่ที่ตามมาเนื่องจากหูฟังอาจปฏิเสธการจับคู่นั้น

ตัวกรองคีย์บัญชีคือตัวกรอง Bloom ที่มีความยาวแปรผันซึ่งสร้างขึ้นดังนี้

  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 แต่ละรายการในรายการคีย์บัญชีที่เก็บไว้
    ก. กำหนดให้ 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;
          ... }
    

    ข. แฮช V โดยใช้ SHA256 ซึ่งจะได้ค่า 32 ไบต์ H = {H0, …, H31}

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

    ค. แบ่ง H เป็นจำนวนเต็ม 4 ไบต์แบบไม่ลงนาม 8 ตัวในรูปแบบ 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 แต่ละรายการ
    1. กำหนดให้ M เป็น Xi หารด้วยจำนวนบิตในตัวกรอง (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 เป็นช่องตัวกรองคีย์บัญชีในข้อมูลการโฆษณา โปรดทราบว่าค่านี้ไม่มี "endianness" เนื่องจากไม่มีไบต์ที่มีนัยสำคัญมากกว่าหรือน้อยกว่า ดังนั้นอย่าเปลี่ยนแปลงลําดับไบต์

นาเกลือ

Salt คือค่าแบบสุ่มที่จะเพิ่มต่อท้ายคีย์บัญชีเมื่อสร้างตัวกรอง Bloom คุณควรสร้าง Salt นี้ใหม่ทุกครั้งที่อัปเดต RPA สําหรับผู้ให้บริการเพื่อหลีกเลี่ยงการติดตามที่อยู่แบบหมุนเวียน

วิธีสร้างตัวกรองคีย์บัญชีโดยใช้เกลือ

  1. สร้าง S แบบสุ่ม 2 ไบต์ โปรดทราบว่าค่านี้ไม่มี "endianness" เนื่องจากไม่มีไบต์ที่มีนัยสำคัญมากกว่าหรือน้อยกว่า ดังนั้นอย่าเปลี่ยนแปลงลําดับไบต์
  2. ใช้ S 2 ไบต์เป็น Salt
  3. ในข้อมูลบัญชีการจับคู่ด่วนที่โฆษณา ให้ใส่ตัวกรองที่สร้างขึ้นในช่องตัวกรองคีย์บัญชี และใส่ S ในช่อง Salt