bumble 0.0.211__py3-none-any.whl → 0.0.213__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/a2dp.py +6 -0
- bumble/apps/README.md +0 -3
- bumble/apps/auracast.py +11 -9
- bumble/apps/bench.py +482 -31
- bumble/apps/console.py +5 -5
- bumble/apps/controller_info.py +47 -10
- bumble/apps/controller_loopback.py +7 -3
- bumble/apps/controllers.py +2 -2
- bumble/apps/device_info.py +2 -2
- bumble/apps/gatt_dump.py +2 -2
- bumble/apps/gg_bridge.py +2 -2
- bumble/apps/hci_bridge.py +2 -2
- bumble/apps/l2cap_bridge.py +2 -2
- bumble/apps/lea_unicast/app.py +6 -1
- bumble/apps/pair.py +204 -43
- bumble/apps/pandora_server.py +2 -2
- bumble/apps/rfcomm_bridge.py +1 -1
- bumble/apps/scan.py +2 -2
- bumble/apps/show.py +4 -2
- bumble/apps/speaker/speaker.html +1 -0
- bumble/apps/speaker/speaker.js +113 -62
- bumble/apps/speaker/speaker.py +126 -18
- bumble/at.py +4 -4
- bumble/att.py +15 -18
- bumble/avc.py +7 -7
- bumble/avctp.py +5 -5
- bumble/avdtp.py +138 -88
- bumble/avrcp.py +52 -58
- bumble/colors.py +2 -2
- bumble/controller.py +84 -23
- bumble/core.py +13 -7
- bumble/{crypto.py → crypto/__init__.py} +11 -95
- bumble/crypto/builtin.py +652 -0
- bumble/crypto/cryptography.py +84 -0
- bumble/device.py +688 -345
- bumble/drivers/__init__.py +2 -2
- bumble/drivers/common.py +0 -2
- bumble/drivers/intel.py +40 -40
- bumble/drivers/rtk.py +28 -35
- bumble/gatt.py +7 -9
- bumble/gatt_adapters.py +4 -5
- bumble/gatt_client.py +31 -34
- bumble/gatt_server.py +15 -17
- bumble/hci.py +2635 -2878
- bumble/helpers.py +4 -5
- bumble/hfp.py +76 -57
- bumble/hid.py +24 -12
- bumble/host.py +117 -34
- bumble/keys.py +68 -52
- bumble/l2cap.py +329 -403
- bumble/link.py +6 -270
- bumble/pairing.py +23 -20
- bumble/pandora/__init__.py +1 -1
- bumble/pandora/config.py +2 -2
- bumble/pandora/device.py +6 -6
- bumble/pandora/host.py +38 -39
- bumble/pandora/l2cap.py +4 -4
- bumble/pandora/security.py +73 -57
- bumble/pandora/utils.py +3 -3
- bumble/profiles/aics.py +3 -5
- bumble/profiles/ancs.py +3 -1
- bumble/profiles/ascs.py +143 -136
- bumble/profiles/asha.py +13 -8
- bumble/profiles/bap.py +3 -4
- bumble/profiles/csip.py +3 -5
- bumble/profiles/device_information_service.py +2 -2
- bumble/profiles/gap.py +2 -2
- bumble/profiles/gatt_service.py +1 -3
- bumble/profiles/hap.py +42 -58
- bumble/profiles/le_audio.py +4 -4
- bumble/profiles/mcp.py +16 -13
- bumble/profiles/vcs.py +8 -10
- bumble/profiles/vocs.py +6 -9
- bumble/rfcomm.py +27 -18
- bumble/rtp.py +1 -2
- bumble/sdp.py +2 -2
- bumble/smp.py +71 -69
- bumble/tools/rtk_util.py +2 -2
- bumble/transport/__init__.py +2 -16
- bumble/transport/android_netsim.py +5 -5
- bumble/transport/common.py +4 -4
- bumble/transport/pyusb.py +2 -2
- bumble/utils.py +2 -5
- bumble/vendor/android/hci.py +118 -200
- bumble/vendor/zephyr/hci.py +32 -27
- {bumble-0.0.211.dist-info → bumble-0.0.213.dist-info}/METADATA +5 -5
- {bumble-0.0.211.dist-info → bumble-0.0.213.dist-info}/RECORD +92 -93
- {bumble-0.0.211.dist-info → bumble-0.0.213.dist-info}/WHEEL +1 -1
- {bumble-0.0.211.dist-info → bumble-0.0.213.dist-info}/entry_points.txt +0 -1
- bumble/apps/link_relay/__init__.py +0 -0
- bumble/apps/link_relay/link_relay.py +0 -289
- bumble/apps/link_relay/logging.yml +0 -21
- {bumble-0.0.211.dist-info → bumble-0.0.213.dist-info}/licenses/LICENSE +0 -0
- {bumble-0.0.211.dist-info → bumble-0.0.213.dist-info}/top_level.txt +0 -0
bumble/apps/console.py
CHANGED
|
@@ -55,7 +55,7 @@ from prompt_toolkit.layout import (
|
|
|
55
55
|
from bumble import __version__
|
|
56
56
|
import bumble.core
|
|
57
57
|
from bumble import colors
|
|
58
|
-
from bumble.core import UUID, AdvertisingData
|
|
58
|
+
from bumble.core import UUID, AdvertisingData
|
|
59
59
|
from bumble.device import (
|
|
60
60
|
ConnectionParametersPreferences,
|
|
61
61
|
ConnectionPHY,
|
|
@@ -64,7 +64,7 @@ from bumble.device import (
|
|
|
64
64
|
Peer,
|
|
65
65
|
)
|
|
66
66
|
from bumble.utils import AsyncRunner
|
|
67
|
-
from bumble.transport import
|
|
67
|
+
from bumble.transport import open_transport
|
|
68
68
|
from bumble.gatt import Characteristic, Service, CharacteristicDeclaration, Descriptor
|
|
69
69
|
from bumble.gatt_client import CharacteristicProxy
|
|
70
70
|
from bumble.hci import (
|
|
@@ -291,7 +291,7 @@ class ConsoleApp:
|
|
|
291
291
|
async def run_async(self, device_config, transport):
|
|
292
292
|
rssi_monitoring_task = asyncio.create_task(self.rssi_monitor_loop())
|
|
293
293
|
|
|
294
|
-
async with await
|
|
294
|
+
async with await open_transport(transport) as (hci_source, hci_sink):
|
|
295
295
|
if device_config:
|
|
296
296
|
self.device = Device.from_config_file_with_hci(
|
|
297
297
|
device_config, hci_source, hci_sink
|
|
@@ -335,9 +335,9 @@ class ConsoleApp:
|
|
|
335
335
|
elif self.connected_peer:
|
|
336
336
|
connection = self.connected_peer.connection
|
|
337
337
|
connection_parameters = (
|
|
338
|
-
f'{connection.parameters.connection_interval}/'
|
|
338
|
+
f'{connection.parameters.connection_interval:.2f}/'
|
|
339
339
|
f'{connection.parameters.peripheral_latency}/'
|
|
340
|
-
f'{connection.parameters.supervision_timeout}'
|
|
340
|
+
f'{connection.parameters.supervision_timeout:.2f}'
|
|
341
341
|
)
|
|
342
342
|
if self.connection_phy is not None:
|
|
343
343
|
phy_state = (
|
bumble/apps/controller_info.py
CHANGED
|
@@ -58,7 +58,7 @@ from bumble.hci import (
|
|
|
58
58
|
HCI_Read_Local_Version_Information_Command,
|
|
59
59
|
)
|
|
60
60
|
from bumble.host import Host
|
|
61
|
-
from bumble.transport import
|
|
61
|
+
from bumble.transport import open_transport
|
|
62
62
|
|
|
63
63
|
|
|
64
64
|
# -----------------------------------------------------------------------------
|
|
@@ -242,28 +242,43 @@ async def get_codecs_info(host: Host) -> None:
|
|
|
242
242
|
|
|
243
243
|
|
|
244
244
|
# -----------------------------------------------------------------------------
|
|
245
|
-
async def async_main(
|
|
245
|
+
async def async_main(
|
|
246
|
+
latency_probes, latency_probe_interval, latency_probe_command, transport
|
|
247
|
+
):
|
|
246
248
|
print('<<< connecting to HCI...')
|
|
247
|
-
async with await
|
|
249
|
+
async with await open_transport(transport) as (hci_source, hci_sink):
|
|
248
250
|
print('<<< connected')
|
|
249
251
|
|
|
250
252
|
host = Host(hci_source, hci_sink)
|
|
251
253
|
await host.reset()
|
|
252
254
|
|
|
253
255
|
# Measure the latency if requested
|
|
256
|
+
# (we add an extra probe at the start, that we ignore, just to ensure that
|
|
257
|
+
# the transport is primed)
|
|
254
258
|
latencies = []
|
|
255
259
|
if latency_probes:
|
|
256
|
-
|
|
260
|
+
if latency_probe_command:
|
|
261
|
+
probe_hci_command = HCI_Command.from_bytes(
|
|
262
|
+
bytes.fromhex(latency_probe_command)
|
|
263
|
+
)
|
|
264
|
+
else:
|
|
265
|
+
probe_hci_command = HCI_Read_Local_Version_Information_Command()
|
|
266
|
+
|
|
267
|
+
for iteration in range(1 + latency_probes):
|
|
268
|
+
if latency_probe_interval:
|
|
269
|
+
await asyncio.sleep(latency_probe_interval / 1000)
|
|
257
270
|
start = time.time()
|
|
258
|
-
await host.send_command(
|
|
259
|
-
|
|
271
|
+
await host.send_command(probe_hci_command)
|
|
272
|
+
if iteration:
|
|
273
|
+
latencies.append(1000 * (time.time() - start))
|
|
260
274
|
print(
|
|
261
275
|
color('HCI Command Latency:', 'yellow'),
|
|
262
276
|
(
|
|
263
277
|
f'min={min(latencies):.2f}, '
|
|
264
278
|
f'max={max(latencies):.2f}, '
|
|
265
|
-
f'average={sum(latencies)/len(latencies):.2f}'
|
|
279
|
+
f'average={sum(latencies)/len(latencies):.2f},'
|
|
266
280
|
),
|
|
281
|
+
[f'{latency:.4}' for latency in latencies],
|
|
267
282
|
'\n',
|
|
268
283
|
)
|
|
269
284
|
|
|
@@ -311,10 +326,32 @@ async def async_main(latency_probes, transport):
|
|
|
311
326
|
type=int,
|
|
312
327
|
help='Send N commands to measure HCI transport latency statistics',
|
|
313
328
|
)
|
|
329
|
+
@click.option(
|
|
330
|
+
'--latency-probe-interval',
|
|
331
|
+
metavar='INTERVAL',
|
|
332
|
+
type=int,
|
|
333
|
+
help='Interval between latency probes (milliseconds)',
|
|
334
|
+
)
|
|
335
|
+
@click.option(
|
|
336
|
+
'--latency-probe-command',
|
|
337
|
+
metavar='COMMAND_HEX',
|
|
338
|
+
help=(
|
|
339
|
+
'Probe command (HCI Command packet bytes, in hex. Use 0177FC00 for'
|
|
340
|
+
' a loopback test with the HCI remote proxy app)'
|
|
341
|
+
),
|
|
342
|
+
)
|
|
314
343
|
@click.argument('transport')
|
|
315
|
-
def main(latency_probes, transport):
|
|
316
|
-
logging.basicConfig(
|
|
317
|
-
|
|
344
|
+
def main(latency_probes, latency_probe_interval, latency_probe_command, transport):
|
|
345
|
+
logging.basicConfig(
|
|
346
|
+
level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper(),
|
|
347
|
+
format="[%(asctime)s.%(msecs)03d] %(levelname)s:%(name)s:%(message)s",
|
|
348
|
+
datefmt="%H:%M:%S",
|
|
349
|
+
)
|
|
350
|
+
asyncio.run(
|
|
351
|
+
async_main(
|
|
352
|
+
latency_probes, latency_probe_interval, latency_probe_command, transport
|
|
353
|
+
)
|
|
354
|
+
)
|
|
318
355
|
|
|
319
356
|
|
|
320
357
|
# -----------------------------------------------------------------------------
|
|
@@ -29,7 +29,7 @@ from bumble.hci import (
|
|
|
29
29
|
LoopbackMode,
|
|
30
30
|
)
|
|
31
31
|
from bumble.host import Host
|
|
32
|
-
from bumble.transport import
|
|
32
|
+
from bumble.transport import open_transport
|
|
33
33
|
import click
|
|
34
34
|
|
|
35
35
|
|
|
@@ -88,7 +88,7 @@ class Loopback:
|
|
|
88
88
|
async def run(self):
|
|
89
89
|
"""Run a loopback throughput test"""
|
|
90
90
|
print(color('>>> Connecting to HCI...', 'green'))
|
|
91
|
-
async with await
|
|
91
|
+
async with await open_transport(self.transport) as (
|
|
92
92
|
hci_source,
|
|
93
93
|
hci_sink,
|
|
94
94
|
):
|
|
@@ -194,7 +194,11 @@ class Loopback:
|
|
|
194
194
|
)
|
|
195
195
|
@click.argument('transport')
|
|
196
196
|
def main(packet_size, packet_count, transport):
|
|
197
|
-
logging.basicConfig(
|
|
197
|
+
logging.basicConfig(
|
|
198
|
+
level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper(),
|
|
199
|
+
format="[%(asctime)s.%(msecs)03d] %(levelname)s:%(name)s:%(message)s",
|
|
200
|
+
datefmt="%H:%M:%S",
|
|
201
|
+
)
|
|
198
202
|
|
|
199
203
|
loopback = Loopback(packet_size, packet_count, transport)
|
|
200
204
|
asyncio.run(loopback.run())
|
bumble/apps/controllers.py
CHANGED
|
@@ -22,7 +22,7 @@ import os
|
|
|
22
22
|
|
|
23
23
|
from bumble.controller import Controller
|
|
24
24
|
from bumble.link import LocalLink
|
|
25
|
-
from bumble.transport import
|
|
25
|
+
from bumble.transport import open_transport
|
|
26
26
|
|
|
27
27
|
|
|
28
28
|
# -----------------------------------------------------------------------------
|
|
@@ -42,7 +42,7 @@ async def async_main():
|
|
|
42
42
|
transports = []
|
|
43
43
|
controllers = []
|
|
44
44
|
for index, transport_name in enumerate(sys.argv[1:]):
|
|
45
|
-
transport = await
|
|
45
|
+
transport = await open_transport(transport_name)
|
|
46
46
|
transports.append(transport)
|
|
47
47
|
controller = Controller(
|
|
48
48
|
f'C{index}',
|
bumble/apps/device_info.py
CHANGED
|
@@ -32,7 +32,7 @@ from bumble.profiles.gap import GenericAccessServiceProxy
|
|
|
32
32
|
from bumble.profiles.pacs import PublishedAudioCapabilitiesServiceProxy
|
|
33
33
|
from bumble.profiles.tmap import TelephonyAndMediaAudioServiceProxy
|
|
34
34
|
from bumble.profiles.vcs import VolumeControlServiceProxy
|
|
35
|
-
from bumble.transport import
|
|
35
|
+
from bumble.transport import open_transport
|
|
36
36
|
|
|
37
37
|
|
|
38
38
|
# -----------------------------------------------------------------------------
|
|
@@ -215,7 +215,7 @@ async def show_device_info(peer, done: Optional[asyncio.Future]) -> None:
|
|
|
215
215
|
|
|
216
216
|
# -----------------------------------------------------------------------------
|
|
217
217
|
async def async_main(device_config, encrypt, transport, address_or_name):
|
|
218
|
-
async with await
|
|
218
|
+
async with await open_transport(transport) as (hci_source, hci_sink):
|
|
219
219
|
|
|
220
220
|
# Create a device
|
|
221
221
|
if device_config:
|
bumble/apps/gatt_dump.py
CHANGED
|
@@ -24,7 +24,7 @@ import bumble.core
|
|
|
24
24
|
from bumble.colors import color
|
|
25
25
|
from bumble.device import Device, Peer
|
|
26
26
|
from bumble.gatt import show_services
|
|
27
|
-
from bumble.transport import
|
|
27
|
+
from bumble.transport import open_transport
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
# -----------------------------------------------------------------------------
|
|
@@ -60,7 +60,7 @@ async def dump_gatt_db(peer, done):
|
|
|
60
60
|
|
|
61
61
|
# -----------------------------------------------------------------------------
|
|
62
62
|
async def async_main(device_config, encrypt, transport, address_or_name):
|
|
63
|
-
async with await
|
|
63
|
+
async with await open_transport(transport) as (hci_source, hci_sink):
|
|
64
64
|
|
|
65
65
|
# Create a device
|
|
66
66
|
if device_config:
|
bumble/apps/gg_bridge.py
CHANGED
|
@@ -27,7 +27,7 @@ from bumble.device import Device, Peer
|
|
|
27
27
|
from bumble.core import AdvertisingData
|
|
28
28
|
from bumble.gatt import Service, Characteristic, CharacteristicValue
|
|
29
29
|
from bumble.utils import AsyncRunner
|
|
30
|
-
from bumble.transport import
|
|
30
|
+
from bumble.transport import open_transport
|
|
31
31
|
from bumble.hci import HCI_Constant
|
|
32
32
|
|
|
33
33
|
|
|
@@ -325,7 +325,7 @@ async def run(
|
|
|
325
325
|
receive_port,
|
|
326
326
|
):
|
|
327
327
|
print('<<< connecting to HCI...')
|
|
328
|
-
async with await
|
|
328
|
+
async with await open_transport(hci_transport) as (hci_source, hci_sink):
|
|
329
329
|
print('<<< connected')
|
|
330
330
|
|
|
331
331
|
# Instantiate a bridge object
|
bumble/apps/hci_bridge.py
CHANGED
|
@@ -46,14 +46,14 @@ async def async_main():
|
|
|
46
46
|
return
|
|
47
47
|
|
|
48
48
|
print('>>> connecting to HCI...')
|
|
49
|
-
async with await transport.
|
|
49
|
+
async with await transport.open_transport(sys.argv[1]) as (
|
|
50
50
|
hci_host_source,
|
|
51
51
|
hci_host_sink,
|
|
52
52
|
):
|
|
53
53
|
print('>>> connected')
|
|
54
54
|
|
|
55
55
|
print('>>> connecting to HCI...')
|
|
56
|
-
async with await transport.
|
|
56
|
+
async with await transport.open_transport(sys.argv[2]) as (
|
|
57
57
|
hci_controller_source,
|
|
58
58
|
hci_controller_sink,
|
|
59
59
|
):
|
bumble/apps/l2cap_bridge.py
CHANGED
|
@@ -22,7 +22,7 @@ import click
|
|
|
22
22
|
|
|
23
23
|
from bumble import l2cap
|
|
24
24
|
from bumble.colors import color
|
|
25
|
-
from bumble.transport import
|
|
25
|
+
from bumble.transport import open_transport
|
|
26
26
|
from bumble.device import Device
|
|
27
27
|
from bumble.utils import FlowControlAsyncPipe
|
|
28
28
|
from bumble.hci import HCI_Constant
|
|
@@ -258,7 +258,7 @@ class ClientBridge:
|
|
|
258
258
|
# -----------------------------------------------------------------------------
|
|
259
259
|
async def run(device_config, hci_transport, bridge):
|
|
260
260
|
print('<<< connecting to HCI...')
|
|
261
|
-
async with await
|
|
261
|
+
async with await open_transport(hci_transport) as (hci_source, hci_sink):
|
|
262
262
|
print('<<< connected')
|
|
263
263
|
|
|
264
264
|
device = Device.from_config_file_with_hci(device_config, hci_source, hci_sink)
|
bumble/apps/lea_unicast/app.py
CHANGED
|
@@ -337,7 +337,12 @@ class Speaker:
|
|
|
337
337
|
),
|
|
338
338
|
(
|
|
339
339
|
AdvertisingData.FLAGS,
|
|
340
|
-
bytes(
|
|
340
|
+
bytes(
|
|
341
|
+
[
|
|
342
|
+
AdvertisingData.LE_GENERAL_DISCOVERABLE_MODE_FLAG
|
|
343
|
+
| AdvertisingData.BR_EDR_NOT_SUPPORTED_FLAG
|
|
344
|
+
]
|
|
345
|
+
),
|
|
341
346
|
),
|
|
342
347
|
(
|
|
343
348
|
AdvertisingData.INCOMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS,
|