Exemplo n.º 1
0
    async def discover_descriptors(
            self, characteristic: CBCharacteristic) -> NSArray:
        future = self._event_loop.create_future()
        self._characteristic_descriptor_discover_futures[
            characteristic.handle()] = future
        self.peripheral.discoverDescriptorsForCharacteristic_(characteristic)
        await future

        return characteristic.descriptors()
Exemplo n.º 2
0
    def __init__(self, service : CoreBluetoothService, cbcharacteristic : CoreBluetooth.CBCharacteristic, queue, *args, **kwargs):
        super(CoreBluetoothCharacteristic, self).__init__(service, *args, **kwargs)
        self._cbcharacteristic = cbcharacteristic
        self._cbperipheral = cbcharacteristic.service().peripheral()
        self._queue = queue

        self._identifier = cbcharacteristic.UUID().UUIDString()

        self.read_value_future = None
Exemplo n.º 3
0
    async def discover_descriptors(self,
                                   characteristic: CBCharacteristic,
                                   use_cached: bool = True) -> NSArray:
        if characteristic.descriptors() is not None and use_cached:
            return characteristic.descriptors()

        future = self._event_loop.create_future()
        self._characteristic_descriptor_discover_futures[
            characteristic.handle()] = future
        self.peripheral.discoverDescriptorsForCharacteristic_(characteristic)
        await future

        return characteristic.descriptors()
Exemplo n.º 4
0
    async def read_characteristic(self,
                                  characteristic: CBCharacteristic,
                                  use_cached: bool = True) -> NSData:
        if characteristic.value() is not None and use_cached:
            return characteristic.value()

        future = self._event_loop.create_future()
        self._characteristic_read_futures[characteristic.handle()] = future
        self.peripheral.readValueForCharacteristic_(characteristic)
        await asyncio.wait_for(future, timeout=5)
        if characteristic.value():
            return characteristic.value()
        else:
            return b""
Exemplo n.º 5
0
    async def _did_update_value_for_characteristic(
            self, cbcharacteristic: CoreBluetooth.CBCharacteristic,
            error: Foundation.NSError):
        cbservice = cbcharacteristic.service()
        service = self._services_by_identifier.get(
            cbservice.UUID().UUIDString())
        if service is None:
            return

        char = await service.characteristic_with_identifier(
            cbcharacteristic.UUID().UUIDString())
        if char is None:
            return

        char._did_update_value(error)
Exemplo n.º 6
0
    def did_update_value_for_characteristic(
        self,
        peripheral: CBPeripheral,
        characteristic: CBCharacteristic,
        value: NSData,
        error: Optional[NSError],
    ):
        c_handle = characteristic.handle()

        if error is None:
            notify_callback = self._characteristic_notify_callbacks.get(
                c_handle)
            if notify_callback:
                notify_callback(c_handle, bytearray(value))

        future = self._characteristic_read_futures.get(c_handle)
        if not future:
            return  # only expected on read
        if error is not None:
            exception = BleakError(
                f"Failed to read characteristic {c_handle}: {error}")
            future.set_exception(exception)
        else:
            logger.debug("Read characteristic value")
            future.set_result(None)
Exemplo n.º 7
0
 def peripheral_didUpdateValueForCharacteristic_error_(
     self,
     peripheral: CBPeripheral,
     characteristic: CBCharacteristic,
     error: Optional[NSError],
 ):
     logger.debug("peripheral_didUpdateValueForCharacteristic_error_")
     self._event_loop.call_soon_threadsafe(
         self.did_update_value_for_characteristic,
         peripheral,
         characteristic,
         characteristic.value(),
         error,
     )
Exemplo n.º 8
0
    async def start_notifications(self, characteristic: CBCharacteristic,
                                  callback: Callable[[str, Any], Any]) -> bool:
        c_handle = characteristic.handle()
        if c_handle in self._characteristic_notify_callbacks:
            raise ValueError("Characteristic notifications already started")

        self._characteristic_notify_callbacks[c_handle] = callback

        future = self._event_loop.create_future()
        self._characteristic_notify_change_futures[c_handle] = future
        self.peripheral.setNotifyValue_forCharacteristic_(True, characteristic)
        await future

        return True
Exemplo n.º 9
0
    async def stop_notifications(self,
                                 characteristic: CBCharacteristic) -> bool:
        c_handle = characteristic.handle()
        if c_handle not in self._characteristic_notify_callbacks:
            raise ValueError("Characteristic notification never started")

        future = self._event_loop.create_future()
        self._characteristic_notify_change_futures[c_handle] = future
        self.peripheral.setNotifyValue_forCharacteristic_(
            False, characteristic)
        await future

        self._characteristic_notify_callbacks.pop(c_handle)

        return True
Exemplo n.º 10
0
    async def write_characteristic(
        self,
        characteristic: CBCharacteristic,
        value: NSData,
        response: CBCharacteristicWriteType,
    ) -> bool:
        future = self._event_loop.create_future()
        self._characteristic_write_futures[characteristic.handle()] = future
        self.peripheral.writeValue_forCharacteristic_type_(
            value, characteristic, response)

        if response == CBCharacteristicWriteWithResponse:
            await future

        return True
Exemplo n.º 11
0
 def did_write_value_for_characteristic(
     self,
     peripheral: CBPeripheral,
     characteristic: CBCharacteristic,
     error: Optional[NSError],
 ):
     future = self._characteristic_write_futures.get(
         characteristic.handle())
     if not future:
         return  # event only expected on write with response
     if error is not None:
         exception = BleakError(
             f"Failed to write characteristic {characteristic.handle()}: {error}"
         )
         future.set_exception(exception)
     else:
         logger.debug("Write Characteristic Value")
         future.set_result(None)
Exemplo n.º 12
0
 def did_update_notification_for_characteristic(
     self,
     peripheral: CBPeripheral,
     characteristic: CBCharacteristic,
     error: Optional[NSError],
 ):
     c_handle = characteristic.handle()
     future = self._characteristic_notify_change_futures.get(c_handle)
     if not future:
         logger.warning(
             "Unexpected event didUpdateNotificationStateForCharacteristic")
         return
     if error is not None:
         exception = BleakError(
             f"Failed to update the notification status for characteristic {c_handle}: {error}"
         )
         future.set_exception(exception)
     else:
         logger.debug("Character Notify Update")
         future.set_result(None)
Exemplo n.º 13
0
    async def write_characteristic(
        self,
        characteristic: CBCharacteristic,
        value: NSData,
        response: CBCharacteristicWriteType,
    ) -> bool:
        # in CoreBluetooth there is no indication of success or failure of
        # CBCharacteristicWriteWithoutResponse
        if response == CBCharacteristicWriteWithResponse:
            future = self._event_loop.create_future()
            self._characteristic_write_futures[
                characteristic.handle()] = future

        self.peripheral.writeValue_forCharacteristic_type_(
            value, characteristic, response)

        if response == CBCharacteristicWriteWithResponse:
            await future

        return True
Exemplo n.º 14
0
 def did_discover_descriptors_for_characteristic(
     self,
     peripheral: CBPeripheral,
     characteristic: CBCharacteristic,
     error: Optional[NSError],
 ):
     future = self._characteristic_descriptor_discover_futures.get(
         characteristic.handle())
     if not future:
         logger.warning(
             f"Unexpected event didDiscoverDescriptorsForCharacteristic for {characteristic.handle()}"
         )
         return
     if error is not None:
         exception = BleakError(
             f"Failed to discover descriptors for characteristic {characteristic.handle()}: {error}"
         )
         future.set_exception(exception)
     else:
         logger.debug(f"Descriptor discovered {characteristic.handle()}")
         future.set_result(None)