bleak icon indicating copy to clipboard operation
bleak copied to clipboard

BlueZ client._acquire_mtu() raises RuntimeError on many devices

Open bdraco opened this issue 1 year ago • 4 comments

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)

bdraco avatar Aug 08 '22 16:08 bdraco

I'm planning on working on a solution for this

bdraco avatar Aug 08 '22 17:08 bdraco

See #738.

dlech avatar Aug 08 '22 17:08 dlech

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

bdraco avatar Aug 08 '22 17:08 bdraco

I will work on a pr to implement your suggested property

bdraco avatar Aug 08 '22 17:08 bdraco

_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.

dlech avatar Aug 26 '22 22:08 dlech

Agreed, max_write_without_response_size is a much better idea

bdraco avatar Aug 26 '22 23:08 bdraco