adafruit / Adafruit_CircuitPython_BLE

Bluetooth Low Energy (BLE) library for CircuitPython
MIT License
123 stars 57 forks source link

CircuitPython Locks Up on Disconnect #91

Open madgrizzle opened 4 years ago

madgrizzle commented 4 years ago

Using the current time service example on a Adafruit Feather nRF52840 Sense with CircuitPython 5.3 (and on 5.4-beta1):

https://github.com/adafruit/Adafruit_CircuitPython_BLE/blob/master/examples/ble_current_time_service.py

I connected the sense with my android phone running the Nordic nRF Connect for Mobile app.

Upon connecting to the sense, it proceeds to print the current time. If you disconnect from the sense via the app (close the tab), depending upon the timing of the disconnect, the sense will either print disconnected, as expected, or lock-up. When it's locked up, it appears that its hung up on the cts.current_time statement (line 28). Because of the delay between the time the app disconnects from the sense and the time the sense detects the disconnect, the program attempts to retrieve the current time even though it is really disconnected. You can increase the odds of reproducing this by changing time.sleep(1) in line 29 to time.sleep(0.1).

When locked-up, it becomes unresponsive and you have to manually reset the board.

dhalbert commented 4 years ago

I have tried this on a Samsung tablet, but it doesn't seem to provide the time service.

I thought that nRFConnect doesn't provide the time service, so have you paired the Sense previously with your phone via the Bluetooth settings? I'm guessing you are not connecting via the Connect button in nRFConnect, but are somehow forcing a disconnect from there. Could you give a step-by-step recipe? If you could start by forgetting Sense in Android, and then going from there, that would be helpful.

madgrizzle commented 4 years ago

I configured the GATT Server in nRFConnect to include Current Time Service (menu->Configure GATT Server->Add Service and select the Current Time Service under Select server configuration). I then connect to the sense using the connect button in nRFConnect, it then asks me if I want to pair (I did the forget as requested). Once paired, the sense starts streaming the time. When I close the tab for the sense, the sense locks up. But if I press the disconnect instead of closing the tab, the time service still runs (not sure why). If instead I swipe the nRFConnect program away (to close it), the sense crashes and provides a _bleio.BluetootError: Unknown gatt error: 0x0101 but doesn't lock up.

madgrizzle commented 4 years ago

I can also confirm this happens using a custom built version of GadgetBridge, not just nRFConnect. It appears that killing the connection (shutting down the app) typically results in an "unknown gatt error 0x101", which can be caught (try/exception). But if you ruthlessly shutdown (i.e., power off the phone) or you move the phone too far away from the board, it often results in a complete lock-up of the board (requiring a hard reset).

tannewt commented 3 years ago

@madgrizzle Please try CircuitPython 6.2.0-rc.0. I think I just fixed this. The underlying PacketBuffer wasn't tracking the disconnect correctly.