Skip to content

Commit

Permalink
Fix corebluetooth client issue #319 (#323)
Browse files Browse the repository at this point in the history
* Fix `self._device_info` always set to `None`
* Keep reference to `CentralManagerDelegate` object instead of relying on undocumented `CBPeriperal.manager()` method.
  • Loading branch information
Carglglz authored Oct 9, 2020
1 parent 36f25f4 commit 583c08e
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 17 deletions.
5 changes: 2 additions & 3 deletions bleak/backends/corebluetooth/CentralManagerDelegate.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@


logger = logging.getLogger(__name__)

CBCentralManagerDelegate = objc.protocolNamed("CBCentralManagerDelegate")

try:
Expand Down Expand Up @@ -235,8 +234,8 @@ def did_discover_peripheral(
callback(peripheral, advertisementData, RSSI)

logger.debug(
"Discovered device {}: {} @ RSSI: {} (kCBAdvData {})".format(
uuid_string, device.name, RSSI, advertisementData.keys()
"Discovered device {}: {} @ RSSI: {} (kCBAdvData {}) and Central: {}".format(
uuid_string, device.name, RSSI, advertisementData.keys(), central
)
)

Expand Down
32 changes: 18 additions & 14 deletions bleak/backends/corebluetooth/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,10 +48,12 @@ def __init__(self, address_or_ble_device: Union[BLEDevice, str], **kwargs):

if isinstance(address_or_ble_device, BLEDevice):
self._device_info = address_or_ble_device.details
self._central_manager_delegate = address_or_ble_device.metadata.get(
"delegate"
)
else:
self._device_info = None

self._device_info = None
self._central_manager_delegate = None
self._requester = None
self._callbacks = {}
self._services = None
Expand All @@ -77,14 +79,16 @@ async def connect(self, **kwargs) -> bool:

if device:
self._device_info = device.details
self._central_manager_delegate = device.metadata.get("delegate")
else:
raise BleakError(
"Device with address {} was not found".format(self.address)
)
# self._device_info.manager() should return a CBCentralManager

manager = self._central_manager_delegate
logger.debug("CentralManagerDelegate at {}".format(manager))
logger.debug("Connecting to BLE device @ {}".format(self.address))

manager = self._device_info.manager().delegate()
await manager.connect_(self._device_info)
manager.disconnected_callback = self._disconnected_callback_client

Expand All @@ -105,7 +109,7 @@ def _disconnected_callback_client(self):

async def disconnect(self) -> bool:
"""Disconnect from the peripheral device"""
manager = self._device_info.manager().delegate()
manager = self._central_manager_delegate
await manager.disconnect()
self.services = BleakGATTServiceCollection()
# Ensure that `get_services` retrieves services again, rather than using the cached object
Expand All @@ -115,7 +119,7 @@ async def disconnect(self) -> bool:

async def is_connected(self) -> bool:
"""Checks for current active connection"""
manager = self._device_info.manager().delegate()
manager = self._central_manager_delegate
return manager.isConnected

async def pair(self, *args, **kwargs) -> bool:
Expand Down Expand Up @@ -158,7 +162,7 @@ async def get_services(self) -> BleakGATTServiceCollection:
return self.services

logger.debug("Retrieving services...")
manager = self._device_info.manager().delegate()
manager = self._central_manager_delegate
services = await manager.connected_peripheral_delegate.discoverServices()

for service in services:
Expand Down Expand Up @@ -220,7 +224,7 @@ async def read_gatt_char(
(bytearray) The read data.
"""
manager = self._device_info.manager().delegate()
manager = self._central_manager_delegate

if not isinstance(char_specifier, BleakGATTCharacteristic):
characteristic = self.services.get_characteristic(char_specifier)
Expand Down Expand Up @@ -249,7 +253,7 @@ async def read_gatt_descriptor(
Returns:
(bytearray) The read data.
"""
manager = self._device_info.manager().delegate()
manager = self._central_manager_delegate

descriptor = self.services.get_descriptor(handle)
if not descriptor:
Expand Down Expand Up @@ -283,7 +287,7 @@ async def write_gatt_char(
response (bool): If write-with-response operation should be done. Defaults to `False`.
"""
manager = self._device_info.manager().delegate()
manager = self._central_manager_delegate

if not isinstance(char_specifier, BleakGATTCharacteristic):
characteristic = self.services.get_characteristic(char_specifier)
Expand Down Expand Up @@ -321,7 +325,7 @@ 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()
manager = self._central_manager_delegate

descriptor = self.services.get_descriptor(handle)
if not descriptor:
Expand Down Expand Up @@ -364,7 +368,7 @@ def callback(sender: int, data: bytearray):
callback (function): The function to be called on notification.
"""
manager = self._device_info.manager().delegate()
manager = self._central_manager_delegate

if not isinstance(char_specifier, BleakGATTCharacteristic):
characteristic = self.services.get_characteristic(char_specifier)
Expand Down Expand Up @@ -395,7 +399,7 @@ async def stop_notify(
"""
manager = self._device_info.manager().delegate()
manager = self._central_manager_delegate

if not isinstance(char_specifier, BleakGATTCharacteristic):
characteristic = self.services.get_characteristic(char_specifier)
Expand All @@ -416,7 +420,7 @@ async def get_rssi(self) -> int:
"""To get RSSI value in dBm of the connected Peripheral"""

self._device_info.readRSSI()
manager = self._device_info.manager().delegate()
manager = self._central_manager_delegate
RSSI = manager.connected_peripheral.RSSI()
for i in range(20): # First time takes a little otherwise returns None
RSSI = manager.connected_peripheral.RSSI()
Expand Down
1 change: 1 addition & 0 deletions bleak/backends/corebluetooth/scanner.py
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ async def get_discovered_devices(self) -> List[BLEDevice]:
details,
uuids=uuids,
manufacturer_data=manufacturer_data,
delegate=self._manager.central_manager.delegate(),
)
)

Expand Down

0 comments on commit 583c08e

Please sign in to comment.