bumble 0.0.207__py3-none-any.whl → 0.0.208__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 +9 -4
- bumble/apps/auracast.py +29 -35
- bumble/apps/bench.py +13 -10
- bumble/apps/console.py +19 -12
- bumble/apps/gg_bridge.py +1 -1
- bumble/att.py +51 -37
- bumble/core.py +301 -155
- bumble/device.py +102 -56
- bumble/gatt.py +9 -228
- bumble/gatt_adapters.py +374 -0
- bumble/gatt_client.py +38 -31
- bumble/gatt_server.py +5 -5
- bumble/host.py +11 -5
- bumble/pairing.py +5 -5
- bumble/pandora/host.py +7 -12
- bumble/profiles/aics.py +33 -23
- bumble/profiles/ascs.py +2 -1
- bumble/profiles/asha.py +11 -9
- bumble/profiles/bass.py +8 -5
- bumble/profiles/battery_service.py +13 -3
- bumble/profiles/device_information_service.py +16 -14
- bumble/profiles/gap.py +12 -8
- bumble/profiles/gatt_service.py +1 -0
- bumble/profiles/gmap.py +16 -11
- bumble/profiles/hap.py +8 -6
- bumble/profiles/heart_rate_service.py +20 -4
- bumble/profiles/mcp.py +11 -9
- bumble/profiles/pacs.py +37 -24
- bumble/profiles/tmap.py +6 -4
- bumble/profiles/vcs.py +6 -5
- bumble/profiles/vocs.py +49 -41
- bumble/utils.py +10 -0
- {bumble-0.0.207.dist-info → bumble-0.0.208.dist-info}/METADATA +3 -3
- {bumble-0.0.207.dist-info → bumble-0.0.208.dist-info}/RECORD +38 -37
- {bumble-0.0.207.dist-info → bumble-0.0.208.dist-info}/LICENSE +0 -0
- {bumble-0.0.207.dist-info → bumble-0.0.208.dist-info}/WHEEL +0 -0
- {bumble-0.0.207.dist-info → bumble-0.0.208.dist-info}/entry_points.txt +0 -0
- {bumble-0.0.207.dist-info → bumble-0.0.208.dist-info}/top_level.txt +0 -0
bumble/core.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# Copyright 2021-
|
|
1
|
+
# Copyright 2021-2025 Google LLC
|
|
2
2
|
#
|
|
3
3
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
4
|
# you may not use this file except in compliance with the License.
|
|
@@ -16,10 +16,10 @@
|
|
|
16
16
|
# Imports
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
from __future__ import annotations
|
|
19
|
-
|
|
19
|
+
|
|
20
20
|
import enum
|
|
21
21
|
import struct
|
|
22
|
-
from typing import
|
|
22
|
+
from typing import cast, overload, Literal, Union, Optional
|
|
23
23
|
from typing_extensions import Self
|
|
24
24
|
|
|
25
25
|
from bumble.company_ids import COMPANY_IDENTIFIERS
|
|
@@ -57,7 +57,7 @@ def bit_flags_to_strings(bits, bit_flag_names):
|
|
|
57
57
|
return names
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
def name_or_number(dictionary:
|
|
60
|
+
def name_or_number(dictionary: dict[int, str], number: int, width: int = 2) -> str:
|
|
61
61
|
name = dictionary.get(number)
|
|
62
62
|
if name is not None:
|
|
63
63
|
return name
|
|
@@ -200,7 +200,7 @@ class UUID:
|
|
|
200
200
|
'''
|
|
201
201
|
|
|
202
202
|
BASE_UUID = bytes.fromhex('00001000800000805F9B34FB')[::-1] # little-endian
|
|
203
|
-
UUIDS:
|
|
203
|
+
UUIDS: list[UUID] = [] # Registry of all instances created
|
|
204
204
|
|
|
205
205
|
uuid_bytes: bytes
|
|
206
206
|
name: Optional[str]
|
|
@@ -259,11 +259,11 @@ class UUID:
|
|
|
259
259
|
return cls.from_bytes(struct.pack('<I', uuid_32), name)
|
|
260
260
|
|
|
261
261
|
@classmethod
|
|
262
|
-
def parse_uuid(cls, uuid_as_bytes: bytes, offset: int) ->
|
|
262
|
+
def parse_uuid(cls, uuid_as_bytes: bytes, offset: int) -> tuple[int, UUID]:
|
|
263
263
|
return len(uuid_as_bytes), cls.from_bytes(uuid_as_bytes[offset:])
|
|
264
264
|
|
|
265
265
|
@classmethod
|
|
266
|
-
def parse_uuid_2(cls, uuid_as_bytes: bytes, offset: int) ->
|
|
266
|
+
def parse_uuid_2(cls, uuid_as_bytes: bytes, offset: int) -> tuple[int, UUID]:
|
|
267
267
|
return offset + 2, cls.from_bytes(uuid_as_bytes[offset : offset + 2])
|
|
268
268
|
|
|
269
269
|
def to_bytes(self, force_128: bool = False) -> bytes:
|
|
@@ -1280,13 +1280,13 @@ class Appearance:
|
|
|
1280
1280
|
# Advertising Data
|
|
1281
1281
|
# -----------------------------------------------------------------------------
|
|
1282
1282
|
AdvertisingDataObject = Union[
|
|
1283
|
-
|
|
1284
|
-
|
|
1283
|
+
list[UUID],
|
|
1284
|
+
tuple[UUID, bytes],
|
|
1285
1285
|
bytes,
|
|
1286
1286
|
str,
|
|
1287
1287
|
int,
|
|
1288
|
-
|
|
1289
|
-
|
|
1288
|
+
tuple[int, int],
|
|
1289
|
+
tuple[int, bytes],
|
|
1290
1290
|
Appearance,
|
|
1291
1291
|
]
|
|
1292
1292
|
|
|
@@ -1295,116 +1295,116 @@ class AdvertisingData:
|
|
|
1295
1295
|
# fmt: off
|
|
1296
1296
|
# pylint: disable=line-too-long
|
|
1297
1297
|
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
1303
|
-
|
|
1304
|
-
|
|
1305
|
-
|
|
1306
|
-
|
|
1307
|
-
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1298
|
+
class Type(OpenIntEnum):
|
|
1299
|
+
FLAGS = 0x01
|
|
1300
|
+
INCOMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS = 0x02
|
|
1301
|
+
COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS = 0x03
|
|
1302
|
+
INCOMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS = 0x04
|
|
1303
|
+
COMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS = 0x05
|
|
1304
|
+
INCOMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS = 0x06
|
|
1305
|
+
COMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS = 0x07
|
|
1306
|
+
SHORTENED_LOCAL_NAME = 0x08
|
|
1307
|
+
COMPLETE_LOCAL_NAME = 0x09
|
|
1308
|
+
TX_POWER_LEVEL = 0x0A
|
|
1309
|
+
CLASS_OF_DEVICE = 0x0D
|
|
1310
|
+
SIMPLE_PAIRING_HASH_C = 0x0E
|
|
1311
|
+
SIMPLE_PAIRING_HASH_C_192 = 0x0E
|
|
1312
|
+
SIMPLE_PAIRING_RANDOMIZER_R = 0x0F
|
|
1313
|
+
SIMPLE_PAIRING_RANDOMIZER_R_192 = 0x0F
|
|
1314
|
+
DEVICE_ID = 0x10
|
|
1315
|
+
SECURITY_MANAGER_TK_VALUE = 0x10
|
|
1316
|
+
SECURITY_MANAGER_OUT_OF_BAND_FLAGS = 0x11
|
|
1317
|
+
PERIPHERAL_CONNECTION_INTERVAL_RANGE = 0x12
|
|
1318
|
+
LIST_OF_16_BIT_SERVICE_SOLICITATION_UUIDS = 0x14
|
|
1319
|
+
LIST_OF_128_BIT_SERVICE_SOLICITATION_UUIDS = 0x15
|
|
1320
|
+
SERVICE_DATA_16_BIT_UUID = 0x16
|
|
1321
|
+
PUBLIC_TARGET_ADDRESS = 0x17
|
|
1322
|
+
RANDOM_TARGET_ADDRESS = 0x18
|
|
1323
|
+
APPEARANCE = 0x19
|
|
1324
|
+
ADVERTISING_INTERVAL = 0x1A
|
|
1325
|
+
LE_BLUETOOTH_DEVICE_ADDRESS = 0x1B
|
|
1326
|
+
LE_ROLE = 0x1C
|
|
1327
|
+
SIMPLE_PAIRING_HASH_C_256 = 0x1D
|
|
1328
|
+
SIMPLE_PAIRING_RANDOMIZER_R_256 = 0x1E
|
|
1329
|
+
LIST_OF_32_BIT_SERVICE_SOLICITATION_UUIDS = 0x1F
|
|
1330
|
+
SERVICE_DATA_32_BIT_UUID = 0x20
|
|
1331
|
+
SERVICE_DATA_128_BIT_UUID = 0x21
|
|
1332
|
+
LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE = 0x22
|
|
1333
|
+
LE_SECURE_CONNECTIONS_RANDOM_VALUE = 0x23
|
|
1334
|
+
URI = 0x24
|
|
1335
|
+
INDOOR_POSITIONING = 0x25
|
|
1336
|
+
TRANSPORT_DISCOVERY_DATA = 0x26
|
|
1337
|
+
LE_SUPPORTED_FEATURES = 0x27
|
|
1338
|
+
CHANNEL_MAP_UPDATE_INDICATION = 0x28
|
|
1339
|
+
PB_ADV = 0x29
|
|
1340
|
+
MESH_MESSAGE = 0x2A
|
|
1341
|
+
MESH_BEACON = 0x2B
|
|
1342
|
+
BIGINFO = 0x2C
|
|
1343
|
+
BROADCAST_CODE = 0x2D
|
|
1344
|
+
RESOLVABLE_SET_IDENTIFIER = 0x2E
|
|
1345
|
+
ADVERTISING_INTERVAL_LONG = 0x2F
|
|
1346
|
+
BROADCAST_NAME = 0x30
|
|
1347
|
+
ENCRYPTED_ADVERTISING_DATA = 0x31
|
|
1348
|
+
PERIODIC_ADVERTISING_RESPONSE_TIMING_INFORMATION = 0x32
|
|
1349
|
+
ELECTRONIC_SHELF_LABEL = 0x34
|
|
1350
|
+
THREE_D_INFORMATION_DATA = 0x3D
|
|
1351
|
+
MANUFACTURER_SPECIFIC_DATA = 0xFF
|
|
1352
|
+
|
|
1353
|
+
# For backward-compatibility
|
|
1354
|
+
FLAGS = Type.FLAGS
|
|
1355
|
+
INCOMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS = Type.INCOMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS
|
|
1356
|
+
COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS = Type.COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS
|
|
1357
|
+
INCOMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS = Type.INCOMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS
|
|
1358
|
+
COMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS = Type.COMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS
|
|
1359
|
+
INCOMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS = Type.INCOMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS
|
|
1360
|
+
COMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS = Type.COMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS
|
|
1361
|
+
SHORTENED_LOCAL_NAME = Type.SHORTENED_LOCAL_NAME
|
|
1362
|
+
COMPLETE_LOCAL_NAME = Type.COMPLETE_LOCAL_NAME
|
|
1363
|
+
TX_POWER_LEVEL = Type.TX_POWER_LEVEL
|
|
1364
|
+
CLASS_OF_DEVICE = Type.CLASS_OF_DEVICE
|
|
1365
|
+
SIMPLE_PAIRING_HASH_C = Type.SIMPLE_PAIRING_HASH_C
|
|
1366
|
+
SIMPLE_PAIRING_HASH_C_192 = Type.SIMPLE_PAIRING_HASH_C_192
|
|
1367
|
+
SIMPLE_PAIRING_RANDOMIZER_R = Type.SIMPLE_PAIRING_RANDOMIZER_R
|
|
1368
|
+
SIMPLE_PAIRING_RANDOMIZER_R_192 = Type.SIMPLE_PAIRING_RANDOMIZER_R_192
|
|
1369
|
+
DEVICE_ID = Type.DEVICE_ID
|
|
1370
|
+
SECURITY_MANAGER_TK_VALUE = Type.SECURITY_MANAGER_TK_VALUE
|
|
1371
|
+
SECURITY_MANAGER_OUT_OF_BAND_FLAGS = Type.SECURITY_MANAGER_OUT_OF_BAND_FLAGS
|
|
1372
|
+
PERIPHERAL_CONNECTION_INTERVAL_RANGE = Type.PERIPHERAL_CONNECTION_INTERVAL_RANGE
|
|
1373
|
+
LIST_OF_16_BIT_SERVICE_SOLICITATION_UUIDS = Type.LIST_OF_16_BIT_SERVICE_SOLICITATION_UUIDS
|
|
1374
|
+
LIST_OF_128_BIT_SERVICE_SOLICITATION_UUIDS = Type.LIST_OF_128_BIT_SERVICE_SOLICITATION_UUIDS
|
|
1375
|
+
SERVICE_DATA = Type.SERVICE_DATA_16_BIT_UUID
|
|
1376
|
+
SERVICE_DATA_16_BIT_UUID = Type.SERVICE_DATA_16_BIT_UUID
|
|
1377
|
+
PUBLIC_TARGET_ADDRESS = Type.PUBLIC_TARGET_ADDRESS
|
|
1378
|
+
RANDOM_TARGET_ADDRESS = Type.RANDOM_TARGET_ADDRESS
|
|
1379
|
+
APPEARANCE = Type.APPEARANCE
|
|
1380
|
+
ADVERTISING_INTERVAL = Type.ADVERTISING_INTERVAL
|
|
1381
|
+
LE_BLUETOOTH_DEVICE_ADDRESS = Type.LE_BLUETOOTH_DEVICE_ADDRESS
|
|
1382
|
+
LE_ROLE = Type.LE_ROLE
|
|
1383
|
+
SIMPLE_PAIRING_HASH_C_256 = Type.SIMPLE_PAIRING_HASH_C_256
|
|
1384
|
+
SIMPLE_PAIRING_RANDOMIZER_R_256 = Type.SIMPLE_PAIRING_RANDOMIZER_R_256
|
|
1385
|
+
LIST_OF_32_BIT_SERVICE_SOLICITATION_UUIDS = Type.LIST_OF_32_BIT_SERVICE_SOLICITATION_UUIDS
|
|
1386
|
+
SERVICE_DATA_32_BIT_UUID = Type.SERVICE_DATA_32_BIT_UUID
|
|
1387
|
+
SERVICE_DATA_128_BIT_UUID = Type.SERVICE_DATA_128_BIT_UUID
|
|
1388
|
+
LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE = Type.LE_SECURE_CONNECTIONS_CONFIRMATION_VALUE
|
|
1389
|
+
LE_SECURE_CONNECTIONS_RANDOM_VALUE = Type.LE_SECURE_CONNECTIONS_RANDOM_VALUE
|
|
1390
|
+
URI = Type.URI
|
|
1391
|
+
INDOOR_POSITIONING = Type.INDOOR_POSITIONING
|
|
1392
|
+
TRANSPORT_DISCOVERY_DATA = Type.TRANSPORT_DISCOVERY_DATA
|
|
1393
|
+
LE_SUPPORTED_FEATURES = Type.LE_SUPPORTED_FEATURES
|
|
1394
|
+
CHANNEL_MAP_UPDATE_INDICATION = Type.CHANNEL_MAP_UPDATE_INDICATION
|
|
1395
|
+
PB_ADV = Type.PB_ADV
|
|
1396
|
+
MESH_MESSAGE = Type.MESH_MESSAGE
|
|
1397
|
+
MESH_BEACON = Type.MESH_BEACON
|
|
1398
|
+
BIGINFO = Type.BIGINFO
|
|
1399
|
+
BROADCAST_CODE = Type.BROADCAST_CODE
|
|
1400
|
+
RESOLVABLE_SET_IDENTIFIER = Type.RESOLVABLE_SET_IDENTIFIER
|
|
1401
|
+
ADVERTISING_INTERVAL_LONG = Type.ADVERTISING_INTERVAL_LONG
|
|
1402
|
+
BROADCAST_NAME = Type.BROADCAST_NAME
|
|
1403
|
+
ENCRYPTED_ADVERTISING_DATA = Type.ENCRYPTED_ADVERTISING_DATA
|
|
1404
|
+
PERIODIC_ADVERTISING_RESPONSE_TIMING_INFORMATION = Type.PERIODIC_ADVERTISING_RESPONSE_TIMING_INFORMATION
|
|
1405
|
+
ELECTRONIC_SHELF_LABEL = Type.ELECTRONIC_SHELF_LABEL
|
|
1406
|
+
THREE_D_INFORMATION_DATA = Type.THREE_D_INFORMATION_DATA
|
|
1407
|
+
MANUFACTURER_SPECIFIC_DATA = Type.MANUFACTURER_SPECIFIC_DATA
|
|
1408
1408
|
|
|
1409
1409
|
LE_LIMITED_DISCOVERABLE_MODE_FLAG = 0x01
|
|
1410
1410
|
LE_GENERAL_DISCOVERABLE_MODE_FLAG = 0x02
|
|
@@ -1412,12 +1412,12 @@ class AdvertisingData:
|
|
|
1412
1412
|
BR_EDR_CONTROLLER_FLAG = 0x08
|
|
1413
1413
|
BR_EDR_HOST_FLAG = 0x10
|
|
1414
1414
|
|
|
1415
|
-
ad_structures:
|
|
1415
|
+
ad_structures: list[tuple[int, bytes]]
|
|
1416
1416
|
|
|
1417
1417
|
# fmt: on
|
|
1418
1418
|
# pylint: enable=line-too-long
|
|
1419
1419
|
|
|
1420
|
-
def __init__(self, ad_structures: Optional[
|
|
1420
|
+
def __init__(self, ad_structures: Optional[list[tuple[int, bytes]]] = None) -> None:
|
|
1421
1421
|
if ad_structures is None:
|
|
1422
1422
|
ad_structures = []
|
|
1423
1423
|
self.ad_structures = ad_structures[:]
|
|
@@ -1444,7 +1444,7 @@ class AdvertisingData:
|
|
|
1444
1444
|
return ','.join(bit_flags_to_strings(flags, flag_names))
|
|
1445
1445
|
|
|
1446
1446
|
@staticmethod
|
|
1447
|
-
def uuid_list_to_objects(ad_data: bytes, uuid_size: int) ->
|
|
1447
|
+
def uuid_list_to_objects(ad_data: bytes, uuid_size: int) -> list[UUID]:
|
|
1448
1448
|
uuids = []
|
|
1449
1449
|
offset = 0
|
|
1450
1450
|
while (offset + uuid_size) <= len(ad_data):
|
|
@@ -1461,8 +1461,8 @@ class AdvertisingData:
|
|
|
1461
1461
|
]
|
|
1462
1462
|
)
|
|
1463
1463
|
|
|
1464
|
-
@
|
|
1465
|
-
def ad_data_to_string(ad_type, ad_data):
|
|
1464
|
+
@classmethod
|
|
1465
|
+
def ad_data_to_string(cls, ad_type: int, ad_data: bytes) -> str:
|
|
1466
1466
|
if ad_type == AdvertisingData.FLAGS:
|
|
1467
1467
|
ad_type_str = 'Flags'
|
|
1468
1468
|
ad_data_str = AdvertisingData.flags_to_string(ad_data[0], short=True)
|
|
@@ -1521,72 +1521,72 @@ class AdvertisingData:
|
|
|
1521
1521
|
ad_type_str = 'Broadcast Name'
|
|
1522
1522
|
ad_data_str = ad_data.decode('utf-8')
|
|
1523
1523
|
else:
|
|
1524
|
-
ad_type_str = AdvertisingData.
|
|
1524
|
+
ad_type_str = AdvertisingData.Type(ad_type).name
|
|
1525
1525
|
ad_data_str = ad_data.hex()
|
|
1526
1526
|
|
|
1527
1527
|
return f'[{ad_type_str}]: {ad_data_str}'
|
|
1528
1528
|
|
|
1529
1529
|
# pylint: disable=too-many-return-statements
|
|
1530
|
-
@
|
|
1531
|
-
def ad_data_to_object(ad_type: int, ad_data: bytes) -> AdvertisingDataObject:
|
|
1530
|
+
@classmethod
|
|
1531
|
+
def ad_data_to_object(cls, ad_type: int, ad_data: bytes) -> AdvertisingDataObject:
|
|
1532
1532
|
if ad_type in (
|
|
1533
|
-
AdvertisingData.COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS,
|
|
1534
|
-
AdvertisingData.INCOMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS,
|
|
1535
|
-
AdvertisingData.LIST_OF_16_BIT_SERVICE_SOLICITATION_UUIDS,
|
|
1533
|
+
AdvertisingData.Type.COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS,
|
|
1534
|
+
AdvertisingData.Type.INCOMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS,
|
|
1535
|
+
AdvertisingData.Type.LIST_OF_16_BIT_SERVICE_SOLICITATION_UUIDS,
|
|
1536
1536
|
):
|
|
1537
1537
|
return AdvertisingData.uuid_list_to_objects(ad_data, 2)
|
|
1538
1538
|
|
|
1539
1539
|
if ad_type in (
|
|
1540
|
-
AdvertisingData.COMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS,
|
|
1541
|
-
AdvertisingData.INCOMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS,
|
|
1542
|
-
AdvertisingData.LIST_OF_32_BIT_SERVICE_SOLICITATION_UUIDS,
|
|
1540
|
+
AdvertisingData.Type.COMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS,
|
|
1541
|
+
AdvertisingData.Type.INCOMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS,
|
|
1542
|
+
AdvertisingData.Type.LIST_OF_32_BIT_SERVICE_SOLICITATION_UUIDS,
|
|
1543
1543
|
):
|
|
1544
1544
|
return AdvertisingData.uuid_list_to_objects(ad_data, 4)
|
|
1545
1545
|
|
|
1546
1546
|
if ad_type in (
|
|
1547
|
-
AdvertisingData.COMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS,
|
|
1548
|
-
AdvertisingData.INCOMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS,
|
|
1549
|
-
AdvertisingData.LIST_OF_128_BIT_SERVICE_SOLICITATION_UUIDS,
|
|
1547
|
+
AdvertisingData.Type.COMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS,
|
|
1548
|
+
AdvertisingData.Type.INCOMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS,
|
|
1549
|
+
AdvertisingData.Type.LIST_OF_128_BIT_SERVICE_SOLICITATION_UUIDS,
|
|
1550
1550
|
):
|
|
1551
1551
|
return AdvertisingData.uuid_list_to_objects(ad_data, 16)
|
|
1552
1552
|
|
|
1553
|
-
if ad_type == AdvertisingData.SERVICE_DATA_16_BIT_UUID:
|
|
1553
|
+
if ad_type == AdvertisingData.Type.SERVICE_DATA_16_BIT_UUID:
|
|
1554
1554
|
return (UUID.from_bytes(ad_data[:2]), ad_data[2:])
|
|
1555
1555
|
|
|
1556
|
-
if ad_type == AdvertisingData.SERVICE_DATA_32_BIT_UUID:
|
|
1556
|
+
if ad_type == AdvertisingData.Type.SERVICE_DATA_32_BIT_UUID:
|
|
1557
1557
|
return (UUID.from_bytes(ad_data[:4]), ad_data[4:])
|
|
1558
1558
|
|
|
1559
|
-
if ad_type == AdvertisingData.SERVICE_DATA_128_BIT_UUID:
|
|
1559
|
+
if ad_type == AdvertisingData.Type.SERVICE_DATA_128_BIT_UUID:
|
|
1560
1560
|
return (UUID.from_bytes(ad_data[:16]), ad_data[16:])
|
|
1561
1561
|
|
|
1562
1562
|
if ad_type in (
|
|
1563
|
-
AdvertisingData.SHORTENED_LOCAL_NAME,
|
|
1564
|
-
AdvertisingData.COMPLETE_LOCAL_NAME,
|
|
1565
|
-
AdvertisingData.URI,
|
|
1566
|
-
AdvertisingData.BROADCAST_NAME,
|
|
1563
|
+
AdvertisingData.Type.SHORTENED_LOCAL_NAME,
|
|
1564
|
+
AdvertisingData.Type.COMPLETE_LOCAL_NAME,
|
|
1565
|
+
AdvertisingData.Type.URI,
|
|
1566
|
+
AdvertisingData.Type.BROADCAST_NAME,
|
|
1567
1567
|
):
|
|
1568
1568
|
return ad_data.decode("utf-8")
|
|
1569
1569
|
|
|
1570
|
-
if ad_type in (AdvertisingData.TX_POWER_LEVEL, AdvertisingData.FLAGS):
|
|
1570
|
+
if ad_type in (AdvertisingData.Type.TX_POWER_LEVEL, AdvertisingData.Type.FLAGS):
|
|
1571
1571
|
return cast(int, struct.unpack('B', ad_data)[0])
|
|
1572
1572
|
|
|
1573
|
-
if ad_type in (AdvertisingData.ADVERTISING_INTERVAL,):
|
|
1573
|
+
if ad_type in (AdvertisingData.Type.ADVERTISING_INTERVAL,):
|
|
1574
1574
|
return cast(int, struct.unpack('<H', ad_data)[0])
|
|
1575
1575
|
|
|
1576
|
-
if ad_type == AdvertisingData.CLASS_OF_DEVICE:
|
|
1576
|
+
if ad_type == AdvertisingData.Type.CLASS_OF_DEVICE:
|
|
1577
1577
|
return cast(int, struct.unpack('<I', bytes([*ad_data, 0]))[0])
|
|
1578
1578
|
|
|
1579
|
-
if ad_type == AdvertisingData.PERIPHERAL_CONNECTION_INTERVAL_RANGE:
|
|
1580
|
-
return cast(
|
|
1579
|
+
if ad_type == AdvertisingData.Type.PERIPHERAL_CONNECTION_INTERVAL_RANGE:
|
|
1580
|
+
return cast(tuple[int, int], struct.unpack('<HH', ad_data))
|
|
1581
1581
|
|
|
1582
|
-
if ad_type == AdvertisingData.
|
|
1583
|
-
return (cast(int, struct.unpack_from('<H', ad_data, 0)[0]), ad_data[2:])
|
|
1584
|
-
|
|
1585
|
-
if ad_type == AdvertisingData.APPEARANCE:
|
|
1582
|
+
if ad_type == AdvertisingData.Type.APPEARANCE:
|
|
1586
1583
|
return Appearance.from_int(
|
|
1587
1584
|
cast(int, struct.unpack_from('<H', ad_data, 0)[0])
|
|
1588
1585
|
)
|
|
1589
1586
|
|
|
1587
|
+
if ad_type == AdvertisingData.Type.MANUFACTURER_SPECIFIC_DATA:
|
|
1588
|
+
return (cast(int, struct.unpack_from('<H', ad_data, 0)[0]), ad_data[2:])
|
|
1589
|
+
|
|
1590
1590
|
return ad_data
|
|
1591
1591
|
|
|
1592
1592
|
def append(self, data: bytes) -> None:
|
|
@@ -1600,7 +1600,80 @@ class AdvertisingData:
|
|
|
1600
1600
|
self.ad_structures.append((ad_type, ad_data))
|
|
1601
1601
|
offset += length
|
|
1602
1602
|
|
|
1603
|
-
|
|
1603
|
+
@overload
|
|
1604
|
+
def get_all(
|
|
1605
|
+
self,
|
|
1606
|
+
type_id: Literal[
|
|
1607
|
+
AdvertisingData.Type.COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS,
|
|
1608
|
+
AdvertisingData.Type.INCOMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS,
|
|
1609
|
+
AdvertisingData.Type.LIST_OF_16_BIT_SERVICE_SOLICITATION_UUIDS,
|
|
1610
|
+
AdvertisingData.Type.COMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS,
|
|
1611
|
+
AdvertisingData.Type.INCOMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS,
|
|
1612
|
+
AdvertisingData.Type.LIST_OF_32_BIT_SERVICE_SOLICITATION_UUIDS,
|
|
1613
|
+
AdvertisingData.Type.COMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS,
|
|
1614
|
+
AdvertisingData.Type.INCOMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS,
|
|
1615
|
+
AdvertisingData.Type.LIST_OF_128_BIT_SERVICE_SOLICITATION_UUIDS,
|
|
1616
|
+
],
|
|
1617
|
+
raw: Literal[False] = False,
|
|
1618
|
+
) -> list[list[UUID]]: ...
|
|
1619
|
+
@overload
|
|
1620
|
+
def get_all(
|
|
1621
|
+
self,
|
|
1622
|
+
type_id: Literal[
|
|
1623
|
+
AdvertisingData.Type.SERVICE_DATA_16_BIT_UUID,
|
|
1624
|
+
AdvertisingData.Type.SERVICE_DATA_32_BIT_UUID,
|
|
1625
|
+
AdvertisingData.Type.SERVICE_DATA_128_BIT_UUID,
|
|
1626
|
+
],
|
|
1627
|
+
raw: Literal[False] = False,
|
|
1628
|
+
) -> list[tuple[UUID, bytes]]: ...
|
|
1629
|
+
@overload
|
|
1630
|
+
def get_all(
|
|
1631
|
+
self,
|
|
1632
|
+
type_id: Literal[
|
|
1633
|
+
AdvertisingData.Type.SHORTENED_LOCAL_NAME,
|
|
1634
|
+
AdvertisingData.Type.COMPLETE_LOCAL_NAME,
|
|
1635
|
+
AdvertisingData.Type.URI,
|
|
1636
|
+
AdvertisingData.Type.BROADCAST_NAME,
|
|
1637
|
+
],
|
|
1638
|
+
raw: Literal[False] = False,
|
|
1639
|
+
) -> list[str]: ...
|
|
1640
|
+
@overload
|
|
1641
|
+
def get_all(
|
|
1642
|
+
self,
|
|
1643
|
+
type_id: Literal[
|
|
1644
|
+
AdvertisingData.Type.TX_POWER_LEVEL,
|
|
1645
|
+
AdvertisingData.Type.FLAGS,
|
|
1646
|
+
AdvertisingData.Type.ADVERTISING_INTERVAL,
|
|
1647
|
+
AdvertisingData.Type.CLASS_OF_DEVICE,
|
|
1648
|
+
],
|
|
1649
|
+
raw: Literal[False] = False,
|
|
1650
|
+
) -> list[int]: ...
|
|
1651
|
+
@overload
|
|
1652
|
+
def get_all(
|
|
1653
|
+
self,
|
|
1654
|
+
type_id: Literal[AdvertisingData.Type.PERIPHERAL_CONNECTION_INTERVAL_RANGE,],
|
|
1655
|
+
raw: Literal[False] = False,
|
|
1656
|
+
) -> list[tuple[int, int]]: ...
|
|
1657
|
+
@overload
|
|
1658
|
+
def get_all(
|
|
1659
|
+
self,
|
|
1660
|
+
type_id: Literal[AdvertisingData.Type.MANUFACTURER_SPECIFIC_DATA,],
|
|
1661
|
+
raw: Literal[False] = False,
|
|
1662
|
+
) -> list[tuple[int, bytes]]: ...
|
|
1663
|
+
@overload
|
|
1664
|
+
def get_all(
|
|
1665
|
+
self,
|
|
1666
|
+
type_id: Literal[AdvertisingData.Type.APPEARANCE,],
|
|
1667
|
+
raw: Literal[False] = False,
|
|
1668
|
+
) -> list[Appearance]: ...
|
|
1669
|
+
@overload
|
|
1670
|
+
def get_all(self, type_id: int, raw: Literal[True]) -> list[bytes]: ...
|
|
1671
|
+
@overload
|
|
1672
|
+
def get_all(
|
|
1673
|
+
self, type_id: int, raw: bool = False
|
|
1674
|
+
) -> list[AdvertisingDataObject]: ...
|
|
1675
|
+
|
|
1676
|
+
def get_all(self, type_id: int, raw: bool = False) -> list[AdvertisingDataObject]: # type: ignore[misc]
|
|
1604
1677
|
'''
|
|
1605
1678
|
Get Advertising Data Structure(s) with a given type
|
|
1606
1679
|
|
|
@@ -1612,6 +1685,79 @@ class AdvertisingData:
|
|
|
1612
1685
|
|
|
1613
1686
|
return [process_ad_data(ad[1]) for ad in self.ad_structures if ad[0] == type_id]
|
|
1614
1687
|
|
|
1688
|
+
@overload
|
|
1689
|
+
def get(
|
|
1690
|
+
self,
|
|
1691
|
+
type_id: Literal[
|
|
1692
|
+
AdvertisingData.Type.COMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS,
|
|
1693
|
+
AdvertisingData.Type.INCOMPLETE_LIST_OF_16_BIT_SERVICE_CLASS_UUIDS,
|
|
1694
|
+
AdvertisingData.Type.LIST_OF_16_BIT_SERVICE_SOLICITATION_UUIDS,
|
|
1695
|
+
AdvertisingData.Type.COMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS,
|
|
1696
|
+
AdvertisingData.Type.INCOMPLETE_LIST_OF_32_BIT_SERVICE_CLASS_UUIDS,
|
|
1697
|
+
AdvertisingData.Type.LIST_OF_32_BIT_SERVICE_SOLICITATION_UUIDS,
|
|
1698
|
+
AdvertisingData.Type.COMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS,
|
|
1699
|
+
AdvertisingData.Type.INCOMPLETE_LIST_OF_128_BIT_SERVICE_CLASS_UUIDS,
|
|
1700
|
+
AdvertisingData.Type.LIST_OF_128_BIT_SERVICE_SOLICITATION_UUIDS,
|
|
1701
|
+
],
|
|
1702
|
+
raw: Literal[False] = False,
|
|
1703
|
+
) -> Optional[list[UUID]]: ...
|
|
1704
|
+
@overload
|
|
1705
|
+
def get(
|
|
1706
|
+
self,
|
|
1707
|
+
type_id: Literal[
|
|
1708
|
+
AdvertisingData.Type.SERVICE_DATA_16_BIT_UUID,
|
|
1709
|
+
AdvertisingData.Type.SERVICE_DATA_32_BIT_UUID,
|
|
1710
|
+
AdvertisingData.Type.SERVICE_DATA_128_BIT_UUID,
|
|
1711
|
+
],
|
|
1712
|
+
raw: Literal[False] = False,
|
|
1713
|
+
) -> Optional[tuple[UUID, bytes]]: ...
|
|
1714
|
+
@overload
|
|
1715
|
+
def get(
|
|
1716
|
+
self,
|
|
1717
|
+
type_id: Literal[
|
|
1718
|
+
AdvertisingData.Type.SHORTENED_LOCAL_NAME,
|
|
1719
|
+
AdvertisingData.Type.COMPLETE_LOCAL_NAME,
|
|
1720
|
+
AdvertisingData.Type.URI,
|
|
1721
|
+
AdvertisingData.Type.BROADCAST_NAME,
|
|
1722
|
+
],
|
|
1723
|
+
raw: Literal[False] = False,
|
|
1724
|
+
) -> Optional[Optional[str]]: ...
|
|
1725
|
+
@overload
|
|
1726
|
+
def get(
|
|
1727
|
+
self,
|
|
1728
|
+
type_id: Literal[
|
|
1729
|
+
AdvertisingData.Type.TX_POWER_LEVEL,
|
|
1730
|
+
AdvertisingData.Type.FLAGS,
|
|
1731
|
+
AdvertisingData.Type.ADVERTISING_INTERVAL,
|
|
1732
|
+
AdvertisingData.Type.CLASS_OF_DEVICE,
|
|
1733
|
+
],
|
|
1734
|
+
raw: Literal[False] = False,
|
|
1735
|
+
) -> Optional[int]: ...
|
|
1736
|
+
@overload
|
|
1737
|
+
def get(
|
|
1738
|
+
self,
|
|
1739
|
+
type_id: Literal[AdvertisingData.Type.PERIPHERAL_CONNECTION_INTERVAL_RANGE,],
|
|
1740
|
+
raw: Literal[False] = False,
|
|
1741
|
+
) -> Optional[tuple[int, int]]: ...
|
|
1742
|
+
@overload
|
|
1743
|
+
def get(
|
|
1744
|
+
self,
|
|
1745
|
+
type_id: Literal[AdvertisingData.Type.MANUFACTURER_SPECIFIC_DATA,],
|
|
1746
|
+
raw: Literal[False] = False,
|
|
1747
|
+
) -> Optional[tuple[int, bytes]]: ...
|
|
1748
|
+
@overload
|
|
1749
|
+
def get(
|
|
1750
|
+
self,
|
|
1751
|
+
type_id: Literal[AdvertisingData.Type.APPEARANCE,],
|
|
1752
|
+
raw: Literal[False] = False,
|
|
1753
|
+
) -> Optional[Appearance]: ...
|
|
1754
|
+
@overload
|
|
1755
|
+
def get(self, type_id: int, raw: Literal[True]) -> Optional[bytes]: ...
|
|
1756
|
+
@overload
|
|
1757
|
+
def get(
|
|
1758
|
+
self, type_id: int, raw: bool = False
|
|
1759
|
+
) -> Optional[AdvertisingDataObject]: ...
|
|
1760
|
+
|
|
1615
1761
|
def get(self, type_id: int, raw: bool = False) -> Optional[AdvertisingDataObject]:
|
|
1616
1762
|
'''
|
|
1617
1763
|
Get Advertising Data Structure(s) with a given type
|