107 lines
3.3 KiB
Python
107 lines
3.3 KiB
Python
from typing import Callable, List, Union
|
|
from uuid import UUID
|
|
|
|
from ..characteristic import BleakGATTCharacteristic
|
|
from ..descriptor import BleakGATTDescriptor
|
|
from .defs import GattCharacteristic1
|
|
from .utils import extract_service_handle_from_path
|
|
|
|
_GattCharacteristicsFlagsEnum = {
|
|
0x0001: "broadcast",
|
|
0x0002: "read",
|
|
0x0004: "write-without-response",
|
|
0x0008: "write",
|
|
0x0010: "notify",
|
|
0x0020: "indicate",
|
|
0x0040: "authenticated-signed-writes",
|
|
0x0080: "extended-properties",
|
|
0x0100: "reliable-write",
|
|
0x0200: "writable-auxiliaries",
|
|
# "encrypt-read"
|
|
# "encrypt-write"
|
|
# "encrypt-authenticated-read"
|
|
# "encrypt-authenticated-write"
|
|
# "secure-read" #(Server only)
|
|
# "secure-write" #(Server only)
|
|
# "authorize"
|
|
}
|
|
|
|
|
|
class BleakGATTCharacteristicBlueZDBus(BleakGATTCharacteristic):
|
|
"""GATT Characteristic implementation for the BlueZ DBus backend"""
|
|
|
|
def __init__(
|
|
self,
|
|
obj: GattCharacteristic1,
|
|
object_path: str,
|
|
service_uuid: str,
|
|
service_handle: int,
|
|
max_write_without_response_size: Callable[[], int],
|
|
):
|
|
super(BleakGATTCharacteristicBlueZDBus, self).__init__(
|
|
obj, max_write_without_response_size
|
|
)
|
|
self.__descriptors = []
|
|
self.__path = object_path
|
|
self.__service_uuid = service_uuid
|
|
self.__service_handle = service_handle
|
|
self._handle = extract_service_handle_from_path(object_path)
|
|
|
|
@property
|
|
def service_uuid(self) -> str:
|
|
"""The uuid of the Service containing this characteristic"""
|
|
return self.__service_uuid
|
|
|
|
@property
|
|
def service_handle(self) -> int:
|
|
"""The handle of the Service containing this characteristic"""
|
|
return self.__service_handle
|
|
|
|
@property
|
|
def handle(self) -> int:
|
|
"""The handle of this characteristic"""
|
|
return self._handle
|
|
|
|
@property
|
|
def uuid(self) -> str:
|
|
"""The uuid of this characteristic"""
|
|
return self.obj.get("UUID")
|
|
|
|
@property
|
|
def properties(self) -> List[str]:
|
|
"""Properties of this characteristic
|
|
|
|
Returns the characteristics `Flags` present in the DBus API.
|
|
"""
|
|
return self.obj["Flags"]
|
|
|
|
@property
|
|
def descriptors(self) -> List[BleakGATTDescriptor]:
|
|
"""List of descriptors for this service"""
|
|
return self.__descriptors
|
|
|
|
def get_descriptor(
|
|
self, specifier: Union[int, str, UUID]
|
|
) -> Union[BleakGATTDescriptor, None]:
|
|
"""Get a descriptor by handle (int) or UUID (str or uuid.UUID)"""
|
|
try:
|
|
if isinstance(specifier, int):
|
|
return next(filter(lambda x: x.handle == specifier, self.descriptors))
|
|
else:
|
|
return next(
|
|
filter(lambda x: x.uuid == str(specifier), self.descriptors)
|
|
)
|
|
except StopIteration:
|
|
return None
|
|
|
|
def add_descriptor(self, descriptor: BleakGATTDescriptor) -> None:
|
|
"""Add a :py:class:`~BleakGATTDescriptor` to the characteristic.
|
|
|
|
Should not be used by end user, but rather by `bleak` itself.
|
|
"""
|
|
self.__descriptors.append(descriptor)
|
|
|
|
@property
|
|
def path(self) -> str:
|
|
"""The DBus path. Mostly needed by `bleak`, not by end user"""
|
|
return self.__path
|