bumble 0.0.213__py3-none-any.whl → 0.0.214__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/apps/auracast.py +3 -2
- bumble/apps/bench.py +2 -6
- bumble/apps/controller_info.py +2 -7
- bumble/apps/controller_loopback.py +5 -9
- bumble/apps/controllers.py +2 -3
- bumble/apps/device_info.py +2 -3
- bumble/apps/gatt_dump.py +3 -3
- bumble/apps/gg_bridge.py +3 -3
- bumble/apps/hci_bridge.py +3 -2
- bumble/apps/l2cap_bridge.py +3 -3
- bumble/apps/lea_unicast/app.py +2 -2
- bumble/apps/player/player.py +2 -3
- bumble/apps/rfcomm_bridge.py +2 -3
- bumble/apps/scan.py +2 -3
- bumble/apps/show.py +2 -2
- bumble/apps/speaker/speaker.py +2 -6
- bumble/apps/unbond.py +2 -3
- bumble/apps/usb_probe.py +2 -3
- bumble/avrcp.py +1 -1
- bumble/controller.py +90 -22
- bumble/device.py +55 -5
- bumble/hci.py +47 -0
- bumble/host.py +10 -0
- bumble/l2cap.py +17 -30
- bumble/link.py +10 -10
- bumble/logging.py +65 -0
- bumble/pandora/__init__.py +1 -1
- bumble/profiles/ams.py +404 -0
- bumble/profiles/ascs.py +10 -0
- bumble/smp.py +9 -6
- bumble/tools/intel_util.py +3 -2
- bumble/tools/rtk_util.py +4 -3
- {bumble-0.0.213.dist-info → bumble-0.0.214.dist-info}/METADATA +3 -2
- {bumble-0.0.213.dist-info → bumble-0.0.214.dist-info}/RECORD +39 -37
- {bumble-0.0.213.dist-info → bumble-0.0.214.dist-info}/WHEEL +0 -0
- {bumble-0.0.213.dist-info → bumble-0.0.214.dist-info}/entry_points.txt +0 -0
- {bumble-0.0.213.dist-info → bumble-0.0.214.dist-info}/licenses/LICENSE +0 -0
- {bumble-0.0.213.dist-info → bumble-0.0.214.dist-info}/top_level.txt +0 -0
bumble/_version.py
CHANGED
bumble/apps/auracast.py
CHANGED
|
@@ -23,7 +23,6 @@ import contextlib
|
|
|
23
23
|
import dataclasses
|
|
24
24
|
import functools
|
|
25
25
|
import logging
|
|
26
|
-
import os
|
|
27
26
|
import struct
|
|
28
27
|
from typing import (
|
|
29
28
|
Any,
|
|
@@ -54,6 +53,8 @@ from bumble.profiles import bass
|
|
|
54
53
|
import bumble.device
|
|
55
54
|
import bumble.transport
|
|
56
55
|
import bumble.utils
|
|
56
|
+
import bumble.logging
|
|
57
|
+
|
|
57
58
|
|
|
58
59
|
# -----------------------------------------------------------------------------
|
|
59
60
|
# Logging
|
|
@@ -1235,7 +1236,7 @@ def transmit(
|
|
|
1235
1236
|
|
|
1236
1237
|
|
|
1237
1238
|
def main():
|
|
1238
|
-
logging.
|
|
1239
|
+
bumble.logging.setup_basic_logging()
|
|
1239
1240
|
auracast()
|
|
1240
1241
|
|
|
1241
1242
|
|
bumble/apps/bench.py
CHANGED
|
@@ -19,7 +19,6 @@ import asyncio
|
|
|
19
19
|
import dataclasses
|
|
20
20
|
import enum
|
|
21
21
|
import logging
|
|
22
|
-
import os
|
|
23
22
|
import statistics
|
|
24
23
|
import struct
|
|
25
24
|
import time
|
|
@@ -70,6 +69,7 @@ import bumble.rfcomm
|
|
|
70
69
|
import bumble.core
|
|
71
70
|
from bumble.utils import AsyncRunner
|
|
72
71
|
from bumble.pairing import PairingConfig
|
|
72
|
+
import bumble.logging
|
|
73
73
|
|
|
74
74
|
|
|
75
75
|
# -----------------------------------------------------------------------------
|
|
@@ -2321,11 +2321,7 @@ def peripheral(ctx, transport):
|
|
|
2321
2321
|
|
|
2322
2322
|
|
|
2323
2323
|
def main():
|
|
2324
|
-
logging.
|
|
2325
|
-
level=os.environ.get('BUMBLE_LOGLEVEL', 'INFO').upper(),
|
|
2326
|
-
format="[%(asctime)s.%(msecs)03d] %(levelname)s:%(name)s:%(message)s",
|
|
2327
|
-
datefmt="%H:%M:%S",
|
|
2328
|
-
)
|
|
2324
|
+
bumble.logging.setup_basic_logging('INFO')
|
|
2329
2325
|
bench()
|
|
2330
2326
|
|
|
2331
2327
|
|
bumble/apps/controller_info.py
CHANGED
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
# Imports
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
import asyncio
|
|
19
|
-
import os
|
|
20
|
-
import logging
|
|
21
19
|
import time
|
|
22
20
|
|
|
23
21
|
import click
|
|
@@ -59,6 +57,7 @@ from bumble.hci import (
|
|
|
59
57
|
)
|
|
60
58
|
from bumble.host import Host
|
|
61
59
|
from bumble.transport import open_transport
|
|
60
|
+
import bumble.logging
|
|
62
61
|
|
|
63
62
|
|
|
64
63
|
# -----------------------------------------------------------------------------
|
|
@@ -342,11 +341,7 @@ async def async_main(
|
|
|
342
341
|
)
|
|
343
342
|
@click.argument('transport')
|
|
344
343
|
def main(latency_probes, latency_probe_interval, latency_probe_command, transport):
|
|
345
|
-
logging.
|
|
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
|
-
)
|
|
344
|
+
bumble.logging.setup_basic_logging()
|
|
350
345
|
asyncio.run(
|
|
351
346
|
async_main(
|
|
352
347
|
latency_probes, latency_probe_interval, latency_probe_command, transport
|
|
@@ -16,10 +16,11 @@
|
|
|
16
16
|
# Imports
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
import asyncio
|
|
19
|
-
import logging
|
|
20
|
-
import os
|
|
21
19
|
import time
|
|
22
20
|
from typing import Optional
|
|
21
|
+
|
|
22
|
+
import click
|
|
23
|
+
|
|
23
24
|
from bumble.colors import color
|
|
24
25
|
from bumble.hci import (
|
|
25
26
|
HCI_READ_LOOPBACK_MODE_COMMAND,
|
|
@@ -30,7 +31,7 @@ from bumble.hci import (
|
|
|
30
31
|
)
|
|
31
32
|
from bumble.host import Host
|
|
32
33
|
from bumble.transport import open_transport
|
|
33
|
-
import
|
|
34
|
+
import bumble.logging
|
|
34
35
|
|
|
35
36
|
|
|
36
37
|
class Loopback:
|
|
@@ -194,12 +195,7 @@ class Loopback:
|
|
|
194
195
|
)
|
|
195
196
|
@click.argument('transport')
|
|
196
197
|
def main(packet_size, packet_count, transport):
|
|
197
|
-
logging.
|
|
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
|
-
)
|
|
202
|
-
|
|
198
|
+
bumble.logging.setup_basic_logging()
|
|
203
199
|
loopback = Loopback(packet_size, packet_count, transport)
|
|
204
200
|
asyncio.run(loopback.run())
|
|
205
201
|
|
bumble/apps/controllers.py
CHANGED
|
@@ -15,14 +15,13 @@
|
|
|
15
15
|
# -----------------------------------------------------------------------------
|
|
16
16
|
# Imports
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
|
-
import logging
|
|
19
18
|
import asyncio
|
|
20
19
|
import sys
|
|
21
|
-
import os
|
|
22
20
|
|
|
23
21
|
from bumble.controller import Controller
|
|
24
22
|
from bumble.link import LocalLink
|
|
25
23
|
from bumble.transport import open_transport
|
|
24
|
+
import bumble.logging
|
|
26
25
|
|
|
27
26
|
|
|
28
27
|
# -----------------------------------------------------------------------------
|
|
@@ -62,7 +61,7 @@ async def async_main():
|
|
|
62
61
|
|
|
63
62
|
# -----------------------------------------------------------------------------
|
|
64
63
|
def main():
|
|
65
|
-
logging.
|
|
64
|
+
bumble.logging.setup_basic_logging()
|
|
66
65
|
asyncio.run(async_main())
|
|
67
66
|
|
|
68
67
|
|
bumble/apps/device_info.py
CHANGED
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
# Imports
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
import asyncio
|
|
19
|
-
import os
|
|
20
|
-
import logging
|
|
21
19
|
from typing import Callable, Iterable, Optional
|
|
22
20
|
|
|
23
21
|
import click
|
|
@@ -33,6 +31,7 @@ from bumble.profiles.pacs import PublishedAudioCapabilitiesServiceProxy
|
|
|
33
31
|
from bumble.profiles.tmap import TelephonyAndMediaAudioServiceProxy
|
|
34
32
|
from bumble.profiles.vcs import VolumeControlServiceProxy
|
|
35
33
|
from bumble.transport import open_transport
|
|
34
|
+
import bumble.logging
|
|
36
35
|
|
|
37
36
|
|
|
38
37
|
# -----------------------------------------------------------------------------
|
|
@@ -267,7 +266,7 @@ def main(device_config, encrypt, transport, address_or_name):
|
|
|
267
266
|
Dump the GATT database on a remote device. If ADDRESS_OR_NAME is not specified,
|
|
268
267
|
wait for an incoming connection.
|
|
269
268
|
"""
|
|
270
|
-
logging.
|
|
269
|
+
bumble.logging.setup_basic_logging()
|
|
271
270
|
asyncio.run(async_main(device_config, encrypt, transport, address_or_name))
|
|
272
271
|
|
|
273
272
|
|
bumble/apps/gatt_dump.py
CHANGED
|
@@ -16,8 +16,7 @@
|
|
|
16
16
|
# Imports
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
import asyncio
|
|
19
|
-
|
|
20
|
-
import logging
|
|
19
|
+
|
|
21
20
|
import click
|
|
22
21
|
|
|
23
22
|
import bumble.core
|
|
@@ -25,6 +24,7 @@ from bumble.colors import color
|
|
|
25
24
|
from bumble.device import Device, Peer
|
|
26
25
|
from bumble.gatt import show_services
|
|
27
26
|
from bumble.transport import open_transport
|
|
27
|
+
import bumble.logging
|
|
28
28
|
|
|
29
29
|
|
|
30
30
|
# -----------------------------------------------------------------------------
|
|
@@ -112,7 +112,7 @@ def main(device_config, encrypt, transport, address_or_name):
|
|
|
112
112
|
Dump the GATT database on a remote device. If ADDRESS_OR_NAME is not specified,
|
|
113
113
|
wait for an incoming connection.
|
|
114
114
|
"""
|
|
115
|
-
logging.
|
|
115
|
+
bumble.logging.setup_basic_logging()
|
|
116
116
|
asyncio.run(async_main(device_config, encrypt, transport, address_or_name))
|
|
117
117
|
|
|
118
118
|
|
bumble/apps/gg_bridge.py
CHANGED
|
@@ -16,9 +16,8 @@
|
|
|
16
16
|
# Imports
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
import asyncio
|
|
19
|
-
import os
|
|
20
19
|
import struct
|
|
21
|
-
|
|
20
|
+
|
|
22
21
|
import click
|
|
23
22
|
|
|
24
23
|
from bumble import l2cap
|
|
@@ -29,6 +28,7 @@ from bumble.gatt import Service, Characteristic, CharacteristicValue
|
|
|
29
28
|
from bumble.utils import AsyncRunner
|
|
30
29
|
from bumble.transport import open_transport
|
|
31
30
|
from bumble.hci import HCI_Constant
|
|
31
|
+
import bumble.logging
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
# -----------------------------------------------------------------------------
|
|
@@ -383,6 +383,7 @@ def main(
|
|
|
383
383
|
receive_host,
|
|
384
384
|
receive_port,
|
|
385
385
|
):
|
|
386
|
+
bumble.logging.setup_basic_logging('WARNING')
|
|
386
387
|
asyncio.run(
|
|
387
388
|
run(
|
|
388
389
|
hci_transport,
|
|
@@ -397,6 +398,5 @@ def main(
|
|
|
397
398
|
|
|
398
399
|
|
|
399
400
|
# -----------------------------------------------------------------------------
|
|
400
|
-
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'WARNING').upper())
|
|
401
401
|
if __name__ == '__main__':
|
|
402
402
|
main()
|
bumble/apps/hci_bridge.py
CHANGED
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
import logging
|
|
19
19
|
import asyncio
|
|
20
|
-
import os
|
|
21
20
|
import sys
|
|
22
21
|
|
|
23
22
|
from bumble import hci, transport
|
|
24
23
|
from bumble.bridge import HCI_Bridge
|
|
24
|
+
import bumble.logging
|
|
25
|
+
|
|
25
26
|
|
|
26
27
|
# -----------------------------------------------------------------------------
|
|
27
28
|
# Logging
|
|
@@ -100,7 +101,7 @@ async def async_main():
|
|
|
100
101
|
|
|
101
102
|
# -----------------------------------------------------------------------------
|
|
102
103
|
def main():
|
|
103
|
-
logging.
|
|
104
|
+
bumble.logging.setup_basic_logging()
|
|
104
105
|
asyncio.run(async_main())
|
|
105
106
|
|
|
106
107
|
|
bumble/apps/l2cap_bridge.py
CHANGED
|
@@ -16,8 +16,7 @@
|
|
|
16
16
|
# Imports
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
import asyncio
|
|
19
|
-
|
|
20
|
-
import os
|
|
19
|
+
|
|
21
20
|
import click
|
|
22
21
|
|
|
23
22
|
from bumble import l2cap
|
|
@@ -26,6 +25,7 @@ from bumble.transport import open_transport
|
|
|
26
25
|
from bumble.device import Device
|
|
27
26
|
from bumble.utils import FlowControlAsyncPipe
|
|
28
27
|
from bumble.hci import HCI_Constant
|
|
28
|
+
import bumble.logging
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
# -----------------------------------------------------------------------------
|
|
@@ -356,6 +356,6 @@ def client(context, bluetooth_address, tcp_host, tcp_port):
|
|
|
356
356
|
|
|
357
357
|
|
|
358
358
|
# -----------------------------------------------------------------------------
|
|
359
|
-
logging.basicConfig(level=os.environ.get('BUMBLE_LOGLEVEL', 'WARNING').upper())
|
|
360
359
|
if __name__ == '__main__':
|
|
360
|
+
bumble.logging.setup_basic_logging('WARNING')
|
|
361
361
|
cli(obj={}) # pylint: disable=no-value-for-parameter
|
bumble/apps/lea_unicast/app.py
CHANGED
|
@@ -22,7 +22,6 @@ import datetime
|
|
|
22
22
|
import functools
|
|
23
23
|
from importlib import resources
|
|
24
24
|
import json
|
|
25
|
-
import os
|
|
26
25
|
import logging
|
|
27
26
|
import pathlib
|
|
28
27
|
import weakref
|
|
@@ -44,6 +43,7 @@ from bumble.device import Device, DeviceConfiguration, AdvertisingParameters, Ci
|
|
|
44
43
|
from bumble.transport import open_transport
|
|
45
44
|
from bumble.profiles import ascs, bap, pacs
|
|
46
45
|
from bumble.hci import Address, CodecID, CodingFormat, HCI_IsoDataPacket
|
|
46
|
+
import bumble.logging
|
|
47
47
|
|
|
48
48
|
|
|
49
49
|
# -----------------------------------------------------------------------------
|
|
@@ -454,7 +454,7 @@ def speaker(ui_port: int, device_config: str, transport: str, lc3_file: str) ->
|
|
|
454
454
|
|
|
455
455
|
# -----------------------------------------------------------------------------
|
|
456
456
|
def main():
|
|
457
|
-
logging.
|
|
457
|
+
bumble.logging.setup_basic_logging()
|
|
458
458
|
speaker()
|
|
459
459
|
|
|
460
460
|
|
bumble/apps/player/player.py
CHANGED
|
@@ -17,8 +17,6 @@
|
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
from __future__ import annotations
|
|
19
19
|
import asyncio
|
|
20
|
-
import asyncio.subprocess
|
|
21
|
-
import os
|
|
22
20
|
import logging
|
|
23
21
|
from typing import Optional, Union
|
|
24
22
|
|
|
@@ -63,6 +61,7 @@ from bumble.hci import Address, HCI_CONNECTION_ALREADY_EXISTS_ERROR, HCI_Constan
|
|
|
63
61
|
from bumble.pairing import PairingConfig
|
|
64
62
|
from bumble.transport import open_transport
|
|
65
63
|
from bumble.utils import AsyncRunner
|
|
64
|
+
import bumble.logging
|
|
66
65
|
|
|
67
66
|
|
|
68
67
|
# -----------------------------------------------------------------------------
|
|
@@ -599,7 +598,7 @@ def play(context, address, audio_format, audio_file):
|
|
|
599
598
|
|
|
600
599
|
# -----------------------------------------------------------------------------
|
|
601
600
|
def main():
|
|
602
|
-
logging.
|
|
601
|
+
bumble.logging.setup_basic_logging("WARNING")
|
|
603
602
|
player_cli()
|
|
604
603
|
|
|
605
604
|
|
bumble/apps/rfcomm_bridge.py
CHANGED
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
# Imports
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
import asyncio
|
|
19
|
-
import logging
|
|
20
|
-
import os
|
|
21
19
|
import time
|
|
22
20
|
from typing import Optional
|
|
23
21
|
|
|
@@ -30,6 +28,7 @@ from bumble import hci
|
|
|
30
28
|
from bumble import rfcomm
|
|
31
29
|
from bumble import transport
|
|
32
30
|
from bumble import utils
|
|
31
|
+
import bumble.logging
|
|
33
32
|
|
|
34
33
|
|
|
35
34
|
# -----------------------------------------------------------------------------
|
|
@@ -515,6 +514,6 @@ def client(context, bluetooth_address, tcp_host, tcp_port, authenticate, encrypt
|
|
|
515
514
|
|
|
516
515
|
|
|
517
516
|
# -----------------------------------------------------------------------------
|
|
518
|
-
logging.basicConfig(level=os.environ.get("BUMBLE_LOGLEVEL", "WARNING").upper())
|
|
519
517
|
if __name__ == "__main__":
|
|
518
|
+
bumble.logging.setup_basic_logging("WARNING")
|
|
520
519
|
cli(obj={}) # pylint: disable=no-value-for-parameter
|
bumble/apps/scan.py
CHANGED
|
@@ -16,8 +16,6 @@
|
|
|
16
16
|
# Imports
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
import asyncio
|
|
19
|
-
import os
|
|
20
|
-
import logging
|
|
21
19
|
import click
|
|
22
20
|
|
|
23
21
|
from bumble.colors import color
|
|
@@ -27,6 +25,7 @@ from bumble.keys import JsonKeyStore
|
|
|
27
25
|
from bumble.smp import AddressResolver
|
|
28
26
|
from bumble.device import Advertisement
|
|
29
27
|
from bumble.hci import Address, HCI_Constant, HCI_LE_1M_PHY, HCI_LE_CODED_PHY
|
|
28
|
+
import bumble.logging
|
|
30
29
|
|
|
31
30
|
|
|
32
31
|
# -----------------------------------------------------------------------------
|
|
@@ -237,7 +236,7 @@ def main(
|
|
|
237
236
|
device_config,
|
|
238
237
|
transport,
|
|
239
238
|
):
|
|
240
|
-
logging.
|
|
239
|
+
bumble.logging.setup_basic_logging('WARNING')
|
|
241
240
|
asyncio.run(
|
|
242
241
|
scan(
|
|
243
242
|
min_rssi,
|
bumble/apps/show.py
CHANGED
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
import datetime
|
|
19
19
|
import importlib
|
|
20
20
|
import logging
|
|
21
|
-
import os
|
|
22
21
|
import struct
|
|
23
22
|
|
|
24
23
|
import click
|
|
@@ -27,6 +26,7 @@ from bumble.colors import color
|
|
|
27
26
|
from bumble import hci
|
|
28
27
|
from bumble.transport.common import PacketReader
|
|
29
28
|
from bumble.helpers import PacketTracer
|
|
29
|
+
import bumble.logging
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
# -----------------------------------------------------------------------------
|
|
@@ -188,5 +188,5 @@ def main(format, vendor, filename):
|
|
|
188
188
|
|
|
189
189
|
# -----------------------------------------------------------------------------
|
|
190
190
|
if __name__ == '__main__':
|
|
191
|
-
logging.
|
|
191
|
+
bumble.logging.setup_basic_logging('WARNING')
|
|
192
192
|
main() # pylint: disable=no-value-for-parameter
|
bumble/apps/speaker/speaker.py
CHANGED
|
@@ -21,7 +21,6 @@ import asyncio.subprocess
|
|
|
21
21
|
from importlib import resources
|
|
22
22
|
import enum
|
|
23
23
|
import json
|
|
24
|
-
import os
|
|
25
24
|
import logging
|
|
26
25
|
import pathlib
|
|
27
26
|
import subprocess
|
|
@@ -58,6 +57,7 @@ from bumble.a2dp import (
|
|
|
58
57
|
from bumble.utils import AsyncRunner
|
|
59
58
|
from bumble.codecs import AacAudioRtpPacket
|
|
60
59
|
from bumble.rtp import MediaPacket
|
|
60
|
+
import bumble.logging
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
# -----------------------------------------------------------------------------
|
|
@@ -833,11 +833,7 @@ def speaker(
|
|
|
833
833
|
|
|
834
834
|
# -----------------------------------------------------------------------------
|
|
835
835
|
def main():
|
|
836
|
-
logging.
|
|
837
|
-
level=os.environ.get('BUMBLE_LOGLEVEL', 'WARNING').upper(),
|
|
838
|
-
format="[%(asctime)s.%(msecs)03d] %(levelname)s:%(name)s:%(message)s",
|
|
839
|
-
datefmt="%H:%M:%S",
|
|
840
|
-
)
|
|
836
|
+
bumble.logging.setup_basic_logging('WARNING')
|
|
841
837
|
speaker()
|
|
842
838
|
|
|
843
839
|
|
bumble/apps/unbond.py
CHANGED
|
@@ -16,13 +16,12 @@
|
|
|
16
16
|
# Imports
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
import asyncio
|
|
19
|
-
import os
|
|
20
|
-
import logging
|
|
21
19
|
import click
|
|
22
20
|
|
|
23
21
|
from bumble.device import Device
|
|
24
22
|
from bumble.keys import JsonKeyStore
|
|
25
23
|
from bumble.transport import open_transport
|
|
24
|
+
import bumble.logging
|
|
26
25
|
|
|
27
26
|
|
|
28
27
|
# -----------------------------------------------------------------------------
|
|
@@ -68,7 +67,7 @@ def main(keystore_file, hci_transport, device_config, address):
|
|
|
68
67
|
instantiated.
|
|
69
68
|
If no address is passed, the existing pairing keys for all addresses are printed.
|
|
70
69
|
"""
|
|
71
|
-
logging.
|
|
70
|
+
bumble.logging.setup_basic_logging()
|
|
72
71
|
|
|
73
72
|
if not keystore_file and not hci_transport:
|
|
74
73
|
print('either --keystore-file or --hci-transport must be specified.')
|
bumble/apps/usb_probe.py
CHANGED
|
@@ -26,13 +26,12 @@
|
|
|
26
26
|
# -----------------------------------------------------------------------------
|
|
27
27
|
# Imports
|
|
28
28
|
# -----------------------------------------------------------------------------
|
|
29
|
-
import os
|
|
30
|
-
import logging
|
|
31
29
|
import click
|
|
32
30
|
import usb1
|
|
33
31
|
|
|
34
32
|
from bumble.colors import color
|
|
35
33
|
from bumble.transport.usb import load_libusb
|
|
34
|
+
import bumble.logging
|
|
36
35
|
|
|
37
36
|
|
|
38
37
|
# -----------------------------------------------------------------------------
|
|
@@ -169,7 +168,7 @@ def is_bluetooth_hci(device):
|
|
|
169
168
|
@click.command()
|
|
170
169
|
@click.option('--verbose', is_flag=True, default=False, help='Print more details')
|
|
171
170
|
def main(verbose):
|
|
172
|
-
logging.
|
|
171
|
+
bumble.logging.setup_basic_logging('WARNING')
|
|
173
172
|
|
|
174
173
|
load_libusb()
|
|
175
174
|
with usb1.USBContext() as context:
|
bumble/avrcp.py
CHANGED
|
@@ -1117,7 +1117,7 @@ class Protocol(utils.EventEmitter):
|
|
|
1117
1117
|
|
|
1118
1118
|
@staticmethod
|
|
1119
1119
|
def _check_vendor_dependent_frame(
|
|
1120
|
-
frame: Union[avc.VendorDependentCommandFrame, avc.VendorDependentResponseFrame]
|
|
1120
|
+
frame: Union[avc.VendorDependentCommandFrame, avc.VendorDependentResponseFrame],
|
|
1121
1121
|
) -> bool:
|
|
1122
1122
|
if frame.company_id != AVRCP_BLUETOOTH_SIG_COMPANY_ID:
|
|
1123
1123
|
logger.debug("unsupported company id, ignoring")
|
bumble/controller.py
CHANGED
|
@@ -370,6 +370,12 @@ class Controller:
|
|
|
370
370
|
return connection
|
|
371
371
|
return None
|
|
372
372
|
|
|
373
|
+
def find_peripheral_connection_by_handle(self, handle):
|
|
374
|
+
for connection in self.peripheral_connections.values():
|
|
375
|
+
if connection.handle == handle:
|
|
376
|
+
return connection
|
|
377
|
+
return None
|
|
378
|
+
|
|
373
379
|
def find_classic_connection_by_handle(self, handle):
|
|
374
380
|
for connection in self.classic_connections.values():
|
|
375
381
|
if connection.handle == handle:
|
|
@@ -414,7 +420,7 @@ class Controller:
|
|
|
414
420
|
)
|
|
415
421
|
)
|
|
416
422
|
|
|
417
|
-
def
|
|
423
|
+
def on_link_disconnected(self, peer_address, reason):
|
|
418
424
|
'''
|
|
419
425
|
Called when an active disconnection occurs from a peer
|
|
420
426
|
'''
|
|
@@ -431,6 +437,17 @@ class Controller:
|
|
|
431
437
|
|
|
432
438
|
# Remove the connection
|
|
433
439
|
del self.peripheral_connections[peer_address]
|
|
440
|
+
elif connection := self.central_connections.get(peer_address):
|
|
441
|
+
self.send_hci_packet(
|
|
442
|
+
HCI_Disconnection_Complete_Event(
|
|
443
|
+
status=HCI_SUCCESS,
|
|
444
|
+
connection_handle=connection.handle,
|
|
445
|
+
reason=reason,
|
|
446
|
+
)
|
|
447
|
+
)
|
|
448
|
+
|
|
449
|
+
# Remove the connection
|
|
450
|
+
del self.central_connections[peer_address]
|
|
434
451
|
else:
|
|
435
452
|
logger.warning(f'!!! No peripheral connection found for {peer_address}')
|
|
436
453
|
|
|
@@ -479,7 +496,7 @@ class Controller:
|
|
|
479
496
|
)
|
|
480
497
|
)
|
|
481
498
|
|
|
482
|
-
def
|
|
499
|
+
def on_link_disconnection_complete(self, disconnection_command, status):
|
|
483
500
|
'''
|
|
484
501
|
Called when a disconnection has been completed
|
|
485
502
|
'''
|
|
@@ -499,26 +516,11 @@ class Controller:
|
|
|
499
516
|
):
|
|
500
517
|
logger.debug(f'CENTRAL Connection removed: {connection}')
|
|
501
518
|
del self.central_connections[connection.peer_address]
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
# Send a disconnection complete event
|
|
509
|
-
if connection := self.central_connections.get(peer_address):
|
|
510
|
-
self.send_hci_packet(
|
|
511
|
-
HCI_Disconnection_Complete_Event(
|
|
512
|
-
status=HCI_SUCCESS,
|
|
513
|
-
connection_handle=connection.handle,
|
|
514
|
-
reason=HCI_CONNECTION_TIMEOUT_ERROR,
|
|
515
|
-
)
|
|
516
|
-
)
|
|
517
|
-
|
|
518
|
-
# Remove the connection
|
|
519
|
-
del self.central_connections[peer_address]
|
|
520
|
-
else:
|
|
521
|
-
logger.warning(f'!!! No central connection found for {peer_address}')
|
|
519
|
+
elif connection := self.find_peripheral_connection_by_handle(
|
|
520
|
+
disconnection_command.connection_handle
|
|
521
|
+
):
|
|
522
|
+
logger.debug(f'PERIPHERAL Connection removed: {connection}')
|
|
523
|
+
del self.peripheral_connections[connection.peer_address]
|
|
522
524
|
|
|
523
525
|
def on_link_encrypted(self, peer_address, _rand, _ediv, _ltk):
|
|
524
526
|
# For now, just setup the encryption without asking the host
|
|
@@ -877,6 +879,14 @@ class Controller:
|
|
|
877
879
|
else:
|
|
878
880
|
# Remove the connection
|
|
879
881
|
del self.central_connections[connection.peer_address]
|
|
882
|
+
elif connection := self.find_peripheral_connection_by_handle(handle):
|
|
883
|
+
if self.link:
|
|
884
|
+
self.link.disconnect(
|
|
885
|
+
self.random_address, connection.peer_address, command
|
|
886
|
+
)
|
|
887
|
+
else:
|
|
888
|
+
# Remove the connection
|
|
889
|
+
del self.peripheral_connections[connection.peer_address]
|
|
880
890
|
elif connection := self.find_classic_connection_by_handle(handle):
|
|
881
891
|
if self.link:
|
|
882
892
|
self.link.classic_disconnect(
|
|
@@ -1259,6 +1269,56 @@ class Controller:
|
|
|
1259
1269
|
)
|
|
1260
1270
|
return bytes([HCI_SUCCESS]) + bd_addr
|
|
1261
1271
|
|
|
1272
|
+
def on_hci_le_set_default_subrate_command(
|
|
1273
|
+
self, command: hci.HCI_LE_Set_Default_Subrate_Command
|
|
1274
|
+
):
|
|
1275
|
+
'''
|
|
1276
|
+
See Bluetooth spec Vol 6, Part E - 7.8.123 LE Set Event Mask Command
|
|
1277
|
+
'''
|
|
1278
|
+
|
|
1279
|
+
if (
|
|
1280
|
+
command.subrate_max * (command.max_latency) > 500
|
|
1281
|
+
or command.subrate_max < command.subrate_min
|
|
1282
|
+
or command.continuation_number >= command.subrate_max
|
|
1283
|
+
):
|
|
1284
|
+
return bytes([HCI_INVALID_HCI_COMMAND_PARAMETERS_ERROR])
|
|
1285
|
+
|
|
1286
|
+
return bytes([HCI_SUCCESS])
|
|
1287
|
+
|
|
1288
|
+
def on_hci_le_subrate_request_command(
|
|
1289
|
+
self, command: hci.HCI_LE_Subrate_Request_Command
|
|
1290
|
+
):
|
|
1291
|
+
'''
|
|
1292
|
+
See Bluetooth spec Vol 6, Part E - 7.8.124 LE Subrate Request command
|
|
1293
|
+
'''
|
|
1294
|
+
if (
|
|
1295
|
+
command.subrate_max * (command.max_latency) > 500
|
|
1296
|
+
or command.continuation_number < command.continuation_number
|
|
1297
|
+
or command.subrate_max < command.subrate_min
|
|
1298
|
+
or command.continuation_number >= command.subrate_max
|
|
1299
|
+
):
|
|
1300
|
+
return bytes([HCI_INVALID_HCI_COMMAND_PARAMETERS_ERROR])
|
|
1301
|
+
|
|
1302
|
+
self.send_hci_packet(
|
|
1303
|
+
hci.HCI_Command_Status_Event(
|
|
1304
|
+
status=hci.HCI_SUCCESS,
|
|
1305
|
+
num_hci_command_packets=1,
|
|
1306
|
+
command_opcode=command.op_code,
|
|
1307
|
+
)
|
|
1308
|
+
)
|
|
1309
|
+
|
|
1310
|
+
self.send_hci_packet(
|
|
1311
|
+
hci.HCI_LE_Subrate_Change_Event(
|
|
1312
|
+
status=hci.HCI_SUCCESS,
|
|
1313
|
+
connection_handle=command.connection_handle,
|
|
1314
|
+
subrate_factor=2,
|
|
1315
|
+
peripheral_latency=2,
|
|
1316
|
+
continuation_number=command.continuation_number,
|
|
1317
|
+
supervision_timeout=command.supervision_timeout,
|
|
1318
|
+
)
|
|
1319
|
+
)
|
|
1320
|
+
return None
|
|
1321
|
+
|
|
1262
1322
|
def on_hci_le_set_event_mask_command(self, command):
|
|
1263
1323
|
'''
|
|
1264
1324
|
See Bluetooth spec Vol 4, Part E - 7.8.1 LE Set Event Mask Command
|
|
@@ -1805,3 +1865,11 @@ class Controller:
|
|
|
1805
1865
|
See Bluetooth spec Vol 4, Part E - 7.8.110 LE Remove ISO Data Path Command
|
|
1806
1866
|
'''
|
|
1807
1867
|
return struct.pack('<BH', HCI_SUCCESS, command.connection_handle)
|
|
1868
|
+
|
|
1869
|
+
def on_hci_le_set_host_feature_command(
|
|
1870
|
+
self, _command: hci.HCI_LE_Set_Host_Feature_Command
|
|
1871
|
+
):
|
|
1872
|
+
'''
|
|
1873
|
+
See Bluetooth spec Vol 4, Part E - 7.8.115 LE Set Host Feature command
|
|
1874
|
+
'''
|
|
1875
|
+
return bytes([HCI_SUCCESS])
|