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/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(OpenIntEnum):
|
|
3444
|
+
BR_EDR_ACL = 0x00
|
|
3445
|
+
BR_EDR_SCO = 0x01
|
|
3446
|
+
LE_CIS = 0x02
|
|
3447
|
+
LE_BIS = 0x03
|
|
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
|
[
|
|
@@ -6225,6 +6473,23 @@ class HCI_Synchronous_Connection_Changed_Event(HCI_Event):
|
|
|
6225
6473
|
'''
|
|
6226
6474
|
|
|
6227
6475
|
|
|
6476
|
+
# -----------------------------------------------------------------------------
|
|
6477
|
+
@HCI_Event.event(
|
|
6478
|
+
[
|
|
6479
|
+
('status', STATUS_SPEC),
|
|
6480
|
+
('connection_handle', 2),
|
|
6481
|
+
('max_tx_latency', 2),
|
|
6482
|
+
('max_rx_latency', 2),
|
|
6483
|
+
('min_remote_timeout', 2),
|
|
6484
|
+
('min_local_timeout', 2),
|
|
6485
|
+
]
|
|
6486
|
+
)
|
|
6487
|
+
class HCI_Sniff_Subrating_Event(HCI_Event):
|
|
6488
|
+
'''
|
|
6489
|
+
See Bluetooth spec @ 7.7.37 Sniff Subrating Event
|
|
6490
|
+
'''
|
|
6491
|
+
|
|
6492
|
+
|
|
6228
6493
|
# -----------------------------------------------------------------------------
|
|
6229
6494
|
@HCI_Event.event(
|
|
6230
6495
|
[
|
bumble/host.py
CHANGED
|
@@ -171,7 +171,7 @@ class Host(AbortableEventEmitter):
|
|
|
171
171
|
self.cis_links = {} # CIS links, by connection handle
|
|
172
172
|
self.sco_links = {} # SCO links, by connection handle
|
|
173
173
|
self.pending_command = None
|
|
174
|
-
self.pending_response = None
|
|
174
|
+
self.pending_response: Optional[asyncio.Future[Any]] = None
|
|
175
175
|
self.number_of_supported_advertising_sets = 0
|
|
176
176
|
self.maximum_advertising_data_length = 31
|
|
177
177
|
self.local_version = None
|
|
@@ -514,7 +514,9 @@ class Host(AbortableEventEmitter):
|
|
|
514
514
|
if self.hci_sink:
|
|
515
515
|
self.hci_sink.on_packet(bytes(packet))
|
|
516
516
|
|
|
517
|
-
async def send_command(
|
|
517
|
+
async def send_command(
|
|
518
|
+
self, command, check_result=False, response_timeout: Optional[int] = None
|
|
519
|
+
):
|
|
518
520
|
# Wait until we can send (only one pending command at a time)
|
|
519
521
|
async with self.command_semaphore:
|
|
520
522
|
assert self.pending_command is None
|
|
@@ -526,12 +528,13 @@ class Host(AbortableEventEmitter):
|
|
|
526
528
|
|
|
527
529
|
try:
|
|
528
530
|
self.send_hci_packet(command)
|
|
529
|
-
|
|
531
|
+
await asyncio.wait_for(self.pending_response, timeout=response_timeout)
|
|
532
|
+
response = self.pending_response.result()
|
|
530
533
|
|
|
531
534
|
# Check the return parameters if required
|
|
532
535
|
if check_result:
|
|
533
536
|
if isinstance(response, hci.HCI_Command_Status_Event):
|
|
534
|
-
status = response.status
|
|
537
|
+
status = response.status # type: ignore[attr-defined]
|
|
535
538
|
elif isinstance(response.return_parameters, int):
|
|
536
539
|
status = response.return_parameters
|
|
537
540
|
elif isinstance(response.return_parameters, bytes):
|
|
@@ -625,14 +628,21 @@ class Host(AbortableEventEmitter):
|
|
|
625
628
|
|
|
626
629
|
# Packet Sink protocol (packets coming from the controller via HCI)
|
|
627
630
|
def on_packet(self, packet: bytes) -> None:
|
|
628
|
-
|
|
631
|
+
try:
|
|
632
|
+
hci_packet = hci.HCI_Packet.from_bytes(packet)
|
|
633
|
+
except Exception as error:
|
|
634
|
+
logger.warning(f'!!! error parsing packet from bytes: {error}')
|
|
635
|
+
return
|
|
636
|
+
|
|
629
637
|
if self.ready or (
|
|
630
638
|
isinstance(hci_packet, hci.HCI_Command_Complete_Event)
|
|
631
639
|
and hci_packet.command_opcode == hci.HCI_RESET_COMMAND
|
|
632
640
|
):
|
|
633
641
|
self.on_hci_packet(hci_packet)
|
|
634
642
|
else:
|
|
635
|
-
logger.debug(
|
|
643
|
+
logger.debug(
|
|
644
|
+
f'reset not done, ignoring packet from controller: {hci_packet}'
|
|
645
|
+
)
|
|
636
646
|
|
|
637
647
|
def on_transport_lost(self):
|
|
638
648
|
# Called by the source when the transport has been lost.
|
bumble/pandora/__init__.py
CHANGED
|
@@ -25,8 +25,10 @@ import grpc.aio
|
|
|
25
25
|
from .config import Config
|
|
26
26
|
from .device import PandoraDevice
|
|
27
27
|
from .host import HostService
|
|
28
|
+
from .l2cap import L2CAPService
|
|
28
29
|
from .security import SecurityService, SecurityStorageService
|
|
29
30
|
from pandora.host_grpc_aio import add_HostServicer_to_server
|
|
31
|
+
from pandora.l2cap_grpc_aio import add_L2CAPServicer_to_server
|
|
30
32
|
from pandora.security_grpc_aio import (
|
|
31
33
|
add_SecurityServicer_to_server,
|
|
32
34
|
add_SecurityStorageServicer_to_server,
|
|
@@ -77,6 +79,7 @@ async def serve(
|
|
|
77
79
|
add_SecurityStorageServicer_to_server(
|
|
78
80
|
SecurityStorageService(bumble.device, config), server
|
|
79
81
|
)
|
|
82
|
+
add_L2CAPServicer_to_server(L2CAPService(bumble.device, config), server)
|
|
80
83
|
|
|
81
84
|
# call hooks if any.
|
|
82
85
|
for hook in _SERVICERS_HOOKS:
|