ESP32 BLE绕过安卓MAC随机化检测多台自有安卓手机存在的方案咨询
绕过安卓BLE MAC随机化实现多台手机存在检测的实现方案
可行方案原理
BLE绑定机制本身就能避开MAC随机化问题:完成配对绑定后,ESP32会存储每台手机的身份解析密钥(IRK),可自动解析手机发出的随机MAC得到真实设备身份,无需嗅探固定MAC,也不需要在手机安装额外应用。你之前的HID方案无需大改,仅需开启多连接支持、新增设备身份识别逻辑即可实现单ESP32检测多台手机。
核心修改步骤
- 开启BLE多连接支持:Arduino-ESP32的BLE库默认最大连接数为1,需手动调整配置,在初始化BLE设备前设置最大连接数≥你需要检测的设备数(这里设3留冗余)
- 替换单连接状态标记:改用容器存储已连接设备的连接ID与对应身份地址,区分不同手机
- 连接时校验身份:每次设备连接成功后,读取对端的解析后身份地址,匹配已绑定的手机地址,触发对应动作
修改后的参考代码
#include <Arduino.h> #include <BLEDevice.h> #include <BLEUtils.h> #include <BLEServer.h> #include "BLE2902.h" #include "BLEHIDDevice.h" #include "HIDTypes.h" #include "HIDKeyboardTypes.h" #include <driver/adc.h> #include <map> // 提前录入两台已配对手机的身份地址,配对成功后可从串口打印获取 const std::string PHONE1_ADDR = "xx:xx:xx:xx:xx:xx"; const std::string PHONE2_ADDR = "yy:yy:yy:yy:yy:yy"; BLEHIDDevice* hid; BLECharacteristic* input; BLECharacteristic* output; BLEAdvertising *pAdvertising; BLEServer *pServer; // 存储当前已连接的设备:key为连接ID,value为设备地址 std::map<uint16_t, std::string> connected_devices; bool restart_advertising = false; class MyCallbacks : public BLEServerCallbacks { void onConnect(BLEServer* pServer, ble_gap_conn_desc desc){ uint16_t conn_id = desc.conn_handle; std::string peer_addr = BLEAddress(desc.peer_id_addr).toString(); connected_devices[conn_id] = peer_addr; Serial.print("Connected device: "); Serial.println(peer_addr.c_str()); BLE2902* desc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902)); desc->setNotifications(true); // 匹配设备触发对应动作 if(peer_addr == PHONE1_ADDR){ Serial.println("Phone 1 detected"); // 触发手机1对应的操作 } else if(peer_addr == PHONE2_ADDR){ Serial.println("Phone 2 detected"); // 触发手机2对应的操作 } // 原有逻辑:触发动作后断开连接、重启广播 pServer->disconnect(conn_id); } void onDisconnect(BLEServer* pServer){ connected_devices.clear(); Serial.println("Device disconnected"); BLE2902* desc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902)); desc->setNotifications(false); restart_advertising = true; } }; void setup() { Serial.begin(115200); Serial.println("Starting BLE work!"); BLEDevice::init("Backpack-MeowMeow"); // 开启最大3个连接,可按需调整 BLEDevice::setMTU(517); pServer = BLEDevice::createServer(); pServer->setMaxConnections(3); pServer->setCallbacks(new MyCallbacks()); pServer->getPeerDevices(true); hid = new BLEHIDDevice(pServer); input = hid->inputReport(1); // <-- input REPORTID from report map output = hid->outputReport(1); // <-- output REPORTID from report map std::string name = "ElectronicCats"; hid->manufacturer()->setValue(name); hid->pnp(0x02, 0xe502, 0xa111, 0x0210); hid->hidInfo(0x00,0x02); BLESecurity *pSecurity = new BLESecurity(); pSecurity->setAuthenticationMode(ESP_LE_AUTH_BOND); hid->startServices(); pAdvertising = pServer->getAdvertising(); pAdvertising->setAppearance(HID_BARCODE); pAdvertising->addServiceUUID(hid->hidService()->getUUID()); pAdvertising->start(); hid->setBatteryLevel(7); } void loop() { if (restart_advertising) { restart_advertising = false; pAdvertising->start(); } delay(50); }
使用说明
- 首次使用时先注释掉PHONE1_ADDR、PHONE2_ADDR的匹配逻辑,分别给两台手机和ESP32完成BLE配对绑定,配对连接时从串口打印获取两台手机的真实身份地址,替换代码中的示例地址即可
- 该方案功耗和你原来的单设备方案完全一致,不需要保持长连接,仅在设备进入范围连接时触发动作
内容的提问来源于stack exchange,提问作者Jan Novák
相关产品推荐
相关产品推荐

