You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

使用说明

  1. 首次使用时先注释掉PHONE1_ADDR、PHONE2_ADDR的匹配逻辑,分别给两台手机和ESP32完成BLE配对绑定,配对连接时从串口打印获取两台手机的真实身份地址,替换代码中的示例地址即可
  2. 该方案功耗和你原来的单设备方案完全一致,不需要保持长连接,仅在设备进入范围连接时触发动作

内容的提问来源于stack exchange,提问作者Jan Novák

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.18 20:15:10