nkolban / esp32-snippets

Sample ESP32 snippets and code fragments
https://leanpub.com/kolban-ESP32
Apache License 2.0
2.35k stars 710 forks source link

BLEClient heap memory exhausted after some disconnect/connect ricycle #786

Closed qrpfun closed 5 years ago

qrpfun commented 5 years ago

Hi all, I'm actually using official Arduino ESP32 library available from inside the Arduino IDE. I need to connect via BT from an ESP32 to a peripheral made with an HC-08 connected to an arduino micro, all configured to sleep as much as possible to save energy (about 300uA in sleep), than read/write some info from there and close connection to get peripheral back in sleep mode, than reconnect only once needed and cycle this way over and over.

I'have started with BLE Client examples in the lib distribution but after some cycles everything crashes. After some debugging find out a problem with a heap memory exhaustion.

Just tried to do some research and some debugging but I would appreciate if someone would be so kind to get me some tips to find a way out from here.

this is the output from very first cycles where you can see rapid memory exhaustion:

rst:0x10 (RTCWDT_RTC_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1100
load:0x40078000,len:10088
load:0x40080400,len:6380
entry 0x400806a4
BLE FreeHeap: 274408
Starting Arduino BLE Client application...
BLE Advertised Device found: Name: HC-08, Address: 88:4a:ea:8e:38:5d, manufacturer data: 48432d30380000000000000000000000000000000000, serviceUUID: 0000fff0-0000-1000-8000-00805f9b34fb, txPower: -6
BLE RSSI: -65
Forming a connection to 88:4a:ea:8e:38:5d
1-BLE FreeHeap: 181876
 - Created client
2-BLE FreeHeap: 181148
 - Connected to server
3-BLE FreeHeap: 177004
 - Found our service
4-BLE FreeHeap: 172504
 - Found our characteristic
5-BLE FreeHeap: 171076
We are now connected to the BLE Server.
Setting new characteristic value to "Time since boot: 2"
BLE FreeHeap: 171024
onDisconnect
BLE Advertised Device found: Name: HC-08, Address: 88:4a:ea:8e:38:5d, manufacturer data: 48432d30380000000000000000000000000000000000, serviceUUID: 0000fff0-0000-1000-8000-00805f9b34fb, txPower: -6
BLE RSSI: -66
Forming a connection to 88:4a:ea:8e:38:5d
1-BLE FreeHeap: 177236
 - Created client
2-BLE FreeHeap: 176508
 - Connected to server
3-BLE FreeHeap: 172360
 - Found our service
4-BLE FreeHeap: 167972
 - Found our characteristic
5-BLE FreeHeap: 166544
We are now connected to the BLE Server.
Setting new characteristic value to "Time since boot: 10"
BLE FreeHeap: 166492
....

and here the modified BLEClient.ino code:

/**
 * A BLE client example that is rich in capabilities.
 * There is a lot new capabilities implemented.
 * author unknown
 * updated by chegewara
 */

#include "BLEDevice.h"
//#include "BLEScan.h"

// The remote service we wish to connect to.
static BLEUUID serviceUUID("0000fff0-0000-1000-8000-00805f9b34fb");
static BLEUUID serviceIn_UUID("0000ffe0-0000-1000-8000-00805f9b34fb");
// The characteristic of the remote service we are interested in.
static BLEUUID    charUUID("0000ffe1-0000-1000-8000-00805f9b34fb");

static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;
static BLEClient*  pClient;
static BLERemoteService* pRemoteService;

static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify) {
    Serial.print("Notify callback for characteristic ");
    Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
    Serial.print(" of data length ");
    Serial.println(length);
    Serial.print("data: ");
    Serial.println((char*)pData);
}

class MyClientCallback : public BLEClientCallbacks {
  void onConnect(BLEClient* pclient) {
  }

  void onDisconnect(BLEClient* pclient) {
    connected = false;
    Serial.println("onDisconnect");
//    free(pClient);
//    free(pRemoteService);
//    free(pRemoteCharacteristic);
//    delete(myDevice);
//    delete pClient; //crash
  }
};

bool connectToServer() {
    Serial.print("Forming a connection to ");
    Serial.println(myDevice->getAddress().toString().c_str());

    Serial.print("1-BLE FreeHeap: ");
    Serial.println(ESP.getFreeHeap());
    //BLEClient*  pClient  = BLEDevice::createClient();
    pClient  = BLEDevice::createClient();
    Serial.println(" - Created client");

    Serial.print("2-BLE FreeHeap: ");
    Serial.println(ESP.getFreeHeap());
    pClient->setClientCallbacks(new MyClientCallback());

    // Connect to the remove BLE Server.
    pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
    Serial.println(" - Connected to server");

    Serial.print("3-BLE FreeHeap: ");
    Serial.println(ESP.getFreeHeap());
    // Obtain a reference to the service we are after in the remote BLE server.
    //BLERemoteService* pRemoteService = pClient->getService(serviceIn_UUID);

    pRemoteService = pClient->getService(serviceIn_UUID);
    if (pRemoteService == nullptr) {
      Serial.print("Failed to find our service UUID: ");
      Serial.println(serviceUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our service");

    Serial.print("4-BLE FreeHeap: ");
    Serial.println(ESP.getFreeHeap());
    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
    if (pRemoteCharacteristic == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic");

    Serial.print("5-BLE FreeHeap: ");
    Serial.println(ESP.getFreeHeap());
//    // BIG CRASH HERE - Read the value of the characteristic.
//    if(pRemoteCharacteristic->canRead()) {
//      std::string value = pRemoteCharacteristic->readValue();
//      Serial.print("The characteristic value was: ");
//      Serial.println(value.c_str());
//    }
//    if(pRemoteCharacteristic->canNotify())
//      pRemoteCharacteristic->registerForNotify(notifyCallback);

    connected = true;
    return true;
}
/**
 * Scan for BLE servers and find the first one that advertises the service we are looking for.
 */
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
 /**
   * Called for each advertising BLE server.
   */
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    Serial.print("BLE Advertised Device found: ");
    Serial.println(advertisedDevice.toString().c_str());
    Serial.print("BLE RSSI: ");
    Serial.println(advertisedDevice.getRSSI() );

    // We have found a device, let us now see if it contains the service we are looking for.
    if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {

      BLEDevice::getScan()->stop();
      myDevice = new BLEAdvertisedDevice(advertisedDevice);
      doConnect = true;
      doScan = true;

    } // Found our server
  } // onResult
}; // MyAdvertisedDeviceCallbacks

void setup() {
  Serial.begin(115200);
  Serial.print("BLE FreeHeap: ");
  Serial.println(ESP.getFreeHeap());
  Serial.println("Starting Arduino BLE Client application...");
  BLEDevice::init("");

  // Retrieve a Scanner and set the callback we want to use to be informed when we
  // have detected a new device.  Specify that we want active scanning and start the
  // scan to run for 5 seconds.
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setInterval(1349);
  pBLEScan->setWindow(449);
  pBLEScan->setActiveScan(true);
  pBLEScan->start(5, false);
} // End of setup.

// This is the Arduino main loop function.
void loop() {

  // If the flag "doConnect" is true then we have scanned for and found the desired
  // BLE Server with which we wish to connect.  Now we connect to it.  Once we are 
  // connected we set the connected flag to be true.
  if (doConnect == true) {
    if (connectToServer()) {
      Serial.println("We are now connected to the BLE Server.");
    } else {
      Serial.println("We have failed to connect to the server; there is nothin more we will do.");
    }
    doConnect = false;
  }

  // If we are connected to a peer BLE Server, update the characteristic each time we are reached
  // with the current time since boot.
  if (connected) {
    String newValue = "Time since boot: " + String(millis()/1000);
    Serial.println("Setting new characteristic value to \"" + newValue + "\"");
    Serial.print("BLE FreeHeap: ");
    Serial.println(ESP.getFreeHeap());

    // Set the characteristic's value to be the array of bytes that is actually a string.
    //pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
    pRemoteCharacteristic->writeValue("LedOn", 5);
    delay(1000);
    pRemoteCharacteristic->writeValue("LedOn", 5);
    delay(2000);
    pRemoteCharacteristic->writeValue("LedOff", 6);
    delay(2000);
    pClient->disconnect();
    doConnect = false;

  }else if(doScan){
    BLEDevice::getScan()->start(0);  // this is just example to start scan after disconnect, most likely there is better way to do it in arduino
  }

  delay(1000); // Delay a second between loops.
} // End of loop
chegewara commented 5 years ago

Every time you call this pClient = BLEDevice::createClient(); you create new BLEClient, so you have to delete it somewhere in code after disconnect. I have updated library to do it from onDisconnect() but in current library iyt will cause crash. What i can suggest now is something like that:

if(pClient != nullptr)
    delete(pClient); 
pClient  = BLEDevice::createClient();
qrpfun commented 5 years ago

chegewara many thanks for the ultra rapid answer!

Ok for the need to clear memory that way. I have applied your suggestion and now a very strange behaviour occurs. It runs a cycle ok, than when pointer is not clean the delete command crashes all as you can see the output here after. Mhh.. very critical

BLE FreeHeap: 274408
Starting Arduino BLE Client application...
BLE Advertised Device found: Name: , Address: 4a:61:ff:c1:be:1a, manufacturer data: 4c0010050a1c897627
BLE RSSI: -61
BLE Advertised Device found: Name: HC-08, Address: 88:4a:ea:8e:38:5d, manufacturer data: 48432d30380000000000000000000000000000000000, serviceUUID: 0000fff0-0000-1000-8000-00805f9b34fb, txPower: -6
BLE RSSI: -64
Forming a connection to 88:4a:ea:8e:38:5d
1-BLE FreeHeap: 181608
 - Created client
2-BLE FreeHeap: 180880
 - Connected to server
3-BLE FreeHeap: 176736
 - Found our service
4-BLE FreeHeap: 172244
 - Found our characteristic
5-BLE FreeHeap: 170816
We are now connected to the BLE Server.
Setting new characteristic value to "Time since boot: 1"
BLE FreeHeap: 170764
onDisconnect
BLE Advertised Device found: Name: HC-08, Address: 88:4a:ea:8e:38:5d, manufacturer data: 48432d30380000000000000000000000000000000000, serviceUUID: 0000fff0-0000-1000-8000-00805f9b34fb, txPower: -6
BLE RSSI: -64
Forming a connection to 88:4a:ea:8e:38:5d
1-BLE FreeHeap: 177248
CORRUPT HEAP: Bad head at 0x3ffe226c. Expected 0xabba1234 got 0x3ffe25b4
assertion "head != NULL" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/multi_heap_poisoning.c", line 214, function: multi_heap_free
abort() was called at PC 0x40149b97 on core 1

Backtrace: 0x4008d8d0:0x3ffc9f40 0x4008db01:0x3ffc9f60 0x40149b97:0x3ffc9f80 0x4009302d:0x3ffc9fb0 0x400846b2:0x3ffc9fd0 0x4008a3e5:0x3ffc9ff0 0x4000bec7:0x3ffca010 0x40090387:0x3ffca030 0x400d6923:0x3ffca050 0x400d46cf:0x3ffca070 0x400d4d99:0x3ffca090 0x400d5142:0x3ffca0b0 0x400d5161:0x3ffca0d0 0x400d34da:0x3ffca0f0 0x400d1732:0x3ffca120 0x400d1a5a:0x3ffca170 0x400d791d:0x3ffca210 0x40092545:0x3ffca230

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
chegewara commented 5 years ago

Try to decode this backtrace: Backtrace: 0x4008d8d0:0x3ffc9f40 0x4008db01:0x3ffc9f60 0x40149b97:0x3ffc9f80 0x4009302d:0x3ffc9fb0 0x400846b2:0x3ffc9fd0 0x4008a3e5:0x3ffc9ff0 0x4000bec7:0x3ffca010 0x40090387:0x3ffca030 0x400d6923:0x3ffca050 0x400d46cf:0x3ffca070 0x400d4d99:0x3ffca090 0x400d5142:0x3ffca0b0 0x400d5161:0x3ffca0d0 0x400d34da:0x3ffca0f0 0x400d1732:0x3ffca120 0x400d1a5a:0x3ffca170 0x400d791d:0x3ffca210 0x40092545:0x3ffca230

chegewara commented 5 years ago

Also you can try this code: https://gist.github.com/chegewara/d3ed0e3365407f6d3abcffc486b2c462

qrpfun commented 5 years ago

I tried to substitute BLEClient.cpp with the one you suggested but no success Same behaviour at the same place when deleting pClient

BLE FreeHeap: 171024
onDisconnect
BLE Advertised Device found: Name: HC-08, Address: 88:4a:ea:8e:38:5d, manufacturer data: 48432d30380000000000000000000000000000000000, serviceUUID: 0000fff0-0000-1000-8000-00805f9b34fb, txPower: -6
BLE RSSI: -66
Forming a connection to 88:4a:ea:8e:38:5d
1-BLE FreeHeap: 177432
CORRUPT HEAP: Bad head at 0x3ffe2148. Expected 0xabba1234 got 0x3ffe2490
assertion "head != NULL" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/multi_heap_poisoning.c", line 214, function: multi_heap_free
abort() was called at PC 0x40149c23 on core 1

Backtrace: 0x4008d8d0:0x3ffc9f20 0x4008db01:0x3ffc9f40 0x40149c23:0x3ffc9f60 0x4009302d:0x3ffc9f90 0x400846b2:0x3ffc9fb0 0x4008a3e5:0x3ffc9fd0 0x4000bec7:0x3ffc9ff0 0x40090387:0x3ffca010 0x400d699b:0x3ffca030 0x400d4747:0x3ffca050 0x400d4e11:0x3ffca070 0x400d51ba:0x3ffca090 0x400d51d9:0x3ffca0b0 0x400d33e6:0x3ffca0d0 0x400d3569:0x3ffca100 0x400d1772:0x3ffca120 0x400d1a9a:0x3ffca170 0x400d7995:0x3ffca210 0x40092545:0x3ffca230

Rebooting...
ets Jun  8 2016 00:22:57
chegewara commented 5 years ago

Hi, i just uploaded code with few bug fixes. Could you try it?

qrpfun commented 5 years ago

do you suggest to git clone all the esp32-snippets/cpp_utils and use it instead of BLE lib inside arduino package or just last few specific file from this lib ? Is my code right for the test or I have to change something ? As soon I will be home I will try your code. many thanks for your time

chegewara commented 5 years ago

git clone or download zip from this library and replace only those files which already exist in arduino library. There is no new file that needs to be added, just fixes.

qrpfun commented 5 years ago

Hi chegewara, I have followed all you suggestions and it seems to work fine !! Only pay attention to 2 wrong comments inside BLEDevice.cpp and BLEDevice.h where

static BLEServer*  m_pServer;
static BLEClient*   m_pClient;

I simply have removed comments and no problem to compile all.

it seems there is a remaining small memory leak but it may be caused by some minor problem in the code. I will clean the code and let it run all night and see is how long it keeps running and let you know. By now many thanks for ultra kind support

Here is an output from the loop with memory check enabled:

**BLE FreeHeap: 169948**
onDisconnect
BLE Advertised Device found: Name: HC-08, Address: 88:4a:ea:8e:38:5d, manufacturer data: 48432d30380000000000000000000000000000000000, serviceUUID: 0000fff0-0000-1000-8000-00805f9b34fb, txPower: -6
BLE RSSI: -65
Forming a connection to 88:4a:ea:8e:38:5d
1-BLE FreeHeap: 176296
 - Created client
2-BLE FreeHeap: 179936
 - Connected to server
3-BLE FreeHeap: 175880
 - Found our service
4-BLE FreeHeap: 171412
 - Found our characteristic
5-BLE FreeHeap: 169984
We are now connected to the BLE Server.
Setting new characteristic value to "Time since boot: 424"
**BLE FreeHeap: 169932**
onDisconnect
BLE Advertised Device found: Name: , Address: 53:68:00:e5:48:ae, manufacturer data: 4c001005031804bc64
BLE RSSI: -64
BLE Advertised Device found: Name: HC-08, Address: 88:4a:ea:8e:38:5d, manufacturer data: 48432d30380000000000000000000000000000000000, serviceUUID: 0000fff0-0000-1000-8000-00805f9b34fb, txPower: -6
BLE RSSI: -67
Forming a connection to 88:4a:ea:8e:38:5d
1-BLE FreeHeap: 175996
 - Created client
2-BLE FreeHeap: 179644
 - Connected to server
3-BLE FreeHeap: 175584
 - Found our service
4-BLE FreeHeap: 171116
 - Found our characteristic
5-BLE FreeHeap: 169688
We are now connected to the BLE Server.
Setting new characteristic value to "Time since boot: 432"
**BLE FreeHeap: 169636**
onDisconnect
chegewara commented 5 years ago

Thanks for feedback.

qrpfun commented 5 years ago

OK and thanks again to you. Here is an other issue that may be it should be better open in an other thread .. let me know. The problem was present before updating library files and I just commented out those lines (you can see in the very first code submitted where was commented out)

here are related lines from BLEClient example:

    ....
    Serial.println(" - Found our characteristic");
    Serial.print("5-BLE FreeHeap: ");
    Serial.println(ESP.getFreeHeap());
    // BIG CRASH HERE - Read the value of the characteristic.
    if(pRemoteCharacteristic->canRead()) {
      std::string value = pRemoteCharacteristic->readValue(); // HERE HEAP CRASH
      Serial.print("The characteristic value was: ");
      Serial.println(value.c_str());
    }
    if(pRemoteCharacteristic->canNotify())
      pRemoteCharacteristic->registerForNotify(notifyCallback);
    connected = true;

And here the other related heap crash that happens just while reading characteristic:

4-BLE FreeHeap: 172000
 - Found our characteristic
5-BLE FreeHeap: 170576
CORRUPT HEAP: Bad head at 0x3ffe1da4. Expected 0xabba1234 got 0xad567800
assertion "head != NULL" failed: file "/Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/heap/multi_heap_poisoning.c", line 214, function: multi_heap_free
abort() was called at PC 0x4014a37b on core 0

Backtrace: 0x4008d8d0:0x3ffcf900 0x4008db01:0x3ffcf920 0x4014a37b:0x3ffcf940 0x4009302d:0x3ffcf970 0x400846b2:0x3ffcf990 0x4008a3e5:0x3ffcf9b0 0x4000bec7:0x3ffcf9d0 0x400d45b2:0x3ffcf9f0 0x400d5185:0x3ffcfa30 0x400d3abd:0x3ffcfa50 0x400d4435:0x3ffcfb00 0x400e3225:0x3ffcfb50 0x400df212:0x3ffcfba0 0x40092545:0x3ffcfbd0

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0018,len:4
load:0x3fff001c,len:1100
load:0x40078000,len:10088
load:0x40080400,len:6380
entry 0x400806a4
BLE FreeHeap: 274384
chegewara commented 5 years ago

Yes, it would be good if you open new issue and try to encode backtrace too. Thanks.

qrpfun commented 5 years ago

OK, will soon open new issue Just returning on previous issue, as mentioned before, I had leaved program running during the night and in the morning I have found it in crash status: Probably the small memory leak has grown enough to crash the system. Now I will activate debugging on esp core will run it again this night.

qrpfun commented 5 years ago

This is the consolle output status when this morning I have check the sw has stopped to run without any other message

 - Found our characteristic
5-BLE FreeHeap: 169192
[D][BLERemoteCharacteristic.cpp:444] registerForNotify(): >> registerForNotify(): Characteristic: uuid: 0000ffe1-0000-1000-8000-00805f9b34fb, handle: 54 0x36, props: broadcast: 0, read: 1, write_nr: 1, write: 0, notify: 1, indicate: 0, auth: 0
[D][FreeRTOS.cpp:164] take(): Semaphore taking: name: RegForNotifyEvt (0x3ffe34dc), owner: <N/A> for registerForNotify
[D][FreeRTOS.cpp:173] take(): Semaphore taken:  name: RegForNotifyEvt (0x3ffe34dc), owner: registerForNotify
[D][BLERemoteCharacteristic.cpp:329] getDescriptor(): >> getDescriptor: uuid: 00002902-0000-1000-8000-00805f9b34fb
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_REG_FOR_NOTIFY_EVT
[D][BLERemoteCharact[D][BLERemoteCharacteristic.cpp:553] writeValue(): >> writeValue(), length: 6
[D][FreeRTOS.cpp:164] take(): Semaphore taking: name: WriteCharEvt (0x3ffe353c), owner: <N/A> for writeValue
[D][FreeRTOS.cpp:173] take(): Semaphore taken:  name: WriteCharEvt (0x3ffe353c), owner: writeValue
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[D][BLEClient.cpp:168] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[D][BLERemoteCharacteristic.cpp:580] writeValue(): << writeValue
[D][BLEClient.cpp:148] disconnect(): >> disconnect()
[D][BLEClient.cpp:155] disconnect(): << disconnect()
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_CLOSE_EVT
[D][BLEClient.cpp:168] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_CLOSE_EVT
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ..[D][BLEClient.cpp:148] disconnect(): >> disconnect()
[D][BLEClient.cpp:155] disconnect(): << disconnect()
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_CLOSE_EVT
[D][BLEClient.cpp:168] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_CLOSE_EVT
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_DISCONNECT_EVT
[D][BLEClient.cpp:168] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_DISCONNECT_EVT
[E][BLEClient.cpp:192] gattClientEventHandler(): disconnect event, conn_id: 0
onDisconnect
[D][BLEScan.cpp:205] start(): >> start(duration=0)
[D][FreeRTOS.cpp:164] take(): Semaphore taking: name: ScanEnd (0x3ffdeeb8), owner: <N/A> for start
[D][FreeRTOS.cpp:173] take(): Semaphore taken:  name: ScanEnd (0x3ffdeeb8), owner: start
[D][BLEScan.cpp:237] start(): << start()
[D][BLEAdvertisedDevice.cpp:424] setRSSI(): - setRSSI(): rssi: -65
[D][BLEAdvertisedDevice.cpp:253] parseAdvertisement(): Type: 0x01 (ESP_BLE_AD_TYPE_FLAG), length: 1, data: 06
[D][BLEAdvertisedDevice.cpp:253] parseAdvertisement(): Type: 0x02 (ESP_BLE_AD_TYPE_16SRV_PART), length: 2, data: f0ff
[D][BLEAdvertisedDevice.cpp:453] setServiceUUID(): - addServiceUUID(): serviceUUID: 0000fff0-0000-1000-8000-00805f9b34fb
[D][BLEAdvertisedDevice.cpp:253] parseAdvertisement(): Type: 0xff (ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE), length: 22, data: 48432d30380000000000000000000000000000000000
[D][BLEAdvertisedDevice.cpp:401] setManufacturerData(): - manufacturer data: 48432d30380000000000000000000000000000000000
[D][BLEAdvertisedDevice.cpp:253] parseAdvertisement(): Type: 0x12 (ESP_BLE_AD_TYPE_INT_RANGE), length: 4, data: 06000c00
[D][BLEAdvertisedDevice.cpp:349] parseAdvertisement(): Unhandled type: adType: 18 - 0x12
[D][BLEAdvertisedDevice.cpp:253] parseAdvertisement(): Type: 0x0a (ESP_BLE_AD_TYPE_TX_PWR), length: 1, data: fa
[D][BLEAdvertisedDevice.cpp:484] setTXPower(): - t[D][BLEScan.cpp:205] start(): >> start(duration=0)
[D][FreeRTOS.cpp:164] take(): Semaphore taking: name: ScanEnd (0x3ffdeeb8), owner: <N/A> for start
[D][FreeRTOS.cpp:173] take(): Semaphore taken:  name: ScanEnd (0x3ffdeeb8), owner: start
[D][BLEScan.cpp:237] start(): << start()
[D][BLEAdvertisedDevice.cpp:424] setRSSI(): - setRSSI(): rssi: -65
[D][BLEAdvertisedDevice.cpp:253] parseAdvertisement(): Type: 0x01 (ESP_BLE_AD_TYPE_FLAG), length: 1, data: 06
[D][BLEAdvertisedDevice.cpp:253] parseAdvertisement(): Type: 0x02 (ESP_BLE_AD_TYPE_16SRV_PART), length: 2, data: f0ff
[D][BLEAdvertisedDevice.cpp:453] setServiceUUID(): - addServiceUUID(): serviceUUID: 0000fff0-0000-1000-8000-00805f9b34fb
[D][BLEAdvertisedDevice.cpp:253] parseAdvertisement(): Type: 0xff (ESP_BLE_AD_MANUFACTURER_SPECIFIC_TYPE), length: 22, data: 48432d30380000000000000000000000000000000000
[D][BLEAdvertisedDevice.cpp:401] setManufacturerData(): - manufacturer data: 48432d30380000000000000000000000000000000000
[D][BLEAdvertisedDevic[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[D][BLEClient.cpp:168] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
[D][BLERemoteCharacteristic.cpp:580] writeValue(): << writeValue
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_DISCONNECT_EVT
[D][BLEClient.cpp:168] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_DISCONNECT_EVT
[E][BLEClient.cpp:192] gattClientEventHandler(): disconnect event, conn_id: 0
onDisconnect
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_CLOSE_EVT
[D][BLEClient.cpp:168] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_CLOSE_EVT
[D][BLERemoteCharacteristic.cpp:553] writeValue(): >> writeValue(), length: 6
[E][BLERemoteCharacteristic.cpp:557] writeValue(): Disconnected
[D][BLEClient.cpp:148] disconnect(): >> disconnect()
[D][BLEClient.cpp:155] disconnect(): << disconnect()
[D][BLEScan.cpp:205] start(): >> start(duration=0)
[D][FreeRTOS.cpp:164] take(): Semaphore taking: name: ScanEnd (0x3ffdeeb8), owner: <N/A> for start
[D][FreeRTOS.cpp:173] take(): Semaphore taken:  name: ScanEnd (0x3ffdeeb8), owner: start
[D][BLEScan.cpp:237] start(): << start()
qrpfun commented 5 years ago

It clearly sill a memory leak problem I Have run the code for about 12 hours and log are clear in heap memory exausthion Strange is that the code does not reboot but seem frozen and no work, not even watchdog Is are latest debug lines

09:04:09.599 -> [D][BLERemoteService.cpp:40] BLERemoteService(): << BLERemoteService()
09:04:09.599 -> [D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
09:04:09.599 -> [D][BLEClient.cpp:168] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
09:04:09.599 -> [D][BLERemoteService.cpp:32] BLERemoteService(): >> BLERemoteService()
09:04:09.599 -> [D][BLERemoteService.cpp:40] BLERemoteService(): << BLERemoteService()
[D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
09:04:09.680 -> [D][BLEClient.cpp:168] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
09:04:09.680 -> [D][BLERemoteServittClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_RES_EVT
09:04:09.680 -> [D][BLERemoteService.cpp:32] BLERemoteService(): >> BLERemoteService()
09:04:09.680 -> [D][BLERemoteService.cpp:40] BLERemoteService(): << BLERemoteService()
09:04:09.680 -> [D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_CMPL_EVT
09:04:09.680 -> [D][BLEClient.cpp:168] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_SEARCH_CMPL_EVT
09:04:09.680 -> [D][BLEClient.cpp:455] getServices(): << getServices
09:04:09.680 -> [D][BLEClient.cpp:415] getService(): << getService: found the service with uuid: 0000ffe0-0000-1000-8000-00805f9b34fb
09:04:09.680 ->  - Found our service
09:04:09.680 -> 4-BLE FreeHeap: 57484
09:04:09.680 -> [D][BLERemoteService.cpp:122] retrieveCharacteristics(): >> retrieveCharacteristics() for service: 0000ffe0-0000-1000-8000-00805f9b34fb
09:04:29.713 -> [D][BLERemoteService.cpp:153] retrieveCharacteristics(): Found a characteristic: Handle: 54, UUID: 0000ffe1-0000-1000-8000-00805f9b34fb
09:04:29.713 -> [D][BLERemoteCharacteristic.cpp:43] BLERemoteCharacteristic(): >> BLERemoteC[D][BLERemoteCharacteristic.cpp:553] writeValue(): >> writeValue(), length: 6
09:04:29.713 -> [D][FreeRTOS.cpp:164] take(): Semaphore taking: name: WriteCharEvt (0x3fffed60), owner: <N/A> for writeValue
09:04:29.713 -> [D][FreeRTOS.cpp:173] take(): Semaphore taken:  name: WriteCharEvt (0x3fffed60), owner: writeValue
09:04:29.713 -> [D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
09:04:29.713 -> [D][BLEClient.cpp:168] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_WRITE_CHAR_EVT
09:04:29.713 -> [D][BLERemoteCharacteristic.cpp:580] writeValue(): << writeValue
09:04:29.713 -> [D][BLEClient.cpp:148] disconnect(): >> disconnect()
09:04:29.713 -> [D][BLEClient.cpp:155] disconnect(): << disconnect()
09:04:29.713 -> [D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_CLOSE_EVT
09:04:41.065 -> [D][BLEClient.cpp:168] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ... ESP_GATTC_CLOSE_EVT
09:04:41.065 -> [D][BLEDevice.cpp:152] gattClientEventHandler(): gattClientEventHandler [esp_gatt_if: 4] ..
chegewara commented 5 years ago

I see here 3 possibilities:

  1. you dont clear BLEScan from scanned devices,
  2. you have leak in your code,
  3. less likely but possible (i tested it and didnt find memory leak) there is leak somewhere i couldnt find yet
qrpfun commented 5 years ago

the code is not different from the one in the very first post, nothing special. I understand it's not easy without the other device running the same way, but the only possibility I can see is that there shoud be something somewhere else.

chegewara commented 5 years ago

Looks like there still is leak even with master library.

chegewara commented 5 years ago

Ok, like i said, there is 3 possibilities. I tested library, i found all leaks and i can say we have leak in point 2 and/or 3. It all depends on point of view. This is the cause of leak i couldnt find: pClient->setClientCallbacks(new MyClientCallback()); Each time we are creating new instance of this class which is never deleted. This is how you can fix it:

MyClientCallback* my_callback = new MyClientCallback();
bool connectToServer() {
...
    pClient->setClientCallbacks(my_callback);
...

Or we can fix it by deleting it in BLEClient destructor, then i have to add proper code.

Another leak was here:

//    delete(myDevice);
//    delete pClient; //crash

With bugfixes those lines should be uncommented.

EDIT: I thought i will add delete m_callback to BLEClient to make this library even more easy to use, but i decided to not do that. The reason i wont do that is because one may want to use one instance of clientCallback for few connected clients and if one client will disconnect and delete clientCallback then whole app will crash. The reason to use one instance is obvious, heap saving.

chegewara commented 5 years ago

This is your code i changed a bit to avoid code stuck in some cases (change service and char UUIDs). Only issue there still is in library and i have to find and fix is crash after some few notifiCallback registrations:

/**
 * A BLE client example that is rich in capabilities.
 * There is a lot new capabilities implemented.
 * author unknown
 * updated by chegewara
 */

#include "BLEDevice.h"
//#include "BLEScan.h"

// The remote service we wish to connect to.
static BLEUUID serviceIn_UUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
static BLEUUID serviceUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8");
// The characteristic of the remote service we are interested in.
static BLEUUID    charUUID("00009999-0000-1000-8000-00805f9b34fb");
static int count = 0;
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
static bool isScanContinue = true;
static BLERemoteCharacteristic* pRemoteCharacteristic;
static BLEAdvertisedDevice* myDevice;
static BLEClient*  pClient;
static BLERemoteService* pRemoteService;

static void notifyCallback(
  BLERemoteCharacteristic* pBLERemoteCharacteristic,
  uint8_t* pData,
  size_t length,
  bool isNotify) {
    Serial.print("Notify callback for characteristic ");
    Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
    Serial.print(" of data length ");
    Serial.println(length);
    Serial.print("data: ");
    Serial.println((char*)pData);
}

class MyClientCallback : public BLEClientCallbacks {
  void onConnect(BLEClient* pclient) {
  }

  void onDisconnect(BLEClient* pclient) {
    connected = false;
    Serial.print("onDisconnect: ");
    Serial.println(++count);
    if(isScanContinue){
      BLEDevice::getScan()->erase(pclient->getPeerAddress());
    }
    delete myDevice;
    delete pclient; //crash
  }
};

bool connectToServer() {
    Serial.print("Forming a connection to ");
    Serial.println(myDevice->getAddress().toString().c_str());

    Serial.print("1-BLE FreeHeap: ");
    Serial.println(ESP.getFreeHeap());
//    BLEClient*  pClient  = BLEDevice::createClient();
    pClient  = BLEDevice::createClient();
    Serial.println(" - Created client");

    Serial.print("2-BLE FreeHeap: ");
    Serial.println(ESP.getFreeHeap());
    pClient->setClientCallbacks(new MyClientCallback(), true); // optional parameter to delete callbacks in destructor, by default its set to true

    // Connect to the remove BLE Server.
    bool _connected = pClient->connect(myDevice);  // if you pass BLEAdvertisedDevice instead of address, it will be recognized type of peer device address (public or private)
    if(!_connected){
      delete pClient;
      delete myDevice;
      return false;
    }
    Serial.println(" - Connected to server");
    Serial.print("3-BLE FreeHeap: ");
    Serial.println(ESP.getFreeHeap());
    // Obtain a reference to the service we are after in the remote BLE server.
    //BLERemoteService* pRemoteService = pClient->getService(serviceIn_UUID);

    pRemoteService = pClient->getService(serviceIn_UUID);
    if (pRemoteService == nullptr) {
      Serial.print("Failed to find our service UUID: ");
      Serial.println(serviceUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our service");

    Serial.print("4-BLE FreeHeap: ");
    Serial.println(ESP.getFreeHeap());
    // Obtain a reference to the characteristic in the service of the remote BLE server.
    pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
    if (pRemoteCharacteristic == nullptr) {
      Serial.print("Failed to find our characteristic UUID: ");
      Serial.println(charUUID.toString().c_str());
      pClient->disconnect();
      return false;
    }
    Serial.println(" - Found our characteristic");

    Serial.print("5-BLE FreeHeap: ");
    Serial.println(ESP.getFreeHeap());
////    // BIG CRASH HERE - Read the value of the characteristic.
    if(pRemoteCharacteristic->canRead()) {
      std::string value = pRemoteCharacteristic->readValue();
      Serial.print("The characteristic value was: ");
      Serial.println(value.c_str());
    }
    if(pRemoteCharacteristic->canNotify())
      pRemoteCharacteristic->registerForNotify(notifyCallback); // code sometimes crashes here after many registrations 

    connected = true;
    return true;
}
/**
 * Scan for BLE servers and find the first one that advertises the service we are looking for.
 */
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
 /**
   * Called for each advertising BLE server.
   */
  void onResult(BLEAdvertisedDevice advertisedDevice) {
    Serial.print("BLE Advertised Device found: ");
    Serial.println(advertisedDevice.toString().c_str());
    Serial.print("BLE RSSI: ");
    Serial.println(advertisedDevice.getRSSI() );

    // We have found a device, let us now see if it contains the service we are looking for.
    if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(BLEUUID("9999"))) {

      BLEDevice::getScan()->stop();
      myDevice = new BLEAdvertisedDevice(advertisedDevice);
      doConnect = true;
      doScan = true;

    } // Found our server
  } // onResult
}; // MyAdvertisedDeviceCallbacks

void setup() {
  Serial.begin(115200);
  Serial.print("BLE FreeHeap: ");
  Serial.println(ESP.getFreeHeap());
  Serial.println("Starting Arduino BLE Client application...");
  BLEDevice::init("");

  // Retrieve a Scanner and set the callback we want to use to be informed when we
  // have detected a new device.  Specify that we want active scanning and start the
  // scan to run for 5 seconds.
  BLEScan* pBLEScan = BLEDevice::getScan();
  pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
  pBLEScan->setInterval(1349);
  pBLEScan->setWindow(449);
  pBLEScan->setActiveScan(true);
  pBLEScan->start(5, false);
} // End of setup.

// This is the Arduino main loop function.
void loop() {

  // If the flag "doConnect" is true then we have scanned for and found the desired
  // BLE Server with which we wish to connect.  Now we connect to it.  Once we are 
  // connected we set the connected flag to be true.
  if (doConnect == true) {
    if (connectToServer()) {
      Serial.println("We are now connected to the BLE Server.");
    } else {
      Serial.println("We have failed to connect to the server; there is nothin more we will do.");
    }
    doConnect = false;
  }

  // If we are connected to a peer BLE Server, update the characteristic each time we are reached
  // with the current time since boot.
  if (connected) {
    String newValue = "Time since boot: " + String(millis()/1000);
    Serial.println("Setting new characteristic value to \"" + newValue + "\"");
    Serial.print("BLE FreeHeap: ");
    Serial.println(ESP.getFreeHeap());

    // Set the characteristic's value to be the array of bytes that is actually a string.
    //pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
    pRemoteCharacteristic->writeValue("LedOn", 5);
    delay(1000);
    pRemoteCharacteristic->writeValue("LedOn", 5);
    delay(2000);
    pRemoteCharacteristic->writeValue("LedOff", 6);
    delay(2000);
    pClient->disconnect();
    doConnect = false;

  }else if(doScan){
    BLEDevice::getScan()->start(0);  // this is just example to start scan after disconnect, most likely there is better way to do it in arduino
  }

  delay(1000); // Delay a second between loops.
} // End of loop
qrpfun commented 5 years ago

super nice job chegewara ! by now many many thanks and I try it asap and leave it work to check proper resilience

qrpfun commented 5 years ago

So, I had updated ESP snippets with git pull and replaced BLE* into Arduino ESP32 BLE lib. very first impressions are great not a single byte lost super good job ! now let it run (rock) all night long

here a snapshot

onDisconnect: 26
BLE Advertised Device found: Name: HC-08, Address: 88:4a:ea:8e:38:5d, manufacturer data: 48432d30380000000000000000000000000000000000, serviceUUID: 0000fff0-0000-1000-8000-00805f9b34fb, txPower: -6
21:04:30.000 -> BLE RSSI: -47
Forming a connection to 88:4a:ea:8e:38:5d
21:04:30.991 -> 1-BLE FreeHeap: 181836
21:04:30.991 ->  - Created client
21:04:30.991 -> 2-BLE FreeHeap: 181068
 - Connected to server
21:04:31.059 -> 3-BLE FreeHeap: 176960
 - Found our service
21:04:31.976 -> 4-BLE FreeHeap: 172556
21:04:31.976 ->  - Found our characteristic
21:04:31.976 -> 5-BLE FreeHeap: 171128
21:04:31.976 -> The characteristic value was: 
21:04:32.010 -> We are now connected to the BLE Server.
21:04:32.010 -> Setting new characteristic value to "Time since boot: 214"
21:04:32.010 -> BLE FreeHeap: 170276
onDisconnect: 27
BLE Advertised Device found: Name: HC-08, Address: 88:4a:ea:8e:38:5d, manufacturer data: 48432d30380000000000000000000000000000000000, serviceUUID: 0000fff0-0000-1000-8000-00805f9b34fb, txPower: -6
21:04:38.147 -> BLE RSSI: -48
Forming a connection to 88:4a:ea:8e:38:5d
21:04:39.139 -> 1-BLE FreeHeap: 181836
21:04:39.139 ->  - Created client
21:04:39.139 -> 2-BLE FreeHeap: 181068
 - Connected to server
21:04:39.209 -> 3-BLE FreeHeap: 176960
 - Found our service
21:04:40.098 -> 4-BLE FreeHeap: 172556
21:04:40.098 ->  - Found our characteristic
21:04:40.135 -> 5-BLE FreeHeap: 171128
21:04:40.135 -> The characteristic value was: 
21:04:40.135 -> We are now connected to the BLE Server.
21:04:40.135 -> Setting new characteristic value to "Time since boot: 222"
21:04:40.135 -> BLE FreeHeap: 170276
onDisconnect: 28
qrpfun commented 5 years ago

sw has run all night and more than 5000 cycles have been successfully done without any loss ! very good thanks a lot for you support ! do you think you will officially release libs in arduino esp32 package soon or better stay tuned on this snippet snapshot ? ciao

qrpfun commented 5 years ago

P.S. with this library release there is no crash in in readValue() too as stated in issue #794

chegewara commented 5 years ago

I will release arduino version soon, but before i do that i have to be sure most bugs and issues are fixed, which requires testing and positive feedback from users.

TheNitek commented 4 years ago

Any chance this will find it's way into the arduino version any time soon? I am having memory leak issues as well.

chegewara commented 4 years ago

All changes has been already merged.

TheNitek commented 4 years ago

But not into the arduino-esp32 core, right? E.g. https://github.com/espressif/arduino-esp32/blob/master/libraries/BLE/src/BLEClient.cpp is still "broken"

chegewara commented 4 years ago

Yes, in arduino too. What is still broken?

TheNitek commented 4 years ago

delete on the client fails because of "CORRUPT HEAP", the onDisconnect callback is called before the disconnect is processed properly and the destructor doesn't seem to cleanup as thoroughly as the one in your implementation (e.g. no delete of the callbacks)

TheNitek commented 4 years ago

The corrupt heap seems to occur because BLERemoteService::removeCharacteristics is still deleting the characteristics twice, something you also have fixed in your files.

chegewara commented 4 years ago

Well, yes, it is possible.

BTW, there is no need to delete callbacks, its just a pointer(address) to function

evanfahy112 commented 4 years ago

Hey guys,

I hope I'm not hijacking this thread but I think I have a similar issue and I'm hoping you can help.

I'm seeing an intermittent crash at this point of the onDisconnect():

if (isScanContinue) { BLEDevice::getScan()->erase(pclient->getPeerAddress()); }

I can usually go through 4/5 cycles of connecting but then it crashes. This is the output on the serial monitor:

`` BLE Advertised Device found: Name: BlueTooth Printer, Address: 66:12:0d:a9:03:34, serviceUUID: 000018f0-0000-1000-8000-00805f9b34fb, txPower: 4 BLE RSSI: -86 In Settings Menu

connectBLE... Forming a connection to 66:12:0d:a9:03:34 1 BLE FreeHeap: 121508 Created client 2 BLE FreeHeap: 120780 pClient->setClientCallbacks(new MyClientCallback(), true); onConnect: - Connected to server 3 BLE FreeHeap: 115860 Found our service 4 BLE FreeHeap: 112984 Found our characteristic 5 BLE FreeHeap: 111904 The characteristic value was: We are now connected to the BLE Server. Setting new characteristic value to "Time since boot: 18" BLE FreeHeap: 110564 onDisconnect: 1 66:12:0d:a9:03:34 1 device and client deleted Client deleted Initialising scan... BLE Advertised Device found: Name: , Address: 1a:8d:4c:69:6b:b0, manufacturer data: 060001092002b8ced8efa5940c756358b9cbd4a9bdea708a53da804aca BLE RSSI: -78 BLE Advertised Device found: Name: , Address: 66:12:0d:a9:03:34, serviceUUID: 000018f0-0000-1000-8000-00805f9b34fb, txPower: 4 BLE RSSI: -80

connectBLE... 1 0 Forming a connection to 66:12:0d:a9:03:34 1 BLE FreeHeap: 121216 Created client 2 BLE FreeHeap: 120488 pClient->setClientCallbacks(new MyClientCallback(), true); onConnect: - Connected to server 3 BLE FreeHeap: 115564 Found our service 4 BLE FreeHeap: 112696 Found our characteristic 5 BLE FreeHeap: 111612 The characteristic value was: We are now connected to the BLE Server. Setting new characteristic value to "Time since boot: 28" BLE FreeHeap: 110276 onDisconnect: 2 66:12:0d:a9:03:34 1 device and client deleted Client deleted Initialising scan... BLE Advertised Device found: Name: , Address: 66:12:0d:a9:03:34, serviceUUID: 000018f0-0000-1000-8000-00805f9b34fb, txPower: 4 BLE RSSI: -78 In Settings Menu connectBLE... 1 0 Forming a connection to 66:12:0d:a9:03:34 1 BLE FreeHeap: 121512 Created client 2 BLE FreeHeap: 120784 pClient->setClientCallbacks(new MyClientCallback(), true); onDisconnect: 3 66:12:0d:a9:03:34 0 Client deleted We have failed to connect to the server; We should reconnect!

Forming a connection to 66:12:0d:a9:03:34 1 BLE FreeHeap: 121832 Created client 2 BLE FreeHeap: 121108 pClient->setClientCallbacks(new MyClientCallback(), true); onConnect: - Connected to server 3 BLE FreeHeap: 116172 Found our service 4 BLE FreeHeap: 113312 Found our characteristic 5 BLE FreeHeap: 112228 The characteristic value was: We are now connected to the BLE Server. Setting new characteristic value to "Time since boot: 35" BLE FreeHeap: 110884 onDisconnect: 4 Guru Meditation Error: Core 0 panic'ed (LoadProhibited). Exception was unhandled. Core 0 register dump: PC : 0x401857d7 PS : 0x00060830 A0 : 0x800e99b8 A1 : 0x3ffdd5c0
A2 : 0x0000007c A3 : 0x00000000 A4 : 0x3ffdd624 A5 : 0x3ffdd554
A6 : 0x3ffdd518 A7 : 0x3f418450 A8 : 0x80182134 A9 : 0x3ffdd5a0
A10 : 0x3ffef2d4 A11 : 0x4008b9e4 A12 : 0x00000004 A13 : 0x00000011
A14 : 0x00000011 A15 : 0xff000000 SAR : 0x00000018 EXCCAUSE: 0x0000001c
EXCVADDR: 0x0000007c LBEG : 0x4000c2e0 LEND : 0x4000c2f6 LCOUNT : 0x00000000
``

Backtrace:

Backtrace: 0x401857d7:0x3ffdd5c0 0x400e99b5:0x3ffdd5e0 0x400e9d50:0x3ffdd600 0x400d2216:0x3ffdd660 0x400e7a21:0x3ffdd6b0 0x400e855d:0x3ffdd760 0x40100c36:0x3ffdd7b0 0x400fc7e6:0x3ffdd800 0x4008e295:0x3ffdd830

Backtrace: 0x401857d7:0x3ffdd5c0 0x400e99b5:0x3ffdd5e0 0x400e9d50:0x3ffdd600 0x400d2216:0x3ffdd660 0x400e7a21:0x3ffdd6b0 0x400e855d:0x3ffdd760 0x40100c36:0x3ffdd7b0 0x400fc7e6:0x3ffdd800 0x4008e295:0x3ffdd830

0x401857d7: std::__cxx11::basic_string , std::allocator >::_M_dispose() at /builds/idf/crosstool-NG/.build/xtensa-esp32-elf/build/build-cc-gcc-final/xtensa-esp32-elf/libstdc++-v3/include/bits/basic_string.h line 135

0x400e99b5: BLEAdvertisedDevice::~BLEAdvertisedDevice() at c:\users\alank\appdata\local\arduino15\packages\esp32\tools\xtensa-esp32-elf-gcc\1.22.0-80-g6c4433a-5.2.0\xtensa-esp32-elf\include\c++\5.2.0\bits/basic_string.h line 544

0x400e9d50: BLEScan::erase(BLEAddress) at C:\Users\alank\Documents\Arduino\libraries\BLE\src\BLEScan.cpp line 276

0x400d2216: MyClientCallback::onDisconnect(BLEClient*) at C:\WINDOWS\TEMP\arduino_build_209878\sketch/BLE_Client.h line 53

0x400e7a21: BLEClient::gattClientEventHandler(esp_gattc_cb_event_t, unsigned char, esp_ble_gattc_cb_param_t*) at C:\Users\alank\Documents\Arduino\libraries\BLE\src\BLEClient.cpp line 191

0x400e855d: BLEDevice::gattClientEventHandler(esp_gattc_cb_event_t, unsigned char, esp_ble_gattc_cb_param_t*) at C:\Users\alank\Documents\Arduino\libraries\BLE\src\BLEDevice.cpp line 173

0x40100c36: btc_gattc_cb_handler at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/bt/bluedroid/btc/profile/std/gatt/btc_gattc.c line 31

0x400fc7e6: btc_task at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/bt/bluedroid/btc/core/btc_task.c line 110

0x4008e295: vPortTaskWrapper at /Users/ficeto/Desktop/ESP32/ESP32/esp-idf-public/components/freertos/port.c line 143

chegewara commented 4 years ago

Hi, This is not the same issue. I think this may be the problem, because IIRC client is deleted by stack after disconnecting: BLEDevice::getScan()->erase(pclient->getPeerAddress()); Its strange it does not crash on every call thou. When you try to get address from deleted object it should crash, but sometimes it may works because memory is still not rewritten.

Maybe try to call it in onDisconnect, when pclient still has not been deleted.

evanfahy112 commented 4 years ago

This is how I'm calling the onDisconnect function and I think its being called before the delete.:

void onDisconnect(BLEClient* pclient) { Serial.print("onDisconnect: "); Serial.println(++count); if (isScanContinue) { Serial.print("Trying to erase address "); Serial.println(pclient->getPeerAddress().toString().c_str()); BLEDevice::getScan()->erase(pclient->getPeerAddress()); Serial.println("Erased!"); } connected = false; Serial.println(myDevicePresent); if (myDevicePresent == true) { delete myDevice; //deallocating a memory cell using delete //myDevice = NULL; Serial.println("----device and client deleted----"); myDevicePresent = false; } delete pclient; //crash //myDevice = NULL; delay(100); Serial.println("----Client deleted----"); connected = false; doConnect = true; }

If I look at the verbose debugging log I can see that in void BLEScan::erase(BLEAddress address) the crash occurs on the delete(advertisedDevice); Could timing be causing an issue? I have implemented code you guys have shared above in a bigger project. If I run just the core BLEClient connect/disconnect functionaloty which is similar to your shared code I can cycle it hundreds of times.

chegewara commented 4 years ago

For some reason, i dont know why, sometimes delete is trying to destroy not existing advertised device or trying to access corrupted memory. There is function to clear scan data, which will delete all scanned devices. You may try this, if its not a problem and dont collide with your app logic.

Also IIRC scan->start(time, false) should clear scanned devices. Second parameter control if you continue scan and dont want to delete already found devices if true, or delete devices and perform new scan if false.

madubashana1990 commented 4 years ago

Hi @chegewara , I have a problem in BLE Client example, that every time I do pClient->disconnect(); command to disconnect the client when I connect my heap memory getting smaller. after several cycles, heap memory is getting to low and esp get restart. is there any proper way to disconnect server form ble client? .