bumble 0.0.198__py3-none-any.whl → 0.0.199__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/pair.py +32 -5
- bumble/att.py +56 -40
- bumble/avdtp.py +2 -2
- bumble/decoder.py +14 -10
- bumble/drivers/rtk.py +19 -5
- bumble/gatt.py +24 -19
- bumble/gatt_client.py +5 -25
- bumble/gatt_server.py +14 -6
- bumble/hci.py +272 -7
- bumble/host.py +16 -6
- bumble/pandora/__init__.py +3 -0
- bumble/pandora/l2cap.py +310 -0
- bumble/profiles/aics.py +520 -0
- bumble/profiles/asha.py +295 -0
- bumble/profiles/hap.py +665 -0
- bumble/profiles/vcp.py +5 -3
- bumble/smp.py +23 -4
- bumble/transport/pyusb.py +19 -2
- {bumble-0.0.198.dist-info → bumble-0.0.199.dist-info}/METADATA +1 -1
- {bumble-0.0.198.dist-info → bumble-0.0.199.dist-info}/RECORD +25 -22
- {bumble-0.0.198.dist-info → bumble-0.0.199.dist-info}/WHEEL +1 -1
- bumble/profiles/asha_service.py +0 -193
- {bumble-0.0.198.dist-info → bumble-0.0.199.dist-info}/LICENSE +0 -0
- {bumble-0.0.198.dist-info → bumble-0.0.199.dist-info}/entry_points.txt +0 -0
- {bumble-0.0.198.dist-info → bumble-0.0.199.dist-info}/top_level.txt +0 -0
bumble/smp.py
CHANGED
|
@@ -764,7 +764,9 @@ class Session:
|
|
|
764
764
|
self.peer_io_capability = SMP_NO_INPUT_NO_OUTPUT_IO_CAPABILITY
|
|
765
765
|
|
|
766
766
|
# OOB
|
|
767
|
-
self.oob_data_flag =
|
|
767
|
+
self.oob_data_flag = (
|
|
768
|
+
1 if pairing_config.oob and pairing_config.oob.peer_data else 0
|
|
769
|
+
)
|
|
768
770
|
|
|
769
771
|
# Set up addresses
|
|
770
772
|
self_address = connection.self_resolvable_address or connection.self_address
|
|
@@ -1014,8 +1016,10 @@ class Session:
|
|
|
1014
1016
|
self.send_command(response)
|
|
1015
1017
|
|
|
1016
1018
|
def send_pairing_confirm_command(self) -> None:
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
+
|
|
1020
|
+
if self.pairing_method != PairingMethod.OOB:
|
|
1021
|
+
self.r = crypto.r()
|
|
1022
|
+
logger.debug(f'generated random: {self.r.hex()}')
|
|
1019
1023
|
|
|
1020
1024
|
if self.sc:
|
|
1021
1025
|
|
|
@@ -1735,7 +1739,6 @@ class Session:
|
|
|
1735
1739
|
if self.pairing_method in (
|
|
1736
1740
|
PairingMethod.JUST_WORKS,
|
|
1737
1741
|
PairingMethod.NUMERIC_COMPARISON,
|
|
1738
|
-
PairingMethod.OOB,
|
|
1739
1742
|
):
|
|
1740
1743
|
ra = bytes(16)
|
|
1741
1744
|
rb = ra
|
|
@@ -1743,6 +1746,22 @@ class Session:
|
|
|
1743
1746
|
assert self.passkey
|
|
1744
1747
|
ra = self.passkey.to_bytes(16, byteorder='little')
|
|
1745
1748
|
rb = ra
|
|
1749
|
+
elif self.pairing_method == PairingMethod.OOB:
|
|
1750
|
+
if self.is_initiator:
|
|
1751
|
+
if self.peer_oob_data:
|
|
1752
|
+
rb = self.peer_oob_data.r
|
|
1753
|
+
ra = self.r
|
|
1754
|
+
else:
|
|
1755
|
+
rb = bytes(16)
|
|
1756
|
+
ra = self.r
|
|
1757
|
+
else:
|
|
1758
|
+
if self.peer_oob_data:
|
|
1759
|
+
ra = self.peer_oob_data.r
|
|
1760
|
+
rb = self.r
|
|
1761
|
+
else:
|
|
1762
|
+
ra = bytes(16)
|
|
1763
|
+
rb = self.r
|
|
1764
|
+
|
|
1746
1765
|
else:
|
|
1747
1766
|
return
|
|
1748
1767
|
|
bumble/transport/pyusb.py
CHANGED
|
@@ -23,7 +23,7 @@ import time
|
|
|
23
23
|
import usb.core
|
|
24
24
|
import usb.util
|
|
25
25
|
|
|
26
|
-
from typing import Optional
|
|
26
|
+
from typing import Optional, Set
|
|
27
27
|
from usb.core import Device as UsbDevice
|
|
28
28
|
from usb.core import USBError
|
|
29
29
|
from usb.util import CTRL_TYPE_CLASS, CTRL_RECIPIENT_OTHER
|
|
@@ -46,6 +46,11 @@ RESET_DELAY = 3
|
|
|
46
46
|
# -----------------------------------------------------------------------------
|
|
47
47
|
logger = logging.getLogger(__name__)
|
|
48
48
|
|
|
49
|
+
# -----------------------------------------------------------------------------
|
|
50
|
+
# Global
|
|
51
|
+
# -----------------------------------------------------------------------------
|
|
52
|
+
devices_in_use: Set[int] = set()
|
|
53
|
+
|
|
49
54
|
|
|
50
55
|
# -----------------------------------------------------------------------------
|
|
51
56
|
async def open_pyusb_transport(spec: str) -> Transport:
|
|
@@ -216,6 +221,7 @@ async def open_pyusb_transport(spec: str) -> Transport:
|
|
|
216
221
|
async def close(self):
|
|
217
222
|
await self.source.stop()
|
|
218
223
|
await self.sink.stop()
|
|
224
|
+
devices_in_use.remove(device.address)
|
|
219
225
|
usb.util.release_interface(self.device, 0)
|
|
220
226
|
|
|
221
227
|
usb_find = usb.core.find
|
|
@@ -233,7 +239,18 @@ async def open_pyusb_transport(spec: str) -> Transport:
|
|
|
233
239
|
spec = spec[1:]
|
|
234
240
|
if ':' in spec:
|
|
235
241
|
vendor_id, product_id = spec.split(':')
|
|
236
|
-
device =
|
|
242
|
+
device = None
|
|
243
|
+
devices = usb_find(
|
|
244
|
+
find_all=True, idVendor=int(vendor_id, 16), idProduct=int(product_id, 16)
|
|
245
|
+
)
|
|
246
|
+
for d in devices:
|
|
247
|
+
if d.address in devices_in_use:
|
|
248
|
+
continue
|
|
249
|
+
device = d
|
|
250
|
+
devices_in_use.add(d.address)
|
|
251
|
+
break
|
|
252
|
+
if device is None:
|
|
253
|
+
raise ValueError('device already in use')
|
|
237
254
|
elif '-' in spec:
|
|
238
255
|
|
|
239
256
|
def device_path(device):
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
bumble/__init__.py,sha256=Q8jkz6rgl95IMAeInQVt_2GLoJl3DcEP2cxtrQ-ho5c,110
|
|
2
|
-
bumble/_version.py,sha256
|
|
2
|
+
bumble/_version.py,sha256=-5ruRKhgD06H9Dn3PntBTwUGHMNmAuViLLPxyfe0nAg,415
|
|
3
3
|
bumble/a2dp.py,sha256=VEeAOCfT1ZqpwnEgel6DJ32vxR8jYX3IAaBfCqPdWO8,22675
|
|
4
4
|
bumble/at.py,sha256=Giu2VUSJKH-jIh10lOfumiqy-FyO99Ra6nJ7UiWQ0H8,3114
|
|
5
|
-
bumble/att.py,sha256=
|
|
5
|
+
bumble/att.py,sha256=i-rs_xyTBUdGpyjoZCjb68f1IDiiS2kX9RylCeh6K0o,32757
|
|
6
6
|
bumble/avc.py,sha256=Ho-WweU9lU15vlTwIbrGBa18M5vUKYm5q8aToaLSh70,16311
|
|
7
7
|
bumble/avctp.py,sha256=yHAjJRjLGtR0Q-iWcLS7cJRz5Jr2YiRmZd6LZV4Xjt4,9935
|
|
8
|
-
bumble/avdtp.py,sha256=
|
|
8
|
+
bumble/avdtp.py,sha256=K_Ujbruw0cNfSXeMU3OvgWedrLjZ8A3i6f_hy1rtpRo,77470
|
|
9
9
|
bumble/avrcp.py,sha256=BhDjc8TxhOpPnuvGn5-dGB6JK1aqshg4x7tm_vI4LLU,69363
|
|
10
10
|
bumble/bridge.py,sha256=T6es5oS1dy8QgkxQ8iOD-YcZ0SWOv8jaqC7TGxqodk4,3003
|
|
11
11
|
bumble/codecs.py,sha256=yels_alICohfM5DuvR2wMpYlebt7OrZHCtRXWyMyYYI,15581
|
|
@@ -14,17 +14,17 @@ bumble/company_ids.py,sha256=B68e2QPsDeRYP9jjbGs4GGDwEkGxcXGTsON_CHA0uuI,118528
|
|
|
14
14
|
bumble/controller.py,sha256=XkYTQb2J5MhH_dGfnFkrLXdChFD2s1wSvqXaHQFeo48,59688
|
|
15
15
|
bumble/core.py,sha256=T43ZszjsU_89B0UJwQ9GCzvKU7oj1_RBzsdGr9jX9xY,72440
|
|
16
16
|
bumble/crypto.py,sha256=L6z3dn9-dgKYRtOM6O3F6n6Ju4PwTM3LAFJtCg_ie78,9382
|
|
17
|
-
bumble/decoder.py,sha256=
|
|
17
|
+
bumble/decoder.py,sha256=0-VNWZT-u7lvK3qBpAuYT0M6Rz_bMgMi4CjfUXX_6RM,9728
|
|
18
18
|
bumble/device.py,sha256=4TcC6v_zwyTcZMAMZd7qb06oLVGtw84LtdlgIsilFbU,194632
|
|
19
19
|
bumble/gap.py,sha256=dRU2_TWvqTDx80hxeSbXlWIeWvptWH4_XbItG5y948Q,2138
|
|
20
|
-
bumble/gatt.py,sha256=
|
|
21
|
-
bumble/gatt_client.py,sha256=
|
|
22
|
-
bumble/gatt_server.py,sha256=
|
|
23
|
-
bumble/hci.py,sha256=
|
|
20
|
+
bumble/gatt.py,sha256=a07mQ3O0LFt5zgUzSUwa4Jak_FXOXSFX-njxnQNS_zY,39014
|
|
21
|
+
bumble/gatt_client.py,sha256=gIpgNQj5WNm9RirXXT4vuXQZ4WK82IFMOqnfqBtoYRU,42809
|
|
22
|
+
bumble/gatt_server.py,sha256=pafGMeAuGAAELnr_1pB_l3CcR5u4H4Y1-MRHjN53gdE,37449
|
|
23
|
+
bumble/hci.py,sha256=fx8BmNV29fiZWQPLLstihLWScb0_8zy5O-mX9IfngcI,285388
|
|
24
24
|
bumble/helpers.py,sha256=m0w4UgFFNDEnXwHrDyfRlcBObdVed2fqXGL0lvR3c8s,12733
|
|
25
25
|
bumble/hfp.py,sha256=OsBDREelxhLMi_UZO9Kxlqzbts08CcGxoiicUgrYlXg,75353
|
|
26
26
|
bumble/hid.py,sha256=hJKm6qhNa0kQTGmp_VxNh3-ywgBDdJpPPFcvtFiRL0A,20335
|
|
27
|
-
bumble/host.py,sha256=
|
|
27
|
+
bumble/host.py,sha256=s7ZzGbExvewZ7qoMF3cdjyvFKae8NqiFH-xtHhd_a2M,48814
|
|
28
28
|
bumble/keys.py,sha256=WbIQ7Ob81mW75qmEPQ2rBLfnqBMA-ts2yowWXP9UaCY,12654
|
|
29
29
|
bumble/l2cap.py,sha256=Bu6oTD3DzqLOKiarynT1cfQefNgR0gCJoKxnwQJl2_o,81398
|
|
30
30
|
bumble/link.py,sha256=MYKsIKpbbAkh_ldxPZKu_GhS90ImC0IQtCAqbY4Ddg4,24034
|
|
@@ -32,7 +32,7 @@ bumble/pairing.py,sha256=tgPUba6xNxMi-2plm3xfRlzHq-uPRNZEIGWaN0qNGCs,9853
|
|
|
32
32
|
bumble/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
33
33
|
bumble/rfcomm.py,sha256=dh5t5vlDEfw3yHgQfzegMYPnShP8Zo-3ScABUvmXNLI,40751
|
|
34
34
|
bumble/sdp.py,sha256=aajRQybcMWh_Kc4IuQahix6bXnHg61OXl1gSdrSysl4,45465
|
|
35
|
-
bumble/smp.py,sha256=
|
|
35
|
+
bumble/smp.py,sha256=FNLn-pt2n6CKNttQGJJDnfaeof2SVkxlapwySHWAVJY,77640
|
|
36
36
|
bumble/snoop.py,sha256=1mzwmp9LToUXbPnFsLrt8S4UHs0kqzbu7LDydwbmkZI,5715
|
|
37
37
|
bumble/utils.py,sha256=e0i-4d28-9zP3gYcd1rdNd669rkPnRs5oJCERUEDfxo,15099
|
|
38
38
|
bumble/apps/README.md,sha256=XTwjRAY-EJWDXpl1V8K3Mw8B7kIqzUIUizRjVBVhoIE,1769
|
|
@@ -49,7 +49,7 @@ bumble/apps/gatt_dump.py,sha256=wwA-NhRnbgUkbj-Ukym7NDG2j2n_36t_tn93dLDVdIg,4487
|
|
|
49
49
|
bumble/apps/gg_bridge.py,sha256=JdW5QT6xN9c2XDDJoHDRo5W3N_RdVkCtTmlcOsJhlx8,14693
|
|
50
50
|
bumble/apps/hci_bridge.py,sha256=KISv352tKnsQsoxjkDiCQbMFmhnPWdnug5wSFAAXxEs,4033
|
|
51
51
|
bumble/apps/l2cap_bridge.py,sha256=524VgEmgCP4g7T0UdgmsePmNVhDFRJECeaZ_uzKsbco,13062
|
|
52
|
-
bumble/apps/pair.py,sha256=
|
|
52
|
+
bumble/apps/pair.py,sha256=NtDxLfdnlOY_ZEtVNGVXWjv6_x_hndok_ydhV6zkFtI,18503
|
|
53
53
|
bumble/apps/pandora_server.py,sha256=5qaoLCpcZE2KsGO21-7t6Vg4dBjBWbnyOQXwrLhxkuE,1397
|
|
54
54
|
bumble/apps/rfcomm_bridge.py,sha256=PSszh4Qh1IsIw8ETs0fevOCAXEdVtqlgnV-ruzqGrZI,17215
|
|
55
55
|
bumble/apps/scan.py,sha256=b6hIppiJqDfR7VFW2wl3-lkPdFvHLqYZKY8VjjNnhls,8366
|
|
@@ -71,17 +71,19 @@ bumble/apps/speaker/speaker.py,sha256=f7cOyVqD6HOiLPCgdcnwN7sakj2SScybVHVTBR6eFw
|
|
|
71
71
|
bumble/drivers/__init__.py,sha256=lxqJTghh21rQFThRTurwLysZm385TUcn8ZdpHQSWD88,3196
|
|
72
72
|
bumble/drivers/common.py,sha256=pS783hudolLZAzF8IUWp7g6TXyQsUCEzqCsd1VGeYfQ,1507
|
|
73
73
|
bumble/drivers/intel.py,sha256=-YcJI4ZC_fhHHxWyE8b4eB8V7suOFH1n9uayckGE9Uw,3231
|
|
74
|
-
bumble/drivers/rtk.py,sha256=
|
|
75
|
-
bumble/pandora/__init__.py,sha256=
|
|
74
|
+
bumble/drivers/rtk.py,sha256=nsfAqNzvxvAwbh6UYgxOCSNwgw7XouIBFA03FrLTs4M,22088
|
|
75
|
+
bumble/pandora/__init__.py,sha256=jaPtYCLfLeLUGj8-TmS3Gkv0l1_DBadYj8ZMAPLPAao,3463
|
|
76
76
|
bumble/pandora/config.py,sha256=KD85n3oRbuvD65sRah2H0gpxEW4YbD7HbYbsxdcpDDA,2388
|
|
77
77
|
bumble/pandora/device.py,sha256=LFqCWrgYkQWrFUSKArsAABXkge8sB2DhvaQoEsC4Jn0,5344
|
|
78
78
|
bumble/pandora/host.py,sha256=LnEQ3DJAhmJVgHA7VyokvypQejsi2VcbauSFYn1a9Jk,39235
|
|
79
|
+
bumble/pandora/l2cap.py,sha256=OT-pPprVAQr7xwjYnNwDQujayG2zWUS5FPXVBGNCW3o,11725
|
|
79
80
|
bumble/pandora/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
80
81
|
bumble/pandora/security.py,sha256=YErueKNLsnmcRe6dKo724Ht-buOqmZl2Gauswcc8FW0,21946
|
|
81
82
|
bumble/pandora/utils.py,sha256=Fq4glL0T5cJ2FODoDotmDNdYFOkTOR7DyyL8vkcxp20,3949
|
|
82
83
|
bumble/profiles/__init__.py,sha256=yBGC8Ti5LvZuoh1F42XtfrBilb39T77_yuxESZeX2yI,581
|
|
84
|
+
bumble/profiles/aics.py,sha256=U0K03XqOKtqahXtq7U47WxftsAD7tkiDeUqxfaF4pwk,18540
|
|
83
85
|
bumble/profiles/ascs.py,sha256=Y2_fd_5LOb9hon60LcQl3R-FoAIsOd_J37RZpveh-7c,25471
|
|
84
|
-
bumble/profiles/
|
|
86
|
+
bumble/profiles/asha.py,sha256=QXUp7ImuMD48L0mpuNxPcIkv8VvoENynCuF2PEVqzFM,10373
|
|
85
87
|
bumble/profiles/bap.py,sha256=wLnrbXso203rgw0WNa91qIdMdjuIoGc9VqOHc9Ey_b4,19421
|
|
86
88
|
bumble/profiles/bass.py,sha256=Wiqum0Wsr5PpVzTAPDcyKLTfJoKXJUYOzqB320aSiUs,14950
|
|
87
89
|
bumble/profiles/battery_service.py,sha256=w-uF4jLoDozJOoykimb2RkrKjVyCke6ts2-h-F1PYyc,2292
|
|
@@ -89,6 +91,7 @@ bumble/profiles/cap.py,sha256=6gH7oOnUKjOggMPuB7rtbwj0AneoNmnWzQ_iR3io8e0,1945
|
|
|
89
91
|
bumble/profiles/csip.py,sha256=qpI9W0_FWIpsuJrHhxfbKaa-TD21epxEa3EuCm8gh6c,10156
|
|
90
92
|
bumble/profiles/device_information_service.py,sha256=RfqnXywcwcSTiFalxd1LVTTdeWLxHGsMvlvr9fI0GJI,6193
|
|
91
93
|
bumble/profiles/gap.py,sha256=jUjfy6MPL7k6wgNn3ny3PVgSX6-SLmjUepFYHjGc3IU,3870
|
|
94
|
+
bumble/profiles/hap.py,sha256=9K6FR0FAjpRdDHoU5sgddndeVH2r1fQyWKRXM0dyoa0,25265
|
|
92
95
|
bumble/profiles/heart_rate_service.py,sha256=_MG1ApmF1B7b4xRzELuahtRWzLm49i9O4m7I6ZFU4mw,8644
|
|
93
96
|
bumble/profiles/le_audio.py,sha256=1x6OpIc0JMa32YVcfM8lq6jnXHlriHUcOkAs0EttJJk,3093
|
|
94
97
|
bumble/profiles/mcp.py,sha256=vIN1r_if4LmOcGCgZuDYTYLMQzU6-1pKUFx1Z3iSAeY,17415
|
|
@@ -96,7 +99,7 @@ bumble/profiles/pacs.py,sha256=bhlU5M6E9e1YKf-qJnJL3GwTqOPuSvYDpY_UYq0Nnd8,8730
|
|
|
96
99
|
bumble/profiles/pbp.py,sha256=51aoQcZMXzTzeatHd0zNVN7kYcv4atzr2OWpzxlSVP8,1630
|
|
97
100
|
bumble/profiles/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
98
101
|
bumble/profiles/tmap.py,sha256=hpz5VYEdEOty4D9ApCRDero9Tf3L9arSZWnLCNkZoHI,3005
|
|
99
|
-
bumble/profiles/vcp.py,sha256=
|
|
102
|
+
bumble/profiles/vcp.py,sha256=Lx1Odg7PQO9nXkpxRpK04MRuy975uIK8kSqcwrk4iSE,8035
|
|
100
103
|
bumble/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
101
104
|
bumble/tools/generate_company_id_list.py,sha256=ysbPb3zmxKFBiSQ_MBG2r15-sqR5P_GWT6i0YUTTXOM,1736
|
|
102
105
|
bumble/tools/rtk_fw_download.py,sha256=KEPG-rDrdPGKBzZ78P4s3udLRYT3p7vesGhXvJTWTic,5453
|
|
@@ -109,7 +112,7 @@ bumble/transport/file.py,sha256=eVM2V6Nk2nDAFdE7Rt01ZI3JdTovsH9OEU1gKYPJjpE,2010
|
|
|
109
112
|
bumble/transport/hci_socket.py,sha256=EdgWi3-O5yvYcH4R4BkPtG79pnUo7GQtXWawuUHDoDQ,6331
|
|
110
113
|
bumble/transport/pty.py,sha256=grTl-yvjMWHflNwuME4ccVqDbk6NIEgQMgH6Y9lf1fU,2732
|
|
111
114
|
bumble/transport/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
112
|
-
bumble/transport/pyusb.py,sha256=
|
|
115
|
+
bumble/transport/pyusb.py,sha256=IGcFJsYOlHaQRXcFCmGlwLZjg8D2BQq9IQrAs6TA2UA,16109
|
|
113
116
|
bumble/transport/serial.py,sha256=loQxkeG7uE09enXWg2uGbxi6CeG70wn3kzPbEwULKw4,2446
|
|
114
117
|
bumble/transport/tcp_client.py,sha256=deyUJYpj04QE00Mw_PTU5PHPA6mr1Nui3f5-QCy2zOw,1854
|
|
115
118
|
bumble/transport/tcp_server.py,sha256=tvu7FuPeqiXfoj2HQU8wu4AiwKjDDDCKlKjgtqWc5hg,3779
|
|
@@ -152,9 +155,9 @@ bumble/vendor/android/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3h
|
|
|
152
155
|
bumble/vendor/android/hci.py,sha256=GZrkhaWmcMt1JpnRhv0NoySGkf2H4lNUV2f_omRZW0I,10741
|
|
153
156
|
bumble/vendor/zephyr/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
154
157
|
bumble/vendor/zephyr/hci.py,sha256=d83bC0TvT947eN4roFjLkQefWtHOoNsr4xib2ctSkvA,3195
|
|
155
|
-
bumble-0.0.
|
|
156
|
-
bumble-0.0.
|
|
157
|
-
bumble-0.0.
|
|
158
|
-
bumble-0.0.
|
|
159
|
-
bumble-0.0.
|
|
160
|
-
bumble-0.0.
|
|
158
|
+
bumble-0.0.199.dist-info/LICENSE,sha256=FvaYh4NRWIGgS_OwoBs5gFgkCmAghZ-DYnIGBZPuw-s,12142
|
|
159
|
+
bumble-0.0.199.dist-info/METADATA,sha256=Qfi-AevfEFjLoT0FfXuAjznE0U8MONF87tArGkqVIK0,5672
|
|
160
|
+
bumble-0.0.199.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
|
161
|
+
bumble-0.0.199.dist-info/entry_points.txt,sha256=AOFf_gnWbZ7jk5fzspxXHCQUay1ik71pK3HYO7sZQsk,937
|
|
162
|
+
bumble-0.0.199.dist-info/top_level.txt,sha256=tV6JJKaHPYMFiJYiBYFW24PCcfLxTJZdlu6BmH3Cb00,7
|
|
163
|
+
bumble-0.0.199.dist-info/RECORD,,
|
bumble/profiles/asha_service.py
DELETED
|
@@ -1,193 +0,0 @@
|
|
|
1
|
-
# Copyright 2021-2022 Google LLC
|
|
2
|
-
#
|
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
-
# you may not use this file except in compliance with the License.
|
|
5
|
-
# You may obtain a copy of the License at
|
|
6
|
-
#
|
|
7
|
-
# https://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
-
#
|
|
9
|
-
# Unless required by applicable law or agreed to in writing, software
|
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
-
# See the License for the specific language governing permissions and
|
|
13
|
-
# limitations under the License.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
# -----------------------------------------------------------------------------
|
|
17
|
-
# Imports
|
|
18
|
-
# -----------------------------------------------------------------------------
|
|
19
|
-
import struct
|
|
20
|
-
import logging
|
|
21
|
-
from typing import List, Optional
|
|
22
|
-
|
|
23
|
-
from bumble import l2cap
|
|
24
|
-
from ..core import AdvertisingData
|
|
25
|
-
from ..device import Device, Connection
|
|
26
|
-
from ..gatt import (
|
|
27
|
-
GATT_ASHA_SERVICE,
|
|
28
|
-
GATT_ASHA_READ_ONLY_PROPERTIES_CHARACTERISTIC,
|
|
29
|
-
GATT_ASHA_AUDIO_CONTROL_POINT_CHARACTERISTIC,
|
|
30
|
-
GATT_ASHA_AUDIO_STATUS_CHARACTERISTIC,
|
|
31
|
-
GATT_ASHA_VOLUME_CHARACTERISTIC,
|
|
32
|
-
GATT_ASHA_LE_PSM_OUT_CHARACTERISTIC,
|
|
33
|
-
TemplateService,
|
|
34
|
-
Characteristic,
|
|
35
|
-
CharacteristicValue,
|
|
36
|
-
)
|
|
37
|
-
from ..utils import AsyncRunner
|
|
38
|
-
|
|
39
|
-
# -----------------------------------------------------------------------------
|
|
40
|
-
# Logging
|
|
41
|
-
# -----------------------------------------------------------------------------
|
|
42
|
-
logger = logging.getLogger(__name__)
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
# -----------------------------------------------------------------------------
|
|
46
|
-
class AshaService(TemplateService):
|
|
47
|
-
UUID = GATT_ASHA_SERVICE
|
|
48
|
-
OPCODE_START = 1
|
|
49
|
-
OPCODE_STOP = 2
|
|
50
|
-
OPCODE_STATUS = 3
|
|
51
|
-
PROTOCOL_VERSION = 0x01
|
|
52
|
-
RESERVED_FOR_FUTURE_USE = [00, 00]
|
|
53
|
-
FEATURE_MAP = [0x01] # [LE CoC audio output streaming supported]
|
|
54
|
-
SUPPORTED_CODEC_ID = [0x02, 0x01] # Codec IDs [G.722 at 16 kHz]
|
|
55
|
-
RENDER_DELAY = [00, 00]
|
|
56
|
-
|
|
57
|
-
def __init__(self, capability: int, hisyncid: List[int], device: Device, psm=0):
|
|
58
|
-
self.hisyncid = hisyncid
|
|
59
|
-
self.capability = capability # Device Capabilities [Left, Monaural]
|
|
60
|
-
self.device = device
|
|
61
|
-
self.audio_out_data = b''
|
|
62
|
-
self.psm = psm # a non-zero psm is mainly for testing purpose
|
|
63
|
-
|
|
64
|
-
# Handler for volume control
|
|
65
|
-
def on_volume_write(connection, value):
|
|
66
|
-
logger.info(f'--- VOLUME Write:{value[0]}')
|
|
67
|
-
self.emit('volume', connection, value[0])
|
|
68
|
-
|
|
69
|
-
# Handler for audio control commands
|
|
70
|
-
def on_audio_control_point_write(connection: Optional[Connection], value):
|
|
71
|
-
logger.info(f'--- AUDIO CONTROL POINT Write:{value.hex()}')
|
|
72
|
-
opcode = value[0]
|
|
73
|
-
if opcode == AshaService.OPCODE_START:
|
|
74
|
-
# Start
|
|
75
|
-
audio_type = ('Unknown', 'Ringtone', 'Phone Call', 'Media')[value[2]]
|
|
76
|
-
logger.info(
|
|
77
|
-
f'### START: codec={value[1]}, '
|
|
78
|
-
f'audio_type={audio_type}, '
|
|
79
|
-
f'volume={value[3]}, '
|
|
80
|
-
f'otherstate={value[4]}'
|
|
81
|
-
)
|
|
82
|
-
self.emit(
|
|
83
|
-
'start',
|
|
84
|
-
connection,
|
|
85
|
-
{
|
|
86
|
-
'codec': value[1],
|
|
87
|
-
'audiotype': value[2],
|
|
88
|
-
'volume': value[3],
|
|
89
|
-
'otherstate': value[4],
|
|
90
|
-
},
|
|
91
|
-
)
|
|
92
|
-
elif opcode == AshaService.OPCODE_STOP:
|
|
93
|
-
logger.info('### STOP')
|
|
94
|
-
self.emit('stop', connection)
|
|
95
|
-
elif opcode == AshaService.OPCODE_STATUS:
|
|
96
|
-
logger.info(f'### STATUS: connected={value[1]}')
|
|
97
|
-
|
|
98
|
-
# OPCODE_STATUS does not need audio status point update
|
|
99
|
-
if opcode != AshaService.OPCODE_STATUS:
|
|
100
|
-
AsyncRunner.spawn(
|
|
101
|
-
device.notify_subscribers(
|
|
102
|
-
self.audio_status_characteristic, force=True
|
|
103
|
-
)
|
|
104
|
-
)
|
|
105
|
-
|
|
106
|
-
self.read_only_properties_characteristic = Characteristic(
|
|
107
|
-
GATT_ASHA_READ_ONLY_PROPERTIES_CHARACTERISTIC,
|
|
108
|
-
Characteristic.Properties.READ,
|
|
109
|
-
Characteristic.READABLE,
|
|
110
|
-
bytes(
|
|
111
|
-
[
|
|
112
|
-
AshaService.PROTOCOL_VERSION, # Version
|
|
113
|
-
self.capability,
|
|
114
|
-
]
|
|
115
|
-
)
|
|
116
|
-
+ bytes(self.hisyncid)
|
|
117
|
-
+ bytes(AshaService.FEATURE_MAP)
|
|
118
|
-
+ bytes(AshaService.RENDER_DELAY)
|
|
119
|
-
+ bytes(AshaService.RESERVED_FOR_FUTURE_USE)
|
|
120
|
-
+ bytes(AshaService.SUPPORTED_CODEC_ID),
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
self.audio_control_point_characteristic = Characteristic(
|
|
124
|
-
GATT_ASHA_AUDIO_CONTROL_POINT_CHARACTERISTIC,
|
|
125
|
-
Characteristic.Properties.WRITE
|
|
126
|
-
| Characteristic.Properties.WRITE_WITHOUT_RESPONSE,
|
|
127
|
-
Characteristic.WRITEABLE,
|
|
128
|
-
CharacteristicValue(write=on_audio_control_point_write),
|
|
129
|
-
)
|
|
130
|
-
self.audio_status_characteristic = Characteristic(
|
|
131
|
-
GATT_ASHA_AUDIO_STATUS_CHARACTERISTIC,
|
|
132
|
-
Characteristic.Properties.READ | Characteristic.Properties.NOTIFY,
|
|
133
|
-
Characteristic.READABLE,
|
|
134
|
-
bytes([0]),
|
|
135
|
-
)
|
|
136
|
-
self.volume_characteristic = Characteristic(
|
|
137
|
-
GATT_ASHA_VOLUME_CHARACTERISTIC,
|
|
138
|
-
Characteristic.Properties.WRITE_WITHOUT_RESPONSE,
|
|
139
|
-
Characteristic.WRITEABLE,
|
|
140
|
-
CharacteristicValue(write=on_volume_write),
|
|
141
|
-
)
|
|
142
|
-
|
|
143
|
-
# Register an L2CAP CoC server
|
|
144
|
-
def on_coc(channel):
|
|
145
|
-
def on_data(data):
|
|
146
|
-
logging.debug(f'<<< data received:{data}')
|
|
147
|
-
|
|
148
|
-
self.emit('data', channel.connection, data)
|
|
149
|
-
self.audio_out_data += data
|
|
150
|
-
|
|
151
|
-
channel.sink = on_data
|
|
152
|
-
|
|
153
|
-
# let the server find a free PSM
|
|
154
|
-
self.psm = device.create_l2cap_server(
|
|
155
|
-
spec=l2cap.LeCreditBasedChannelSpec(psm=self.psm, max_credits=8),
|
|
156
|
-
handler=on_coc,
|
|
157
|
-
).psm
|
|
158
|
-
self.le_psm_out_characteristic = Characteristic(
|
|
159
|
-
GATT_ASHA_LE_PSM_OUT_CHARACTERISTIC,
|
|
160
|
-
Characteristic.Properties.READ,
|
|
161
|
-
Characteristic.READABLE,
|
|
162
|
-
struct.pack('<H', self.psm),
|
|
163
|
-
)
|
|
164
|
-
|
|
165
|
-
characteristics = [
|
|
166
|
-
self.read_only_properties_characteristic,
|
|
167
|
-
self.audio_control_point_characteristic,
|
|
168
|
-
self.audio_status_characteristic,
|
|
169
|
-
self.volume_characteristic,
|
|
170
|
-
self.le_psm_out_characteristic,
|
|
171
|
-
]
|
|
172
|
-
|
|
173
|
-
super().__init__(characteristics)
|
|
174
|
-
|
|
175
|
-
def get_advertising_data(self):
|
|
176
|
-
# Advertisement only uses 4 least significant bytes of the HiSyncId.
|
|
177
|
-
return bytes(
|
|
178
|
-
AdvertisingData(
|
|
179
|
-
[
|
|
180
|
-
(
|
|
181
|
-
AdvertisingData.SERVICE_DATA_16_BIT_UUID,
|
|
182
|
-
bytes(GATT_ASHA_SERVICE)
|
|
183
|
-
+ bytes(
|
|
184
|
-
[
|
|
185
|
-
AshaService.PROTOCOL_VERSION,
|
|
186
|
-
self.capability,
|
|
187
|
-
]
|
|
188
|
-
)
|
|
189
|
-
+ bytes(self.hisyncid[:4]),
|
|
190
|
-
),
|
|
191
|
-
]
|
|
192
|
-
)
|
|
193
|
-
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|