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/_version.py +2 -2
- bumble/apps/auracast.py +22 -13
- bumble/apps/hci_bridge.py +1 -1
- bumble/apps/lea_unicast/app.py +24 -6
- bumble/att.py +1 -4
- bumble/controller.py +58 -2
- bumble/device.py +454 -494
- bumble/gatt.py +1 -1
- bumble/gatt_client.py +3 -3
- bumble/gatt_server.py +2 -2
- bumble/hci.py +93 -33
- bumble/hfp.py +20 -17
- bumble/host.py +1 -1
- bumble/l2cap.py +2 -8
- bumble/pandora/host.py +1 -1
- bumble/profiles/aics.py +3 -3
- bumble/profiles/bap.py +114 -42
- bumble/sdp.py +1 -7
- bumble/smp.py +2 -5
- {bumble-0.0.202.dist-info → bumble-0.0.203.dist-info}/METADATA +15 -15
- {bumble-0.0.202.dist-info → bumble-0.0.203.dist-info}/RECORD +25 -25
- {bumble-0.0.202.dist-info → bumble-0.0.203.dist-info}/WHEEL +1 -1
- {bumble-0.0.202.dist-info → bumble-0.0.203.dist-info}/LICENSE +0 -0
- {bumble-0.0.202.dist-info → bumble-0.0.203.dist-info}/entry_points.txt +0 -0
- {bumble-0.0.202.dist-info → bumble-0.0.203.dist-info}/top_level.txt +0 -0
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
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, '
|
|
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
|
|
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.
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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,
|
|
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.
|
|
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
|
-
|
|
1644
|
+
WIDE_BAND_SPEECH = 0x20
|
|
1644
1645
|
ENHANCED_VOICE_RECOGNITION_STATUS = 0x40
|
|
1645
|
-
|
|
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.
|
|
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
|
-
|
|
1662
|
+
WIDE_BAND_SPEECH = 0x20
|
|
1661
1663
|
ENHANCED_VOICE_RECOGNITION_STATUS = 0x40
|
|
1662
|
-
|
|
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.
|
|
1696
|
-
hf_supported_features |= HfSdpFeature.
|
|
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.
|
|
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.
|
|
1776
|
-
ag_supported_features |= AgSdpFeature.
|
|
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.
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
|
|
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 =
|
|
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("
|
|
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:
|