Reedyuk / blue-falcon

A Bluetooth kotlin multiplatform "Cross-Platform" library for iOS and Android
https://bluefalcon.dev
Apache License 2.0
328 stars 43 forks source link

GATT connection not closing (ANDROID) #53

Open felislynx-silae opened 3 years ago

felislynx-silae commented 3 years ago

Hi, during more stress test of my app, i've discovered that Android device after some time causes peripheral to stop accept connections and stops from being visible in ble scan. This is not a case for iOS. Steps to reproduce:

  1. Transport type LE
  2. Start LE scan if peripheral MAC found, connect
  3. If onConnected emited, stop LE scan
  4. acquire all characteristics (setup notifications etc)
  5. wait a little time
  6. disconnect
  7. wait a little time
  8. repeat from point 1

After few loops, you will not be able to find peripheral MAC. Reseting peripheral or Android BT restores connectivity, removing Initializing BlueFalcon again also solves this issue. As far as i can tell, the GATT connection is held and this causes to reach maximum available connections. Good peripheral to test is Raspberry PI 3b+ with simple code using bluez.

Reedyuk commented 3 years ago

Nice catch, so maybe we need to purge the Gatt objects?

felislynx-silae commented 3 years ago

I would start with setting references to null. Calling close and disconnect or searching for more solutions. This is clearly issue with android bt stack since internet is full of posts about ble issues :) shame that we need to do something with this not google. Kudos for Apple for better BT stack. If you provide some branches to test i will do stress tests ASAP (between 5am and 2pm :) )

PeterKucera commented 3 years ago

I can reproduce the exact same issue.

I have tried to investigate a little bit, e.g. have a look on following link .

"As previously stated, the problem is caused by calling connectGatt multiple times. Each one of those calls create a new BluetoothGatt instance and they are all kept alive, while you have only the last one. Given the fact that sometimes it is needed to call connectGatt multiple times, I just keep all the instances that it returns and call disconnect/close on all of them when I'm done. "

Possible solution for this could be storing all BluetoothGatt objects returned by method connectGatt() in a list and on device disconnection, try to trigger disconnect() + close() on all of these BluetoothGatt objects, not only on one that is returned by mGattClientCallback.gattForDevice() .

felislynx-silae commented 3 years ago

I think that solution from @PeterKucera might work, worth a try

PeterKucera commented 3 years ago

Hi all,

I have done some tests and tried to modify the library.

It looks like approach mentioned in my previous comment will not fix the issue.

However, it looks like the issue could be calling close() method right after disconnect() method - when I added some delay between these 2 method calls, I cannot reproduce the issues I previously had, and therefore it looks like GATT connection is closed properly.

Please @felislynx-silae can I ask for retesting using this fix ?

https://github.com/PeterKucera/blue-falcon/commit/67eb76776e1100e2168f3c176460500d45ee18d4

Edit - After some additional testing (50+ requested connections in a loop) I can still reproduce reported issue (device is not responding and only turning BT on/off or reseting peripherial will resolve the issue). However, I would still suggest adding 500 ms delay between disconnect() and close(), because without this delay disconnect() is not working properly for me. I am working on functionality that dynamically initializes devices, and literally without this 500ms delay re-initialization of device fails everytime. I can open open new issue and provide more proof if neccessary.

Edit 2 - I tried to have a look on other BLE libraries, they have to face the similar issues, right ?

"This is OS related problem. There is nothing can be done afaik. Their BLE stack is probably getting off and there is no programmatic way that could ensure proper functionality. You could try turning off/on the Bluetooth Adapter and Wifi (on <=6.0)"

Source : https://github.com/Polidea/RxAndroidBle/issues/688#issuecomment-627825971

felislynx-silae commented 3 years ago

@PeterKucera I've tested your commit. It is not fixing this issue. Currently only working solution is nulling all references to BlueFalcon and recreate object