BLE MAC Address filtering

Hello,
I am using ESP32 and the Arduino framework to scan for BLE devices, and will need to use a filter. I decided to implement the filter as a std::map<std::string, bool> in the BLEScan callback. I've added the map as a class member:

private:
    std::map<std::string, bool> mac_address_whitelist;

Here's how I add an address to the whitelist:

void addMACAddress(BLEAddress address)
    {
      std::string mac_address = address.toString();
      mac_address_whitelist.insert(std::pair<std::string, bool> (mac_address, true));

      Serial.print("Whitelist got a new MAC: ");
      Serial.print(address.toString().c_str());
      Serial.print(", length of ");
      Serial.println(mac_address.length());
    }

Here's how I check if the address entry exists in the map:

bool mac_in_whitelist(BLEAddress address)
    {
      auto it = mac_address_whitelist.find(address.toString());

      if (mac_address_whitelist.end() == it)
      {
        Serial.print("Could not find address in whitelist: ");
        Serial.print(address.toString().c_str());
        Serial.print(", length of ");
        Serial.println(address.toString().length());

        return false;
      }
      return mac_address_whitelist.at(address.toString());
    }

I never get any matches from the map. Printing out the MAC addresses shows they are identical to what's in the map keys.

What am I missing here?

here is an example where I use your 'map' representation to store the result of a scan and then I look for one (that I know is in the list because I added that address on purpose).

it works fine for me

#include <BLEAdvertisedDevice.h>
#include <BLEDevice.h>
#include <BLEScan.h>
#include <map>

std::map<std::string, bool> mac_address_whitelist;

BLEScan* pBLEScan;

void addMACAddress(BLEAddress address)
{
  std::string mac_address = address.toString();
  mac_address_whitelist.insert(std::pair<std::string, bool> (mac_address, true));
}

void setup() {
  Serial.begin(115200);
  Serial.println("Scanning...");

  BLEDevice::init("");
  pBLEScan = BLEDevice::getScan();
  pBLEScan->setActiveScan(true);

  BLEScanResults scanList = pBLEScan->start(5); // 5 second scan
  int deviceCount = scanList.getCount();
  Serial.printf("Found %d device(s)\n", deviceCount);
  for (uint32_t i = 0; i < deviceCount; i++) {
    addMACAddress(scanList.getDevice(i).getAddress());
  }
  pBLEScan->clearResults();

  Serial.println("Here is the whitelist:");
  for (const auto& m : mac_address_whitelist) {
    Serial.print(m.first.c_str()); Serial.write('\t'); Serial.println(m.second ? "true" : "false");
  }

  // Now that we built the list, check if an address is in that list
  BLEAddress checkThisOne("6f:c9:96:29:0d:e5"); // <=== PICK ONE OF YOURS
  Serial.print("Looking for address: "); Serial.println(checkThisOne.toString().c_str());

  auto result = mac_address_whitelist.find(checkThisOne.toString());
  if (result != mac_address_whitelist.end()) {
    Serial.print("Found it: ");
    Serial.print(result->first.c_str()); Serial.write('\t'); Serial.println(result->second ? "true" : "false");
  } else {
    Serial.println("Could not find it...");
  }
}

void loop() {}

of course you need to tailor the code to include a known BLE address for your environment by editing

  BLEAddress checkThisOne("6f:c9:96:29:0d:e5"); // <=== PICK ONE OF YOURS

The problem was that I've been passing a new instance of the callback object to the BLEScan. MAC address filtering works fine now.

Good news

The map storage might be costly compared to a smaller array of struct containing the raw address and the bool

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.