mirror of
https://github.com/google/bumble.git
synced 2026-06-01 07:37:02 +00:00
classic: update Device.connect to allow parallels connection creation
According to the specification nothing prevent the Host from creating multiple connections at the same time. This commit add this mechanisme by matching the `connection` and `connection_failure` events against the peer address.
This commit is contained in:
+26
-9
@@ -1144,7 +1144,7 @@ class Device(CompositeEventEmitter):
|
||||
transport = BT_LE_TRANSPORT
|
||||
|
||||
# Check that there isn't already a pending connection
|
||||
if self.is_connecting:
|
||||
if transport == BT_LE_TRANSPORT and self.is_connecting:
|
||||
raise InvalidStateError('connection already pending')
|
||||
|
||||
if type(peer_address) is str:
|
||||
@@ -1155,10 +1155,22 @@ class Device(CompositeEventEmitter):
|
||||
logger.debug('looking for peer by name')
|
||||
peer_address = await self.find_peer_by_name(peer_address, transport) # TODO: timeout
|
||||
|
||||
def on_connection(connection):
|
||||
if transport == BT_LE_TRANSPORT or (
|
||||
# match BR/EDR connection event against peer address
|
||||
connection.transport == transport and connection.peer_address == peer_address):
|
||||
pending_connection.set_result(connection)
|
||||
|
||||
def on_connection_failure(error):
|
||||
if transport == BT_LE_TRANSPORT or (
|
||||
# match BR/EDR connection failure event against peer address
|
||||
error.transport == transport and error.peer_address == peer_address):
|
||||
pending_connection.set_exception(error)
|
||||
|
||||
# Create a future so that we can wait for the connection's result
|
||||
pending_connection = asyncio.get_running_loop().create_future()
|
||||
self.on('connection', pending_connection.set_result)
|
||||
self.on('connection_failure', pending_connection.set_exception)
|
||||
self.on('connection', on_connection)
|
||||
self.on('connection_failure', on_connection_failure)
|
||||
|
||||
try:
|
||||
# Tell the controller to connect
|
||||
@@ -1248,7 +1260,8 @@ class Device(CompositeEventEmitter):
|
||||
raise HCI_StatusError(result)
|
||||
|
||||
# Wait for the connection process to complete
|
||||
self.connecting = True
|
||||
if transport == BT_LE_TRANSPORT:
|
||||
self.connecting = True
|
||||
if timeout is None:
|
||||
return await pending_connection
|
||||
else:
|
||||
@@ -1265,9 +1278,10 @@ class Device(CompositeEventEmitter):
|
||||
except ConnectionError:
|
||||
raise TimeoutError()
|
||||
finally:
|
||||
self.remove_listener('connection', pending_connection.set_result)
|
||||
self.remove_listener('connection_failure', pending_connection.set_exception)
|
||||
self.connecting = False
|
||||
self.remove_listener('connection', on_connection)
|
||||
self.remove_listener('connection_failure', on_connection_failure)
|
||||
if transport == BT_LE_TRANSPORT:
|
||||
self.connecting = False
|
||||
|
||||
@asynccontextmanager
|
||||
async def connect_as_gatt(self, peer_address):
|
||||
@@ -1704,11 +1718,11 @@ class Device(CompositeEventEmitter):
|
||||
asyncio.create_task(new_connection())
|
||||
|
||||
@host_event_handler
|
||||
def on_connection_failure(self, connection_handle, error_code):
|
||||
def on_connection_failure(self, transport, connection_handle, peer_address, error_code):
|
||||
logger.debug(f'*** Connection failed: {HCI_Constant.error_name(error_code)}')
|
||||
|
||||
# For directed advertising, this means a timeout
|
||||
if self.advertising and self.advertising_type.is_directed:
|
||||
if transport == BT_LE_TRANSPORT and self.advertising and self.advertising_type.is_directed:
|
||||
self.advertising = False
|
||||
|
||||
# Notify listeners
|
||||
@@ -1717,6 +1731,9 @@ class Device(CompositeEventEmitter):
|
||||
'hci',
|
||||
HCI_Constant.error_name(error_code)
|
||||
)
|
||||
error.transport = transport
|
||||
error.connection_handle = connection_handle # FIXME: Connection handle sounds to be a dummy value here
|
||||
error.peer_address = peer_address
|
||||
self.emit('connection_failure', error)
|
||||
|
||||
@host_event_handler
|
||||
|
||||
+2
-2
@@ -383,7 +383,7 @@ class Host(EventEmitter):
|
||||
logger.debug(f'### CONNECTION FAILED: {event.status}')
|
||||
|
||||
# Notify the listeners
|
||||
self.emit('connection_failure', event.connection_handle, event.status)
|
||||
self.emit('connection_failure', BT_LE_TRANSPORT, event.connection_handle, event.peer_address, event.status)
|
||||
|
||||
def on_hci_le_enhanced_connection_complete_event(self, event):
|
||||
# Just use the same implementation as for the non-enhanced event for now
|
||||
@@ -413,7 +413,7 @@ class Host(EventEmitter):
|
||||
logger.debug(f'### BR/EDR CONNECTION FAILED: {event.status}')
|
||||
|
||||
# Notify the client
|
||||
self.emit('connection_failure', event.connection_handle, event.status)
|
||||
self.emit('connection_failure', BT_BR_EDR_TRANSPORT, event.connection_handle, event.bd_addr, event.status)
|
||||
|
||||
def on_hci_disconnection_complete_event(self, event):
|
||||
# Find the connection
|
||||
|
||||
Reference in New Issue
Block a user