Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions bless/backends/bluezdbus/dbus/application.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import bleak.backends.bluezdbus.defs as defs # type: ignore

from typing import List, Any, Callable, Optional, Union
from typing import List, Any, Callable, Optional, Union, Dict

from dbus_next.aio import MessageBus, ProxyObject, ProxyInterface # type: ignore
from dbus_next.service import ServiceInterface # type: ignore
Expand Down Expand Up @@ -51,8 +51,12 @@ def __init__(self, name: str, destination: str, bus: MessageBus):
self.advertisements: List[BlueZLEAdvertisement] = []
self.services: List[BlueZGattService] = []

self.Read: Optional[Callable[[BlueZGattCharacteristic], bytes]] = None
self.Write: Optional[Callable[[BlueZGattCharacteristic, bytes], None]] = None
self.Read: Optional[
Callable[[BlueZGattCharacteristic, Dict[str, Any]], bytes]
] = None
self.Write: Optional[
Callable[[BlueZGattCharacteristic, bytes, Dict[str, Any]], None]
] = None
self.StartNotify: Optional[Callable[[None], None]] = None
self.StopNotify: Optional[Callable[[None], None]] = None

Expand Down
4 changes: 2 additions & 2 deletions bless/backends/bluezdbus/dbus/characteristic.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ def ReadValue(self, options: "a{sv}") -> "ay": # type: ignore # noqa: F722 F821
f = self._service.app.Read
if f is None:
raise NotImplementedError()
return f(self)
return f(self, options)

@method() # noqa: F722
def WriteValue(self, value: "ay", options: "a{sv}"): # type: ignore # noqa
Expand All @@ -140,7 +140,7 @@ def WriteValue(self, value: "ay", options: "a{sv}"): # type: ignore # noqa
f = self._service.app.Write
if f is None:
raise NotImplementedError()
f(self, value)
f(self, value, options)

@method()
def StartNotify(self): # noqa: N802
Expand Down
12 changes: 7 additions & 5 deletions bless/backends/bluezdbus/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

from uuid import UUID

from typing import Any, Optional, cast
from typing import Any, Optional, cast, Dict

from asyncio import AbstractEventLoop

Expand Down Expand Up @@ -296,7 +296,7 @@ def update_value(self, service_uuid: str, char_uuid: str) -> bool:
characteristic.Value = bytes(cur_value) # type: ignore
return True

def read(self, char: BlueZGattCharacteristic) -> bytes:
def read(self, char: BlueZGattCharacteristic, options: Dict[str, Any]) -> bytes:
"""
Read request.
This re-routes the the request incomming on the dbus to the server to
Expand All @@ -314,9 +314,11 @@ def read(self, char: BlueZGattCharacteristic) -> bytes:
bytes
The value of the characteristic
"""
return bytes(self.read_request(char.UUID, {}))
return bytes(self.read_request(char.UUID, options))

def write(self, char: BlueZGattCharacteristic, value: bytes):
def write(
self, char: BlueZGattCharacteristic, value: bytes, options: Dict[str, Any]
):
"""
Write request.
This function re-routes the write request sent from the
Expand All @@ -330,4 +332,4 @@ def write(self, char: BlueZGattCharacteristic, value: bytes):
value : bytearray
The value being requested to set
"""
return self.write_request(char.UUID, bytearray(value))
return self.write_request(char.UUID, bytearray(value), options)
10 changes: 10 additions & 0 deletions bless/backends/corebluetooth/peripheral_manager_delegate.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ class PeripheralManagerDelegate: # type: ignore # noqa: F811
_advertisement_started_event: Any
_services_added_events: Dict[str, Any]
_central_subscriptions: Dict[str, Any]
server: Optional[Any]
pyobjc_classMethods: Any

@classmethod
Expand Down Expand Up @@ -98,6 +99,7 @@ def init(self: "PeripheralManagerDelegate"):
self = objc.super(PeripheralManagerDelegate, self).init()

self.event_loop: Optional[asyncio.AbstractEventLoop] = None
self.server: Optional[Any] = None

self.peripheral_manager: CBPeripheralManager = (
CBPeripheralManager.alloc().initWithDelegate_queue_(
Expand Down Expand Up @@ -342,6 +344,14 @@ def peripheralManager_central_didSubscribeToCharacteristic_( # noqa: N802
central_uuid, char_uuid
)
)
mtu_value = None
max_update = getattr(central, "maximumUpdateValueLength", None)
if callable(max_update):
mtu_value = max_update()
else:
mtu_value = max_update
if mtu_value is not None and self.server is not None:
self.server._mtu = int(mtu_value)
if central_uuid in self._central_subscriptions:
subscriptions = self._central_subscriptions[central_uuid]
if char_uuid not in subscriptions:
Expand Down
1 change: 1 addition & 0 deletions bless/backends/corebluetooth/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ def __init__(self, name: str, loop: Optional[AbstractEventLoop] = None, **kwargs
self.peripheral_manager_delegate: PeripheralManagerDelegate = (
PeripheralManagerDelegate.alloc().init()
)
self.peripheral_manager_delegate.server = self
self.peripheral_manager_delegate.read_request_func = self.read_request
self.peripheral_manager_delegate.write_request_func = self.write_request

Expand Down
37 changes: 36 additions & 1 deletion bless/backends/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def __init__(self, loop: Optional[AbstractEventLoop] = None, **kwargs):
self._callbacks: Dict[str, Callable[[Any], Any]] = {}

self.services: Dict[str, BlessGATTService] = {}
self._mtu: Optional[int] = None

# Async Context managers

Expand Down Expand Up @@ -304,6 +305,8 @@ def read_request(self, uuid: str, options: Optional[Dict] = None) -> bytearray:
A bytearray value that represents the value for the characteristic
requested
"""
if options is not None:
self._update_mtu_from_options(options)
characteristic: Optional[BlessGATTCharacteristic] = self.get_characteristic(
uuid
)
Expand All @@ -313,13 +316,15 @@ def read_request(self, uuid: str, options: Optional[Dict] = None) -> bytearray:

return self.read_request_func(characteristic)

def write_request(self, uuid: str, value: Any):
def write_request(self, uuid: str, value: Any, options: Optional[Dict] = None):
"""
Obtain the characteristic to write and pass on to the user-defined
write_request_func

Note: write_request_func must be defined on the child class
"""
if options is not None:
self._update_mtu_from_options(options)
characteristic: Optional[BlessGATTCharacteristic] = self.get_characteristic(
uuid
)
Expand Down Expand Up @@ -406,6 +411,36 @@ def on_write(self, func: Callable):
"""
self._callbacks["write"] = func

@property
def mtu(self) -> Optional[int]:
"""
The most recently observed MTU value for this server.
"""
return self._mtu

@mtu.setter
def mtu(self, value: Optional[int]):
"""
Set the MTU value for this server.
"""
self._mtu = value

@staticmethod
def _coerce_mtu_value(value: Any) -> Optional[int]:
if value is None:
return None
if hasattr(value, "value"):
return BaseBlessServer._coerce_mtu_value(value.value)
try:
return int(value)
except (TypeError, ValueError):
return None

def _update_mtu_from_options(self, options: Dict[str, Any]) -> None:
mtu_value = self._coerce_mtu_value(options.get("mtu"))
if mtu_value is not None:
self._mtu = mtu_value

@staticmethod
def is_uuid(uuid: str) -> bool:
"""
Expand Down
8 changes: 8 additions & 0 deletions bless/backends/winrt/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,4 +444,12 @@ def subscribe_characteristic(self, sender: GattLocalCharacteristic, args: Any):
"""
clients = sender.subscribed_clients
self._subscribed_clients = list(clients) if clients is not None else []
if self._subscribed_clients:
mtu_values = [
int(client.max_pdu_size)
for client in self._subscribed_clients
if getattr(client, "max_pdu_size", None) is not None
]
if mtu_values:
self._mtu = max(mtu_values)
logger.info("New device subscribed")