bumble 0.0.198__py3-none-any.whl → 0.0.200__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 +502 -202
- bumble/apps/controller_info.py +60 -0
- bumble/apps/pair.py +32 -5
- bumble/apps/player/player.py +608 -0
- bumble/apps/speaker/speaker.py +25 -27
- bumble/att.py +57 -41
- bumble/avc.py +1 -2
- bumble/avdtp.py +56 -99
- bumble/avrcp.py +48 -29
- bumble/codecs.py +214 -68
- bumble/decoder.py +14 -10
- bumble/device.py +19 -11
- 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 +298 -7
- bumble/hfp.py +52 -48
- bumble/host.py +28 -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 +674 -0
- bumble/profiles/vcp.py +5 -3
- bumble/rtp.py +110 -0
- bumble/smp.py +23 -4
- bumble/transport/android_netsim.py +3 -0
- bumble/transport/pyusb.py +20 -2
- {bumble-0.0.198.dist-info → bumble-0.0.200.dist-info}/METADATA +2 -2
- {bumble-0.0.198.dist-info → bumble-0.0.200.dist-info}/RECORD +36 -31
- {bumble-0.0.198.dist-info → bumble-0.0.200.dist-info}/WHEEL +1 -1
- {bumble-0.0.198.dist-info → bumble-0.0.200.dist-info}/entry_points.txt +1 -0
- bumble/profiles/asha_service.py +0 -193
- {bumble-0.0.198.dist-info → bumble-0.0.200.dist-info}/LICENSE +0 -0
- {bumble-0.0.198.dist-info → bumble-0.0.200.dist-info}/top_level.txt +0 -0
bumble/gatt_client.py
CHANGED
|
@@ -68,7 +68,7 @@ from .att import (
|
|
|
68
68
|
ATT_Error,
|
|
69
69
|
)
|
|
70
70
|
from . import core
|
|
71
|
-
from .core import UUID, InvalidStateError
|
|
71
|
+
from .core import UUID, InvalidStateError
|
|
72
72
|
from .gatt import (
|
|
73
73
|
GATT_CHARACTERISTIC_ATTRIBUTE_TYPE,
|
|
74
74
|
GATT_CLIENT_CHARACTERISTIC_CONFIGURATION_DESCRIPTOR,
|
|
@@ -345,12 +345,7 @@ class Client:
|
|
|
345
345
|
self.mtu_exchange_done = True
|
|
346
346
|
response = await self.send_request(ATT_Exchange_MTU_Request(client_rx_mtu=mtu))
|
|
347
347
|
if response.op_code == ATT_ERROR_RESPONSE:
|
|
348
|
-
raise
|
|
349
|
-
response.error_code,
|
|
350
|
-
'att',
|
|
351
|
-
ATT_PDU.error_name(response.error_code),
|
|
352
|
-
response,
|
|
353
|
-
)
|
|
348
|
+
raise ATT_Error(error_code=response.error_code, message=response)
|
|
354
349
|
|
|
355
350
|
# Compute the final MTU
|
|
356
351
|
self.connection.att_mtu = min(mtu, response.server_rx_mtu)
|
|
@@ -936,12 +931,7 @@ class Client:
|
|
|
936
931
|
if response is None:
|
|
937
932
|
raise TimeoutError('read timeout')
|
|
938
933
|
if response.op_code == ATT_ERROR_RESPONSE:
|
|
939
|
-
raise
|
|
940
|
-
response.error_code,
|
|
941
|
-
'att',
|
|
942
|
-
ATT_PDU.error_name(response.error_code),
|
|
943
|
-
response,
|
|
944
|
-
)
|
|
934
|
+
raise ATT_Error(error_code=response.error_code, message=response)
|
|
945
935
|
|
|
946
936
|
# If the value is the max size for the MTU, try to read more unless the caller
|
|
947
937
|
# specifically asked not to do that
|
|
@@ -963,12 +953,7 @@ class Client:
|
|
|
963
953
|
ATT_INVALID_OFFSET_ERROR,
|
|
964
954
|
):
|
|
965
955
|
break
|
|
966
|
-
raise
|
|
967
|
-
response.error_code,
|
|
968
|
-
'att',
|
|
969
|
-
ATT_PDU.error_name(response.error_code),
|
|
970
|
-
response,
|
|
971
|
-
)
|
|
956
|
+
raise ATT_Error(error_code=response.error_code, message=response)
|
|
972
957
|
|
|
973
958
|
part = response.part_attribute_value
|
|
974
959
|
attribute_value += part
|
|
@@ -1061,12 +1046,7 @@ class Client:
|
|
|
1061
1046
|
)
|
|
1062
1047
|
)
|
|
1063
1048
|
if response.op_code == ATT_ERROR_RESPONSE:
|
|
1064
|
-
raise
|
|
1065
|
-
response.error_code,
|
|
1066
|
-
'att',
|
|
1067
|
-
ATT_PDU.error_name(response.error_code),
|
|
1068
|
-
response,
|
|
1069
|
-
)
|
|
1049
|
+
raise ATT_Error(error_code=response.error_code, message=response)
|
|
1070
1050
|
else:
|
|
1071
1051
|
await self.send_command(
|
|
1072
1052
|
ATT_Write_Command(
|
bumble/gatt_server.py
CHANGED
|
@@ -915,7 +915,7 @@ class Server(EventEmitter):
|
|
|
915
915
|
See Bluetooth spec Vol 3, Part F - 3.4.5.1 Write Request
|
|
916
916
|
'''
|
|
917
917
|
|
|
918
|
-
# Check
|
|
918
|
+
# Check that the attribute exists
|
|
919
919
|
attribute = self.get_attribute(request.attribute_handle)
|
|
920
920
|
if attribute is None:
|
|
921
921
|
self.send_response(
|
|
@@ -942,11 +942,19 @@ class Server(EventEmitter):
|
|
|
942
942
|
)
|
|
943
943
|
return
|
|
944
944
|
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
|
|
949
|
-
|
|
945
|
+
try:
|
|
946
|
+
# Accept the value
|
|
947
|
+
await attribute.write_value(connection, request.attribute_value)
|
|
948
|
+
except ATT_Error as error:
|
|
949
|
+
response = ATT_Error_Response(
|
|
950
|
+
request_opcode_in_error=request.op_code,
|
|
951
|
+
attribute_handle_in_error=request.attribute_handle,
|
|
952
|
+
error_code=error.error_code,
|
|
953
|
+
)
|
|
954
|
+
else:
|
|
955
|
+
# Done
|
|
956
|
+
response = ATT_Write_Response()
|
|
957
|
+
self.send_response(connection, response)
|
|
950
958
|
|
|
951
959
|
@AsyncRunner.run_in_task()
|
|
952
960
|
async def on_att_write_command(self, connection, request):
|
bumble/hci.py
CHANGED
|
@@ -267,6 +267,19 @@ HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED_V2_EVENT = 0X26
|
|
|
267
267
|
HCI_LE_PERIODIC_ADVERTISING_SUBEVENT_DATA_REQUEST_EVENT = 0X27
|
|
268
268
|
HCI_LE_PERIODIC_ADVERTISING_RESPONSE_REPORT_EVENT = 0X28
|
|
269
269
|
HCI_LE_ENHANCED_CONNECTION_COMPLETE_V2_EVENT = 0X29
|
|
270
|
+
HCI_LE_READ_ALL_REMOTE_FEATURES_COMPLETE_EVENT = 0x2A
|
|
271
|
+
HCI_LE_CIS_ESTABLISHED_V2_EVENT = 0x2B
|
|
272
|
+
HCI_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMPLETE_EVENT = 0x2C
|
|
273
|
+
HCI_LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE_EVENT = 0x2D
|
|
274
|
+
HCI_LE_CS_SECURITY_ENABLE_COMPLETE_EVENT = 0x2E
|
|
275
|
+
HCI_LE_CS_CONFIG_COMPLETE_EVENT = 0x2F
|
|
276
|
+
HCI_LE_CS_PROCEDURE_ENABLE_EVENT = 0x30
|
|
277
|
+
HCI_LE_CS_SUBEVENT_RESULT_EVENT = 0x31
|
|
278
|
+
HCI_LE_CS_SUBEVENT_RESULT_CONTINUE_EVENT = 0x32
|
|
279
|
+
HCI_LE_CS_TEST_END_COMPLETE_EVENT = 0x33
|
|
280
|
+
HCI_LE_MONITORED_ADVERTISERS_REPORT_EVENT = 0x34
|
|
281
|
+
HCI_LE_FRAME_SPACE_UPDATE_EVENT = 0x35
|
|
282
|
+
|
|
270
283
|
|
|
271
284
|
|
|
272
285
|
# HCI Command
|
|
@@ -573,11 +586,36 @@ HCI_LE_SET_DATA_RELATED_ADDRESS_CHANGES_COMMAND = hci_c
|
|
|
573
586
|
HCI_LE_SET_DEFAULT_SUBRATE_COMMAND = hci_command_op_code(0x08, 0x007D)
|
|
574
587
|
HCI_LE_SUBRATE_REQUEST_COMMAND = hci_command_op_code(0x08, 0x007E)
|
|
575
588
|
HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V2_COMMAND = hci_command_op_code(0x08, 0x007F)
|
|
589
|
+
HCI_LE_SET_DECISION_DATA_COMMAND = hci_command_op_code(0x08, 0x0080)
|
|
590
|
+
HCI_LE_SET_DECISION_INSTRUCTIONS_COMMAND = hci_command_op_code(0x08, 0x0081)
|
|
576
591
|
HCI_LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA_COMMAND = hci_command_op_code(0x08, 0x0082)
|
|
577
592
|
HCI_LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0083)
|
|
578
593
|
HCI_LE_SET_PERIODIC_SYNC_SUBEVENT_COMMAND = hci_command_op_code(0x08, 0x0084)
|
|
579
594
|
HCI_LE_EXTENDED_CREATE_CONNECTION_V2_COMMAND = hci_command_op_code(0x08, 0x0085)
|
|
580
595
|
HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V2_COMMAND = hci_command_op_code(0x08, 0x0086)
|
|
596
|
+
HCI_LE_READ_ALL_LOCAL_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0087)
|
|
597
|
+
HCI_LE_READ_ALL_REMOTE_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0088)
|
|
598
|
+
HCI_LE_CS_READ_LOCAL_SUPPORTED_CAPABILITIES_COMMAND = hci_command_op_code(0x08, 0x0089)
|
|
599
|
+
HCI_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMMAND = hci_command_op_code(0x08, 0x008A)
|
|
600
|
+
HCI_LE_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPABILITIES = hci_command_op_code(0x08, 0x008B)
|
|
601
|
+
HCI_LE_CS_SECURITY_ENABLE_COMMAND = hci_command_op_code(0x08, 0x008C)
|
|
602
|
+
HCI_LE_CS_SET_DEFAULT_SETTINGS_COMMAND = hci_command_op_code(0x08, 0x008D)
|
|
603
|
+
HCI_LE_CS_READ_REMOTE_FAE_TABLE_COMMAND = hci_command_op_code(0x08, 0x008E)
|
|
604
|
+
HCI_LE_CS_WRITE_CACHED_REMOTE_FAE_TABLE_COMMAND = hci_command_op_code(0x08, 0x008F)
|
|
605
|
+
HCI_LE_CS_CREATE_CONFIG_COMMAND = hci_command_op_code(0x08, 0x0090)
|
|
606
|
+
HCI_LE_CS_REMOVE_CONFIG_COMMAND = hci_command_op_code(0x08, 0x0091)
|
|
607
|
+
HCI_LE_CS_SET_CHANNEL_CLASSIFICATION_COMMAND = hci_command_op_code(0x08, 0x0092)
|
|
608
|
+
HCI_LE_CS_SET_PROCEDURE_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0093)
|
|
609
|
+
HCI_LE_CS_PROCEDURE_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0094)
|
|
610
|
+
HCI_LE_CS_TEST_COMMAND = hci_command_op_code(0x08, 0x0095)
|
|
611
|
+
HCI_LE_CS_TEST_END_COMMAND = hci_command_op_code(0x08, 0x0096)
|
|
612
|
+
HCI_LE_SET_HOST_FEATURE_V2_COMMAND = hci_command_op_code(0x08, 0x0097)
|
|
613
|
+
HCI_LE_ADD_DEVICE_TO_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x0098)
|
|
614
|
+
HCI_LE_REMOVE_DEVICE_FROM_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x0099)
|
|
615
|
+
HCI_LE_CLEAR_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x009A)
|
|
616
|
+
HCI_LE_READ_MONITORED_ADVERTISERS_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x009B)
|
|
617
|
+
HCI_LE_ENABLE_MONITORING_ADVERTISERS_COMMAND = hci_command_op_code(0x08, 0x009C)
|
|
618
|
+
HCI_LE_FRAME_SPACE_UPDATE_COMMAND = hci_command_op_code(0x08, 0x009D)
|
|
581
619
|
|
|
582
620
|
|
|
583
621
|
# HCI Error Codes
|
|
@@ -1150,8 +1188,16 @@ class LeFeature(OpenIntEnum):
|
|
|
1150
1188
|
CHANNEL_CLASSIFICATION = 39
|
|
1151
1189
|
ADVERTISING_CODING_SELECTION = 40
|
|
1152
1190
|
ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 41
|
|
1191
|
+
DECISION_BASED_ADVERTISING_FILTERING = 42
|
|
1153
1192
|
PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 43
|
|
1154
1193
|
PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 44
|
|
1194
|
+
UNSEGMENTED_FRAMED_MODE = 45
|
|
1195
|
+
CHANNEL_SOUNDING = 46
|
|
1196
|
+
CHANNEL_SOUNDING_HOST_SUPPORT = 47
|
|
1197
|
+
CHANNEL_SOUNDING_TONE_QUALITY_INDICATION = 48
|
|
1198
|
+
LL_EXTENDED_FEATURE_SET = 63
|
|
1199
|
+
MONITORING_ADVERTISERS = 64
|
|
1200
|
+
FRAME_SPACE_UPDATE = 65
|
|
1155
1201
|
|
|
1156
1202
|
class LeFeatureMask(enum.IntFlag):
|
|
1157
1203
|
LE_ENCRYPTION = 1 << LeFeature.LE_ENCRYPTION
|
|
@@ -1196,8 +1242,16 @@ class LeFeatureMask(enum.IntFlag):
|
|
|
1196
1242
|
CHANNEL_CLASSIFICATION = 1 << LeFeature.CHANNEL_CLASSIFICATION
|
|
1197
1243
|
ADVERTISING_CODING_SELECTION = 1 << LeFeature.ADVERTISING_CODING_SELECTION
|
|
1198
1244
|
ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 1 << LeFeature.ADVERTISING_CODING_SELECTION_HOST_SUPPORT
|
|
1245
|
+
DECISION_BASED_ADVERTISING_FILTERING = 1 << LeFeature.DECISION_BASED_ADVERTISING_FILTERING
|
|
1199
1246
|
PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER
|
|
1200
1247
|
PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER
|
|
1248
|
+
UNSEGMENTED_FRAMED_MODE = 1 << LeFeature.UNSEGMENTED_FRAMED_MODE
|
|
1249
|
+
CHANNEL_SOUNDING = 1 << LeFeature.CHANNEL_SOUNDING
|
|
1250
|
+
CHANNEL_SOUNDING_HOST_SUPPORT = 1 << LeFeature.CHANNEL_SOUNDING_HOST_SUPPORT
|
|
1251
|
+
CHANNEL_SOUNDING_TONE_QUALITY_INDICATION = 1 << LeFeature.CHANNEL_SOUNDING_TONE_QUALITY_INDICATION
|
|
1252
|
+
LL_EXTENDED_FEATURE_SET = 1 << LeFeature.LL_EXTENDED_FEATURE_SET
|
|
1253
|
+
MONITORING_ADVERTISERS = 1 << LeFeature.MONITORING_ADVERTISERS
|
|
1254
|
+
FRAME_SPACE_UPDATE = 1 << LeFeature.FRAME_SPACE_UPDATE
|
|
1201
1255
|
|
|
1202
1256
|
class LmpFeature(enum.IntEnum):
|
|
1203
1257
|
# Page 0 (Legacy LMP features)
|
|
@@ -1565,12 +1619,16 @@ class HCI_Object:
|
|
|
1565
1619
|
# This is an array field, starting with a 1-byte item count.
|
|
1566
1620
|
item_count = data[offset]
|
|
1567
1621
|
offset += 1
|
|
1622
|
+
# Set fields first, because item_count might be 0.
|
|
1623
|
+
for sub_field_name, _ in field:
|
|
1624
|
+
result[sub_field_name] = []
|
|
1625
|
+
|
|
1568
1626
|
for _ in range(item_count):
|
|
1569
1627
|
for sub_field_name, sub_field_type in field:
|
|
1570
1628
|
value, size = HCI_Object.parse_field(
|
|
1571
1629
|
data, offset, sub_field_type
|
|
1572
1630
|
)
|
|
1573
|
-
result
|
|
1631
|
+
result[sub_field_name].append(value)
|
|
1574
1632
|
offset += size
|
|
1575
1633
|
continue
|
|
1576
1634
|
|
|
@@ -2982,6 +3040,27 @@ class HCI_Write_Inquiry_Scan_Activity_Command(HCI_Command):
|
|
|
2982
3040
|
'''
|
|
2983
3041
|
|
|
2984
3042
|
|
|
3043
|
+
# -----------------------------------------------------------------------------
|
|
3044
|
+
@HCI_Command.command(
|
|
3045
|
+
return_parameters_fields=[
|
|
3046
|
+
('status', STATUS_SPEC),
|
|
3047
|
+
('authentication_enable', 1),
|
|
3048
|
+
]
|
|
3049
|
+
)
|
|
3050
|
+
class HCI_Read_Authentication_Enable_Command(HCI_Command):
|
|
3051
|
+
'''
|
|
3052
|
+
See Bluetooth spec @ 7.3.23 Read Authentication Enable Command
|
|
3053
|
+
'''
|
|
3054
|
+
|
|
3055
|
+
|
|
3056
|
+
# -----------------------------------------------------------------------------
|
|
3057
|
+
@HCI_Command.command([('authentication_enable', 1)])
|
|
3058
|
+
class HCI_Write_Authentication_Enable_Command(HCI_Command):
|
|
3059
|
+
'''
|
|
3060
|
+
See Bluetooth spec @ 7.3.24 Write Authentication Enable Command
|
|
3061
|
+
'''
|
|
3062
|
+
|
|
3063
|
+
|
|
2985
3064
|
# -----------------------------------------------------------------------------
|
|
2986
3065
|
@HCI_Command.command(
|
|
2987
3066
|
return_parameters_fields=[
|
|
@@ -3022,7 +3101,12 @@ class HCI_Write_Voice_Setting_Command(HCI_Command):
|
|
|
3022
3101
|
|
|
3023
3102
|
|
|
3024
3103
|
# -----------------------------------------------------------------------------
|
|
3025
|
-
@HCI_Command.command(
|
|
3104
|
+
@HCI_Command.command(
|
|
3105
|
+
return_parameters_fields=[
|
|
3106
|
+
('status', STATUS_SPEC),
|
|
3107
|
+
('synchronous_flow_control_enable', 1),
|
|
3108
|
+
]
|
|
3109
|
+
)
|
|
3026
3110
|
class HCI_Read_Synchronous_Flow_Control_Enable_Command(HCI_Command):
|
|
3027
3111
|
'''
|
|
3028
3112
|
See Bluetooth spec @ 7.3.36 Read Synchronous Flow Control Enable Command
|
|
@@ -3191,7 +3275,13 @@ class HCI_Set_Event_Mask_Page_2_Command(HCI_Command):
|
|
|
3191
3275
|
|
|
3192
3276
|
|
|
3193
3277
|
# -----------------------------------------------------------------------------
|
|
3194
|
-
@HCI_Command.command(
|
|
3278
|
+
@HCI_Command.command(
|
|
3279
|
+
return_parameters_fields=[
|
|
3280
|
+
('status', STATUS_SPEC),
|
|
3281
|
+
('le_supported_host', 1),
|
|
3282
|
+
('unused', 1),
|
|
3283
|
+
]
|
|
3284
|
+
)
|
|
3195
3285
|
class HCI_Read_LE_Host_Support_Command(HCI_Command):
|
|
3196
3286
|
'''
|
|
3197
3287
|
See Bluetooth spec @ 7.3.78 Read LE Host Support Command
|
|
@@ -3324,13 +3414,39 @@ class HCI_Read_BD_ADDR_Command(HCI_Command):
|
|
|
3324
3414
|
|
|
3325
3415
|
|
|
3326
3416
|
# -----------------------------------------------------------------------------
|
|
3327
|
-
@HCI_Command.command(
|
|
3417
|
+
@HCI_Command.command(
|
|
3418
|
+
return_parameters_fields=[
|
|
3419
|
+
("status", STATUS_SPEC),
|
|
3420
|
+
[("standard_codec_ids", 1)],
|
|
3421
|
+
[("vendor_specific_codec_ids", 4)],
|
|
3422
|
+
]
|
|
3423
|
+
)
|
|
3328
3424
|
class HCI_Read_Local_Supported_Codecs_Command(HCI_Command):
|
|
3329
3425
|
'''
|
|
3330
3426
|
See Bluetooth spec @ 7.4.8 Read Local Supported Codecs Command
|
|
3331
3427
|
'''
|
|
3332
3428
|
|
|
3333
3429
|
|
|
3430
|
+
# -----------------------------------------------------------------------------
|
|
3431
|
+
@HCI_Command.command(
|
|
3432
|
+
return_parameters_fields=[
|
|
3433
|
+
("status", STATUS_SPEC),
|
|
3434
|
+
[("standard_codec_ids", 1), ("standard_codec_transports", 1)],
|
|
3435
|
+
[("vendor_specific_codec_ids", 4), ("vendor_specific_codec_transports", 1)],
|
|
3436
|
+
]
|
|
3437
|
+
)
|
|
3438
|
+
class HCI_Read_Local_Supported_Codecs_V2_Command(HCI_Command):
|
|
3439
|
+
'''
|
|
3440
|
+
See Bluetooth spec @ 7.4.8 Read Local Supported Codecs Command
|
|
3441
|
+
'''
|
|
3442
|
+
|
|
3443
|
+
class Transport(enum.IntFlag):
|
|
3444
|
+
BR_EDR_ACL = 1 << 0
|
|
3445
|
+
BR_EDR_SCO = 1 << 1
|
|
3446
|
+
LE_CIS = 1 << 2
|
|
3447
|
+
LE_BIS = 1 << 3
|
|
3448
|
+
|
|
3449
|
+
|
|
3334
3450
|
# -----------------------------------------------------------------------------
|
|
3335
3451
|
@HCI_Command.command(
|
|
3336
3452
|
fields=[('handle', 2)],
|
|
@@ -3488,7 +3604,12 @@ class HCI_LE_Set_Advertising_Parameters_Command(HCI_Command):
|
|
|
3488
3604
|
|
|
3489
3605
|
|
|
3490
3606
|
# -----------------------------------------------------------------------------
|
|
3491
|
-
@HCI_Command.command(
|
|
3607
|
+
@HCI_Command.command(
|
|
3608
|
+
return_parameters_fields=[
|
|
3609
|
+
('status', STATUS_SPEC),
|
|
3610
|
+
('tx_power_level', 1),
|
|
3611
|
+
]
|
|
3612
|
+
)
|
|
3492
3613
|
class HCI_LE_Read_Advertising_Physical_Channel_Tx_Power_Command(HCI_Command):
|
|
3493
3614
|
'''
|
|
3494
3615
|
See Bluetooth spec @ 7.8.6 LE Read Advertising Physical Channel Tx Power Command
|
|
@@ -3612,7 +3733,12 @@ class HCI_LE_Create_Connection_Cancel_Command(HCI_Command):
|
|
|
3612
3733
|
|
|
3613
3734
|
|
|
3614
3735
|
# -----------------------------------------------------------------------------
|
|
3615
|
-
@HCI_Command.command(
|
|
3736
|
+
@HCI_Command.command(
|
|
3737
|
+
return_parameters_fields=[
|
|
3738
|
+
('status', STATUS_SPEC),
|
|
3739
|
+
('filter_accept_list_size', 1),
|
|
3740
|
+
]
|
|
3741
|
+
)
|
|
3616
3742
|
class HCI_LE_Read_Filter_Accept_List_Size_Command(HCI_Command):
|
|
3617
3743
|
'''
|
|
3618
3744
|
See Bluetooth spec @ 7.8.14 LE Read Filter Accept List Size Command
|
|
@@ -3723,7 +3849,12 @@ class HCI_LE_Long_Term_Key_Request_Negative_Reply_Command(HCI_Command):
|
|
|
3723
3849
|
|
|
3724
3850
|
|
|
3725
3851
|
# -----------------------------------------------------------------------------
|
|
3726
|
-
@HCI_Command.command(
|
|
3852
|
+
@HCI_Command.command(
|
|
3853
|
+
return_parameters_fields=[
|
|
3854
|
+
('status', STATUS_SPEC),
|
|
3855
|
+
('le_states', 8),
|
|
3856
|
+
]
|
|
3857
|
+
)
|
|
3727
3858
|
class HCI_LE_Read_Supported_States_Command(HCI_Command):
|
|
3728
3859
|
'''
|
|
3729
3860
|
See Bluetooth spec @ 7.8.27 LE Read Supported States Command
|
|
@@ -4698,6 +4829,102 @@ class HCI_LE_Reject_CIS_Request_Command(HCI_Command):
|
|
|
4698
4829
|
reason: int
|
|
4699
4830
|
|
|
4700
4831
|
|
|
4832
|
+
# -----------------------------------------------------------------------------
|
|
4833
|
+
@HCI_Command.command(
|
|
4834
|
+
fields=[
|
|
4835
|
+
('big_handle', 1),
|
|
4836
|
+
('advertising_handle', 1),
|
|
4837
|
+
('num_bis', 1),
|
|
4838
|
+
('sdu_interval', 3),
|
|
4839
|
+
('max_sdu', 2),
|
|
4840
|
+
('max_transport_latency', 2),
|
|
4841
|
+
('rtn', 1),
|
|
4842
|
+
('phy', 1),
|
|
4843
|
+
('packing', 1),
|
|
4844
|
+
('framing', 1),
|
|
4845
|
+
('encryption', 1),
|
|
4846
|
+
('broadcast_code', 16),
|
|
4847
|
+
],
|
|
4848
|
+
)
|
|
4849
|
+
class HCI_LE_Create_BIG_Command(HCI_Command):
|
|
4850
|
+
'''
|
|
4851
|
+
See Bluetooth spec @ 7.8.103 LE Create BIG command
|
|
4852
|
+
'''
|
|
4853
|
+
|
|
4854
|
+
big_handle: int
|
|
4855
|
+
advertising_handle: int
|
|
4856
|
+
num_bis: int
|
|
4857
|
+
sdu_interval: int
|
|
4858
|
+
max_sdu: int
|
|
4859
|
+
max_transport_latency: int
|
|
4860
|
+
rtn: int
|
|
4861
|
+
phy: int
|
|
4862
|
+
packing: int
|
|
4863
|
+
framing: int
|
|
4864
|
+
encryption: int
|
|
4865
|
+
broadcast_code: int
|
|
4866
|
+
|
|
4867
|
+
|
|
4868
|
+
# -----------------------------------------------------------------------------
|
|
4869
|
+
@HCI_Command.command(
|
|
4870
|
+
fields=[
|
|
4871
|
+
('big_handle', 1),
|
|
4872
|
+
('reason', {'size': 1, 'mapper': HCI_Constant.error_name}),
|
|
4873
|
+
],
|
|
4874
|
+
)
|
|
4875
|
+
class HCI_LE_Terminate_BIG_Command(HCI_Command):
|
|
4876
|
+
'''
|
|
4877
|
+
See Bluetooth spec @ 7.8.105 LE Terminate BIG command
|
|
4878
|
+
'''
|
|
4879
|
+
|
|
4880
|
+
big_handle: int
|
|
4881
|
+
reason: int
|
|
4882
|
+
|
|
4883
|
+
|
|
4884
|
+
# -----------------------------------------------------------------------------
|
|
4885
|
+
@HCI_Command.command(
|
|
4886
|
+
fields=[
|
|
4887
|
+
('big_handle', 1),
|
|
4888
|
+
('sync_handle', 2),
|
|
4889
|
+
('encryption', 1),
|
|
4890
|
+
('broadcast_code', 16),
|
|
4891
|
+
('mse', 1),
|
|
4892
|
+
('big_sync_timeout', 2),
|
|
4893
|
+
[('bis', 1)],
|
|
4894
|
+
],
|
|
4895
|
+
)
|
|
4896
|
+
class HCI_LE_BIG_Create_Sync_Command(HCI_Command):
|
|
4897
|
+
'''
|
|
4898
|
+
See Bluetooth spec @ 7.8.106 LE BIG Create Sync command
|
|
4899
|
+
'''
|
|
4900
|
+
|
|
4901
|
+
big_handle: int
|
|
4902
|
+
sync_handle: int
|
|
4903
|
+
encryption: int
|
|
4904
|
+
broadcast_code: int
|
|
4905
|
+
mse: int
|
|
4906
|
+
big_sync_timeout: int
|
|
4907
|
+
bis: List[int]
|
|
4908
|
+
|
|
4909
|
+
|
|
4910
|
+
# -----------------------------------------------------------------------------
|
|
4911
|
+
@HCI_Command.command(
|
|
4912
|
+
fields=[
|
|
4913
|
+
('big_handle', 1),
|
|
4914
|
+
],
|
|
4915
|
+
return_parameters_fields=[
|
|
4916
|
+
('status', STATUS_SPEC),
|
|
4917
|
+
('big_handle', 2),
|
|
4918
|
+
],
|
|
4919
|
+
)
|
|
4920
|
+
class HCI_LE_BIG_Terminate_Sync_Command(HCI_Command):
|
|
4921
|
+
'''
|
|
4922
|
+
See Bluetooth spec @ 7.8.107. LE BIG Terminate Sync command
|
|
4923
|
+
'''
|
|
4924
|
+
|
|
4925
|
+
big_handle: int
|
|
4926
|
+
|
|
4927
|
+
|
|
4701
4928
|
# -----------------------------------------------------------------------------
|
|
4702
4929
|
@HCI_Command.command(
|
|
4703
4930
|
fields=[
|
|
@@ -5533,6 +5760,27 @@ class HCI_LE_Channel_Selection_Algorithm_Event(HCI_LE_Meta_Event):
|
|
|
5533
5760
|
'''
|
|
5534
5761
|
|
|
5535
5762
|
|
|
5763
|
+
# -----------------------------------------------------------------------------
|
|
5764
|
+
@HCI_LE_Meta_Event.event(
|
|
5765
|
+
[
|
|
5766
|
+
('status', STATUS_SPEC),
|
|
5767
|
+
('connection_handle', 2),
|
|
5768
|
+
('service_data', 2),
|
|
5769
|
+
('sync_handle', 2),
|
|
5770
|
+
('advertising_sid', 1),
|
|
5771
|
+
('advertiser_address_type', Address.ADDRESS_TYPE_SPEC),
|
|
5772
|
+
('advertiser_address', Address.parse_address_preceded_by_type),
|
|
5773
|
+
('advertiser_phy', 1),
|
|
5774
|
+
('periodic_advertising_interval', 2),
|
|
5775
|
+
('advertiser_clock_accuracy', 1),
|
|
5776
|
+
]
|
|
5777
|
+
)
|
|
5778
|
+
class HCI_LE_Periodic_Advertising_Sync_Transfer_Received_Event(HCI_LE_Meta_Event):
|
|
5779
|
+
'''
|
|
5780
|
+
See Bluetooth spec @ 7.7.65.24 LE Periodic Advertising Sync Transfer Received Event
|
|
5781
|
+
'''
|
|
5782
|
+
|
|
5783
|
+
|
|
5536
5784
|
# -----------------------------------------------------------------------------
|
|
5537
5785
|
@HCI_LE_Meta_Event.event(
|
|
5538
5786
|
[
|
|
@@ -5817,6 +6065,32 @@ class HCI_Read_Remote_Version_Information_Complete_Event(HCI_Event):
|
|
|
5817
6065
|
'''
|
|
5818
6066
|
|
|
5819
6067
|
|
|
6068
|
+
# -----------------------------------------------------------------------------
|
|
6069
|
+
@HCI_Event.event(
|
|
6070
|
+
[
|
|
6071
|
+
('status', STATUS_SPEC),
|
|
6072
|
+
('connection_handle', 2),
|
|
6073
|
+
('unused', 1),
|
|
6074
|
+
(
|
|
6075
|
+
'service_type',
|
|
6076
|
+
{
|
|
6077
|
+
'size': 1,
|
|
6078
|
+
'mapper': lambda x: HCI_QOS_Setup_Complete_Event.ServiceType(x).name,
|
|
6079
|
+
},
|
|
6080
|
+
),
|
|
6081
|
+
]
|
|
6082
|
+
)
|
|
6083
|
+
class HCI_QOS_Setup_Complete_Event(HCI_Event):
|
|
6084
|
+
'''
|
|
6085
|
+
See Bluetooth spec @ 7.7.13 QoS Setup Complete Event
|
|
6086
|
+
'''
|
|
6087
|
+
|
|
6088
|
+
class ServiceType(OpenIntEnum):
|
|
6089
|
+
NO_TRAFFIC_AVAILABLE = 0x00
|
|
6090
|
+
BEST_EFFORT_AVAILABLE = 0x01
|
|
6091
|
+
GUARANTEED_AVAILABLE = 0x02
|
|
6092
|
+
|
|
6093
|
+
|
|
5820
6094
|
# -----------------------------------------------------------------------------
|
|
5821
6095
|
@HCI_Event.event(
|
|
5822
6096
|
[
|
|
@@ -6225,6 +6499,23 @@ class HCI_Synchronous_Connection_Changed_Event(HCI_Event):
|
|
|
6225
6499
|
'''
|
|
6226
6500
|
|
|
6227
6501
|
|
|
6502
|
+
# -----------------------------------------------------------------------------
|
|
6503
|
+
@HCI_Event.event(
|
|
6504
|
+
[
|
|
6505
|
+
('status', STATUS_SPEC),
|
|
6506
|
+
('connection_handle', 2),
|
|
6507
|
+
('max_tx_latency', 2),
|
|
6508
|
+
('max_rx_latency', 2),
|
|
6509
|
+
('min_remote_timeout', 2),
|
|
6510
|
+
('min_local_timeout', 2),
|
|
6511
|
+
]
|
|
6512
|
+
)
|
|
6513
|
+
class HCI_Sniff_Subrating_Event(HCI_Event):
|
|
6514
|
+
'''
|
|
6515
|
+
See Bluetooth spec @ 7.7.37 Sniff Subrating Event
|
|
6516
|
+
'''
|
|
6517
|
+
|
|
6518
|
+
|
|
6228
6519
|
# -----------------------------------------------------------------------------
|
|
6229
6520
|
@HCI_Event.event(
|
|
6230
6521
|
[
|
bumble/hfp.py
CHANGED
|
@@ -795,29 +795,32 @@ class HfProtocol(pyee.EventEmitter):
|
|
|
795
795
|
# Append to the read buffer.
|
|
796
796
|
self.read_buffer.extend(data)
|
|
797
797
|
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
798
|
+
while self.read_buffer:
|
|
799
|
+
# Locate header and trailer.
|
|
800
|
+
header = self.read_buffer.find(b'\r\n')
|
|
801
|
+
trailer = self.read_buffer.find(b'\r\n', header + 2)
|
|
802
|
+
if header == -1 or trailer == -1:
|
|
803
|
+
return
|
|
804
|
+
|
|
805
|
+
# Isolate the AT response code and parameters.
|
|
806
|
+
raw_response = self.read_buffer[header + 2 : trailer]
|
|
807
|
+
response = AtResponse.parse_from(raw_response)
|
|
808
|
+
logger.debug(f"<<< {raw_response.decode()}")
|
|
809
|
+
|
|
810
|
+
# Consume the response bytes.
|
|
811
|
+
self.read_buffer = self.read_buffer[trailer + 2 :]
|
|
812
|
+
|
|
813
|
+
# Forward the received code to the correct queue.
|
|
814
|
+
if self.command_lock.locked() and (
|
|
815
|
+
response.code in STATUS_CODES or response.code in RESPONSE_CODES
|
|
816
|
+
):
|
|
817
|
+
self.response_queue.put_nowait(response)
|
|
818
|
+
elif response.code in UNSOLICITED_CODES:
|
|
819
|
+
self.unsolicited_queue.put_nowait(response)
|
|
820
|
+
else:
|
|
821
|
+
logger.warning(
|
|
822
|
+
f"dropping unexpected response with code '{response.code}'"
|
|
823
|
+
)
|
|
821
824
|
|
|
822
825
|
async def execute_command(
|
|
823
826
|
self,
|
|
@@ -1244,31 +1247,32 @@ class AgProtocol(pyee.EventEmitter):
|
|
|
1244
1247
|
# Append to the read buffer.
|
|
1245
1248
|
self.read_buffer.extend(data)
|
|
1246
1249
|
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
handler(
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1250
|
+
while self.read_buffer:
|
|
1251
|
+
# Locate the trailer.
|
|
1252
|
+
trailer = self.read_buffer.find(b'\r')
|
|
1253
|
+
if trailer == -1:
|
|
1254
|
+
return
|
|
1255
|
+
|
|
1256
|
+
# Isolate the AT response code and parameters.
|
|
1257
|
+
raw_command = self.read_buffer[:trailer]
|
|
1258
|
+
command = AtCommand.parse_from(raw_command)
|
|
1259
|
+
logger.debug(f"<<< {raw_command.decode()}")
|
|
1260
|
+
|
|
1261
|
+
# Consume the response bytes.
|
|
1262
|
+
self.read_buffer = self.read_buffer[trailer + 1 :]
|
|
1263
|
+
|
|
1264
|
+
if command.sub_code == AtCommand.SubCode.TEST:
|
|
1265
|
+
handler_name = f'_on_{command.code.lower()}_test'
|
|
1266
|
+
elif command.sub_code == AtCommand.SubCode.READ:
|
|
1267
|
+
handler_name = f'_on_{command.code.lower()}_read'
|
|
1268
|
+
else:
|
|
1269
|
+
handler_name = f'_on_{command.code.lower()}'
|
|
1270
|
+
|
|
1271
|
+
if handler := getattr(self, handler_name, None):
|
|
1272
|
+
handler(*command.parameters)
|
|
1273
|
+
else:
|
|
1274
|
+
logger.warning('Handler %s not found', handler_name)
|
|
1275
|
+
self.send_response('ERROR')
|
|
1272
1276
|
|
|
1273
1277
|
def send_response(self, response: str) -> None:
|
|
1274
1278
|
"""Sends an AT response."""
|