Since MAC addresses can be randomized (or spoofed) it's not a good idea to use this as a unique value for identifying a client device. I think of using the peer key as a unique ID (esp_ble_bond_key_info_t.pid_key.irk) but I don't know if this is a good idea.
Is this the way to go or is there a better way to identify a bonded client?
Code: Select all
onAuthenticationComplete(esp_ble_auth_cmpl_t cmpl) {
std::string id = getPeerKey(cmpl.bd_addr).c_str();
}
std::string getHexString(const esp_bt_octet16_t& value) {
char hex[33]; // 16 bytes * 2 hex digits + 1 null terminator
for (size_t i = 0; i < ESP_BT_OCTET16_LEN; ++i) {
sprintf(hex + i * 2, "%02x", value[i]);
}
hex[32] = '\0';
return std::string(hex);
}
const esp_ble_bond_key_info_t* getBondedKey(const esp_bd_addr_t mac) {
int pairedDevices = esp_ble_get_bond_device_num();
if (pairedDevices <= 0) {
// No bonded devices found
return nullptr;
}
esp_ble_bond_dev_t* bondedDevices = (esp_ble_bond_dev_t*)malloc(sizeof(esp_ble_bond_dev_t) * pairedDevices);
if (!bondedDevices) {
// "Memory allocation for bonded devices failed"
return nullptr;
}
esp_ble_get_bond_device_list(&pairedDevices, bondedDevices);
const esp_ble_bond_key_info_t* result = nullptr;
for (int i = 0; i < pairedDevices; i++) {
if (memcmp(bondedDevices[i].bd_addr, mac, ESP_BD_ADDR_LEN) == 0) {
result = &bondedDevices[i].bond_key;
break;
}
}
if (!result) {
// No bonded device matches the given MAC.
}
esp_ble_bond_key_info_t* keyCopy = nullptr;
if (result) {
keyCopy = (esp_ble_bond_key_info_t*)malloc(sizeof(esp_ble_bond_key_info_t));
if (keyCopy) {
memcpy(keyCopy, result, sizeof(esp_ble_bond_key_info_t));
}
}
free(bondedDevices);
return keyCopy; // Don't forget to release by caller!
}
std::string getPeerKey(const esp_bd_addr_t mac) {
const esp_ble_bond_key_info_t* bondKey = getBondedKey(mac);
if (!bondKey) {
return "";
}
std::string irkStr = getHexString(bondKey->pid_key.irk);
free((void*)bondKey); // free the copy we allocated in getBondedKey()
return irkStr;
}