mirror of
https://github.com/google/bumble.git
synced 2026-04-18 00:45:32 +00:00
format with Black
This commit is contained in:
119
bumble/link.py
119
bumble/link.py
@@ -25,7 +25,7 @@ from bumble.hci import (
|
||||
Address,
|
||||
HCI_SUCCESS,
|
||||
HCI_CONNECTION_ACCEPT_TIMEOUT_ERROR,
|
||||
HCI_CONNECTION_TIMEOUT_ERROR
|
||||
HCI_CONNECTION_TIMEOUT_ERROR,
|
||||
)
|
||||
|
||||
# -----------------------------------------------------------------------------
|
||||
@@ -55,7 +55,7 @@ class LocalLink:
|
||||
'''
|
||||
|
||||
def __init__(self):
|
||||
self.controllers = set()
|
||||
self.controllers = set()
|
||||
self.pending_connection = None
|
||||
|
||||
def add_controller(self, controller):
|
||||
@@ -103,23 +103,30 @@ class LocalLink:
|
||||
return
|
||||
|
||||
# Connect to the first controller with a matching address
|
||||
if peripheral_controller := self.find_controller(le_create_connection_command.peer_address):
|
||||
central_controller.on_link_peripheral_connection_complete(le_create_connection_command, HCI_SUCCESS)
|
||||
if peripheral_controller := self.find_controller(
|
||||
le_create_connection_command.peer_address
|
||||
):
|
||||
central_controller.on_link_peripheral_connection_complete(
|
||||
le_create_connection_command, HCI_SUCCESS
|
||||
)
|
||||
peripheral_controller.on_link_central_connected(central_address)
|
||||
return
|
||||
|
||||
# No peripheral found
|
||||
central_controller.on_link_peripheral_connection_complete(
|
||||
le_create_connection_command,
|
||||
HCI_CONNECTION_ACCEPT_TIMEOUT_ERROR
|
||||
le_create_connection_command, HCI_CONNECTION_ACCEPT_TIMEOUT_ERROR
|
||||
)
|
||||
|
||||
def connect(self, central_address, le_create_connection_command):
|
||||
logger.debug(f'$$$ CONNECTION {central_address} -> {le_create_connection_command.peer_address}')
|
||||
logger.debug(
|
||||
f'$$$ CONNECTION {central_address} -> {le_create_connection_command.peer_address}'
|
||||
)
|
||||
self.pending_connection = (central_address, le_create_connection_command)
|
||||
asyncio.get_running_loop().call_soon(self.on_connection_complete)
|
||||
|
||||
def on_disconnection_complete(self, central_address, peripheral_address, disconnect_command):
|
||||
def on_disconnection_complete(
|
||||
self, central_address, peripheral_address, disconnect_command
|
||||
):
|
||||
# Find the controller that initiated the disconnection
|
||||
if not (central_controller := self.find_controller(central_address)):
|
||||
logger.warning('!!! Initiating controller not found')
|
||||
@@ -127,16 +134,24 @@ class LocalLink:
|
||||
|
||||
# Disconnect from the first controller with a matching address
|
||||
if peripheral_controller := self.find_controller(peripheral_address):
|
||||
peripheral_controller.on_link_central_disconnected(central_address, disconnect_command.reason)
|
||||
peripheral_controller.on_link_central_disconnected(
|
||||
central_address, disconnect_command.reason
|
||||
)
|
||||
|
||||
central_controller.on_link_peripheral_disconnection_complete(disconnect_command, HCI_SUCCESS)
|
||||
central_controller.on_link_peripheral_disconnection_complete(
|
||||
disconnect_command, HCI_SUCCESS
|
||||
)
|
||||
|
||||
def disconnect(self, central_address, peripheral_address, disconnect_command):
|
||||
logger.debug(f'$$$ DISCONNECTION {central_address} -> {peripheral_address}: reason = {disconnect_command.reason}')
|
||||
logger.debug(
|
||||
f'$$$ DISCONNECTION {central_address} -> {peripheral_address}: reason = {disconnect_command.reason}'
|
||||
)
|
||||
args = [central_address, peripheral_address, disconnect_command]
|
||||
asyncio.get_running_loop().call_soon(self.on_disconnection_complete, *args)
|
||||
|
||||
def on_connection_encrypted(self, central_address, peripheral_address, rand, ediv, ltk):
|
||||
def on_connection_encrypted(
|
||||
self, central_address, peripheral_address, rand, ediv, ltk
|
||||
):
|
||||
logger.debug(f'*** ENCRYPTION {central_address} -> {peripheral_address}')
|
||||
|
||||
if central_controller := self.find_controller(central_address):
|
||||
@@ -152,15 +167,18 @@ class RemoteLink:
|
||||
A Link implementation that communicates with other virtual controllers via a
|
||||
WebSocket relay
|
||||
'''
|
||||
|
||||
def __init__(self, uri):
|
||||
self.controller = None
|
||||
self.uri = uri
|
||||
self.execution_queue = asyncio.Queue()
|
||||
self.websocket = asyncio.get_running_loop().create_future()
|
||||
self.rpc_result = None
|
||||
self.pending_connection = None
|
||||
self.central_connections = set() # List of addresses that we have connected to
|
||||
self.peripheral_connections = set() # List of addresses that have connected to us
|
||||
self.controller = None
|
||||
self.uri = uri
|
||||
self.execution_queue = asyncio.Queue()
|
||||
self.websocket = asyncio.get_running_loop().create_future()
|
||||
self.rpc_result = None
|
||||
self.pending_connection = None
|
||||
self.central_connections = set() # List of addresses that we have connected to
|
||||
self.peripheral_connections = (
|
||||
set()
|
||||
) # List of addresses that have connected to us
|
||||
|
||||
# Connect and run asynchronously
|
||||
asyncio.create_task(self.run_connection())
|
||||
@@ -192,7 +210,9 @@ class RemoteLink:
|
||||
try:
|
||||
await item
|
||||
except Exception as error:
|
||||
logger.warning(f'{color("!!! Exception in async handler:", "red")} {error}')
|
||||
logger.warning(
|
||||
f'{color("!!! Exception in async handler:", "red")} {error}'
|
||||
)
|
||||
|
||||
async def run_connection(self):
|
||||
# Connect to the relay
|
||||
@@ -227,7 +247,9 @@ class RemoteLink:
|
||||
self.central_connections.remove(address)
|
||||
|
||||
if address in self.peripheral_connections:
|
||||
self.controller.on_link_central_disconnected(address, HCI_CONNECTION_TIMEOUT_ERROR)
|
||||
self.controller.on_link_central_disconnected(
|
||||
address, HCI_CONNECTION_TIMEOUT_ERROR
|
||||
)
|
||||
self.peripheral_connections.remove(address)
|
||||
|
||||
async def on_unreachable_received(self, target):
|
||||
@@ -244,7 +266,9 @@ class RemoteLink:
|
||||
|
||||
async def on_advertisement_message_received(self, sender, advertisement):
|
||||
try:
|
||||
self.controller.on_link_advertising_data(Address(sender), bytes.fromhex(advertisement))
|
||||
self.controller.on_link_advertising_data(
|
||||
Address(sender), bytes.fromhex(advertisement)
|
||||
)
|
||||
except Exception:
|
||||
logger.exception('exception')
|
||||
|
||||
@@ -275,7 +299,9 @@ class RemoteLink:
|
||||
|
||||
# Notify the controller
|
||||
logger.debug(f'connected to peripheral {self.pending_connection.peer_address}')
|
||||
self.controller.on_link_peripheral_connection_complete(self.pending_connection, HCI_SUCCESS)
|
||||
self.controller.on_link_peripheral_connection_complete(
|
||||
self.pending_connection, HCI_SUCCESS
|
||||
)
|
||||
|
||||
async def on_disconnect_message_received(self, sender, message):
|
||||
# Notify the controller
|
||||
@@ -296,7 +322,7 @@ class RemoteLink:
|
||||
websocket = await self.websocket
|
||||
|
||||
# Create a future value to hold the eventual result
|
||||
assert(self.rpc_result is None)
|
||||
assert self.rpc_result is None
|
||||
self.rpc_result = asyncio.get_running_loop().create_future()
|
||||
|
||||
# Send the command
|
||||
@@ -345,16 +371,43 @@ class RemoteLink:
|
||||
logger.warn('connection already pending')
|
||||
return
|
||||
self.pending_connection = le_create_connection_command
|
||||
self.execute(partial(self.send_connection_request_to_relay, str(le_create_connection_command.peer_address)))
|
||||
self.execute(
|
||||
partial(
|
||||
self.send_connection_request_to_relay,
|
||||
str(le_create_connection_command.peer_address),
|
||||
)
|
||||
)
|
||||
|
||||
def on_disconnection_complete(self, disconnect_command):
|
||||
self.controller.on_link_peripheral_disconnection_complete(disconnect_command, HCI_SUCCESS)
|
||||
self.controller.on_link_peripheral_disconnection_complete(
|
||||
disconnect_command, HCI_SUCCESS
|
||||
)
|
||||
|
||||
def disconnect(self, central_address, peripheral_address, disconnect_command):
|
||||
logger.debug(f'disconnect {central_address} -> {peripheral_address}: reason = {disconnect_command.reason}')
|
||||
self.execute(partial(self.send_targetted_message, peripheral_address, f'disconnect:reason={disconnect_command.reason}'))
|
||||
asyncio.get_running_loop().call_soon(self.on_disconnection_complete, disconnect_command)
|
||||
logger.debug(
|
||||
f'disconnect {central_address} -> {peripheral_address}: reason = {disconnect_command.reason}'
|
||||
)
|
||||
self.execute(
|
||||
partial(
|
||||
self.send_targetted_message,
|
||||
peripheral_address,
|
||||
f'disconnect:reason={disconnect_command.reason}',
|
||||
)
|
||||
)
|
||||
asyncio.get_running_loop().call_soon(
|
||||
self.on_disconnection_complete, disconnect_command
|
||||
)
|
||||
|
||||
def on_connection_encrypted(self, central_address, peripheral_address, rand, ediv, ltk):
|
||||
asyncio.get_running_loop().call_soon(self.controller.on_link_encrypted, peripheral_address, rand, ediv, ltk)
|
||||
self.execute(partial(self.send_targetted_message, peripheral_address, f'encrypted:ltk={ltk.hex()}'))
|
||||
def on_connection_encrypted(
|
||||
self, central_address, peripheral_address, rand, ediv, ltk
|
||||
):
|
||||
asyncio.get_running_loop().call_soon(
|
||||
self.controller.on_link_encrypted, peripheral_address, rand, ediv, ltk
|
||||
)
|
||||
self.execute(
|
||||
partial(
|
||||
self.send_targetted_message,
|
||||
peripheral_address,
|
||||
f'encrypted:ltk={ltk.hex()}',
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user