bleak
bleak copied to clipboard
BlueZ client._acquire_mtu() raises RuntimeError on many devices
Most test devices I have result in a RuntimeError
from StopIteration
because there are no write without response chars on the device. I'm able to get the MTU of the device with this proof of concept
from bleak.backends.bluezdbus.manager import get_global_bluez_manager
from bleak.backends.bluezdbus import defs
logger.debug("%s: Acquiring MTU from BlueZ",name)
await client.get_services()
manager = await get_global_bluez_manager()
device_path = client._device_path
mtu: int | None = None
for service_path, service_ifaces in manager._properties.items():
if (
not service_path.startswith(device_path)
or defs.GATT_CHARACTERISTIC_INTERFACE not in service_ifaces
):
continue
if "MTU" in service_ifaces[defs.GATT_CHARACTERISTIC_INTERFACE]:
mtu = service_ifaces[defs.GATT_CHARACTERISTIC_INTERFACE]["MTU"]
break
if not mtu:
try:
await client._acquire_mtu()
mtu = client._mtu_size
except RuntimeError as ex:
logger.debug("%s: Failed to acquire MTU via _acquire_mtu: %s",name, ex)
pass
if mtu:
KNOWN_MTUS[device.address] = mtu
client.set_known_mtu(mtu)
logger.debug("%s: Acquired MTU from BlueZ %s", name, mtu)
else:
logger.debug("%s: No MTU from BlueZ", name)
I'm planning on working on a solution for this
See #738.
See #738.
Thanks. I think your suggested property makes sense. We could pin it to the same value for the backends that don't currently support variations per char
I will work on a pr to implement your suggested property
_acquire_mtu()
is known to not work on all devices, it is only provided as a convenience for the cases where it does work and isn't really possible to make it work in general. Other workarounds are possible like using a hard-coded value or using the new max_write_without_response_size
property.
Closing since there isn't anything else to do here.
Agreed, max_write_without_response_size
is a much better idea