Fix writing without response in BlueZ backend
Currently released versions of BlueZ don't have the "type" option in the "WriteValue" method. So we need to use "AcquireWrite" instead.
Unfortunately, there is a bug in txdbus that causes the returned file descriptor to be None.
# -*- coding: utf-8 -*-
import logging
import asyncio
+import os
import re
import subprocess
from functools import wraps
@@ -307,6 +308,7 @@ class BleakClientBlueZDBus(BaseBleakClient):
"""
characteristic = self.services.get_characteristic(str(_uuid))
+ if response or (self._bluez_version[0] == 5 and self._bluez_version[1] > 50):
# TODO: Add OnValueUpdated handler for response=True?
await self._bus.callRemote(
characteristic.path,
@@ -317,6 +319,23 @@ class BleakClientBlueZDBus(BaseBleakClient):
body=[data, {"type": "request" if response else "command"}],
returnSignature="",
).asFuture(self.loop)
+ else:
+ # Older versions of BlueZ don't have the "type" option, so we have
+ # to write the hard way. This isn't the most efficient way of doing
+ # things, but it works. Also, watch out for txdbus bug that causes
+ # returned fd to be None. https://github.com/cocagne/txdbus/pull/81
+ fd, _ = await self._bus.callRemote(
+ characteristic.path,
+ "AcquireWrite",
+ interface=defs.GATT_CHARACTERISTIC_INTERFACE,
+ destination=defs.BLUEZ_SERVICE,
+ signature="a{sv}",
+ body=[{}],
+ returnSignature="hq",
+ ).asFuture(self.loop)
+ os.write(fd, data)
+ os.close(fd)
+
logger.debug(
"Write Characteristic {0} | {1}: {2}".format(
_uuid, characteristic.path, data
