I'm using an ESP32 to scan BLE advertisers but I have a memory leak. If I comment out line 94 (pBLEScan->start) the leak stops, but so does the scanning. When scanning, it works as expected, but leaks roughly 148 bytes per scan.
How do I identify and fix this leak?
I have tried many variations, but to no avail.
https://pastebin.com/TsNU02h2
#include <iostream>
#include <string>
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEScan.h>
#include <BLEAdvertisedDevice.h>
#define SCAN_TIME 5
// Define a struct to hold the data on a single BLE device
struct BleDevice {
char address[18];
char name[80];
char manufacturer[80];
int appearance;
int rssi;
int txPower;
};
// create a static array to hold 80 BLE Devices
static struct BleDevice BleDevices[80];
static int BleDeviceCounter = 0;
// BLE variables
BLEScan* pBLEScan;
BLEScanResults foundDevices;
static char dev_uuid[80];
static int ind = 0; // used in loop as an index
static int lastFreeHeap = 0;
static int deviceCounter = 0;
// BLE Callback
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice adDevice) {
if (adDevice.haveServiceUUID()) {
strcpy(dev_uuid, adDevice.getServiceUUID().toString().c_str());
} else {
strcpy(dev_uuid, "UNKNOWN");
}
if (adDevice.haveName()) {
strcpy(BleDevices[BleDeviceCounter].name, adDevice.getName().c_str());
} else {
strcpy(BleDevices[BleDeviceCounter].name, "");
}
if (adDevice.haveManufacturerData()) {
strcpy(BleDevices[BleDeviceCounter].manufacturer, BLEUtils::buildHexData(NULL, (uint8_t*)adDevice.getManufacturerData().data(), adDevice.getManufacturerData().length()));
} else {
strcpy(BleDevices[BleDeviceCounter].manufacturer, "");
}
if (adDevice.haveTXPower()) {
BleDevices[BleDeviceCounter].txPower = adDevice.getTXPower();
} else {
BleDevices[BleDeviceCounter].txPower = -999; // -999 means NULL
}
if (adDevice.haveAppearance()) {
BleDevices[BleDeviceCounter].appearance = adDevice.getAppearance();
} else { // clear the appearance
BleDevices[BleDeviceCounter].appearance = -999 ; // -999 means NULL
}
strcpy(BleDevices[BleDeviceCounter].address, adDevice.getAddress().toString().c_str());
BleDevices[BleDeviceCounter].rssi = adDevice.getRSSI();
BleDeviceCounter++; // increment the static device counter last
}
};
void setup()
{
Serial.begin(115200);
Serial.println("\n\n Started...\n");
// BLE setup
Serial.println("Scanning for BT Devices...");
BleDeviceCounter = 0;
BLEDevice::init("");
pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(false);
pBLEScan->setInterval(100);
pBLEScan->setWindow(99); // less or equal setInterval value
}
void loop()
{
BleDeviceCounter = 0; // Set counter to zero
foundDevices = pBLEScan->start(SCAN_TIME, false); // Start scan
deviceCounter = BleDeviceCounter;
for (ind=0; ind < deviceCounter; ind++) {
Serial.printf("[%i] {address=\"%s\", rssi = \"%i\", txPower = \"%i\", mData = \"%s\", app = \"%i\", name = \"%s\"}\n",
ind,
BleDevices[ind].address,
BleDevices[ind].rssi,
BleDevices[ind].txPower,
BleDevices[ind].manufacturer,
BleDevices[ind].appearance,
BleDevices[ind].name
);
}
pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory
Serial.printf("Free Heap = %i <%i> \n", ESP.getFreeHeap(), (ESP.getFreeHeap()-lastFreeHeap));
lastFreeHeap = ESP.getFreeHeap();
delay(500); // delay 1/2 second
}
//eof