Source code for able.bluezdbus.service
# Copyright (c) 2021 Allthenticate
"""
For reference of the implementation of this Gatt service abstraction, see:
https://gitlab.com/allthenticate/dependencies/bluez/-/blob/master/doc/gatt-api.txt
https://dbus.freedesktop.org/doc/dbus-tutorial.html
"""
# Native libraries
import logging
import uuid
from typing import TYPE_CHECKING, Optional
# Dependencies
from dbus_next.constants import PropertyAccess # type: ignore
from dbus_next.service import ServiceInterface, dbus_property # type: ignore
# Able Dependencies
from able.bluezdbus import BluezServiceInterfaces
# Setup logging
from able.service import ABleService
logger = logging.getLogger(name=__name__)
if TYPE_CHECKING:
from able.characteristic import ABleCharacteristic
[docs]class BluezService(ABleService, ServiceInterface):
"""
Class implementation of a BLE GATT Service using Dbus-Next. This class inherits from the `ABleService` so that
it shares the same params for its constructor and supports the same capabilities as the services on other
platforms. It also inherits from `ServiceInterface` so that this class can be exported on the DBus so that
Bluez is able to get a proxy for this with the "org.bluez.GattService1" interface.
:param service_uuid: the uuid for this service
:param is_primary: whether or not this is a primary service, secondary services are rarely used as they
are intended to be used in other services, defaults to True
:ivar characteristics: a dictionary of uuid string - characteristic pairs, this is used to fetch a characteristic
from a service if a reference to the characteristic is lost in your program.
"""
def __init__(self, service_uuid: uuid.UUID, is_primary: bool = True):
"""Initialize the BluezService"""
super().__init__(service_uuid, name=BluezServiceInterfaces.GATT_SERVICE_INTERFACE.value)
# DBus values
self.primary = is_primary
self._path: Optional[str] = None
def __str__(self):
return f"BluezLEService [{self.uuid}]"
@dbus_property(access=PropertyAccess.READ, name="UUID")
def _uuid(self) -> "s": # type: ignore
"""
Read only property for the bluez service to get the uuid of this gatt service interface.
:return: 128-bit service UUID.
"""
return str(self.uuid)
@dbus_property(access=PropertyAccess.READ, name="Primary")
def _primary(self) -> "b": # type: ignore
"""
Read only property for the bluez service to get whether or not this service is the primary service
for the application.
:return: Indicates whether or not this GATT service is a primary service. If false, the service is secondary.
"""
return self.primary
@property
def path(self) -> str:
"""Path property, raises an exception if not properly defined"""
if self._path is None:
raise RuntimeError("Attempting to fetch path of an unset service, has it been added correctly?")
return self._path