Skip to content

Commit

Permalink
support out of order advertising set termination / connection events
Browse files Browse the repository at this point in the history
  • Loading branch information
barbibulle committed Jun 5, 2024
1 parent f910a69 commit 2e3aeb8
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 3 deletions.
31 changes: 28 additions & 3 deletions bumble/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -1574,6 +1574,7 @@ def __init__(

# Extended advertising.
self.extended_advertising_sets: Dict[int, AdvertisingSet] = {}
self.connecting_extended_advertising_sets: Dict[int, AdvertisingSet] = {}

# Legacy advertising.
# The advertising and scan response data, as well as the advertising interval
Expand Down Expand Up @@ -3605,14 +3606,28 @@ def on_advertising_set_termination(
)
return

if not (connection := self.lookup_connection(connection_handle)):
logger.warning(f'no connection for handle 0x{connection_handle:04x}')
if connection := self.lookup_connection(connection_handle):
# We have already received the connection complete event.
self._complete_le_extended_advertising_connection(
connection, advertising_set
)
return

# Associate the connection handle with the advertising set, the connection
# will complete later.
logger.debug(
f'the connection with handle {connection_handle:04X} will complete later'
)
self.connecting_extended_advertising_sets[connection_handle] = advertising_set

def _complete_le_extended_advertising_connection(
self, connection: Connection, advertising_set: AdvertisingSet
) -> None:
# Update the connection address.
connection.self_address = (
advertising_set.random_address
if advertising_set.advertising_parameters.own_address_type
if advertising_set.random_address is not None
and advertising_set.advertising_parameters.own_address_type
in (OwnAddressType.RANDOM, OwnAddressType.RESOLVABLE_OR_RANDOM)
else self.public_address
)
Expand Down Expand Up @@ -3743,6 +3758,16 @@ def on_connection(
if role == HCI_CENTRAL_ROLE or not self.supports_le_extended_advertising:
# We can emit now, we have all the info we need
self._emit_le_connection(connection)
return

if role == HCI_PERIPHERAL_ROLE and self.supports_le_extended_advertising:
if advertising_set := self.connecting_extended_advertising_sets.pop(
connection_handle, None
):
# We have already received the advertising set termination event.
self._complete_le_extended_advertising_connection(
connection, advertising_set
)

@host_event_handler
def on_connection_failure(self, transport, peer_address, error_code):
Expand Down
4 changes: 4 additions & 0 deletions bumble/host.py
Original file line number Diff line number Diff line change
Expand Up @@ -787,6 +787,10 @@ def on_hci_le_enhanced_connection_complete_event(self, event):
# Just use the same implementation as for the non-enhanced event for now
self.on_hci_le_connection_complete_event(event)

def on_hci_le_enhanced_connection_complete_v2_event(self, event):
# Just use the same implementation as for the v1 event for now
self.on_hci_le_enhanced_connection_complete_event(event)

def on_hci_connection_complete_event(self, event):
if event.status == hci.HCI_SUCCESS:
# Create/update the connection
Expand Down

0 comments on commit 2e3aeb8

Please sign in to comment.