Indicador de publicidade do provedor

Publicidade: quando detectável

Quando o dispositivo do provedor é detectável por BR/EDR (ou seja, no modo de pareamento), ele anuncia os dados do ID do modelo do Pareamento rápido por BLE, e o endereço BLE não é rotacionado.

Intervalo de publicidade: quando detectável

O intervalo entre os anúncios não pode ser maior que 100 ms (10 Hz). Uma taxa rápida permite que o Buscador encontre o provedor rapidamente, mesmo ao fazer a verificação no modo de baixo consumo.

Payload de publicidade: dados de ID do modelo do par rápido

O anúncio precisa conter o tipo de dados "Dados do serviço", ibid., § 1.11. O UUID precisa ser o UUID do serviço de Pareamento rápido de 0xFE2C. Os dados do serviço precisam conter o seguinte:

Octeto Tipo de dado Descrição Valor
0-2 uint24 ID do modelo de 24 bits varia

Publicidade: quando não é detectável

Quando não estiver detectável (ou seja, não estiver no modo de pareamento), o dispositivo do provedor vai anunciar os dados da conta do Pareamento rápido, usando as diretrizes a seguir.

A divulgação dos dados da conta permite que os usuários por perto reconheçam quando um provedor pertence à conta deles e iniciem o pareamento sem precisar forçar o provedor a voltar ao modo de pareamento, o que é uma causa comum de reclamação do usuário. Os buscadores vão dar a oportunidade de os usuários ignorarem essa transmissão quando não esperarem para parear com o provedor ou quando a transmissão não for relevante (por exemplo, se já tiverem feito o pareamento). Os buscadores também filtram transmissões obviamente incorretas automaticamente, como quando os dados da conta estão configurados incorretamente.

Intervalo de publicidade: quando não está detectável

O intervalo entre os anúncios precisa ser de no máximo 250 ms (4 Hz).

Payload de publicidade: dados da conta do Pareamento rápido

O anúncio deve conter o tipo de dados "Dados do serviço", Ibid., § 1.11. O UUID precisa ser o UUID do serviço de Pareamento rápido de 0xFE2C. Os dados do serviço precisam conter o seguinte:

Octeto Tipo de dado Descrição Valor
0 uint8 Versão e sinalizações
0bVVVVFFFF
  • V = versão
  • F = flags
0x00
(reservado para uso futuro)
1 - varia Dados da chave da conta varia

Os dados da chave da conta contêm:

Octeto Tipo de dado Descrição Valor
0 uint8 Comprimento e tipo do campo
0bLLLLTTTT
  • L = comprimento do filtro da chave da conta em bytes
  • T = tipo
0bLLLL0000
  • length = 0bLLLL = varia
  • type = 0b0000 (mostrar a indicação da interface) ou 0b0010 (ocultar a indicação da interface), filtro de chave da conta
1 - s Filtro de chave da conta varia
s + 1 uint8 Comprimento e tipo do campo
0bLLLLTTTT
  • L = comprimento em bytes
  • T = tipo
0b00100001
  • length = 0b0010 = 2
  • type = 0b0001, Sal
s + 2 - s + 3 uint16 Salt varia

Filtro de chave da conta

O filtro de chave de conta anunciado permite que um solicitante verifique rapidamente se um provedor pode ter uma determinada chave de conta (com uma probabilidade de falso positivo baixa, em média muito menor que 0,5%), antes de outras interações. O Seeker pode se conectar automaticamente e tentar iniciar o procedimento quando detecta um filtro sendo transmitido com o tipo 0, ou seja, mostrando a indicação da interface, que potencialmente contém uma das chaves da conta, para reduzir ainda mais a taxa de falsos positivos. Em algumas situações, o provedor pode querer ser reconhecido pelo solicitante sem estar pronto para o pareamento. Por exemplo, quando os fones de ouvido são colocados de volta no estojo, queremos parar de mostrar a notificação de pareamento subsequente, já que ela pode ser rejeitada pelo fone de ouvido.

O filtro de chave da conta é um filtro Bloom de comprimento variável construído da seguinte maneira:

  1. Vamos supor que n seja o número de chaves de conta (n >= 1) na lista de chaves de conta persistente.
  2. Vamos supor que s, o tamanho do filtro em bytes, seja (1,2*n + 3) truncado. Por exemplo, se uma chave for mantida, s = 4 bytes.
    uint8_t s = (((uint8_t)(( float )1.2 * n)) + 3);
  3. Inicialize o filtro F como uma matriz de bytes s, cada um definido como 0.
    uint8_t F[s] = {0};
  4. Para cada chave de conta K na lista de chaves de conta persistente:
    a. V é concat(K, Sal).

    // 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. Gerar hash de V usando SHA256, obtendo um valor de 32 bytes H = {H0, …, H31}.

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

    c. Divida H em oito números inteiros não assinados de 4 bytes em big-endian, X = {X0, …, X7}, em que 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. Para cada Xi:
    i. Vamos supor que M seja Xi modulo o número de bits no filtro, (s * 8).
    ii. Recebe o byte em F no índice (M / 8), arredondado para baixo.
    iii. No byte, defina o bit no índice (M % 8) como 1.
    iv. Em outras palavras:

        // 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));
        }
    

Inclua o filtro F como o campo "Filtro de chave de conta" nos dados de publicidade. Não há "endianness" para esse valor, já que não há um byte mais ou menos significativo. Não altere a ordem dos bytes.

Campo de sal

O sal é um valor aleatório que é anexado às chaves da conta ao criar o filtro bloom. Esse sal precisa ser regenerado sempre que o RPA é atualizado para o provedor, a fim de evitar o rastreamento da rotação de endereços.

Para gerar o filtro de chave de conta usando o sal:

  1. Gere uma S de 2 bytes aleatória. Não há "endianidade" para esse valor, já que não há um byte mais ou menos significativo. Não altere a ordem dos bytes.
  2. Use S de 2 bytes como o sal.
  3. Nos dados da conta do Pareamento rápido anunciados, inclua o filtro gerado no campo "Filtro de chave da conta" e S no campo "Sal".