static void scan_le_adv_report(const void *data, uint8_t size, void *user_data) { const struct bt_hci_evt_le_adv_report *evt = data; if (evt->addr_type == 0x01 && (evt->addr[5] & 0xc0) == 0x40) { uint8_t hash[3], irk[16]; memcpy(irk, ADV_IRK, 16); bt_crypto_ah(crypto, irk, evt->addr + 3, hash); if (!memcmp(evt->addr, hash, 3)) { printf("Received advertising report\n"); print_rpa(evt->addr); memcpy(irk, ADV_IRK, 16); bt_crypto_ah(crypto, irk, evt->addr + 3, hash); printf(" -> Computed hash: %02x%02x%02x\n", hash[0], hash[1], hash[2]); mainloop_quit(); } } }
static void adv_le_evtmask_callback(const void *data, uint8_t size, void *user_data) { struct bt_hci_cmd_le_set_resolv_timeout cmd0; struct bt_hci_cmd_le_add_to_resolv_list cmd1; struct bt_hci_cmd_le_set_resolv_enable cmd2; struct bt_hci_cmd_le_set_random_address cmd3; struct bt_hci_cmd_le_set_adv_parameters cmd4; struct bt_hci_cmd_le_set_adv_enable cmd5; cmd0.timeout = cpu_to_le16(0x0384); bt_hci_send(adv_dev, BT_HCI_CMD_LE_SET_RESOLV_TIMEOUT, &cmd0, sizeof(cmd0), NULL, NULL, NULL); cmd1.addr_type = PEER_ADDR_TYPE; memcpy(cmd1.addr, PEER_ADDR, 6); memset(cmd1.peer_irk, 0, 16); memcpy(cmd1.local_irk, ADV_IRK, 16); bt_hci_send(adv_dev, BT_HCI_CMD_LE_ADD_TO_RESOLV_LIST, &cmd1, sizeof(cmd1), NULL, NULL, NULL); cmd2.enable = 0x01; bt_hci_send(adv_dev, BT_HCI_CMD_LE_SET_RESOLV_ENABLE, &cmd2, sizeof(cmd2), NULL, NULL, NULL); bt_crypto_random_bytes(crypto, cmd3.addr + 3, 3); cmd3.addr[5] &= 0x3f; /* Clear two most significant bits */ cmd3.addr[5] |= 0x40; /* Set second most significant bit */ bt_crypto_ah(crypto, cmd1.local_irk, cmd3.addr + 3, cmd3.addr); bt_hci_send(adv_dev, BT_HCI_CMD_LE_SET_RANDOM_ADDRESS, &cmd3, sizeof(cmd3), NULL, NULL, NULL); printf("Setting advertising address\n"); print_rpa(cmd3.addr); cmd4.min_interval = cpu_to_le16(0x0800); cmd4.max_interval = cpu_to_le16(0x0800); cmd4.type = 0x03; /* Non-connectable advertising */ cmd4.own_addr_type = 0x03; /* Local IRK, random address fallback */ cmd4.direct_addr_type = PEER_ADDR_TYPE; memcpy(cmd4.direct_addr, PEER_ADDR, 6); cmd4.channel_map = 0x07; cmd4.filter_policy = 0x00; bt_hci_send(adv_dev, BT_HCI_CMD_LE_SET_ADV_PARAMETERS, &cmd4, sizeof(cmd4), NULL, NULL, NULL); cmd5.enable = 0x01; bt_hci_send(adv_dev, BT_HCI_CMD_LE_SET_ADV_ENABLE, &cmd5, sizeof(cmd5), adv_enable_callback, NULL, NULL); }
static void resolve_peer_addr(struct bt_le *hci, uint8_t peer_addr_type, const uint8_t peer_addr[6], uint8_t *addr_type, uint8_t addr[6]) { int i; if (!hci->le_resolv_enable) goto done; if (peer_addr_type != 0x01) goto done; if ((peer_addr[5] & 0xc0) != 0x40) goto done; for (i = 0; i < hci->le_resolv_list_size; i++) { uint8_t local_hash[3]; if (hci->le_resolv_list[i][0] == 0xff) continue; bt_crypto_ah(hci->crypto, &hci->le_resolv_list[i][7], peer_addr + 3, local_hash); if (!memcmp(peer_addr, local_hash, 3)) { switch (hci->le_resolv_list[i][0]) { case 0x00: *addr_type = 0x02; break; case 0x01: *addr_type = 0x03; break; default: continue; } memcpy(addr, &hci->le_resolv_list[i][1], 6); return; } } done: *addr_type = peer_addr_type; memcpy(addr, peer_addr, 6); }