ESP32 BLE and Android phone(s) - presence detection

2k Views Asked by At

Is there a possibility how to "overcome" BLE MAC address randomization and detect presence of my own Android phone(s)?

I'm looking for a solution how to detect presence of my phone in close-range to ESP32 without installing something like iBeacon app which would drain my battery.

  • I've started with example for BLE sniffer which works nice but with MAC randomization on Android it is useless.
  • Then I moved to the solution using emulation of a HID keyboard. After pairing it, it is nicely reconnecting when the phone comes into the range. Once it is connected I can trigger needed action and then I can turn ESP32 Bluetooth off not to be connected whole time. When I need check the phone again I just can turn the server back on. It would be neat solution but... I need to check more (at least two) phones. I've tried to duplicate BLEServers to swith between or run two simoutinasly but without success - either it is not possible or it is exceeding my knowladge about this BLE advertising/pairing/connecting magic.
  • Third solution would be to have separate ESP for each phone - doable but only as a last resort

Has somebody solved such task somehow already?

For the keyboard solution I'm using this code found online:

#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>

BLEHIDDevice* hid;
BLECharacteristic* input;
BLECharacteristic* output;
BLEAdvertising *pAdvertising;
BLEServer *pServer;

bool connected = false;
bool restart = false;

class MyCallbacks : public BLEServerCallbacks {
  void onConnect(BLEServer* pServer){
    connected = true;
    Serial.println("Connected");
    BLE2902* desc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
    desc->setNotifications(true);
    // NEEDED ACTIONS
  }

  void onDisconnect(BLEServer* pServer){
    connected = false;
    Serial.println("DisConnected");
    BLE2902* desc = (BLE2902*)input->getDescriptorByUUID(BLEUUID((uint16_t)0x2902));
    desc->setNotifications(false);
    restart = true;
  }
};

void setup() {
  Serial.begin(115200);
  Serial.println("Starting BLE work!");
  BLEDevice::init("Backpack-MeowMeow");
  pServer = BLEDevice::createServer();
  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->setKeySize();
    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);

    //ESP_LOGD(LOG_TAG, "Advertising started!");
    //delay(portMAX_DELAY);
}

void loop() {
  
  if(connected){
    delay(10);
  }
  if (restart) {
    restart = false;
    pAdvertising->start();
  }
  delay(50);
}
0

There are 0 best solutions below