bumble 0.0.215__py3-none-any.whl → 0.0.216__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- bumble/_version.py +2 -2
- bumble/device.py +76 -39
- {bumble-0.0.215.dist-info → bumble-0.0.216.dist-info}/METADATA +1 -1
- {bumble-0.0.215.dist-info → bumble-0.0.216.dist-info}/RECORD +8 -8
- {bumble-0.0.215.dist-info → bumble-0.0.216.dist-info}/WHEEL +0 -0
- {bumble-0.0.215.dist-info → bumble-0.0.216.dist-info}/entry_points.txt +0 -0
- {bumble-0.0.215.dist-info → bumble-0.0.216.dist-info}/licenses/LICENSE +0 -0
- {bumble-0.0.215.dist-info → bumble-0.0.216.dist-info}/top_level.txt +0 -0
bumble/_version.py
CHANGED
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.0.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 0,
|
|
31
|
+
__version__ = version = '0.0.216'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 0, 216)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
bumble/device.py
CHANGED
|
@@ -2169,10 +2169,12 @@ def with_connection_from_handle(function):
|
|
|
2169
2169
|
# Decorator that converts the first argument from a bluetooth address to a connection
|
|
2170
2170
|
def with_connection_from_address(function):
|
|
2171
2171
|
@functools.wraps(function)
|
|
2172
|
-
def wrapper(
|
|
2173
|
-
|
|
2172
|
+
def wrapper(device: Device, address: hci.Address, *args, **kwargs):
|
|
2173
|
+
if connection := device.pending_connections.get(address):
|
|
2174
|
+
return function(device, connection, address, *args, **kwargs)
|
|
2175
|
+
for connection in device.connections.values():
|
|
2174
2176
|
if connection.peer_address == address:
|
|
2175
|
-
return function(
|
|
2177
|
+
return function(device, connection, *args, **kwargs)
|
|
2176
2178
|
raise ObjectLookupError('no connection for address')
|
|
2177
2179
|
|
|
2178
2180
|
return wrapper
|
|
@@ -2182,11 +2184,13 @@ def with_connection_from_address(function):
|
|
|
2182
2184
|
# connection
|
|
2183
2185
|
def try_with_connection_from_address(function):
|
|
2184
2186
|
@functools.wraps(function)
|
|
2185
|
-
def wrapper(
|
|
2186
|
-
|
|
2187
|
+
def wrapper(device: Device, address: hci.Address, *args, **kwargs):
|
|
2188
|
+
if connection := device.pending_connections.get(address):
|
|
2189
|
+
return function(device, connection, address, *args, **kwargs)
|
|
2190
|
+
for connection in device.connections.values():
|
|
2187
2191
|
if connection.peer_address == address:
|
|
2188
|
-
return function(
|
|
2189
|
-
return function(
|
|
2192
|
+
return function(device, connection, address, *args, **kwargs)
|
|
2193
|
+
return function(device, None, address, *args, **kwargs)
|
|
2190
2194
|
|
|
2191
2195
|
return wrapper
|
|
2192
2196
|
|
|
@@ -2234,7 +2238,7 @@ class Device(utils.CompositeEventEmitter):
|
|
|
2234
2238
|
scan_response_data: bytes
|
|
2235
2239
|
cs_capabilities: ChannelSoundingCapabilities | None = None
|
|
2236
2240
|
connections: dict[int, Connection]
|
|
2237
|
-
|
|
2241
|
+
pending_connections: dict[hci.Address, Connection]
|
|
2238
2242
|
classic_pending_accepts: dict[
|
|
2239
2243
|
hci.Address,
|
|
2240
2244
|
list[asyncio.Future[Union[Connection, tuple[hci.Address, int, int]]]],
|
|
@@ -2356,9 +2360,9 @@ class Device(utils.CompositeEventEmitter):
|
|
|
2356
2360
|
self.le_connecting = False
|
|
2357
2361
|
self.disconnecting = False
|
|
2358
2362
|
self.connections = {} # Connections, by connection handle
|
|
2359
|
-
self.
|
|
2363
|
+
self.pending_connections = (
|
|
2360
2364
|
{}
|
|
2361
|
-
) #
|
|
2365
|
+
) # Pending connections, by BD address (BR/EDR only)
|
|
2362
2366
|
self.sco_links = {} # ScoLinks, by connection handle (BR/EDR only)
|
|
2363
2367
|
self.cis_links = {} # CisLinks, by connection handle (LE only)
|
|
2364
2368
|
self._pending_cis = {} # (CIS_ID, CIG_ID), by CIS_handle
|
|
@@ -3827,7 +3831,17 @@ class Device(utils.CompositeEventEmitter):
|
|
|
3827
3831
|
)
|
|
3828
3832
|
else:
|
|
3829
3833
|
# Save pending connection
|
|
3830
|
-
self.
|
|
3834
|
+
self.pending_connections[peer_address] = Connection(
|
|
3835
|
+
device=self,
|
|
3836
|
+
handle=0,
|
|
3837
|
+
transport=core.PhysicalTransport.BR_EDR,
|
|
3838
|
+
self_address=self.public_address,
|
|
3839
|
+
self_resolvable_address=None,
|
|
3840
|
+
peer_address=peer_address,
|
|
3841
|
+
peer_resolvable_address=None,
|
|
3842
|
+
role=hci.Role.CENTRAL,
|
|
3843
|
+
parameters=Connection.Parameters(0, 0, 0),
|
|
3844
|
+
)
|
|
3831
3845
|
|
|
3832
3846
|
# TODO: allow passing other settings
|
|
3833
3847
|
result = await self.send_command(
|
|
@@ -3880,7 +3894,7 @@ class Device(utils.CompositeEventEmitter):
|
|
|
3880
3894
|
self.le_connecting = False
|
|
3881
3895
|
self.connect_own_address_type = None
|
|
3882
3896
|
else:
|
|
3883
|
-
self.
|
|
3897
|
+
self.pending_connections.pop(peer_address, None)
|
|
3884
3898
|
|
|
3885
3899
|
async def accept(
|
|
3886
3900
|
self,
|
|
@@ -3978,7 +3992,17 @@ class Device(utils.CompositeEventEmitter):
|
|
|
3978
3992
|
# Even if we requested a role switch in the hci.HCI_Accept_Connection_Request
|
|
3979
3993
|
# command, this connection is still considered Peripheral until an eventual
|
|
3980
3994
|
# role change event.
|
|
3981
|
-
self.
|
|
3995
|
+
self.pending_connections[peer_address] = Connection(
|
|
3996
|
+
device=self,
|
|
3997
|
+
handle=0,
|
|
3998
|
+
transport=core.PhysicalTransport.BR_EDR,
|
|
3999
|
+
self_address=self.public_address,
|
|
4000
|
+
self_resolvable_address=None,
|
|
4001
|
+
peer_address=peer_address,
|
|
4002
|
+
peer_resolvable_address=None,
|
|
4003
|
+
role=hci.Role.PERIPHERAL,
|
|
4004
|
+
parameters=Connection.Parameters(0, 0, 0),
|
|
4005
|
+
)
|
|
3982
4006
|
|
|
3983
4007
|
try:
|
|
3984
4008
|
# Accept connection request
|
|
@@ -3996,7 +4020,7 @@ class Device(utils.CompositeEventEmitter):
|
|
|
3996
4020
|
finally:
|
|
3997
4021
|
self.remove_listener(self.EVENT_CONNECTION, on_connection)
|
|
3998
4022
|
self.remove_listener(self.EVENT_CONNECTION_FAILURE, on_connection_failure)
|
|
3999
|
-
self.
|
|
4023
|
+
self.pending_connections.pop(peer_address, None)
|
|
4000
4024
|
|
|
4001
4025
|
@asynccontextmanager
|
|
4002
4026
|
async def connect_as_gatt(self, peer_address: Union[hci.Address, str]):
|
|
@@ -5441,29 +5465,27 @@ class Device(utils.CompositeEventEmitter):
|
|
|
5441
5465
|
connection_handle: int,
|
|
5442
5466
|
peer_address: hci.Address,
|
|
5443
5467
|
) -> None:
|
|
5444
|
-
|
|
5468
|
+
if connection := self.pending_connections.pop(peer_address, None):
|
|
5469
|
+
connection.handle = connection_handle
|
|
5470
|
+
else:
|
|
5471
|
+
# Create a new connection
|
|
5472
|
+
connection = Connection(
|
|
5473
|
+
device=self,
|
|
5474
|
+
handle=connection_handle,
|
|
5475
|
+
transport=PhysicalTransport.BR_EDR,
|
|
5476
|
+
self_address=self.public_address,
|
|
5477
|
+
self_resolvable_address=None,
|
|
5478
|
+
peer_address=peer_address,
|
|
5479
|
+
peer_resolvable_address=None,
|
|
5480
|
+
role=hci.Role.PERIPHERAL,
|
|
5481
|
+
parameters=Connection.Parameters(0.0, 0, 0.0),
|
|
5482
|
+
)
|
|
5445
5483
|
|
|
5446
|
-
logger.debug(
|
|
5447
|
-
f'*** Connection: [0x{connection_handle:04X}] '
|
|
5448
|
-
f'{peer_address} {hci.HCI_Constant.role_name(connection_role)}'
|
|
5449
|
-
)
|
|
5484
|
+
logger.debug('*** %s', connection)
|
|
5450
5485
|
if connection_handle in self.connections:
|
|
5451
5486
|
logger.warning(
|
|
5452
5487
|
'new connection reuses the same handle as a previous connection'
|
|
5453
5488
|
)
|
|
5454
|
-
|
|
5455
|
-
# Create a new connection
|
|
5456
|
-
connection = Connection(
|
|
5457
|
-
device=self,
|
|
5458
|
-
handle=connection_handle,
|
|
5459
|
-
transport=PhysicalTransport.BR_EDR,
|
|
5460
|
-
self_address=self.public_address,
|
|
5461
|
-
self_resolvable_address=None,
|
|
5462
|
-
peer_address=peer_address,
|
|
5463
|
-
peer_resolvable_address=None,
|
|
5464
|
-
role=connection_role,
|
|
5465
|
-
parameters=Connection.Parameters(0.0, 0, 0.0),
|
|
5466
|
-
)
|
|
5467
5489
|
self.connections[connection_handle] = connection
|
|
5468
5490
|
|
|
5469
5491
|
self.emit(self.EVENT_CONNECTION, connection)
|
|
@@ -5618,7 +5640,9 @@ class Device(utils.CompositeEventEmitter):
|
|
|
5618
5640
|
|
|
5619
5641
|
# FIXME: Explore a delegate-model for BR/EDR wait connection #56.
|
|
5620
5642
|
@host_event_handler
|
|
5621
|
-
def on_connection_request(
|
|
5643
|
+
def on_connection_request(
|
|
5644
|
+
self, bd_addr: hci.Address, class_of_device: int, link_type: int
|
|
5645
|
+
):
|
|
5622
5646
|
logger.debug(f'*** Connection request: {bd_addr}')
|
|
5623
5647
|
|
|
5624
5648
|
# Handle SCO request.
|
|
@@ -5647,7 +5671,17 @@ class Device(utils.CompositeEventEmitter):
|
|
|
5647
5671
|
# device configuration is set to accept any incoming connection
|
|
5648
5672
|
elif self.classic_accept_any:
|
|
5649
5673
|
# Save pending connection
|
|
5650
|
-
self.
|
|
5674
|
+
self.pending_connections[bd_addr] = Connection(
|
|
5675
|
+
device=self,
|
|
5676
|
+
handle=0,
|
|
5677
|
+
transport=core.PhysicalTransport.BR_EDR,
|
|
5678
|
+
self_address=self.public_address,
|
|
5679
|
+
self_resolvable_address=None,
|
|
5680
|
+
peer_address=bd_addr,
|
|
5681
|
+
peer_resolvable_address=None,
|
|
5682
|
+
role=hci.Role.PERIPHERAL,
|
|
5683
|
+
parameters=Connection.Parameters(0, 0, 0),
|
|
5684
|
+
)
|
|
5651
5685
|
|
|
5652
5686
|
self.host.send_command_sync(
|
|
5653
5687
|
hci.HCI_Accept_Connection_Request_Command(
|
|
@@ -5958,7 +5992,7 @@ class Device(utils.CompositeEventEmitter):
|
|
|
5958
5992
|
@host_event_handler
|
|
5959
5993
|
@try_with_connection_from_address
|
|
5960
5994
|
def on_remote_name(
|
|
5961
|
-
self, connection: Connection, address: hci.Address, remote_name: bytes
|
|
5995
|
+
self, connection: Optional[Connection], address: hci.Address, remote_name: bytes
|
|
5962
5996
|
):
|
|
5963
5997
|
# Try to decode the name
|
|
5964
5998
|
try:
|
|
@@ -5977,7 +6011,7 @@ class Device(utils.CompositeEventEmitter):
|
|
|
5977
6011
|
@host_event_handler
|
|
5978
6012
|
@try_with_connection_from_address
|
|
5979
6013
|
def on_remote_name_failure(
|
|
5980
|
-
self, connection: Connection, address: hci.Address, error: int
|
|
6014
|
+
self, connection: Optional[Connection], address: hci.Address, error: int
|
|
5981
6015
|
):
|
|
5982
6016
|
if connection:
|
|
5983
6017
|
connection.emit(connection.EVENT_REMOTE_NAME_FAILURE, error)
|
|
@@ -6411,19 +6445,22 @@ class Device(utils.CompositeEventEmitter):
|
|
|
6411
6445
|
@host_event_handler
|
|
6412
6446
|
@try_with_connection_from_address
|
|
6413
6447
|
def on_role_change(
|
|
6414
|
-
self,
|
|
6448
|
+
self,
|
|
6449
|
+
connection: Optional[Connection],
|
|
6450
|
+
peer_address: hci.Address,
|
|
6451
|
+
new_role: hci.Role,
|
|
6415
6452
|
):
|
|
6416
6453
|
if connection:
|
|
6417
6454
|
connection.role = new_role
|
|
6418
6455
|
connection.emit(connection.EVENT_ROLE_CHANGE, new_role)
|
|
6419
6456
|
else:
|
|
6420
|
-
|
|
6457
|
+
logger.warning("Role change to unknown connection %s", peer_address)
|
|
6421
6458
|
|
|
6422
6459
|
# [Classic only]
|
|
6423
6460
|
@host_event_handler
|
|
6424
6461
|
@try_with_connection_from_address
|
|
6425
6462
|
def on_role_change_failure(
|
|
6426
|
-
self, connection: Connection, address: hci.Address, error: int
|
|
6463
|
+
self, connection: Optional[Connection], address: hci.Address, error: int
|
|
6427
6464
|
):
|
|
6428
6465
|
if connection:
|
|
6429
6466
|
connection.emit(connection.EVENT_ROLE_CHANGE_FAILURE, error)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
bumble/__init__.py,sha256=Q8jkz6rgl95IMAeInQVt_2GLoJl3DcEP2cxtrQ-ho5c,110
|
|
2
|
-
bumble/_version.py,sha256=
|
|
2
|
+
bumble/_version.py,sha256=veynzO9___YfPnIypSQv3tYyxNmoE4TBaM2ten8_gK4,708
|
|
3
3
|
bumble/a2dp.py,sha256=sVo3w6qSsGm7Ttsqu4zeTO_Gfo63a7STTlJnaq8iJ-M,32031
|
|
4
4
|
bumble/at.py,sha256=u93DzB5Ghrxks_ufuUqoYV2RUSowLNLMDhq_j9GrCBc,3108
|
|
5
5
|
bumble/att.py,sha256=vS1dUwiuUgNU6PztARg_qPB_olLOWsAxFz6DZGX8zII,33423
|
|
@@ -15,7 +15,7 @@ bumble/controller.py,sha256=oIo6_3Y2_lhMPn0MUfEEN8997ry1blzT2rTUQabQwv8,68282
|
|
|
15
15
|
bumble/core.py,sha256=QojIUs4nP9qo_r-FWPVxHrCdVSg6CaIzHf6GVPTuu9s,94583
|
|
16
16
|
bumble/data_types.py,sha256=jLELcRiUcvRc4JcEo6vMO9kZmumZ9WuibFN-AK7ZYbc,32831
|
|
17
17
|
bumble/decoder.py,sha256=0-VNWZT-u7lvK3qBpAuYT0M6Rz_bMgMi4CjfUXX_6RM,9728
|
|
18
|
-
bumble/device.py,sha256=
|
|
18
|
+
bumble/device.py,sha256=VDvdXeMhoGTdG3AHuN0-glHDpJKDhSdKVGrauq2kni0,251675
|
|
19
19
|
bumble/gap.py,sha256=j5mevt__i_fSdIc_B3x7YvCJLeCc7bVq8omRphxwXNw,2144
|
|
20
20
|
bumble/gatt.py,sha256=dBd-opQVUumlLPGw7EYZM5DF-ssnym3LsxhskAJMhig,34552
|
|
21
21
|
bumble/gatt_adapters.py,sha256=9uN2uXGIdlvNeSvv3nfwxCEa15uPfm5DVLR5bog_knI,13190
|
|
@@ -175,9 +175,9 @@ bumble/vendor/android/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
|
175
175
|
bumble/vendor/android/hci.py,sha256=LcV4_OBpzoLtpSiP2su7F4r3bDrHWxcQPR4OGnMVXDk,10485
|
|
176
176
|
bumble/vendor/zephyr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
177
177
|
bumble/vendor/zephyr/hci.py,sha256=ysct40uIVohaKKLrWjcWo-7YqozU17xGia2dWeHoMoI,3435
|
|
178
|
-
bumble-0.0.
|
|
179
|
-
bumble-0.0.
|
|
180
|
-
bumble-0.0.
|
|
181
|
-
bumble-0.0.
|
|
182
|
-
bumble-0.0.
|
|
183
|
-
bumble-0.0.
|
|
178
|
+
bumble-0.0.216.dist-info/licenses/LICENSE,sha256=FvaYh4NRWIGgS_OwoBs5gFgkCmAghZ-DYnIGBZPuw-s,12142
|
|
179
|
+
bumble-0.0.216.dist-info/METADATA,sha256=MY056_VlCMC-BwKlWwCW6b29sSrlNeY1_LN4xrfp0pc,6155
|
|
180
|
+
bumble-0.0.216.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
181
|
+
bumble-0.0.216.dist-info/entry_points.txt,sha256=mX5dzixNMRo4CTAEQqiYTr-JIaWF62TYrRvJOstjjL8,1081
|
|
182
|
+
bumble-0.0.216.dist-info/top_level.txt,sha256=tV6JJKaHPYMFiJYiBYFW24PCcfLxTJZdlu6BmH3Cb00,7
|
|
183
|
+
bumble-0.0.216.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|