Skip to content

Scanning for bluetooth-devices works only once #3770

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Elmi77 opened this issue Feb 26, 2020 · 10 comments · Fixed by #4126
Closed

Scanning for bluetooth-devices works only once #3770

Elmi77 opened this issue Feb 26, 2020 · 10 comments · Fixed by #4126

Comments

@Elmi77
Copy link

Elmi77 commented Feb 26, 2020

I have quite a complex application which is low on memory. From time to time this application scans for surrounding bluetooth devices. As the whole BLEScan-stuff consumes plenty of RAM, after such a scan everything is deinitialised to save the related memory:

   BLEDevice::init("");
   pBLEScan = BLEDevice::getScan(); //create new scan
   if (pBLEScan)
   {
      pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
      pBLEScan->setActiveScan(true); //set passive scan; active scan uses more power, but get results faster
      pBLEScan->setInterval(100);
      pBLEScan->setWindow(99);  // less or equal setInterval value
      BLEScanResults foundDevices = pBLEScan->start(5,false);
      pBLEScan->stop();
      pBLEScan->clearResults();   // delete results fromBLEScan buffer to release memory
   }
   BLEDevice::deinit(true);

My problem: this works well for the very first call. On the second and all following calls, no more bluetooth-devices are found, means BLEDevice::deinit() or BLEDevice::init() seems to be incomplete and probably leaves some variables back in a state, which avoids further successful scanning.

So my question: how can I reinitialise the whole BLE-stuff correctly in order to successfully scan the devices more than once?

Thanks!

@chegewara
Copy link
Contributor

@Elmi77
Copy link
Author

Elmi77 commented Feb 27, 2020

As it can be seen above, clearResults() is already used - so that does not solve anything.

@chegewara
Copy link
Contributor

Like i mentioned in 2nd topic, library is not prepared to delete BLEScan object, but it can be easy fixed:

  1. in BLEDevice::deinit delete all "static" class object like BLEScan or BLEAdvertising and set appropriate variables to nullptr
  2. or update BLEScan and BLEAdvertising destructor to do the same
  3. or add functions to have access to m_pScan in BLEDevice and set it to nullptr
  4. ...

@Elmi77
Copy link
Author

Elmi77 commented Feb 28, 2020

I already tried deleting m_pScan and reinitialising all the static variables before the next attempt but with no success, there are still no bluetooth devices found any more on second try.

And: shouldn't this issue be fixed here in the repository as it is definitely a defect and other may stumble upon it too? That's the reason why I filed this bugreport...

@chegewara
Copy link
Contributor

static void BLEDevice::deleteScan() {
	delete m_pScan;
	m_pScan = nullptr;
}

Then:

BLEDevice::deinit();
BLEDevice::deleteScan();
BLEDevice::init();

And: shouldn't this issue be fixed here in the repository as it is definitely a defect and other may stumble upon it too

Feel free to create PR.

@TheNitek
Copy link
Contributor

I think the BLEDevice::deinit(true); is your problem. Make that a "false". deinit(true) releases internal parts of the bluetooth stack that cannot be reinitialized during runtime.

@Elmi77
Copy link
Author

Elmi77 commented Feb 29, 2020

@TheNitek the reason I'm doing it that complicated way is I'm low on memory. When I do not release the BLEDevice-memory as you suggested, this in no way helps as it does not releases the needed RAM.

@TheNitek
Copy link
Contributor

The documentation for esp_bt_controller_mem_release (which is called in case of "true") is pretty clear:

  • This function releases the BSS, data and other sections of the controller to heap. The total size is about 70k bytes.
  • esp_bt_controller_mem_release(mode) should be called only before esp_bt_controller_init()
  • or after esp_bt_controller_deinit().
  • Note that once BT controller memory is released, the process cannot be reversed. It means you cannot use the bluetooth
  • mode which you have released by this function.
  • If your firmware will later upgrade the Bluetooth controller mode (BLE -> BT Classic or disabled -> enabled)
  • then do not call this function.

If you want to use bluetooth again, you cannot use "true". If you are only using BLE however, you can call
esp_bt_controller_mem_release(ESP_BT_MODE_CLASSIC_BT);
before BLEDevice::init() to free up the heap used by the unused bluetooth classic functionality.

@Elmi77
Copy link
Author

Elmi77 commented Mar 1, 2020

OK, that fixed it - thanks!

@Elmi77 Elmi77 closed this as completed Mar 1, 2020
@buxtronix
Copy link
Contributor

This workaround of re-initialising the BLE stack is fine when code is only scanning, but I am getting it with code that both scans and connects to devices. After a connection, it re-scans for further devices to connect to.
This will still need addressing to help narrow down the root cause.

me-no-dev pushed a commit that referenced this issue Oct 1, 2020
This value is uninitialised and as such can be a random (and invalid) value. It's needs to be set per the espressif documentation here:

https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-reference/bluetooth/esp_gap_ble.html#_CPPv4N21esp_ble_scan_params_t14scan_duplicateE

This PR sets it to DUPLICATE_DISABLE. Chosen as this is needed to ensure all scan data is populated in the scan callback, per this comment in the IDF:

https://github.com/espressif/esp-idf/blob/master/components/bt/host/bluedroid/stack/btm/btm_ble_gap.c#L3591

"//if scan duplicate is enabled, the adv packet without scan response is allowed to report to higher layer"

We **don't** want it to report to the higher layer (ie BLEScan.cpp) **unless** it has the active scan response.

Seems to resolve #3770 #3677 and possibly others.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants