diff --git a/bleak/backends/corebluetooth/__init__.py b/bleak/backends/corebluetooth/__init__.py index 107d3bb3c..ed160a3dd 100644 --- a/bleak/backends/corebluetooth/__init__.py +++ b/bleak/backends/corebluetooth/__init__.py @@ -6,22 +6,6 @@ """ -import asyncio -from .CentralManagerDelegate import CentralManagerDelegate import objc objc.options.verbose = True - - -class Application: - """ - This is a temporary application class responsible for running the NSRunLoop - so that events within CoreBluetooth are appropriately handled - """ - def __init__(self): - self.central_manager_delegate = CentralManagerDelegate.alloc().init() - - -# Restructure this later: Global isn't the prettiest way of doing this... -global CBAPP -CBAPP = Application() diff --git a/bleak/backends/corebluetooth/client.py b/bleak/backends/corebluetooth/client.py index 59fea6ed1..af794a134 100644 --- a/bleak/backends/corebluetooth/client.py +++ b/bleak/backends/corebluetooth/client.py @@ -13,7 +13,6 @@ from CoreBluetooth import CBCharacteristicWriteWithResponse, CBCharacteristicWriteWithoutResponse from bleak.backends.client import BaseBleakClient -from bleak.backends.corebluetooth import CBAPP as cbapp from bleak.backends.corebluetooth.characteristic import ( BleakGATTCharacteristicCoreBluetooth ) @@ -76,7 +75,8 @@ async def connect(self, **kwargs) -> bool: logger.debug("Connecting to BLE device @ {}".format(self.address)) - await cbapp.central_manager_delegate.connect_(sought_device[0].details) + manager = self._device_info.manager().delegate() + await manager.connect_(sought_device[0].details) # Now get services await self.get_services() @@ -85,12 +85,14 @@ async def connect(self, **kwargs) -> bool: async def disconnect(self) -> bool: """Disconnect from the peripheral device""" - await cbapp.central_manager_delegate.disconnect() + manager = self._device_info.manager().delegate() + await manager.disconnect() return True async def is_connected(self) -> bool: """Checks for current active connection""" - return cbapp.central_manager_delegate.isConnected + manager = self._device_info.manager().delegate() + return manager.isConnected def set_disconnected_callback( self, callback: Callable[[BaseBleakClient], None], **kwargs @@ -100,8 +102,9 @@ def set_disconnected_callback( callback: callback to be called on disconnection. """ + manager = self._device_info.manager().delegate() self._disconnected_callback = callback - cbapp.central_manager_delegate.disconnected_callback = self._disconnect_callback_client + manager.disconnected_callback = self._disconnect_callback_client def _disconnect_callback_client(self): """ @@ -124,8 +127,9 @@ async def get_services(self) -> BleakGATTServiceCollection: return self._services logger.debug("Retrieving services...") + manager = self._device_info.manager().delegate() services = ( - await cbapp.central_manager_delegate.connected_peripheral_delegate.discoverServices() + await manager.connected_peripheral_delegate.discoverServices() ) for service in services: @@ -133,7 +137,7 @@ async def get_services(self) -> BleakGATTServiceCollection: logger.debug( "Retrieving characteristics for service {}".format(serviceUUID) ) - characteristics = await cbapp.central_manager_delegate.connected_peripheral_delegate.discoverCharacteristics_( + characteristics = await manager.connected_peripheral_delegate.discoverCharacteristics_( service ) @@ -144,7 +148,7 @@ async def get_services(self) -> BleakGATTServiceCollection: logger.debug( "Retrieving descriptors for characteristic {}".format(cUUID) ) - descriptors = await cbapp.central_manager_delegate.connected_peripheral_delegate.discoverDescriptors_( + descriptors = await manager.connected_peripheral_delegate.discoverDescriptors_( characteristic ) @@ -173,12 +177,13 @@ async def read_gatt_char(self, _uuid: Union[str, uuid.UUID], use_cached=False, * (bytearray) The read data. """ + manager = self._device_info.manager().delegate() _uuid = await self.get_appropriate_uuid(str(_uuid)) characteristic = self.services.get_characteristic(str(_uuid)) if not characteristic: raise BleakError("Characteristic {} was not found!".format(_uuid)) - output = await cbapp.central_manager_delegate.connected_peripheral_delegate.readCharacteristic_( + output = await manager.connected_peripheral_delegate.readCharacteristic_( characteristic.obj, use_cached=use_cached ) value = bytearray(output) @@ -198,11 +203,12 @@ async def read_gatt_descriptor( Returns: (bytearray) The read data. """ + manager = self._device_info.manager().delegate() descriptor = self.services.get_descriptor(handle) if not descriptor: raise BleakError("Descriptor {} was not found!".format(handle)) - output = await cbapp.central_manager_delegate.connected_peripheral_delegate.readDescriptor_( + output = await manager.connected_peripheral_delegate.readDescriptor_( descriptor.obj, use_cached=use_cached ) if isinstance( @@ -225,13 +231,14 @@ async def write_gatt_char( response (bool): If write-with-response operation should be done. Defaults to `False`. """ + manager = self._device_info.manager().delegate() _uuid = await self.get_appropriate_uuid(str(_uuid)) characteristic = self.services.get_characteristic(str(_uuid)) if not characteristic: raise BleakError("Characteristic {} was not found!".format(_uuid)) value = NSData.alloc().initWithBytes_length_(data, len(data)) - success = await cbapp.central_manager_delegate.connected_peripheral_delegate.writeCharacteristic_value_type_( + success = await manager.connected_peripheral_delegate.writeCharacteristic_value_type_( characteristic.obj, value, CBCharacteristicWriteWithResponse if response else CBCharacteristicWriteWithoutResponse @@ -253,12 +260,13 @@ async def write_gatt_descriptor(self, handle: int, data: bytearray) -> None: data (bytes or bytearray): The data to send. """ + manager = self._device_info.manager().delegate() descriptor = self.services.get_descriptor(handle) if not descriptor: raise BleakError("Descriptor {} was not found!".format(handle)) value = NSData.alloc().initWithBytes_length_(data, len(data)) - success = await cbapp.central_manager_delegate.connected_peripheral_delegate.writeDescriptor_value_( + success = await manager.connected_peripheral_delegate.writeDescriptor_value_( descriptor.obj, value ) if success: @@ -289,12 +297,13 @@ def callback(sender, data): callback (function): The function to be called on notification. """ + manager = self._device_info.manager().delegate() _uuid = await self.get_appropriate_uuid(str(_uuid)) characteristic = self.services.get_characteristic(str(_uuid)) if not characteristic: raise BleakError("Characteristic {0} not found!".format(_uuid)) - success = await cbapp.central_manager_delegate.connected_peripheral_delegate.startNotify_cb_( + success = await manager.connected_peripheral_delegate.startNotify_cb_( characteristic.obj, callback ) if not success: @@ -311,12 +320,13 @@ async def stop_notify(self, _uuid: Union[str, uuid.UUID]) -> None: _uuid: The characteristic to stop notifying/indicating on. """ + manager = self._device_info.manager().delegate() _uuid = await self.get_appropriate_uuid(str(_uuid)) characteristic = self.services.get_characteristic(str(_uuid)) if not characteristic: raise BleakError("Characteristic {} not found!".format(_uuid)) - success = await cbapp.central_manager_delegate.connected_peripheral_delegate.stopNotify_( + success = await manager.connected_peripheral_delegate.stopNotify_( characteristic.obj ) if not success: diff --git a/bleak/backends/corebluetooth/discovery.py b/bleak/backends/corebluetooth/discovery.py index c8f0a0380..3d80a444a 100644 --- a/bleak/backends/corebluetooth/discovery.py +++ b/bleak/backends/corebluetooth/discovery.py @@ -11,7 +11,7 @@ from asyncio.events import AbstractEventLoop from typing import List -from bleak.backends.corebluetooth import CBAPP as cbapp +from bleak.backends.corebluetooth.CentralManagerDelegate import CentralManagerDelegate from bleak.backends.device import BLEDevice from bleak.exc import BleakError @@ -27,21 +27,21 @@ async def discover( """ loop = loop if loop else asyncio.get_event_loop() + manager = CentralManagerDelegate.alloc().init() try: - await cbapp.central_manager_delegate.wait_for_powered_on(0.1) + await manager.wait_for_powered_on(0.1) except asyncio.TimeoutError: raise BleakError("Bluetooth device is turned off") scan_options = {"timeout": timeout} - await cbapp.central_manager_delegate.scanForPeripherals_(scan_options) + await manager.scanForPeripherals_(scan_options) # CoreBluetooth doesn't explicitly use MAC addresses to identify peripheral # devices because private devices may obscure their MAC addresses. To cope # with this, CoreBluetooth utilizes UUIDs for each peripheral. We'll use # this for the BLEDevice address on macOS - - devices = cbapp.central_manager_delegate.devices + devices = manager.devices return list(devices.values()) diff --git a/bleak/backends/corebluetooth/scanner.py b/bleak/backends/corebluetooth/scanner.py index 38abaef3e..7126968ee 100644 --- a/bleak/backends/corebluetooth/scanner.py +++ b/bleak/backends/corebluetooth/scanner.py @@ -5,7 +5,7 @@ from asyncio.events import AbstractEventLoop from typing import Callable, Any, Union, List -from bleak.backends.corebluetooth import CBAPP as cbapp +from bleak.backends.corebluetooth.CentralManagerDelegate import CentralManagerDelegate from bleak.backends.device import BLEDevice from bleak.exc import BleakError from bleak.backends.scanner import BaseBleakScanner @@ -38,6 +38,7 @@ def __init__(self, loop: AbstractEventLoop = None, **kwargs): super(BleakScannerCoreBluetooth, self).__init__(loop, **kwargs) self._callback = None self._identifiers = None + self._manager = CentralManagerDelegate.alloc().init() self._timeout = kwargs.get("timeout", 5.0) async def start(self):