bumble 0.0.195__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.
Files changed (61) hide show
  1. bumble/_version.py +2 -2
  2. bumble/apps/auracast.py +351 -66
  3. bumble/apps/console.py +5 -20
  4. bumble/apps/device_info.py +230 -0
  5. bumble/apps/gatt_dump.py +4 -0
  6. bumble/apps/lea_unicast/app.py +16 -17
  7. bumble/apps/pair.py +32 -5
  8. bumble/at.py +12 -6
  9. bumble/att.py +56 -40
  10. bumble/avc.py +8 -5
  11. bumble/avctp.py +3 -2
  12. bumble/avdtp.py +7 -3
  13. bumble/avrcp.py +2 -1
  14. bumble/codecs.py +17 -13
  15. bumble/colors.py +6 -2
  16. bumble/core.py +37 -7
  17. bumble/decoder.py +14 -10
  18. bumble/device.py +382 -111
  19. bumble/drivers/rtk.py +32 -13
  20. bumble/gatt.py +30 -20
  21. bumble/gatt_client.py +15 -29
  22. bumble/gatt_server.py +14 -6
  23. bumble/hci.py +322 -32
  24. bumble/hid.py +24 -28
  25. bumble/host.py +20 -6
  26. bumble/l2cap.py +24 -17
  27. bumble/link.py +8 -3
  28. bumble/pandora/__init__.py +3 -0
  29. bumble/pandora/l2cap.py +310 -0
  30. bumble/profiles/aics.py +520 -0
  31. bumble/profiles/ascs.py +739 -0
  32. bumble/profiles/asha.py +295 -0
  33. bumble/profiles/bap.py +1 -874
  34. bumble/profiles/bass.py +440 -0
  35. bumble/profiles/csip.py +4 -4
  36. bumble/profiles/gap.py +110 -0
  37. bumble/profiles/hap.py +665 -0
  38. bumble/profiles/heart_rate_service.py +4 -3
  39. bumble/profiles/le_audio.py +43 -9
  40. bumble/profiles/mcp.py +448 -0
  41. bumble/profiles/pacs.py +210 -0
  42. bumble/profiles/tmap.py +89 -0
  43. bumble/profiles/vcp.py +5 -3
  44. bumble/rfcomm.py +4 -2
  45. bumble/sdp.py +13 -11
  46. bumble/smp.py +43 -12
  47. bumble/snoop.py +5 -4
  48. bumble/transport/__init__.py +8 -2
  49. bumble/transport/android_emulator.py +9 -3
  50. bumble/transport/android_netsim.py +9 -7
  51. bumble/transport/common.py +46 -18
  52. bumble/transport/pyusb.py +21 -4
  53. bumble/transport/unix.py +56 -0
  54. bumble/transport/usb.py +57 -46
  55. {bumble-0.0.195.dist-info → bumble-0.0.199.dist-info}/METADATA +41 -41
  56. {bumble-0.0.195.dist-info → bumble-0.0.199.dist-info}/RECORD +60 -49
  57. {bumble-0.0.195.dist-info → bumble-0.0.199.dist-info}/WHEEL +1 -1
  58. bumble/profiles/asha_service.py +0 -193
  59. {bumble-0.0.195.dist-info → bumble-0.0.199.dist-info}/LICENSE +0 -0
  60. {bumble-0.0.195.dist-info → bumble-0.0.199.dist-info}/entry_points.txt +0 -0
  61. {bumble-0.0.195.dist-info → bumble-0.0.199.dist-info}/top_level.txt +0 -0
bumble/hci.py CHANGED
@@ -31,6 +31,8 @@ from bumble.core import (
31
31
  BT_BR_EDR_TRANSPORT,
32
32
  AdvertisingData,
33
33
  DeviceClass,
34
+ InvalidArgumentError,
35
+ InvalidPacketError,
34
36
  ProtocolError,
35
37
  bit_flags_to_strings,
36
38
  name_or_number,
@@ -92,14 +94,14 @@ def map_class_of_device(class_of_device):
92
94
  )
93
95
 
94
96
 
95
- def phy_list_to_bits(phys):
97
+ def phy_list_to_bits(phys: Optional[Iterable[int]]) -> int:
96
98
  if phys is None:
97
99
  return 0
98
100
 
99
101
  phy_bits = 0
100
102
  for phy in phys:
101
103
  if phy not in HCI_LE_PHY_TYPE_TO_BIT:
102
- raise ValueError('invalid PHY')
104
+ raise InvalidArgumentError('invalid PHY')
103
105
  phy_bits |= 1 << HCI_LE_PHY_TYPE_TO_BIT[phy]
104
106
  return phy_bits
105
107
 
@@ -265,6 +267,19 @@ HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED_V2_EVENT = 0X26
265
267
  HCI_LE_PERIODIC_ADVERTISING_SUBEVENT_DATA_REQUEST_EVENT = 0X27
266
268
  HCI_LE_PERIODIC_ADVERTISING_RESPONSE_REPORT_EVENT = 0X28
267
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
+
268
283
 
269
284
 
270
285
  # HCI Command
@@ -571,11 +586,36 @@ HCI_LE_SET_DATA_RELATED_ADDRESS_CHANGES_COMMAND = hci_c
571
586
  HCI_LE_SET_DEFAULT_SUBRATE_COMMAND = hci_command_op_code(0x08, 0x007D)
572
587
  HCI_LE_SUBRATE_REQUEST_COMMAND = hci_command_op_code(0x08, 0x007E)
573
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)
574
591
  HCI_LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA_COMMAND = hci_command_op_code(0x08, 0x0082)
575
592
  HCI_LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0083)
576
593
  HCI_LE_SET_PERIODIC_SYNC_SUBEVENT_COMMAND = hci_command_op_code(0x08, 0x0084)
577
594
  HCI_LE_EXTENDED_CREATE_CONNECTION_V2_COMMAND = hci_command_op_code(0x08, 0x0085)
578
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)
579
619
 
580
620
 
581
621
  # HCI Error Codes
@@ -1148,8 +1188,16 @@ class LeFeature(OpenIntEnum):
1148
1188
  CHANNEL_CLASSIFICATION = 39
1149
1189
  ADVERTISING_CODING_SELECTION = 40
1150
1190
  ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 41
1191
+ DECISION_BASED_ADVERTISING_FILTERING = 42
1151
1192
  PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 43
1152
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
1153
1201
 
1154
1202
  class LeFeatureMask(enum.IntFlag):
1155
1203
  LE_ENCRYPTION = 1 << LeFeature.LE_ENCRYPTION
@@ -1194,8 +1242,16 @@ class LeFeatureMask(enum.IntFlag):
1194
1242
  CHANNEL_CLASSIFICATION = 1 << LeFeature.CHANNEL_CLASSIFICATION
1195
1243
  ADVERTISING_CODING_SELECTION = 1 << LeFeature.ADVERTISING_CODING_SELECTION
1196
1244
  ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 1 << LeFeature.ADVERTISING_CODING_SELECTION_HOST_SUPPORT
1245
+ DECISION_BASED_ADVERTISING_FILTERING = 1 << LeFeature.DECISION_BASED_ADVERTISING_FILTERING
1197
1246
  PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER
1198
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
1199
1255
 
1200
1256
  class LmpFeature(enum.IntEnum):
1201
1257
  # Page 0 (Legacy LMP features)
@@ -1553,7 +1609,7 @@ class HCI_Object:
1553
1609
  new_offset, field_value = field_type(data, offset)
1554
1610
  return (field_value, new_offset - offset)
1555
1611
 
1556
- raise ValueError(f'unknown field type {field_type}')
1612
+ raise InvalidArgumentError(f'unknown field type {field_type}')
1557
1613
 
1558
1614
  @staticmethod
1559
1615
  def dict_from_bytes(data, offset, fields):
@@ -1563,12 +1619,16 @@ class HCI_Object:
1563
1619
  # This is an array field, starting with a 1-byte item count.
1564
1620
  item_count = data[offset]
1565
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
+
1566
1626
  for _ in range(item_count):
1567
1627
  for sub_field_name, sub_field_type in field:
1568
1628
  value, size = HCI_Object.parse_field(
1569
1629
  data, offset, sub_field_type
1570
1630
  )
1571
- result.setdefault(sub_field_name, []).append(value)
1631
+ result[sub_field_name].append(value)
1572
1632
  offset += size
1573
1633
  continue
1574
1634
 
@@ -1622,7 +1682,7 @@ class HCI_Object:
1622
1682
  if 0 <= field_value <= 255:
1623
1683
  field_bytes = bytes([field_value])
1624
1684
  else:
1625
- raise ValueError('value too large for *-typed field')
1685
+ raise InvalidArgumentError('value too large for *-typed field')
1626
1686
  else:
1627
1687
  field_bytes = bytes(field_value)
1628
1688
  elif field_type == 'v':
@@ -1641,7 +1701,9 @@ class HCI_Object:
1641
1701
  elif len(field_bytes) > field_type:
1642
1702
  field_bytes = field_bytes[:field_type]
1643
1703
  else:
1644
- raise ValueError(f"don't know how to serialize type {type(field_value)}")
1704
+ raise InvalidArgumentError(
1705
+ f"don't know how to serialize type {type(field_value)}"
1706
+ )
1645
1707
 
1646
1708
  return field_bytes
1647
1709
 
@@ -1835,6 +1897,12 @@ class Address:
1835
1897
  data, offset, Address.PUBLIC_DEVICE_ADDRESS
1836
1898
  )
1837
1899
 
1900
+ @staticmethod
1901
+ def parse_random_address(data, offset):
1902
+ return Address.parse_address_with_type(
1903
+ data, offset, Address.RANDOM_DEVICE_ADDRESS
1904
+ )
1905
+
1838
1906
  @staticmethod
1839
1907
  def parse_address_with_type(data, offset, address_type):
1840
1908
  return offset + 6, Address(data[offset : offset + 6], address_type)
@@ -1905,7 +1973,7 @@ class Address:
1905
1973
  self.address_bytes = bytes(reversed(bytes.fromhex(address)))
1906
1974
 
1907
1975
  if len(self.address_bytes) != 6:
1908
- raise ValueError('invalid address length')
1976
+ raise InvalidArgumentError('invalid address length')
1909
1977
 
1910
1978
  self.address_type = address_type
1911
1979
 
@@ -1961,7 +2029,8 @@ class Address:
1961
2029
 
1962
2030
  def __eq__(self, other):
1963
2031
  return (
1964
- self.address_bytes == other.address_bytes
2032
+ isinstance(other, Address)
2033
+ and self.address_bytes == other.address_bytes
1965
2034
  and self.is_public == other.is_public
1966
2035
  )
1967
2036
 
@@ -2108,7 +2177,7 @@ class HCI_Command(HCI_Packet):
2108
2177
  op_code, length = struct.unpack_from('<HB', packet, 1)
2109
2178
  parameters = packet[4:]
2110
2179
  if len(parameters) != length:
2111
- raise ValueError('invalid packet length')
2180
+ raise InvalidPacketError('invalid packet length')
2112
2181
 
2113
2182
  # Look for a registered class
2114
2183
  cls = HCI_Command.command_classes.get(op_code)
@@ -2971,6 +3040,27 @@ class HCI_Write_Inquiry_Scan_Activity_Command(HCI_Command):
2971
3040
  '''
2972
3041
 
2973
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
+
2974
3064
  # -----------------------------------------------------------------------------
2975
3065
  @HCI_Command.command(
2976
3066
  return_parameters_fields=[
@@ -3011,7 +3101,12 @@ class HCI_Write_Voice_Setting_Command(HCI_Command):
3011
3101
 
3012
3102
 
3013
3103
  # -----------------------------------------------------------------------------
3014
- @HCI_Command.command()
3104
+ @HCI_Command.command(
3105
+ return_parameters_fields=[
3106
+ ('status', STATUS_SPEC),
3107
+ ('synchronous_flow_control_enable', 1),
3108
+ ]
3109
+ )
3015
3110
  class HCI_Read_Synchronous_Flow_Control_Enable_Command(HCI_Command):
3016
3111
  '''
3017
3112
  See Bluetooth spec @ 7.3.36 Read Synchronous Flow Control Enable Command
@@ -3180,7 +3275,13 @@ class HCI_Set_Event_Mask_Page_2_Command(HCI_Command):
3180
3275
 
3181
3276
 
3182
3277
  # -----------------------------------------------------------------------------
3183
- @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
+ )
3184
3285
  class HCI_Read_LE_Host_Support_Command(HCI_Command):
3185
3286
  '''
3186
3287
  See Bluetooth spec @ 7.3.78 Read LE Host Support Command
@@ -3313,13 +3414,39 @@ class HCI_Read_BD_ADDR_Command(HCI_Command):
3313
3414
 
3314
3415
 
3315
3416
  # -----------------------------------------------------------------------------
3316
- @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
+ )
3317
3424
  class HCI_Read_Local_Supported_Codecs_Command(HCI_Command):
3318
3425
  '''
3319
3426
  See Bluetooth spec @ 7.4.8 Read Local Supported Codecs Command
3320
3427
  '''
3321
3428
 
3322
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
+
3323
3450
  # -----------------------------------------------------------------------------
3324
3451
  @HCI_Command.command(
3325
3452
  fields=[('handle', 2)],
@@ -3477,7 +3604,12 @@ class HCI_LE_Set_Advertising_Parameters_Command(HCI_Command):
3477
3604
 
3478
3605
 
3479
3606
  # -----------------------------------------------------------------------------
3480
- @HCI_Command.command()
3607
+ @HCI_Command.command(
3608
+ return_parameters_fields=[
3609
+ ('status', STATUS_SPEC),
3610
+ ('tx_power_level', 1),
3611
+ ]
3612
+ )
3481
3613
  class HCI_LE_Read_Advertising_Physical_Channel_Tx_Power_Command(HCI_Command):
3482
3614
  '''
3483
3615
  See Bluetooth spec @ 7.8.6 LE Read Advertising Physical Channel Tx Power Command
@@ -3601,7 +3733,12 @@ class HCI_LE_Create_Connection_Cancel_Command(HCI_Command):
3601
3733
 
3602
3734
 
3603
3735
  # -----------------------------------------------------------------------------
3604
- @HCI_Command.command()
3736
+ @HCI_Command.command(
3737
+ return_parameters_fields=[
3738
+ ('status', STATUS_SPEC),
3739
+ ('filter_accept_list_size', 1),
3740
+ ]
3741
+ )
3605
3742
  class HCI_LE_Read_Filter_Accept_List_Size_Command(HCI_Command):
3606
3743
  '''
3607
3744
  See Bluetooth spec @ 7.8.14 LE Read Filter Accept List Size Command
@@ -3712,7 +3849,12 @@ class HCI_LE_Long_Term_Key_Request_Negative_Reply_Command(HCI_Command):
3712
3849
 
3713
3850
 
3714
3851
  # -----------------------------------------------------------------------------
3715
- @HCI_Command.command()
3852
+ @HCI_Command.command(
3853
+ return_parameters_fields=[
3854
+ ('status', STATUS_SPEC),
3855
+ ('le_states', 8),
3856
+ ]
3857
+ )
3716
3858
  class HCI_LE_Read_Supported_States_Command(HCI_Command):
3717
3859
  '''
3718
3860
  See Bluetooth spec @ 7.8.27 LE Read Supported States Command
@@ -4518,18 +4660,6 @@ class HCI_LE_Periodic_Advertising_Terminate_Sync_Command(HCI_Command):
4518
4660
  '''
4519
4661
 
4520
4662
 
4521
- # -----------------------------------------------------------------------------
4522
- @HCI_Command.command([('sync_handle', 2), ('enable', 1)])
4523
- class HCI_LE_Set_Periodic_Advertising_Receive_Enable_Command(HCI_Command):
4524
- '''
4525
- See Bluetooth spec @ 7.8.88 LE Set Periodic Advertising Receive Enable Command
4526
- '''
4527
-
4528
- class Enable(enum.IntFlag):
4529
- REPORTING_ENABLED = 1 << 0
4530
- DUPLICATE_FILTERING_ENABLED = 1 << 1
4531
-
4532
-
4533
4663
  # -----------------------------------------------------------------------------
4534
4664
  @HCI_Command.command(
4535
4665
  [
@@ -4565,6 +4695,32 @@ class HCI_LE_Set_Privacy_Mode_Command(HCI_Command):
4565
4695
  return name_or_number(cls.PRIVACY_MODE_NAMES, privacy_mode)
4566
4696
 
4567
4697
 
4698
+ # -----------------------------------------------------------------------------
4699
+ @HCI_Command.command([('sync_handle', 2), ('enable', 1)])
4700
+ class HCI_LE_Set_Periodic_Advertising_Receive_Enable_Command(HCI_Command):
4701
+ '''
4702
+ See Bluetooth spec @ 7.8.88 LE Set Periodic Advertising Receive Enable Command
4703
+ '''
4704
+
4705
+ class Enable(enum.IntFlag):
4706
+ REPORTING_ENABLED = 1 << 0
4707
+ DUPLICATE_FILTERING_ENABLED = 1 << 1
4708
+
4709
+
4710
+ # -----------------------------------------------------------------------------
4711
+ @HCI_Command.command(
4712
+ fields=[('connection_handle', 2), ('service_data', 2), ('sync_handle', 2)],
4713
+ return_parameters_fields=[
4714
+ ('status', STATUS_SPEC),
4715
+ ('connection_handle', 2),
4716
+ ],
4717
+ )
4718
+ class HCI_LE_Periodic_Advertising_Sync_Transfer_Command(HCI_Command):
4719
+ '''
4720
+ See Bluetooth spec @ 7.8.89 LE Periodic Advertising Sync Transfer Command
4721
+ '''
4722
+
4723
+
4568
4724
  # -----------------------------------------------------------------------------
4569
4725
  @HCI_Command.command(
4570
4726
  fields=[
@@ -4673,6 +4829,102 @@ class HCI_LE_Reject_CIS_Request_Command(HCI_Command):
4673
4829
  reason: int
4674
4830
 
4675
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
+
4676
4928
  # -----------------------------------------------------------------------------
4677
4929
  @HCI_Command.command(
4678
4930
  fields=[
@@ -4807,7 +5059,7 @@ class HCI_Event(HCI_Packet):
4807
5059
  length = packet[2]
4808
5060
  parameters = packet[3:]
4809
5061
  if len(parameters) != length:
4810
- raise ValueError('invalid packet length')
5062
+ raise InvalidPacketError('invalid packet length')
4811
5063
 
4812
5064
  cls: Any
4813
5065
  if event_code == HCI_LE_META_EVENT:
@@ -5174,8 +5426,8 @@ class HCI_LE_Data_Length_Change_Event(HCI_LE_Meta_Event):
5174
5426
  ),
5175
5427
  ('peer_address_type', Address.ADDRESS_TYPE_SPEC),
5176
5428
  ('peer_address', Address.parse_address_preceded_by_type),
5177
- ('local_resolvable_private_address', Address.parse_address),
5178
- ('peer_resolvable_private_address', Address.parse_address),
5429
+ ('local_resolvable_private_address', Address.parse_random_address),
5430
+ ('peer_resolvable_private_address', Address.parse_random_address),
5179
5431
  ('connection_interval', 2),
5180
5432
  ('peripheral_latency', 2),
5181
5433
  ('supervision_timeout', 2),
@@ -5508,6 +5760,27 @@ class HCI_LE_Channel_Selection_Algorithm_Event(HCI_LE_Meta_Event):
5508
5760
  '''
5509
5761
 
5510
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
+
5511
5784
  # -----------------------------------------------------------------------------
5512
5785
  @HCI_LE_Meta_Event.event(
5513
5786
  [
@@ -6200,6 +6473,23 @@ class HCI_Synchronous_Connection_Changed_Event(HCI_Event):
6200
6473
  '''
6201
6474
 
6202
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
+
6203
6493
  # -----------------------------------------------------------------------------
6204
6494
  @HCI_Event.event(
6205
6495
  [
@@ -6342,7 +6632,7 @@ class HCI_AclDataPacket(HCI_Packet):
6342
6632
  bc_flag = (h >> 14) & 3
6343
6633
  data = packet[5:]
6344
6634
  if len(data) != data_total_length:
6345
- raise ValueError('invalid packet length')
6635
+ raise InvalidPacketError('invalid packet length')
6346
6636
  return HCI_AclDataPacket(
6347
6637
  connection_handle, pb_flag, bc_flag, data_total_length, data
6348
6638
  )
@@ -6390,7 +6680,7 @@ class HCI_SynchronousDataPacket(HCI_Packet):
6390
6680
  packet_status = (h >> 12) & 0b11
6391
6681
  data = packet[4:]
6392
6682
  if len(data) != data_total_length:
6393
- raise ValueError(
6683
+ raise InvalidPacketError(
6394
6684
  f'invalid packet length {len(data)} != {data_total_length}'
6395
6685
  )
6396
6686
  return HCI_SynchronousDataPacket(