question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Code hangs when BLE client disconnects first

See original GitHub issue
  • bleak version: 0.6.5a3 (develop)
  • Python version: 3.7.3
  • Operating System: Raspbian GNU/Linux 10 (buster), kernel: 4.19.118-v7+
  • BlueZ version (bluetoothctl -v) in case of Linux: 5.50

Description

When connecting to a BLE device, if the client disconnects first, bleak seems to hang. This issue was fixed by modifying bluezdbus\client.py.

What I Did

I ran the notifications example “enable_notifications.py”, connecting to a custom-built BLE device. This device was guaranteed to disconnect from the client before the 5 second asyncio.sleep had completed. I only modified it by commenting out the stop_notify line (no longer needed) and by adding a logging line after the BleakClient section, which never ran.

"""
Notifications
-------------
Example showing how to add notifications to a characteristic and handle the responses.
Updated on 2019-07-03 by hbldh <henrik.blidh@gmail.com>
""" 
async def run(address, loop, debug=False):
    if debug:
        import sys

        # loop.set_debug(True)
        l = logging.getLogger("asyncio")
        l.setLevel(logging.DEBUG)
        h = logging.StreamHandler(sys.stdout)
        h.setLevel(logging.DEBUG)
        l.addHandler(h)
        logger.addHandler(h)

    async with BleakClient(address, loop=loop) as client:
        x = await client.is_connected()
        logger.info("Connected: {0}".format(x))

        await client.start_notify(CHARACTERISTIC_UUID, notification_handler)
        await asyncio.sleep(5.0, loop=loop)
        #await client.stop_notify(CHARACTERISTIC_UUID)
    logger.info("BleakClient exited successfully")

In order to debug this problem, logger statements were added to bluezdbus\client.py, which made it clear that the code was hanging on BleakClient.disconnect when called by BleakClient.aexit, during the following section:

# Try to disconnect the actual device/peripheral
try:
	await self._bus.callRemote(
		self._device_path,
		"Disconnect",
		interface=defs.DEVICE_INTERFACE,
		destination=defs.BLUEZ_SERVICE,
	).asFuture(self.loop)
except Exception as e:
	logger.error("Attempt to disconnect device failed: {0}".format(e))

This was fixed by making the following changes to bluezdbus\client.py:

...
def __init__(self, address, loop=None, **kwargs):
   ...
        # BillMicro: device disconnection fix
        self._device_disconnected = False
...
async def disconnect(self) -> bool:
	"""Disconnect from the specified GATT server.

	Returns:
		Boolean representing if device is disconnected.

	"""
	# BillMicro: device disconnection fix
	if not self._device_disconnected:
		logger.debug("Disconnecting from BLE device...")

		# Remove all residual notifications.
		await self._cleanup_notifications()
                ...
        else:
            is_disconnected = True
...
def _properties_changed_callback(self, message):
	...
				task = self.loop.create_task(self._cleanup_all())
				# BillMicro: device disconnection fix
				self._device_disconnected = True
				...

However, this is a non-satisfactory solution. It can be be found here: 8794eacd70a4a4f825338e68372c92a75a6a4086

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Comments:6 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
hbldhcommented, Jun 24, 2020

This is troublesome indeed. An exception is desired, not a complete hanging…

This will be looked at in a later release though. Other issues have precendence right now.

0reactions
Ladviencommented, Jun 19, 2020

Oh nice! Thank you for sharing.

It looks like the Proglove folk are using bleak in testing or production. That’s great. It’s a huge project and would feel bad if Henrik had to maintain it on his own.

I took a look at their additions, they mention a “leaky event loop” on POSIX systems. I’m guessing that’s what we were seeing. Glad there are smarter, more experienced people out there than me. 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

Esp32 BLE Connect and disconnect issue
I ave a server which runs sensor code and client receive data from it , then disconnect from server turning wifi on and...
Read more >
Android 4.3 Bluetooth Low Energy unstable - Stack Overflow
Restarting Bluetooth helps to fix problems with BLE in most cases; If you turn off Wifi, the BLE stack gets much more stable....
Read more >
BLE Client Disconnect causes reboot? : r/esp32 - Reddit
BLE Client Disconnect causes reboot? I have the following code: #include <BLEDevice.h> #include <BLEAddress.
Read more >
The Ultimate Guide to Android Bluetooth Low Energy
To showcase the bare basics of working with Android BLE APIs, we'll be taking little shortcuts in our code snippets and example implementation ......
Read more >
Device getting hanged during sending data through ble ...
Hi, First you should not using blocking mode since this will break the BLE connection. You can take a look our github example ......
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found