idasit/bleak/backends/bluezdbus/characteristic.py
bparodi@lezzo.org 41c244e903 first commit
2024-12-14 14:55:37 +01:00

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