bumble 0.0.216__py3-none-any.whl → 0.0.217__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 +5 -9
- bumble/host.py +1 -1
- bumble/profiles/hap.py +33 -4
- bumble/transport/android_netsim.py +5 -1
- bumble/transport/serial.py +56 -2
- {bumble-0.0.216.dist-info → bumble-0.0.217.dist-info}/METADATA +1 -1
- {bumble-0.0.216.dist-info → bumble-0.0.217.dist-info}/RECORD +12 -12
- {bumble-0.0.216.dist-info → bumble-0.0.217.dist-info}/WHEEL +0 -0
- {bumble-0.0.216.dist-info → bumble-0.0.217.dist-info}/entry_points.txt +0 -0
- {bumble-0.0.216.dist-info → bumble-0.0.217.dist-info}/licenses/LICENSE +0 -0
- {bumble-0.0.216.dist-info → bumble-0.0.217.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.217'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 0, 217)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
bumble/device.py
CHANGED
|
@@ -2171,7 +2171,7 @@ def with_connection_from_address(function):
|
|
|
2171
2171
|
@functools.wraps(function)
|
|
2172
2172
|
def wrapper(device: Device, address: hci.Address, *args, **kwargs):
|
|
2173
2173
|
if connection := device.pending_connections.get(address):
|
|
2174
|
-
return function(device, connection,
|
|
2174
|
+
return function(device, connection, *args, **kwargs)
|
|
2175
2175
|
for connection in device.connections.values():
|
|
2176
2176
|
if connection.peer_address == address:
|
|
2177
2177
|
return function(device, connection, *args, **kwargs)
|
|
@@ -6443,18 +6443,14 @@ class Device(utils.CompositeEventEmitter):
|
|
|
6443
6443
|
|
|
6444
6444
|
# [Classic only]
|
|
6445
6445
|
@host_event_handler
|
|
6446
|
-
@
|
|
6446
|
+
@with_connection_from_address
|
|
6447
6447
|
def on_role_change(
|
|
6448
6448
|
self,
|
|
6449
|
-
connection:
|
|
6450
|
-
peer_address: hci.Address,
|
|
6449
|
+
connection: Connection,
|
|
6451
6450
|
new_role: hci.Role,
|
|
6452
6451
|
):
|
|
6453
|
-
|
|
6454
|
-
|
|
6455
|
-
connection.emit(connection.EVENT_ROLE_CHANGE, new_role)
|
|
6456
|
-
else:
|
|
6457
|
-
logger.warning("Role change to unknown connection %s", peer_address)
|
|
6452
|
+
connection.role = new_role
|
|
6453
|
+
connection.emit(connection.EVENT_ROLE_CHANGE, new_role)
|
|
6458
6454
|
|
|
6459
6455
|
# [Classic only]
|
|
6460
6456
|
@host_event_handler
|
bumble/host.py
CHANGED
|
@@ -550,7 +550,7 @@ class Host(utils.EventEmitter):
|
|
|
550
550
|
logger.debug(
|
|
551
551
|
'HCI LE flow control: '
|
|
552
552
|
f'le_acl_data_packet_length={le_acl_data_packet_length},'
|
|
553
|
-
f'total_num_le_acl_data_packets={total_num_le_acl_data_packets}'
|
|
553
|
+
f'total_num_le_acl_data_packets={total_num_le_acl_data_packets},'
|
|
554
554
|
f'iso_data_packet_length={iso_data_packet_length},'
|
|
555
555
|
f'total_num_iso_data_packets={total_num_iso_data_packets}'
|
|
556
556
|
)
|
bumble/profiles/hap.py
CHANGED
|
@@ -273,12 +273,19 @@ class HearingAccessService(gatt.TemplateService):
|
|
|
273
273
|
def on_disconnection(_reason) -> None:
|
|
274
274
|
self.currently_connected_clients.discard(connection)
|
|
275
275
|
|
|
276
|
+
@connection.on(connection.EVENT_CONNECTION_ATT_MTU_UPDATE)
|
|
277
|
+
def on_mtu_update(*_: Any) -> None:
|
|
278
|
+
self.on_incoming_connection(connection)
|
|
279
|
+
|
|
280
|
+
@connection.on(connection.EVENT_CONNECTION_ENCRYPTION_CHANGE)
|
|
281
|
+
def on_encryption_change(*_: Any) -> None:
|
|
282
|
+
self.on_incoming_connection(connection)
|
|
283
|
+
|
|
276
284
|
@connection.on(connection.EVENT_PAIRING)
|
|
277
285
|
def on_pairing(*_: Any) -> None:
|
|
278
|
-
self.
|
|
286
|
+
self.on_incoming_connection(connection)
|
|
279
287
|
|
|
280
|
-
|
|
281
|
-
self.on_incoming_paired_connection(connection)
|
|
288
|
+
self.on_incoming_connection(connection)
|
|
282
289
|
|
|
283
290
|
self.hearing_aid_features_characteristic = gatt.Characteristic(
|
|
284
291
|
uuid=gatt.GATT_HEARING_AID_FEATURES_CHARACTERISTIC,
|
|
@@ -315,9 +322,30 @@ class HearingAccessService(gatt.TemplateService):
|
|
|
315
322
|
]
|
|
316
323
|
)
|
|
317
324
|
|
|
318
|
-
def
|
|
325
|
+
def on_incoming_connection(self, connection: Connection):
|
|
319
326
|
'''Setup initial operations to handle a remote bonded HAP device'''
|
|
320
327
|
# TODO Should we filter on HAP device only ?
|
|
328
|
+
|
|
329
|
+
if not connection.is_encrypted:
|
|
330
|
+
logging.debug(f'HAS: {connection.peer_address} is not encrypted')
|
|
331
|
+
return
|
|
332
|
+
|
|
333
|
+
if not connection.peer_resolvable_address:
|
|
334
|
+
logging.debug(f'HAS: {connection.peer_address} is not paired')
|
|
335
|
+
return
|
|
336
|
+
|
|
337
|
+
if connection.att_mtu < 49:
|
|
338
|
+
logging.debug(
|
|
339
|
+
f'HAS: {connection.peer_address} invalid MTU={connection.att_mtu}'
|
|
340
|
+
)
|
|
341
|
+
return
|
|
342
|
+
|
|
343
|
+
if connection.peer_address in self.currently_connected_clients:
|
|
344
|
+
logging.debug(
|
|
345
|
+
f'HAS: Already connected to {connection.peer_address} nothing to do'
|
|
346
|
+
)
|
|
347
|
+
return
|
|
348
|
+
|
|
321
349
|
self.currently_connected_clients.add(connection)
|
|
322
350
|
if (
|
|
323
351
|
connection.peer_address
|
|
@@ -457,6 +485,7 @@ class HearingAccessService(gatt.TemplateService):
|
|
|
457
485
|
connection,
|
|
458
486
|
self.hearing_aid_preset_control_point,
|
|
459
487
|
value=op_list[0].to_bytes(len(op_list) == 1),
|
|
488
|
+
force=True, # TODO GATT notification subscription should be persistent
|
|
460
489
|
)
|
|
461
490
|
# Remove item once sent, and keep the non sent item in the list
|
|
462
491
|
op_list.pop(0)
|
|
@@ -131,7 +131,11 @@ def publish_grpc_port(grpc_port: int, instance_number: int) -> bool:
|
|
|
131
131
|
|
|
132
132
|
def cleanup():
|
|
133
133
|
logger.debug("removing .ini file")
|
|
134
|
-
|
|
134
|
+
try:
|
|
135
|
+
ini_file.unlink()
|
|
136
|
+
except OSError as error:
|
|
137
|
+
# Don't log at exception level, since this may happen normally.
|
|
138
|
+
logger.debug(f'failed to remove .ini file ({error})')
|
|
135
139
|
|
|
136
140
|
atexit.register(cleanup)
|
|
137
141
|
return True
|
bumble/transport/serial.py
CHANGED
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
import asyncio
|
|
19
19
|
import logging
|
|
20
|
+
from typing import Optional
|
|
20
21
|
|
|
21
22
|
import serial_asyncio
|
|
22
23
|
|
|
@@ -28,25 +29,56 @@ from bumble.transport.common import StreamPacketSink, StreamPacketSource, Transp
|
|
|
28
29
|
logger = logging.getLogger(__name__)
|
|
29
30
|
|
|
30
31
|
|
|
32
|
+
# -----------------------------------------------------------------------------
|
|
33
|
+
# Constants
|
|
34
|
+
# -----------------------------------------------------------------------------
|
|
35
|
+
DEFAULT_POST_OPEN_DELAY = 0.5 # in seconds
|
|
36
|
+
|
|
37
|
+
# -----------------------------------------------------------------------------
|
|
38
|
+
# Classes and Functions
|
|
39
|
+
# -----------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# -----------------------------------------------------------------------------
|
|
43
|
+
class SerialPacketSource(StreamPacketSource):
|
|
44
|
+
def __init__(self) -> None:
|
|
45
|
+
super().__init__()
|
|
46
|
+
self._ready = asyncio.Event()
|
|
47
|
+
|
|
48
|
+
async def wait_until_ready(self) -> None:
|
|
49
|
+
await self._ready.wait()
|
|
50
|
+
|
|
51
|
+
def connection_made(self, transport: asyncio.BaseTransport) -> None:
|
|
52
|
+
logger.debug('connection made')
|
|
53
|
+
self._ready.set()
|
|
54
|
+
|
|
55
|
+
def connection_lost(self, exc: Optional[Exception]) -> None:
|
|
56
|
+
logger.debug('connection lost')
|
|
57
|
+
self.on_transport_lost()
|
|
58
|
+
|
|
59
|
+
|
|
31
60
|
# -----------------------------------------------------------------------------
|
|
32
61
|
async def open_serial_transport(spec: str) -> Transport:
|
|
33
62
|
'''
|
|
34
63
|
Open a serial port transport.
|
|
35
64
|
The parameter string has this syntax:
|
|
36
|
-
<device-path>[,<speed>][,rtscts][,dsrdtr]
|
|
65
|
+
<device-path>[,<speed>][,rtscts][,dsrdtr][,delay]
|
|
37
66
|
When <speed> is omitted, the default value of 1000000 is used
|
|
38
67
|
When "rtscts" is specified, RTS/CTS hardware flow control is enabled
|
|
39
68
|
When "dsrdtr" is specified, DSR/DTR hardware flow control is enabled
|
|
69
|
+
When "delay" is specified, a short delay is added after opening the port
|
|
40
70
|
|
|
41
71
|
Examples:
|
|
42
72
|
/dev/tty.usbmodem0006839912172
|
|
43
73
|
/dev/tty.usbmodem0006839912172,1000000
|
|
44
74
|
/dev/tty.usbmodem0006839912172,rtscts
|
|
75
|
+
/dev/tty.usbmodem0006839912172,rtscts,delay
|
|
45
76
|
'''
|
|
46
77
|
|
|
47
78
|
speed = 1000000
|
|
48
79
|
rtscts = False
|
|
49
80
|
dsrdtr = False
|
|
81
|
+
delay = 0.0
|
|
50
82
|
if ',' in spec:
|
|
51
83
|
parts = spec.split(',')
|
|
52
84
|
device = parts[0]
|
|
@@ -55,13 +87,16 @@ async def open_serial_transport(spec: str) -> Transport:
|
|
|
55
87
|
rtscts = True
|
|
56
88
|
elif part == 'dsrdtr':
|
|
57
89
|
dsrdtr = True
|
|
90
|
+
elif part == 'delay':
|
|
91
|
+
delay = DEFAULT_POST_OPEN_DELAY
|
|
58
92
|
elif part.isnumeric():
|
|
59
93
|
speed = int(part)
|
|
60
94
|
else:
|
|
61
95
|
device = spec
|
|
96
|
+
|
|
62
97
|
serial_transport, packet_source = await serial_asyncio.create_serial_connection(
|
|
63
98
|
asyncio.get_running_loop(),
|
|
64
|
-
|
|
99
|
+
SerialPacketSource,
|
|
65
100
|
device,
|
|
66
101
|
baudrate=speed,
|
|
67
102
|
rtscts=rtscts,
|
|
@@ -69,4 +104,23 @@ async def open_serial_transport(spec: str) -> Transport:
|
|
|
69
104
|
)
|
|
70
105
|
packet_sink = StreamPacketSink(serial_transport)
|
|
71
106
|
|
|
107
|
+
logger.debug('waiting for the port to be ready')
|
|
108
|
+
await packet_source.wait_until_ready()
|
|
109
|
+
logger.debug('port is ready')
|
|
110
|
+
|
|
111
|
+
# Try to assert DTR
|
|
112
|
+
assert serial_transport.serial is not None
|
|
113
|
+
try:
|
|
114
|
+
serial_transport.serial.dtr = True
|
|
115
|
+
logger.debug(
|
|
116
|
+
f"DSR={serial_transport.serial.dsr}, DTR={serial_transport.serial.dtr}"
|
|
117
|
+
)
|
|
118
|
+
except Exception as e:
|
|
119
|
+
logger.warning(f'could not assert DTR: {e}')
|
|
120
|
+
|
|
121
|
+
# Wait a bit after opening the port, if requested
|
|
122
|
+
if delay > 0.0:
|
|
123
|
+
logger.debug(f'waiting {delay} seconds after opening the port')
|
|
124
|
+
await asyncio.sleep(delay)
|
|
125
|
+
|
|
72
126
|
return Transport(packet_source, packet_sink)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
bumble/__init__.py,sha256=Q8jkz6rgl95IMAeInQVt_2GLoJl3DcEP2cxtrQ-ho5c,110
|
|
2
|
-
bumble/_version.py,sha256=
|
|
2
|
+
bumble/_version.py,sha256=PoO2jYBkVti2LSUuEHv8sargBSqX0YyvJ9djrfZmGJs,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=pV8krw94d42c0hml_XG8v0hSjb7DXLwgs5U2sgIbXNc,251491
|
|
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
|
|
@@ -25,7 +25,7 @@ bumble/hci.py,sha256=2yEJnR6JBtxK6ghituuXCbSalifevnTqvPvnCjyrtAo,327200
|
|
|
25
25
|
bumble/helpers.py,sha256=WFyikseIRdXUqqeOplNlmd0giOegahlXv5e324ax9ck,12611
|
|
26
26
|
bumble/hfp.py,sha256=0ktRzzRSSwGVcmw_jZlayYjvPUGhzlWZY5fVuSH6FcE,76680
|
|
27
27
|
bumble/hid.py,sha256=UCPGHw-jm4i4Akk9pXVEL8_i6EdOwaOuqv2Xd_8EhXo,21054
|
|
28
|
-
bumble/host.py,sha256=
|
|
28
|
+
bumble/host.py,sha256=46fwcskNlfHyW8Ejo5wp8rHtMBZSMkR4URSdekKLPzg,68019
|
|
29
29
|
bumble/keys.py,sha256=VCOrtuw-xF_4Oa5Qt-ECRKaTqabL_GbwdQUKoZX20II,13416
|
|
30
30
|
bumble/l2cap.py,sha256=PZQnZQFB_GJZCCFuPpAsTuYz4E3WTgimDUAk83DUUtE,80758
|
|
31
31
|
bumble/link.py,sha256=O-T9fCJokvpLpTvIMAboEQbT3Sjg8L2ivSWSBH43fP0,14470
|
|
@@ -100,7 +100,7 @@ bumble/profiles/device_information_service.py,sha256=oQ4bWPq-LxlJth4H39H8xc06ulj
|
|
|
100
100
|
bumble/profiles/gap.py,sha256=Fd-J2_d6TdWDyBPDmvEykQPYzkE_T9UGNoiP5uQ6FJg,4026
|
|
101
101
|
bumble/profiles/gatt_service.py,sha256=WVAuW9q-01jmpjpUVG7Gs4vZE_CSLAo51FSK5HDE4tA,6697
|
|
102
102
|
bumble/profiles/gmap.py,sha256=jNsPobH_lSDZQ4-jwlDRhNfpPWPsXcWFJbCCXGTWZQk,7327
|
|
103
|
-
bumble/profiles/hap.py,sha256=
|
|
103
|
+
bumble/profiles/hap.py,sha256=yU-G12ykmj6NVD4f5M1IHV9FAiG83Cy7Dx-3nkI_rzY,26536
|
|
104
104
|
bumble/profiles/heart_rate_service.py,sha256=VB2CKSG2p5GDb5C_q1elpwzKEIIR7slrJfgf4kdTu30,9252
|
|
105
105
|
bumble/profiles/le_audio.py,sha256=w8Ui2AKvt_tDpRXY8AZjlYR-P90caRahBWM3KJ97nRw,5829
|
|
106
106
|
bumble/profiles/mcp.py,sha256=gWB8FqVi7wA8zBsPrh__p_57u4EHwVhA10_YdJXR40c,17763
|
|
@@ -118,14 +118,14 @@ bumble/tools/rtk_fw_download.py,sha256=kuJ2q-75Troc9hCrow0q5zKSMsVhocMeWHKvfdg6H
|
|
|
118
118
|
bumble/tools/rtk_util.py,sha256=4kdaHON_pg2HElzBRaStolqvEJVWPd0eZPUyAQWAqxc,5726
|
|
119
119
|
bumble/transport/__init__.py,sha256=Dk84_3nAC24jY5zcCWVhjC2RxjJahKTz4zChygAqlvs,7027
|
|
120
120
|
bumble/transport/android_emulator.py,sha256=axEdFBj17c0dOD5lMqJjiULInG_SQVx5W7ptjyLtRJs,4281
|
|
121
|
-
bumble/transport/android_netsim.py,sha256=
|
|
121
|
+
bumble/transport/android_netsim.py,sha256=8C2kUITCl7L1ggl5FPwWcFq4It8e9O3esEpMjRaYkkw,17563
|
|
122
122
|
bumble/transport/common.py,sha256=C0wurvCvcEX4r6F0cWbD2x1GhamJwJoyYmYJ21pU04Q,16770
|
|
123
123
|
bumble/transport/file.py,sha256=aqJD5US5TVl01dOb42rV_0OzuvFsBDDlqzipyrYA4q4,2026
|
|
124
124
|
bumble/transport/hci_socket.py,sha256=2PKQ43oDjayKDklx9sF98hSeyNmvTSUOWx_ooPWTjd0,6345
|
|
125
125
|
bumble/transport/pty.py,sha256=yzItc5ZO7WkHZKnAeEK-1XEyY4BWot4ZAMFzQvRiSQ4,2747
|
|
126
126
|
bumble/transport/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
127
127
|
bumble/transport/pyusb.py,sha256=x1uXCVSs-h0dxhOuJ60RkmuuYrcTrxDngFkW8cWEPc4,16187
|
|
128
|
-
bumble/transport/serial.py,sha256=
|
|
128
|
+
bumble/transport/serial.py,sha256=lQsdpv3VHKJwrAgHWnft2pNEzevEHHVutA2SvQNSCpY,4343
|
|
129
129
|
bumble/transport/tcp_client.py,sha256=YM7Y9CN0fBSGSb9dPiOAXAUC9R1fRRwYG4HiP2rvDyc,1883
|
|
130
130
|
bumble/transport/tcp_server.py,sha256=7ZPk097pKbMJBvyTRSrJXla4RDU6SBJ-DeQmSK54mHM,3755
|
|
131
131
|
bumble/transport/udp.py,sha256=_3mePVr9ALzZbOfnlMwcaaMnnLkd5kxhw5-BxkeCSMU,2281
|
|
@@ -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.217.dist-info/licenses/LICENSE,sha256=FvaYh4NRWIGgS_OwoBs5gFgkCmAghZ-DYnIGBZPuw-s,12142
|
|
179
|
+
bumble-0.0.217.dist-info/METADATA,sha256=Mdy5v7BSROxcolAFXgbeSX1fX0lOAQW319HWJNcwicg,6155
|
|
180
|
+
bumble-0.0.217.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
181
|
+
bumble-0.0.217.dist-info/entry_points.txt,sha256=mX5dzixNMRo4CTAEQqiYTr-JIaWF62TYrRvJOstjjL8,1081
|
|
182
|
+
bumble-0.0.217.dist-info/top_level.txt,sha256=tV6JJKaHPYMFiJYiBYFW24PCcfLxTJZdlu6BmH3Cb00,7
|
|
183
|
+
bumble-0.0.217.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|