From 89fb752a734af3a0f9d32605e880fbd0ece57c2f Mon Sep 17 00:00:00 2001 From: kevincar Date: Fri, 18 Jun 2021 09:11:52 -0400 Subject: [PATCH 1/5] Use a hex index value When initializing the associated Bleak object it attempts to extract the handle indentifier from the last 4 digits after the service as a hex string. This changes ensures that creating services is compliant with this expectation. --- bless/backends/bluezdbus/dbus/service.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bless/backends/bluezdbus/dbus/service.py b/bless/backends/bluezdbus/dbus/service.py index ef6c13d..93b83ce 100644 --- a/bless/backends/bluezdbus/dbus/service.py +++ b/bless/backends/bluezdbus/dbus/service.py @@ -61,7 +61,8 @@ def __init__( app : BlueZApp A BlueZApp object that owns this service """ - self.path: str = app.base_path + "/service" + str(index) + hex_index: str = hex(index)[2:].rjust(4, "0") + self.path: str = app.base_path + "/service" + hex_index self.bus: client = app.bus self.destination: str = app.destination self.uuid: str = uuid From 5a01ddf92559d74e9f4468a004dab36188c6f9d0 Mon Sep 17 00:00:00 2001 From: kevincar Date: Fri, 18 Jun 2021 09:13:18 -0400 Subject: [PATCH 2/5] Add a dummy handle value BleakGATTServiceBlueZDBus requires a handle value. Since th real value is within the dbus path, we supply a dummy value here --- bless/backends/bluezdbus/characteristic.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bless/backends/bluezdbus/characteristic.py b/bless/backends/bluezdbus/characteristic.py index 5be5b1b..185b15c 100644 --- a/bless/backends/bluezdbus/characteristic.py +++ b/bless/backends/bluezdbus/characteristic.py @@ -72,7 +72,7 @@ async def init(self, service: "BlessGATTServiceBlueZDBus"): # Add a Bleak Characteristic properties self.gatt = gatt_char super(BlessGATTCharacteristic, self).__init__( - dict_obj, gatt_char.path, service.uuid + dict_obj, gatt_char.path, service.uuid, 0 ) @property From 275dfe91e776cf8784b2746f0e2c4f0df22f90a3 Mon Sep 17 00:00:00 2001 From: Kevin Davis Date: Fri, 9 Jul 2021 17:41:04 -0400 Subject: [PATCH 3/5] Use threading to wait for bluetooth on event --- .../PeripheralManagerDelegate.py | 29 ++++++------------- bless/backends/corebluetooth/server.py | 2 -- 2 files changed, 9 insertions(+), 22 deletions(-) diff --git a/bless/backends/corebluetooth/PeripheralManagerDelegate.py b/bless/backends/corebluetooth/PeripheralManagerDelegate.py index 9625a86..9d2a6b1 100644 --- a/bless/backends/corebluetooth/PeripheralManagerDelegate.py +++ b/bless/backends/corebluetooth/PeripheralManagerDelegate.py @@ -1,6 +1,7 @@ import objc # type: ignore import logging import asyncio +import threading from typing import Any, Dict, List, Optional, Callable @@ -68,10 +69,14 @@ def init(self): self._callbacks: Dict[str, Callable] = {} # Events - self._powered_on_event: asyncio.Event = asyncio.Event() + self._powered_on_event: threading.Event = threading.Event() self._advertisement_started_event: asyncio.Event = asyncio.Event() self._services_added_events: Dict[str, asyncio.Event] = {} + # Documentation requires that no calls be made until we can validate + # that the bluetooth module is powered on + self._powered_on_event.wait() + self._central_subscriptions = {} if not self.compliant(): @@ -96,18 +101,6 @@ def compliant(self) -> bool: self.CBPeripheralManagerDelegate ) - @objc.python_method - async def wait_for_powered_on(self, timeout: float): - """ - Wait for ready state of the peripheralManager - - Parameters - ---------- - timeout : float - How long to wait for the powered on event - """ - await asyncio.wait_for(self._powered_on_event.wait(), timeout) - def is_connected(self) -> bool: """ Determin whether any centrals have subscribed @@ -217,8 +210,9 @@ def write_request_func(self, func: Callable): # Protocol functions - @objc.python_method - def did_update_state(self, peripheral_manager: CBPeripheralManager): + def peripheralManagerDidUpdateState_( # noqa: N802 + self, peripheral_manager: CBPeripheralManager + ): if peripheral_manager.state() == CBManagerStateUnknown: logger.debug("Cannot detect bluetooth device") elif peripheral_manager.state() == CBManagerStateResetting: @@ -238,11 +232,6 @@ def did_update_state(self, peripheral_manager: CBPeripheralManager): self._powered_on_event.clear() self._advertisement_started_event.clear() - def peripheralManagerDidUpdateState_( # noqa: N802 - self, peripheral_manager: CBPeripheralManager - ): - self.event_loop.call_soon_threadsafe(self.did_update_state, peripheral_manager) - def peripheralManager_willRestoreState_( # noqa: N802 self, peripheral: CBPeripheralManager, d: dict ): diff --git a/bless/backends/corebluetooth/server.py b/bless/backends/corebluetooth/server.py index c77d007..0d993ec 100644 --- a/bless/backends/corebluetooth/server.py +++ b/bless/backends/corebluetooth/server.py @@ -69,8 +69,6 @@ async def start(self, timeout: float = 10, **kwargs): Floating point decimal in seconds for how long to wait for the on-board bluetooth module to power on """ - await self.peripheral_manager_delegate.wait_for_powered_on(timeout) - for service_uuid in self.services: bleak_service: BleakGATTService = self.services[service_uuid] service_obj: CBService = bleak_service.obj From e59f37f057ae1d04499916f4e3e4978c0fc5e6ab Mon Sep 17 00:00:00 2001 From: Kevin Davis Date: Fri, 9 Jul 2021 18:40:32 -0400 Subject: [PATCH 4/5] Use stored key values --- bless/backends/corebluetooth/server.py | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/bless/backends/corebluetooth/server.py b/bless/backends/corebluetooth/server.py index 0d993ec..534f603 100644 --- a/bless/backends/corebluetooth/server.py +++ b/bless/backends/corebluetooth/server.py @@ -10,6 +10,8 @@ CBService, CBPeripheralManager, CBMutableCharacteristic, + CBAdvertisementDataLocalNameKey, + CBAdvertisementDataServiceUUIDsKey, ) from bleak.backends.service import BleakGATTService # type: ignore @@ -79,10 +81,10 @@ async def start(self, timeout: float = 10, **kwargs): raise BlessError("Callback functions must be initialized first") advertisement_data = { - "kCBAdvDataServiceUUIDs": list( + CBAdvertisementDataLocalNameKey: self.name, + CBAdvertisementDataServiceUUIDsKey: list( map(lambda x: self.services[x].obj.UUID(), self.services) - ), - "kCBAdvDataLocalName": self.name, + ) } logger.debug("Advertisement Data: {}".format(advertisement_data)) try: From 2567eeac322712f5b7c38c44ebb698fe099a249f Mon Sep 17 00:00:00 2001 From: Kevin Davis Date: Sun, 18 Jul 2021 19:38:41 -0400 Subject: [PATCH 5/5] Version Bump --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 33b2d35..abc1242 100644 --- a/setup.py +++ b/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="bless", - version="0.2.1", + version="0.2.2", author="Kevin Davis", author_email="kevincarrolldavis@gmail.com", description="A Bluetooth Low Energy Server supplement to Bleak",