bumble 0.0.202__py3-none-any.whl → 0.0.203__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/gatt.py CHANGED
@@ -410,7 +410,7 @@ class IncludedServiceDeclaration(Attribute):
410
410
 
411
411
  def __init__(self, service: Service) -> None:
412
412
  declaration_bytes = struct.pack(
413
- '<HH2s', service.handle, service.end_group_handle, service.uuid.to_bytes()
413
+ '<HH2s', service.handle, service.end_group_handle, bytes(service.uuid)
414
414
  )
415
415
  super().__init__(
416
416
  GATT_INCLUDE_ATTRIBUTE_TYPE, Attribute.READABLE, declaration_bytes
bumble/gatt_client.py CHANGED
@@ -292,7 +292,7 @@ class Client:
292
292
  logger.debug(
293
293
  f'GATT Command from client: [0x{self.connection.handle:04X}] {command}'
294
294
  )
295
- self.send_gatt_pdu(command.to_bytes())
295
+ self.send_gatt_pdu(bytes(command))
296
296
 
297
297
  async def send_request(self, request: ATT_PDU):
298
298
  logger.debug(
@@ -310,7 +310,7 @@ class Client:
310
310
  self.pending_request = request
311
311
 
312
312
  try:
313
- self.send_gatt_pdu(request.to_bytes())
313
+ self.send_gatt_pdu(bytes(request))
314
314
  response = await asyncio.wait_for(
315
315
  self.pending_response, GATT_REQUEST_TIMEOUT
316
316
  )
@@ -328,7 +328,7 @@ class Client:
328
328
  f'GATT Confirmation from client: [0x{self.connection.handle:04X}] '
329
329
  f'{confirmation}'
330
330
  )
331
- self.send_gatt_pdu(confirmation.to_bytes())
331
+ self.send_gatt_pdu(bytes(confirmation))
332
332
 
333
333
  async def request_mtu(self, mtu: int) -> int:
334
334
  # Check the range
bumble/gatt_server.py CHANGED
@@ -353,7 +353,7 @@ class Server(EventEmitter):
353
353
  logger.debug(
354
354
  f'GATT Response from server: [0x{connection.handle:04X}] {response}'
355
355
  )
356
- self.send_gatt_pdu(connection.handle, response.to_bytes())
356
+ self.send_gatt_pdu(connection.handle, bytes(response))
357
357
 
358
358
  async def notify_subscriber(
359
359
  self,
@@ -450,7 +450,7 @@ class Server(EventEmitter):
450
450
  )
451
451
 
452
452
  try:
453
- self.send_gatt_pdu(connection.handle, indication.to_bytes())
453
+ self.send_gatt_pdu(connection.handle, bytes(indication))
454
454
  await asyncio.wait_for(pending_confirmation, GATT_REQUEST_TIMEOUT)
455
455
  except asyncio.TimeoutError as error:
456
456
  logger.warning(color('!!! GATT Indicate timeout', 'red'))
bumble/hci.py CHANGED
@@ -915,6 +915,8 @@ HCI_SUPPORTED_COMMANDS_MASKS = {
915
915
  HCI_READ_CURRENT_IAC_LAP_COMMAND : 1 << (11*8+3),
916
916
  HCI_WRITE_CURRENT_IAC_LAP_COMMAND : 1 << (11*8+4),
917
917
  HCI_SET_AFH_HOST_CHANNEL_CLASSIFICATION_COMMAND : 1 << (12*8+1),
918
+ HCI_LE_CS_READ_REMOTE_FAE_TABLE_COMMAND : 1 << (12*8+2),
919
+ HCI_LE_CS_WRITE_CACHED_REMOTE_FAE_TABLE_COMMAND : 1 << (12*8+3),
918
920
  HCI_READ_INQUIRY_SCAN_TYPE_COMMAND : 1 << (12*8+4),
919
921
  HCI_WRITE_INQUIRY_SCAN_TYPE_COMMAND : 1 << (12*8+5),
920
922
  HCI_READ_INQUIRY_MODE_COMMAND : 1 << (12*8+6),
@@ -940,6 +942,8 @@ HCI_SUPPORTED_COMMANDS_MASKS = {
940
942
  HCI_SETUP_SYNCHRONOUS_CONNECTION_COMMAND : 1 << (16*8+3),
941
943
  HCI_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND : 1 << (16*8+4),
942
944
  HCI_REJECT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND : 1 << (16*8+5),
945
+ HCI_LE_CS_CREATE_CONFIG_COMMAND : 1 << (16*8+6),
946
+ HCI_LE_CS_REMOVE_CONFIG_COMMAND : 1 << (16*8+7),
943
947
  HCI_READ_EXTENDED_INQUIRY_RESPONSE_COMMAND : 1 << (17*8+0),
944
948
  HCI_WRITE_EXTENDED_INQUIRY_RESPONSE_COMMAND : 1 << (17*8+1),
945
949
  HCI_REFRESH_ENCRYPTION_KEY_COMMAND : 1 << (17*8+2),
@@ -963,13 +967,20 @@ HCI_SUPPORTED_COMMANDS_MASKS = {
963
967
  HCI_SEND_KEYPRESS_NOTIFICATION_COMMAND : 1 << (20*8+2),
964
968
  HCI_IO_CAPABILITY_REQUEST_NEGATIVE_REPLY_COMMAND : 1 << (20*8+3),
965
969
  HCI_READ_ENCRYPTION_KEY_SIZE_COMMAND : 1 << (20*8+4),
970
+ HCI_LE_CS_READ_LOCAL_SUPPORTED_CAPABILITIES_COMMAND : 1 << (20*8+5),
971
+ HCI_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMMAND : 1 << (20*8+6),
972
+ HCI_LE_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPABILITIES : 1 << (20*8+7),
966
973
  HCI_SET_EVENT_MASK_PAGE_2_COMMAND : 1 << (22*8+2),
967
974
  HCI_READ_FLOW_CONTROL_MODE_COMMAND : 1 << (23*8+0),
968
975
  HCI_WRITE_FLOW_CONTROL_MODE_COMMAND : 1 << (23*8+1),
969
976
  HCI_READ_DATA_BLOCK_SIZE_COMMAND : 1 << (23*8+2),
977
+ HCI_LE_CS_TEST_COMMAND : 1 << (23*8+3),
978
+ HCI_LE_CS_TEST_END_COMMAND : 1 << (23*8+4),
970
979
  HCI_READ_ENHANCED_TRANSMIT_POWER_LEVEL_COMMAND : 1 << (24*8+0),
980
+ HCI_LE_CS_SECURITY_ENABLE_COMMAND : 1 << (24*8+1),
971
981
  HCI_READ_LE_HOST_SUPPORT_COMMAND : 1 << (24*8+5),
972
982
  HCI_WRITE_LE_HOST_SUPPORT_COMMAND : 1 << (24*8+6),
983
+ HCI_LE_CS_SET_DEFAULT_SETTINGS_COMMAND : 1 << (24*8+7),
973
984
  HCI_LE_SET_EVENT_MASK_COMMAND : 1 << (25*8+0),
974
985
  HCI_LE_READ_BUFFER_SIZE_COMMAND : 1 << (25*8+1),
975
986
  HCI_LE_READ_LOCAL_SUPPORTED_FEATURES_COMMAND : 1 << (25*8+2),
@@ -1000,6 +1011,10 @@ HCI_SUPPORTED_COMMANDS_MASKS = {
1000
1011
  HCI_LE_RECEIVER_TEST_COMMAND : 1 << (28*8+4),
1001
1012
  HCI_LE_TRANSMITTER_TEST_COMMAND : 1 << (28*8+5),
1002
1013
  HCI_LE_TEST_END_COMMAND : 1 << (28*8+6),
1014
+ HCI_LE_ENABLE_MONITORING_ADVERTISERS_COMMAND : 1 << (28*8+7),
1015
+ HCI_LE_CS_SET_CHANNEL_CLASSIFICATION_COMMAND : 1 << (29*8+0),
1016
+ HCI_LE_CS_SET_PROCEDURE_PARAMETERS_COMMAND : 1 << (29*8+1),
1017
+ HCI_LE_CS_PROCEDURE_ENABLE_COMMAND : 1 << (29*8+2),
1003
1018
  HCI_ENHANCED_SETUP_SYNCHRONOUS_CONNECTION_COMMAND : 1 << (29*8+3),
1004
1019
  HCI_ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION_REQUEST_COMMAND : 1 << (29*8+4),
1005
1020
  HCI_READ_LOCAL_SUPPORTED_CODECS_COMMAND : 1 << (29*8+5),
@@ -1136,11 +1151,21 @@ HCI_SUPPORTED_COMMANDS_MASKS = {
1136
1151
  HCI_LE_SET_DEFAULT_SUBRATE_COMMAND : 1 << (46*8+0),
1137
1152
  HCI_LE_SUBRATE_REQUEST_COMMAND : 1 << (46*8+1),
1138
1153
  HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V2_COMMAND : 1 << (46*8+2),
1154
+ HCI_LE_SET_DECISION_DATA_COMMAND : 1 << (46*8+3),
1155
+ HCI_LE_SET_DECISION_INSTRUCTIONS_COMMAND : 1 << (46*8+4),
1139
1156
  HCI_LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA_COMMAND : 1 << (46*8+5),
1140
1157
  HCI_LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA_COMMAND : 1 << (46*8+6),
1141
1158
  HCI_LE_SET_PERIODIC_SYNC_SUBEVENT_COMMAND : 1 << (46*8+7),
1142
1159
  HCI_LE_EXTENDED_CREATE_CONNECTION_V2_COMMAND : 1 << (47*8+0),
1143
1160
  HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V2_COMMAND : 1 << (47*8+1),
1161
+ HCI_LE_READ_ALL_LOCAL_SUPPORTED_FEATURES_COMMAND : 1 << (47*8+2),
1162
+ HCI_LE_READ_ALL_REMOTE_FEATURES_COMMAND : 1 << (47*8+3),
1163
+ HCI_LE_SET_HOST_FEATURE_V2_COMMAND : 1 << (47*8+4),
1164
+ HCI_LE_ADD_DEVICE_TO_MONITORED_ADVERTISERS_LIST_COMMAND : 1 << (47*8+5),
1165
+ HCI_LE_REMOVE_DEVICE_FROM_MONITORED_ADVERTISERS_LIST_COMMAND : 1 << (47*8+6),
1166
+ HCI_LE_CLEAR_MONITORED_ADVERTISERS_LIST_COMMAND : 1 << (47*8+7),
1167
+ HCI_LE_READ_MONITORED_ADVERTISERS_LIST_SIZE_COMMAND : 1 << (48*8+0),
1168
+ HCI_LE_FRAME_SPACE_UPDATE_COMMAND : 1 << (48*8+1),
1144
1169
  }
1145
1170
 
1146
1171
  # LE Supported Features
@@ -1457,7 +1482,7 @@ class CodingFormat:
1457
1482
  vendor_specific_codec_id: int = 0
1458
1483
 
1459
1484
  @classmethod
1460
- def parse_from_bytes(cls, data: bytes, offset: int):
1485
+ def parse_from_bytes(cls, data: bytes, offset: int) -> tuple[int, CodingFormat]:
1461
1486
  (codec_id, company_id, vendor_specific_codec_id) = struct.unpack_from(
1462
1487
  '<BHH', data, offset
1463
1488
  )
@@ -1467,14 +1492,15 @@ class CodingFormat:
1467
1492
  vendor_specific_codec_id=vendor_specific_codec_id,
1468
1493
  )
1469
1494
 
1470
- def to_bytes(self) -> bytes:
1495
+ @classmethod
1496
+ def from_bytes(cls, data: bytes) -> CodingFormat:
1497
+ return cls.parse_from_bytes(data, 0)[1]
1498
+
1499
+ def __bytes__(self) -> bytes:
1471
1500
  return struct.pack(
1472
1501
  '<BHH', self.codec_id, self.company_id, self.vendor_specific_codec_id
1473
1502
  )
1474
1503
 
1475
- def __bytes__(self) -> bytes:
1476
- return self.to_bytes()
1477
-
1478
1504
 
1479
1505
  # -----------------------------------------------------------------------------
1480
1506
  class HCI_Constant:
@@ -1691,7 +1717,7 @@ class HCI_Object:
1691
1717
  field_length = len(field_bytes)
1692
1718
  field_bytes = bytes([field_length]) + field_bytes
1693
1719
  elif isinstance(field_value, (bytes, bytearray)) or hasattr(
1694
- field_value, 'to_bytes'
1720
+ field_value, '__bytes__'
1695
1721
  ):
1696
1722
  field_bytes = bytes(field_value)
1697
1723
  if isinstance(field_type, int) and 4 < field_type <= 256:
@@ -1736,7 +1762,7 @@ class HCI_Object:
1736
1762
  def from_bytes(cls, data, offset, fields):
1737
1763
  return cls(fields, **cls.dict_from_bytes(data, offset, fields))
1738
1764
 
1739
- def to_bytes(self):
1765
+ def __bytes__(self):
1740
1766
  return HCI_Object.dict_to_bytes(self.__dict__, self.fields)
1741
1767
 
1742
1768
  @staticmethod
@@ -1831,9 +1857,6 @@ class HCI_Object:
1831
1857
  for field_name, field_value in field_strings
1832
1858
  )
1833
1859
 
1834
- def __bytes__(self):
1835
- return self.to_bytes()
1836
-
1837
1860
  def __init__(self, fields, **kwargs):
1838
1861
  self.fields = fields
1839
1862
  self.init_from_fields(self, fields, kwargs)
@@ -2008,9 +2031,6 @@ class Address:
2008
2031
  def is_static(self):
2009
2032
  return self.is_random and (self.address_bytes[5] >> 6 == 3)
2010
2033
 
2011
- def to_bytes(self):
2012
- return self.address_bytes
2013
-
2014
2034
  def to_string(self, with_type_qualifier=True):
2015
2035
  '''
2016
2036
  String representation of the address, MSB first, with an optional type
@@ -2022,7 +2042,7 @@ class Address:
2022
2042
  return result + '/P'
2023
2043
 
2024
2044
  def __bytes__(self):
2025
- return self.to_bytes()
2045
+ return self.address_bytes
2026
2046
 
2027
2047
  def __hash__(self):
2028
2048
  return hash(self.address_bytes)
@@ -2228,16 +2248,13 @@ class HCI_Command(HCI_Packet):
2228
2248
  self.op_code = op_code
2229
2249
  self.parameters = parameters
2230
2250
 
2231
- def to_bytes(self):
2251
+ def __bytes__(self):
2232
2252
  parameters = b'' if self.parameters is None else self.parameters
2233
2253
  return (
2234
2254
  struct.pack('<BHB', HCI_COMMAND_PACKET, self.op_code, len(parameters))
2235
2255
  + parameters
2236
2256
  )
2237
2257
 
2238
- def __bytes__(self):
2239
- return self.to_bytes()
2240
-
2241
2258
  def __str__(self):
2242
2259
  result = color(self.name, 'green')
2243
2260
  if fields := getattr(self, 'fields', None):
@@ -4302,6 +4319,61 @@ class HCI_LE_Clear_Advertising_Sets_Command(HCI_Command):
4302
4319
  '''
4303
4320
 
4304
4321
 
4322
+ # -----------------------------------------------------------------------------
4323
+ @HCI_Command.command(
4324
+ [
4325
+ ('advertising_handle', 1),
4326
+ ('periodic_advertising_interval_min', 2),
4327
+ ('periodic_advertising_interval_max', 2),
4328
+ ('periodic_advertising_properties', 2),
4329
+ ]
4330
+ )
4331
+ class HCI_LE_Set_Periodic_Advertising_Parameters_Command(HCI_Command):
4332
+ '''
4333
+ See Bluetooth spec @ 7.8.61 LE Set Periodic Advertising Parameters command
4334
+ '''
4335
+
4336
+ class Properties(enum.IntFlag):
4337
+ INCLUDE_TX_POWER = 1 << 6
4338
+
4339
+ advertising_handle: int
4340
+ periodic_advertising_interval_min: int
4341
+ periodic_advertising_interval_max: int
4342
+ periodic_advertising_properties: int
4343
+
4344
+
4345
+ # -----------------------------------------------------------------------------
4346
+ @HCI_Command.command(
4347
+ [
4348
+ ('advertising_handle', 1),
4349
+ (
4350
+ 'operation',
4351
+ {
4352
+ 'size': 1,
4353
+ 'mapper': lambda x: HCI_LE_Set_Extended_Advertising_Data_Command.Operation(
4354
+ x
4355
+ ).name,
4356
+ },
4357
+ ),
4358
+ (
4359
+ 'advertising_data',
4360
+ {
4361
+ 'parser': HCI_Object.parse_length_prefixed_bytes,
4362
+ 'serializer': HCI_Object.serialize_length_prefixed_bytes,
4363
+ },
4364
+ ),
4365
+ ]
4366
+ )
4367
+ class HCI_LE_Set_Periodic_Advertising_Data_Command(HCI_Command):
4368
+ '''
4369
+ See Bluetooth spec @ 7.8.62 LE Set Periodic Advertising Data command
4370
+ '''
4371
+
4372
+ advertising_handle: int
4373
+ operation: int
4374
+ advertising_data: bytes
4375
+
4376
+
4305
4377
  # -----------------------------------------------------------------------------
4306
4378
  @HCI_Command.command([('enable', 1), ('advertising_handle', 1)])
4307
4379
  class HCI_LE_Set_Periodic_Advertising_Enable_Command(HCI_Command):
@@ -5106,13 +5178,10 @@ class HCI_Event(HCI_Packet):
5106
5178
  self.event_code = event_code
5107
5179
  self.parameters = parameters
5108
5180
 
5109
- def to_bytes(self):
5181
+ def __bytes__(self):
5110
5182
  parameters = b'' if self.parameters is None else self.parameters
5111
5183
  return bytes([HCI_EVENT_PACKET, self.event_code, len(parameters)]) + parameters
5112
5184
 
5113
- def __bytes__(self):
5114
- return self.to_bytes()
5115
-
5116
5185
  def __str__(self):
5117
5186
  result = color(self.name, 'magenta')
5118
5187
  if fields := getattr(self, 'fields', None):
@@ -6663,7 +6732,7 @@ class HCI_AclDataPacket(HCI_Packet):
6663
6732
  connection_handle, pb_flag, bc_flag, data_total_length, data
6664
6733
  )
6665
6734
 
6666
- def to_bytes(self):
6735
+ def __bytes__(self):
6667
6736
  h = (self.pb_flag << 12) | (self.bc_flag << 14) | self.connection_handle
6668
6737
  return (
6669
6738
  struct.pack('<BHH', HCI_ACL_DATA_PACKET, h, self.data_total_length)
@@ -6677,9 +6746,6 @@ class HCI_AclDataPacket(HCI_Packet):
6677
6746
  self.data_total_length = data_total_length
6678
6747
  self.data = data
6679
6748
 
6680
- def __bytes__(self):
6681
- return self.to_bytes()
6682
-
6683
6749
  def __str__(self):
6684
6750
  return (
6685
6751
  f'{color("ACL", "blue")}: '
@@ -6713,7 +6779,7 @@ class HCI_SynchronousDataPacket(HCI_Packet):
6713
6779
  connection_handle, packet_status, data_total_length, data
6714
6780
  )
6715
6781
 
6716
- def to_bytes(self) -> bytes:
6782
+ def __bytes__(self) -> bytes:
6717
6783
  h = (self.packet_status << 12) | self.connection_handle
6718
6784
  return (
6719
6785
  struct.pack('<BHB', HCI_SYNCHRONOUS_DATA_PACKET, h, self.data_total_length)
@@ -6732,9 +6798,6 @@ class HCI_SynchronousDataPacket(HCI_Packet):
6732
6798
  self.data_total_length = data_total_length
6733
6799
  self.data = data
6734
6800
 
6735
- def __bytes__(self) -> bytes:
6736
- return self.to_bytes()
6737
-
6738
6801
  def __str__(self) -> str:
6739
6802
  return (
6740
6803
  f'{color("SCO", "blue")}: '
@@ -6807,9 +6870,6 @@ class HCI_IsoDataPacket(HCI_Packet):
6807
6870
  )
6808
6871
 
6809
6872
  def __bytes__(self) -> bytes:
6810
- return self.to_bytes()
6811
-
6812
- def to_bytes(self) -> bytes:
6813
6873
  fmt = '<BHH'
6814
6874
  args = [
6815
6875
  HCI_ISO_DATA_PACKET,
bumble/hfp.py CHANGED
@@ -141,7 +141,7 @@ class HfFeature(enum.IntFlag):
141
141
  """
142
142
  HF supported features (AT+BRSF=) (normative).
143
143
 
144
- Hands-Free Profile v1.8, 4.34.2, AT Capabilities Re-Used from GSM 07.07 and 3GPP 27.007.
144
+ Hands-Free Profile v1.9, 4.34.2, AT Capabilities Re-Used from GSM 07.07 and 3GPP 27.007.
145
145
  """
146
146
 
147
147
  EC_NR = 0x001 # Echo Cancel & Noise reduction
@@ -155,14 +155,14 @@ class HfFeature(enum.IntFlag):
155
155
  HF_INDICATORS = 0x100
156
156
  ESCO_S4_SETTINGS_SUPPORTED = 0x200
157
157
  ENHANCED_VOICE_RECOGNITION_STATUS = 0x400
158
- VOICE_RECOGNITION_TEST = 0x800
158
+ VOICE_RECOGNITION_TEXT = 0x800
159
159
 
160
160
 
161
161
  class AgFeature(enum.IntFlag):
162
162
  """
163
163
  AG supported features (+BRSF:) (normative).
164
164
 
165
- Hands-Free Profile v1.8, 4.34.2, AT Capabilities Re-Used from GSM 07.07 and 3GPP 27.007.
165
+ Hands-Free Profile v1.9, 4.34.2, AT Capabilities Re-Used from GSM 07.07 and 3GPP 27.007.
166
166
  """
167
167
 
168
168
  THREE_WAY_CALLING = 0x001
@@ -178,7 +178,7 @@ class AgFeature(enum.IntFlag):
178
178
  HF_INDICATORS = 0x400
179
179
  ESCO_S4_SETTINGS_SUPPORTED = 0x800
180
180
  ENHANCED_VOICE_RECOGNITION_STATUS = 0x1000
181
- VOICE_RECOGNITION_TEST = 0x2000
181
+ VOICE_RECOGNITION_TEXT = 0x2000
182
182
 
183
183
 
184
184
  class AudioCodec(enum.IntEnum):
@@ -1390,6 +1390,7 @@ class AgProtocol(pyee.EventEmitter):
1390
1390
 
1391
1391
  def _on_bac(self, *args) -> None:
1392
1392
  self.supported_audio_codecs = [AudioCodec(int(value)) for value in args]
1393
+ self.emit('supported_audio_codecs', self.supported_audio_codecs)
1393
1394
  self.send_ok()
1394
1395
 
1395
1396
  def _on_bcs(self, codec: bytes) -> None:
@@ -1618,7 +1619,7 @@ class ProfileVersion(enum.IntEnum):
1618
1619
  """
1619
1620
  Profile version (normative).
1620
1621
 
1621
- Hands-Free Profile v1.8, 5.3 SDP Interoperability Requirements.
1622
+ Hands-Free Profile v1.8, 6.3 SDP Interoperability Requirements.
1622
1623
  """
1623
1624
 
1624
1625
  V1_5 = 0x0105
@@ -1632,7 +1633,7 @@ class HfSdpFeature(enum.IntFlag):
1632
1633
  """
1633
1634
  HF supported features (normative).
1634
1635
 
1635
- Hands-Free Profile v1.8, 5.3 SDP Interoperability Requirements.
1636
+ Hands-Free Profile v1.9, 6.3 SDP Interoperability Requirements.
1636
1637
  """
1637
1638
 
1638
1639
  EC_NR = 0x01 # Echo Cancel & Noise reduction
@@ -1640,16 +1641,17 @@ class HfSdpFeature(enum.IntFlag):
1640
1641
  CLI_PRESENTATION_CAPABILITY = 0x04
1641
1642
  VOICE_RECOGNITION_ACTIVATION = 0x08
1642
1643
  REMOTE_VOLUME_CONTROL = 0x10
1643
- WIDE_BAND = 0x20 # Wide band speech
1644
+ WIDE_BAND_SPEECH = 0x20
1644
1645
  ENHANCED_VOICE_RECOGNITION_STATUS = 0x40
1645
- VOICE_RECOGNITION_TEST = 0x80
1646
+ VOICE_RECOGNITION_TEXT = 0x80
1647
+ SUPER_WIDE_BAND = 0x100
1646
1648
 
1647
1649
 
1648
1650
  class AgSdpFeature(enum.IntFlag):
1649
1651
  """
1650
1652
  AG supported features (normative).
1651
1653
 
1652
- Hands-Free Profile v1.8, 5.3 SDP Interoperability Requirements.
1654
+ Hands-Free Profile v1.9, 6.3 SDP Interoperability Requirements.
1653
1655
  """
1654
1656
 
1655
1657
  THREE_WAY_CALLING = 0x01
@@ -1657,9 +1659,10 @@ class AgSdpFeature(enum.IntFlag):
1657
1659
  VOICE_RECOGNITION_FUNCTION = 0x04
1658
1660
  IN_BAND_RING_TONE_CAPABILITY = 0x08
1659
1661
  VOICE_TAG = 0x10 # Attach a number to voice tag
1660
- WIDE_BAND = 0x20 # Wide band speech
1662
+ WIDE_BAND_SPEECH = 0x20
1661
1663
  ENHANCED_VOICE_RECOGNITION_STATUS = 0x40
1662
- VOICE_RECOGNITION_TEST = 0x80
1664
+ VOICE_RECOGNITION_TEXT = 0x80
1665
+ SUPER_WIDE_BAND_SPEED_SPEECH = 0x100
1663
1666
 
1664
1667
 
1665
1668
  def make_hf_sdp_records(
@@ -1692,11 +1695,11 @@ def make_hf_sdp_records(
1692
1695
  in configuration.supported_hf_features
1693
1696
  ):
1694
1697
  hf_supported_features |= HfSdpFeature.ENHANCED_VOICE_RECOGNITION_STATUS
1695
- if HfFeature.VOICE_RECOGNITION_TEST in configuration.supported_hf_features:
1696
- hf_supported_features |= HfSdpFeature.VOICE_RECOGNITION_TEST
1698
+ if HfFeature.VOICE_RECOGNITION_TEXT in configuration.supported_hf_features:
1699
+ hf_supported_features |= HfSdpFeature.VOICE_RECOGNITION_TEXT
1697
1700
 
1698
1701
  if AudioCodec.MSBC in configuration.supported_audio_codecs:
1699
- hf_supported_features |= HfSdpFeature.WIDE_BAND
1702
+ hf_supported_features |= HfSdpFeature.WIDE_BAND_SPEECH
1700
1703
 
1701
1704
  return [
1702
1705
  sdp.ServiceAttribute(
@@ -1772,14 +1775,14 @@ def make_ag_sdp_records(
1772
1775
  in configuration.supported_ag_features
1773
1776
  ):
1774
1777
  ag_supported_features |= AgSdpFeature.ENHANCED_VOICE_RECOGNITION_STATUS
1775
- if AgFeature.VOICE_RECOGNITION_TEST in configuration.supported_ag_features:
1776
- ag_supported_features |= AgSdpFeature.VOICE_RECOGNITION_TEST
1778
+ if AgFeature.VOICE_RECOGNITION_TEXT in configuration.supported_ag_features:
1779
+ ag_supported_features |= AgSdpFeature.VOICE_RECOGNITION_TEXT
1777
1780
  if AgFeature.IN_BAND_RING_TONE_CAPABILITY in configuration.supported_ag_features:
1778
1781
  ag_supported_features |= AgSdpFeature.IN_BAND_RING_TONE_CAPABILITY
1779
1782
  if AgFeature.VOICE_RECOGNITION_FUNCTION in configuration.supported_ag_features:
1780
1783
  ag_supported_features |= AgSdpFeature.VOICE_RECOGNITION_FUNCTION
1781
1784
  if AudioCodec.MSBC in configuration.supported_audio_codecs:
1782
- ag_supported_features |= AgSdpFeature.WIDE_BAND
1785
+ ag_supported_features |= AgSdpFeature.WIDE_BAND_SPEECH
1783
1786
 
1784
1787
  return [
1785
1788
  sdp.ServiceAttribute(
bumble/host.py CHANGED
@@ -199,7 +199,7 @@ class Host(AbortableEventEmitter):
199
199
  check_address_type: bool = False,
200
200
  ) -> Optional[Connection]:
201
201
  for connection in self.connections.values():
202
- if connection.peer_address.to_bytes() == bd_addr.to_bytes():
202
+ if bytes(connection.peer_address) == bytes(bd_addr):
203
203
  if (
204
204
  check_address_type
205
205
  and connection.peer_address.address_type != bd_addr.address_type
bumble/l2cap.py CHANGED
@@ -225,7 +225,7 @@ class L2CAP_PDU:
225
225
 
226
226
  return L2CAP_PDU(l2cap_pdu_cid, l2cap_pdu_payload)
227
227
 
228
- def to_bytes(self) -> bytes:
228
+ def __bytes__(self) -> bytes:
229
229
  header = struct.pack('<HH', len(self.payload), self.cid)
230
230
  return header + self.payload
231
231
 
@@ -233,9 +233,6 @@ class L2CAP_PDU:
233
233
  self.cid = cid
234
234
  self.payload = payload
235
235
 
236
- def __bytes__(self) -> bytes:
237
- return self.to_bytes()
238
-
239
236
  def __str__(self) -> str:
240
237
  return f'{color("L2CAP", "green")} [CID={self.cid}]: {self.payload.hex()}'
241
238
 
@@ -333,11 +330,8 @@ class L2CAP_Control_Frame:
333
330
  def init_from_bytes(self, pdu, offset):
334
331
  return HCI_Object.init_from_bytes(self, pdu, offset, self.fields)
335
332
 
336
- def to_bytes(self) -> bytes:
337
- return self.pdu
338
-
339
333
  def __bytes__(self) -> bytes:
340
- return self.to_bytes()
334
+ return self.pdu
341
335
 
342
336
  def __str__(self) -> str:
343
337
  result = f'{color(self.name, "yellow")} [ID={self.identifier}]'
bumble/pandora/host.py CHANGED
@@ -39,7 +39,6 @@ from bumble.device import (
39
39
  AdvertisingEventProperties,
40
40
  AdvertisingType,
41
41
  Device,
42
- Phy,
43
42
  )
44
43
  from bumble.gatt import Service
45
44
  from bumble.hci import (
@@ -47,6 +46,7 @@ from bumble.hci import (
47
46
  HCI_PAGE_TIMEOUT_ERROR,
48
47
  HCI_REMOTE_USER_TERMINATED_CONNECTION_ERROR,
49
48
  Address,
49
+ Phy,
50
50
  )
51
51
  from google.protobuf import any_pb2 # pytype: disable=pyi-error
52
52
  from google.protobuf import empty_pb2 # pytype: disable=pyi-error
bumble/profiles/aics.py CHANGED
@@ -95,7 +95,7 @@ class AudioInputStatus(OpenIntEnum):
95
95
  Cf. 3.4 Audio Input Status
96
96
  '''
97
97
 
98
- INATIVE = 0x00
98
+ INACTIVE = 0x00
99
99
  ACTIVE = 0x01
100
100
 
101
101
 
@@ -104,7 +104,7 @@ class AudioInputControlPointOpCode(OpenIntEnum):
104
104
  Cf. 3.5.1 Audio Input Control Point procedure requirements
105
105
  '''
106
106
 
107
- SET_GAIN_SETTING = 0x00
107
+ SET_GAIN_SETTING = 0x01
108
108
  UNMUTE = 0x02
109
109
  MUTE = 0x03
110
110
  SET_MANUAL_GAIN_MODE = 0x04
@@ -239,7 +239,7 @@ class AudioInputControlPoint:
239
239
  or gain_settings_operand
240
240
  > self.gain_settings_properties.gain_settings_maximum
241
241
  ):
242
- logger.error("gain_seetings value out of range")
242
+ logger.error("gain_settings value out of range")
243
243
  raise ATT_Error(ErrorCode.VALUE_OUT_OF_RANGE)
244
244
 
245
245
  if self.audio_input_state.gain_settings != gain_settings_operand: