bumble 0.0.214__py3-none-any.whl → 0.0.215__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 +16 -3
- bumble/a2dp.py +15 -16
- bumble/apps/auracast.py +13 -38
- bumble/apps/bench.py +9 -10
- bumble/apps/ble_rpa_tool.py +1 -0
- bumble/apps/console.py +22 -25
- bumble/apps/controller_info.py +19 -19
- bumble/apps/controller_loopback.py +2 -2
- bumble/apps/controllers.py +1 -1
- bumble/apps/device_info.py +3 -3
- bumble/apps/gatt_dump.py +1 -1
- bumble/apps/gg_bridge.py +5 -6
- bumble/apps/hci_bridge.py +3 -3
- bumble/apps/l2cap_bridge.py +3 -3
- bumble/apps/lea_unicast/app.py +15 -25
- bumble/apps/pair.py +30 -43
- bumble/apps/pandora_server.py +5 -4
- bumble/apps/player/player.py +19 -22
- bumble/apps/rfcomm_bridge.py +3 -8
- bumble/apps/scan.py +16 -6
- bumble/apps/show.py +3 -4
- bumble/apps/speaker/speaker.py +22 -22
- bumble/apps/unbond.py +2 -1
- bumble/apps/usb_probe.py +1 -2
- bumble/att.py +241 -246
- bumble/audio/io.py +5 -9
- bumble/avc.py +2 -2
- bumble/avctp.py +6 -7
- bumble/avdtp.py +19 -22
- bumble/avrcp.py +1096 -588
- bumble/codecs.py +2 -0
- bumble/controller.py +52 -13
- bumble/core.py +567 -248
- bumble/crypto/__init__.py +2 -2
- bumble/crypto/builtin.py +1 -1
- bumble/crypto/cryptography.py +2 -4
- bumble/data_types.py +1025 -0
- bumble/device.py +280 -278
- bumble/drivers/__init__.py +3 -2
- bumble/drivers/intel.py +3 -4
- bumble/drivers/rtk.py +26 -9
- bumble/gap.py +4 -4
- bumble/gatt.py +3 -2
- bumble/gatt_adapters.py +3 -11
- bumble/gatt_client.py +69 -81
- bumble/gatt_server.py +124 -124
- bumble/hci.py +67 -18
- bumble/helpers.py +19 -26
- bumble/hfp.py +10 -21
- bumble/hid.py +22 -16
- bumble/host.py +181 -103
- bumble/keys.py +5 -3
- bumble/l2cap.py +121 -74
- bumble/link.py +8 -9
- bumble/pairing.py +7 -6
- bumble/pandora/__init__.py +8 -7
- bumble/pandora/config.py +3 -1
- bumble/pandora/device.py +3 -2
- bumble/pandora/host.py +38 -36
- bumble/pandora/l2cap.py +22 -21
- bumble/pandora/security.py +15 -15
- bumble/pandora/utils.py +5 -3
- bumble/profiles/aics.py +11 -11
- bumble/profiles/ams.py +7 -8
- bumble/profiles/ancs.py +6 -7
- bumble/profiles/ascs.py +4 -9
- bumble/profiles/asha.py +8 -12
- bumble/profiles/bap.py +11 -23
- bumble/profiles/bass.py +2 -7
- bumble/profiles/battery_service.py +3 -4
- bumble/profiles/cap.py +1 -2
- bumble/profiles/csip.py +2 -6
- bumble/profiles/device_information_service.py +2 -2
- bumble/profiles/gap.py +4 -4
- bumble/profiles/gatt_service.py +1 -4
- bumble/profiles/gmap.py +5 -5
- bumble/profiles/hap.py +62 -59
- bumble/profiles/heart_rate_service.py +5 -4
- bumble/profiles/le_audio.py +3 -1
- bumble/profiles/mcp.py +3 -7
- bumble/profiles/pacs.py +3 -6
- bumble/profiles/pbp.py +2 -0
- bumble/profiles/tmap.py +2 -3
- bumble/profiles/vcs.py +2 -8
- bumble/profiles/vocs.py +8 -8
- bumble/rfcomm.py +11 -14
- bumble/rtp.py +1 -0
- bumble/sdp.py +10 -8
- bumble/smp.py +142 -153
- bumble/snoop.py +5 -5
- bumble/tools/generate_company_id_list.py +1 -0
- bumble/tools/intel_fw_download.py +3 -3
- bumble/tools/intel_util.py +4 -4
- bumble/tools/rtk_fw_download.py +6 -3
- bumble/tools/rtk_util.py +24 -7
- bumble/transport/__init__.py +19 -15
- bumble/transport/android_emulator.py +8 -13
- bumble/transport/android_netsim.py +19 -18
- bumble/transport/common.py +12 -15
- bumble/transport/file.py +1 -1
- bumble/transport/hci_socket.py +4 -6
- bumble/transport/pty.py +5 -6
- bumble/transport/pyusb.py +7 -10
- bumble/transport/serial.py +2 -1
- bumble/transport/tcp_client.py +2 -2
- bumble/transport/tcp_server.py +11 -14
- bumble/transport/udp.py +3 -3
- bumble/transport/unix.py +67 -1
- bumble/transport/usb.py +6 -6
- bumble/transport/vhci.py +0 -1
- bumble/transport/ws_client.py +2 -1
- bumble/transport/ws_server.py +3 -2
- bumble/utils.py +20 -5
- bumble/vendor/android/hci.py +1 -2
- bumble/vendor/zephyr/hci.py +0 -1
- {bumble-0.0.214.dist-info → bumble-0.0.215.dist-info}/METADATA +2 -1
- bumble-0.0.215.dist-info/RECORD +183 -0
- bumble-0.0.214.dist-info/RECORD +0 -182
- {bumble-0.0.214.dist-info → bumble-0.0.215.dist-info}/WHEEL +0 -0
- {bumble-0.0.214.dist-info → bumble-0.0.215.dist-info}/entry_points.txt +0 -0
- {bumble-0.0.214.dist-info → bumble-0.0.215.dist-info}/licenses/LICENSE +0 -0
- {bumble-0.0.214.dist-info → bumble-0.0.215.dist-info}/top_level.txt +0 -0
bumble/host.py
CHANGED
|
@@ -16,33 +16,19 @@
|
|
|
16
16
|
# Imports
|
|
17
17
|
# -----------------------------------------------------------------------------
|
|
18
18
|
from __future__ import annotations
|
|
19
|
+
|
|
19
20
|
import asyncio
|
|
20
21
|
import collections
|
|
21
22
|
import dataclasses
|
|
22
23
|
import logging
|
|
23
24
|
import struct
|
|
25
|
+
from typing import TYPE_CHECKING, Any, Awaitable, Callable, Optional, Union, cast
|
|
24
26
|
|
|
25
|
-
from
|
|
26
|
-
Any,
|
|
27
|
-
Awaitable,
|
|
28
|
-
Callable,
|
|
29
|
-
Optional,
|
|
30
|
-
cast,
|
|
31
|
-
TYPE_CHECKING,
|
|
32
|
-
)
|
|
33
|
-
|
|
34
|
-
|
|
27
|
+
from bumble import drivers, hci, utils
|
|
35
28
|
from bumble.colors import color
|
|
29
|
+
from bumble.core import ConnectionPHY, InvalidStateError, PhysicalTransport
|
|
36
30
|
from bumble.l2cap import L2CAP_PDU
|
|
37
31
|
from bumble.snoop import Snooper
|
|
38
|
-
from bumble import drivers
|
|
39
|
-
from bumble import hci
|
|
40
|
-
from bumble.core import (
|
|
41
|
-
PhysicalTransport,
|
|
42
|
-
ConnectionPHY,
|
|
43
|
-
ConnectionParameters,
|
|
44
|
-
)
|
|
45
|
-
from bumble import utils
|
|
46
32
|
from bumble.transport.common import TransportLostError
|
|
47
33
|
|
|
48
34
|
if TYPE_CHECKING:
|
|
@@ -707,11 +693,9 @@ class Host(utils.EventEmitter):
|
|
|
707
693
|
raise hci.HCI_Error(status)
|
|
708
694
|
|
|
709
695
|
return response
|
|
710
|
-
except Exception
|
|
711
|
-
logger.exception(
|
|
712
|
-
|
|
713
|
-
)
|
|
714
|
-
raise error
|
|
696
|
+
except Exception:
|
|
697
|
+
logger.exception(color("!!! Exception while sending command:", "red"))
|
|
698
|
+
raise
|
|
715
699
|
finally:
|
|
716
700
|
self.pending_command = None
|
|
717
701
|
self.pending_response = None
|
|
@@ -918,10 +902,14 @@ class Host(utils.EventEmitter):
|
|
|
918
902
|
def on_l2cap_pdu(self, connection: Connection, cid: int, pdu: bytes) -> None:
|
|
919
903
|
self.emit('l2cap_pdu', connection.handle, cid, pdu)
|
|
920
904
|
|
|
921
|
-
def on_command_processed(
|
|
905
|
+
def on_command_processed(
|
|
906
|
+
self, event: Union[hci.HCI_Command_Complete_Event, hci.HCI_Command_Status_Event]
|
|
907
|
+
):
|
|
922
908
|
if self.pending_response:
|
|
923
909
|
# Check that it is what we were expecting
|
|
924
|
-
if self.pending_command
|
|
910
|
+
if self.pending_command is None:
|
|
911
|
+
logger.warning('!!! pending_command is None ')
|
|
912
|
+
elif self.pending_command.op_code != event.command_opcode:
|
|
925
913
|
logger.warning(
|
|
926
914
|
'!!! command result mismatch, expected '
|
|
927
915
|
f'0x{self.pending_command.op_code:X} but got '
|
|
@@ -935,10 +923,10 @@ class Host(utils.EventEmitter):
|
|
|
935
923
|
############################################################
|
|
936
924
|
# HCI handlers
|
|
937
925
|
############################################################
|
|
938
|
-
def on_hci_event(self, event):
|
|
926
|
+
def on_hci_event(self, event: hci.HCI_Event):
|
|
939
927
|
logger.warning(f'{color(f"--- Ignoring event {event}", "red")}')
|
|
940
928
|
|
|
941
|
-
def on_hci_command_complete_event(self, event):
|
|
929
|
+
def on_hci_command_complete_event(self, event: hci.HCI_Command_Complete_Event):
|
|
942
930
|
if event.command_opcode == 0:
|
|
943
931
|
# This is used just for the Num_HCI_Command_Packets field, not related to
|
|
944
932
|
# an actual command
|
|
@@ -947,7 +935,7 @@ class Host(utils.EventEmitter):
|
|
|
947
935
|
|
|
948
936
|
return self.on_command_processed(event)
|
|
949
937
|
|
|
950
|
-
def on_hci_command_status_event(self, event):
|
|
938
|
+
def on_hci_command_status_event(self, event: hci.HCI_Command_Status_Event):
|
|
951
939
|
return self.on_command_processed(event)
|
|
952
940
|
|
|
953
941
|
def on_hci_number_of_completed_packets_event(
|
|
@@ -967,7 +955,7 @@ class Host(utils.EventEmitter):
|
|
|
967
955
|
)
|
|
968
956
|
|
|
969
957
|
# Classic only
|
|
970
|
-
def on_hci_connection_request_event(self, event):
|
|
958
|
+
def on_hci_connection_request_event(self, event: hci.HCI_Connection_Request_Event):
|
|
971
959
|
# Notify the listeners
|
|
972
960
|
self.emit(
|
|
973
961
|
'connection_request',
|
|
@@ -976,7 +964,14 @@ class Host(utils.EventEmitter):
|
|
|
976
964
|
event.link_type,
|
|
977
965
|
)
|
|
978
966
|
|
|
979
|
-
def on_hci_le_connection_complete_event(
|
|
967
|
+
def on_hci_le_connection_complete_event(
|
|
968
|
+
self,
|
|
969
|
+
event: Union[
|
|
970
|
+
hci.HCI_LE_Connection_Complete_Event,
|
|
971
|
+
hci.HCI_LE_Enhanced_Connection_Complete_Event,
|
|
972
|
+
hci.HCI_LE_Enhanced_Connection_Complete_V2_Event,
|
|
973
|
+
],
|
|
974
|
+
):
|
|
980
975
|
# Check if this is a cancellation
|
|
981
976
|
if event.status == hci.HCI_SUCCESS:
|
|
982
977
|
# Create/update the connection
|
|
@@ -996,20 +991,16 @@ class Host(utils.EventEmitter):
|
|
|
996
991
|
self.connections[event.connection_handle] = connection
|
|
997
992
|
|
|
998
993
|
# Notify the client
|
|
999
|
-
connection_parameters = ConnectionParameters(
|
|
1000
|
-
event.connection_interval,
|
|
1001
|
-
event.peripheral_latency,
|
|
1002
|
-
event.supervision_timeout,
|
|
1003
|
-
)
|
|
1004
994
|
self.emit(
|
|
1005
|
-
'
|
|
995
|
+
'le_connection',
|
|
1006
996
|
event.connection_handle,
|
|
1007
|
-
PhysicalTransport.LE,
|
|
1008
997
|
event.peer_address,
|
|
1009
998
|
getattr(event, 'local_resolvable_private_address', None),
|
|
1010
999
|
getattr(event, 'peer_resolvable_private_address', None),
|
|
1011
1000
|
hci.Role(event.role),
|
|
1012
|
-
|
|
1001
|
+
event.connection_interval,
|
|
1002
|
+
event.peripheral_latency,
|
|
1003
|
+
event.supervision_timeout,
|
|
1013
1004
|
)
|
|
1014
1005
|
else:
|
|
1015
1006
|
logger.debug(f'### CONNECTION FAILED: {event.status}')
|
|
@@ -1022,15 +1013,25 @@ class Host(utils.EventEmitter):
|
|
|
1022
1013
|
event.status,
|
|
1023
1014
|
)
|
|
1024
1015
|
|
|
1025
|
-
def on_hci_le_enhanced_connection_complete_event(
|
|
1016
|
+
def on_hci_le_enhanced_connection_complete_event(
|
|
1017
|
+
self,
|
|
1018
|
+
event: Union[
|
|
1019
|
+
hci.HCI_LE_Enhanced_Connection_Complete_Event,
|
|
1020
|
+
hci.HCI_LE_Enhanced_Connection_Complete_V2_Event,
|
|
1021
|
+
],
|
|
1022
|
+
):
|
|
1026
1023
|
# Just use the same implementation as for the non-enhanced event for now
|
|
1027
1024
|
self.on_hci_le_connection_complete_event(event)
|
|
1028
1025
|
|
|
1029
|
-
def on_hci_le_enhanced_connection_complete_v2_event(
|
|
1026
|
+
def on_hci_le_enhanced_connection_complete_v2_event(
|
|
1027
|
+
self, event: hci.HCI_LE_Enhanced_Connection_Complete_V2_Event
|
|
1028
|
+
):
|
|
1030
1029
|
# Just use the same implementation as for the v1 event for now
|
|
1031
1030
|
self.on_hci_le_enhanced_connection_complete_event(event)
|
|
1032
1031
|
|
|
1033
|
-
def on_hci_connection_complete_event(
|
|
1032
|
+
def on_hci_connection_complete_event(
|
|
1033
|
+
self, event: hci.HCI_Connection_Complete_Event
|
|
1034
|
+
):
|
|
1034
1035
|
if event.status == hci.HCI_SUCCESS:
|
|
1035
1036
|
# Create/update the connection
|
|
1036
1037
|
logger.debug(
|
|
@@ -1050,14 +1051,9 @@ class Host(utils.EventEmitter):
|
|
|
1050
1051
|
|
|
1051
1052
|
# Notify the client
|
|
1052
1053
|
self.emit(
|
|
1053
|
-
'
|
|
1054
|
+
'classic_connection',
|
|
1054
1055
|
event.connection_handle,
|
|
1055
|
-
PhysicalTransport.BR_EDR,
|
|
1056
1056
|
event.bd_addr,
|
|
1057
|
-
None,
|
|
1058
|
-
None,
|
|
1059
|
-
None,
|
|
1060
|
-
None,
|
|
1061
1057
|
)
|
|
1062
1058
|
else:
|
|
1063
1059
|
logger.debug(f'### BR/EDR CONNECTION FAILED: {event.status}')
|
|
@@ -1070,7 +1066,9 @@ class Host(utils.EventEmitter):
|
|
|
1070
1066
|
event.status,
|
|
1071
1067
|
)
|
|
1072
1068
|
|
|
1073
|
-
def on_hci_disconnection_complete_event(
|
|
1069
|
+
def on_hci_disconnection_complete_event(
|
|
1070
|
+
self, event: hci.HCI_Disconnection_Complete_Event
|
|
1071
|
+
):
|
|
1074
1072
|
# Find the connection
|
|
1075
1073
|
handle = event.connection_handle
|
|
1076
1074
|
if (
|
|
@@ -1109,27 +1107,30 @@ class Host(utils.EventEmitter):
|
|
|
1109
1107
|
# Notify the listeners
|
|
1110
1108
|
self.emit('disconnection_failure', handle, event.status)
|
|
1111
1109
|
|
|
1112
|
-
def on_hci_le_connection_update_complete_event(
|
|
1110
|
+
def on_hci_le_connection_update_complete_event(
|
|
1111
|
+
self, event: hci.HCI_LE_Connection_Update_Complete_Event
|
|
1112
|
+
):
|
|
1113
1113
|
if (connection := self.connections.get(event.connection_handle)) is None:
|
|
1114
1114
|
logger.warning('!!! CONNECTION PARAMETERS UPDATE COMPLETE: unknown handle')
|
|
1115
1115
|
return
|
|
1116
1116
|
|
|
1117
1117
|
# Notify the client
|
|
1118
1118
|
if event.status == hci.HCI_SUCCESS:
|
|
1119
|
-
|
|
1119
|
+
self.emit(
|
|
1120
|
+
'connection_parameters_update',
|
|
1121
|
+
connection.handle,
|
|
1120
1122
|
event.connection_interval,
|
|
1121
1123
|
event.peripheral_latency,
|
|
1122
1124
|
event.supervision_timeout,
|
|
1123
1125
|
)
|
|
1124
|
-
self.emit(
|
|
1125
|
-
'connection_parameters_update', connection.handle, connection_parameters
|
|
1126
|
-
)
|
|
1127
1126
|
else:
|
|
1128
1127
|
self.emit(
|
|
1129
1128
|
'connection_parameters_update_failure', connection.handle, event.status
|
|
1130
1129
|
)
|
|
1131
1130
|
|
|
1132
|
-
def on_hci_le_phy_update_complete_event(
|
|
1131
|
+
def on_hci_le_phy_update_complete_event(
|
|
1132
|
+
self, event: hci.HCI_LE_PHY_Update_Complete_Event
|
|
1133
|
+
):
|
|
1133
1134
|
if (connection := self.connections.get(event.connection_handle)) is None:
|
|
1134
1135
|
logger.warning('!!! CONNECTION PHY UPDATE COMPLETE: unknown handle')
|
|
1135
1136
|
return
|
|
@@ -1159,7 +1160,9 @@ class Host(utils.EventEmitter):
|
|
|
1159
1160
|
):
|
|
1160
1161
|
self.on_hci_le_advertising_report_event(event)
|
|
1161
1162
|
|
|
1162
|
-
def on_hci_le_advertising_set_terminated_event(
|
|
1163
|
+
def on_hci_le_advertising_set_terminated_event(
|
|
1164
|
+
self, event: hci.HCI_LE_Advertising_Set_Terminated_Event
|
|
1165
|
+
):
|
|
1163
1166
|
self.emit(
|
|
1164
1167
|
'advertising_set_termination',
|
|
1165
1168
|
event.status,
|
|
@@ -1168,7 +1171,9 @@ class Host(utils.EventEmitter):
|
|
|
1168
1171
|
event.num_completed_extended_advertising_events,
|
|
1169
1172
|
)
|
|
1170
1173
|
|
|
1171
|
-
def on_hci_le_periodic_advertising_sync_established_event(
|
|
1174
|
+
def on_hci_le_periodic_advertising_sync_established_event(
|
|
1175
|
+
self, event: hci.HCI_LE_Periodic_Advertising_Sync_Established_Event
|
|
1176
|
+
):
|
|
1172
1177
|
self.emit(
|
|
1173
1178
|
'periodic_advertising_sync_establishment',
|
|
1174
1179
|
event.status,
|
|
@@ -1180,16 +1185,22 @@ class Host(utils.EventEmitter):
|
|
|
1180
1185
|
event.advertiser_clock_accuracy,
|
|
1181
1186
|
)
|
|
1182
1187
|
|
|
1183
|
-
def on_hci_le_periodic_advertising_sync_lost_event(
|
|
1188
|
+
def on_hci_le_periodic_advertising_sync_lost_event(
|
|
1189
|
+
self, event: hci.HCI_LE_Periodic_Advertising_Sync_Lost_Event
|
|
1190
|
+
):
|
|
1184
1191
|
self.emit('periodic_advertising_sync_loss', event.sync_handle)
|
|
1185
1192
|
|
|
1186
|
-
def on_hci_le_periodic_advertising_report_event(
|
|
1193
|
+
def on_hci_le_periodic_advertising_report_event(
|
|
1194
|
+
self, event: hci.HCI_LE_Periodic_Advertising_Report_Event
|
|
1195
|
+
):
|
|
1187
1196
|
self.emit('periodic_advertising_report', event.sync_handle, event)
|
|
1188
1197
|
|
|
1189
|
-
def on_hci_le_biginfo_advertising_report_event(
|
|
1198
|
+
def on_hci_le_biginfo_advertising_report_event(
|
|
1199
|
+
self, event: hci.HCI_LE_BIGInfo_Advertising_Report_Event
|
|
1200
|
+
):
|
|
1190
1201
|
self.emit('biginfo_advertising_report', event.sync_handle, event)
|
|
1191
1202
|
|
|
1192
|
-
def on_hci_le_cis_request_event(self, event):
|
|
1203
|
+
def on_hci_le_cis_request_event(self, event: hci.HCI_LE_CIS_Request_Event):
|
|
1193
1204
|
self.emit(
|
|
1194
1205
|
'cis_request',
|
|
1195
1206
|
event.acl_connection_handle,
|
|
@@ -1198,10 +1209,12 @@ class Host(utils.EventEmitter):
|
|
|
1198
1209
|
event.cis_id,
|
|
1199
1210
|
)
|
|
1200
1211
|
|
|
1201
|
-
def on_hci_le_create_big_complete_event(
|
|
1212
|
+
def on_hci_le_create_big_complete_event(
|
|
1213
|
+
self, event: hci.HCI_LE_Create_BIG_Complete_Event
|
|
1214
|
+
):
|
|
1202
1215
|
self.bigs[event.big_handle] = set(event.connection_handle)
|
|
1203
1216
|
if self.iso_packet_queue is None:
|
|
1204
|
-
|
|
1217
|
+
raise InvalidStateError("BIS established but ISO packets not supported")
|
|
1205
1218
|
|
|
1206
1219
|
for connection_handle in event.connection_handle:
|
|
1207
1220
|
self.bis_links[connection_handle] = IsoLink(
|
|
@@ -1224,8 +1237,13 @@ class Host(utils.EventEmitter):
|
|
|
1224
1237
|
event.iso_interval,
|
|
1225
1238
|
)
|
|
1226
1239
|
|
|
1227
|
-
def on_hci_le_big_sync_established_event(
|
|
1240
|
+
def on_hci_le_big_sync_established_event(
|
|
1241
|
+
self, event: hci.HCI_LE_BIG_Sync_Established_Event
|
|
1242
|
+
):
|
|
1228
1243
|
self.bigs[event.big_handle] = set(event.connection_handle)
|
|
1244
|
+
if self.iso_packet_queue is None:
|
|
1245
|
+
raise InvalidStateError("BIS established but ISO packets not supported")
|
|
1246
|
+
|
|
1229
1247
|
for connection_handle in event.connection_handle:
|
|
1230
1248
|
self.bis_links[connection_handle] = IsoLink(
|
|
1231
1249
|
connection_handle, self.iso_packet_queue
|
|
@@ -1245,15 +1263,19 @@ class Host(utils.EventEmitter):
|
|
|
1245
1263
|
event.connection_handle,
|
|
1246
1264
|
)
|
|
1247
1265
|
|
|
1248
|
-
def on_hci_le_big_sync_lost_event(self, event):
|
|
1266
|
+
def on_hci_le_big_sync_lost_event(self, event: hci.HCI_LE_BIG_Sync_Lost_Event):
|
|
1249
1267
|
self.remove_big(event.big_handle)
|
|
1250
1268
|
self.emit('big_sync_lost', event.big_handle, event.reason)
|
|
1251
1269
|
|
|
1252
|
-
def on_hci_le_terminate_big_complete_event(
|
|
1270
|
+
def on_hci_le_terminate_big_complete_event(
|
|
1271
|
+
self, event: hci.HCI_LE_Terminate_BIG_Complete_Event
|
|
1272
|
+
):
|
|
1253
1273
|
self.remove_big(event.big_handle)
|
|
1254
1274
|
self.emit('big_termination', event.reason, event.big_handle)
|
|
1255
1275
|
|
|
1256
|
-
def on_hci_le_periodic_advertising_sync_transfer_received_event(
|
|
1276
|
+
def on_hci_le_periodic_advertising_sync_transfer_received_event(
|
|
1277
|
+
self, event: hci.HCI_LE_Periodic_Advertising_Sync_Transfer_Received_Event
|
|
1278
|
+
):
|
|
1257
1279
|
self.emit(
|
|
1258
1280
|
'periodic_advertising_sync_transfer',
|
|
1259
1281
|
event.status,
|
|
@@ -1266,7 +1288,9 @@ class Host(utils.EventEmitter):
|
|
|
1266
1288
|
event.advertiser_clock_accuracy,
|
|
1267
1289
|
)
|
|
1268
1290
|
|
|
1269
|
-
def on_hci_le_periodic_advertising_sync_transfer_received_v2_event(
|
|
1291
|
+
def on_hci_le_periodic_advertising_sync_transfer_received_v2_event(
|
|
1292
|
+
self, event: hci.HCI_LE_Periodic_Advertising_Sync_Transfer_Received_V2_Event
|
|
1293
|
+
):
|
|
1270
1294
|
self.emit(
|
|
1271
1295
|
'periodic_advertising_sync_transfer',
|
|
1272
1296
|
event.status,
|
|
@@ -1279,11 +1303,11 @@ class Host(utils.EventEmitter):
|
|
|
1279
1303
|
event.advertiser_clock_accuracy,
|
|
1280
1304
|
)
|
|
1281
1305
|
|
|
1282
|
-
def on_hci_le_cis_established_event(self, event):
|
|
1306
|
+
def on_hci_le_cis_established_event(self, event: hci.HCI_LE_CIS_Established_Event):
|
|
1283
1307
|
# The remaining parameters are unused for now.
|
|
1284
1308
|
if event.status == hci.HCI_SUCCESS:
|
|
1285
1309
|
if self.iso_packet_queue is None:
|
|
1286
|
-
|
|
1310
|
+
raise InvalidStateError("CIS established but ISO packets not supported")
|
|
1287
1311
|
self.cis_links[event.connection_handle] = IsoLink(
|
|
1288
1312
|
handle=event.connection_handle, packet_queue=self.iso_packet_queue
|
|
1289
1313
|
)
|
|
@@ -1310,7 +1334,9 @@ class Host(utils.EventEmitter):
|
|
|
1310
1334
|
'cis_establishment_failure', event.connection_handle, event.status
|
|
1311
1335
|
)
|
|
1312
1336
|
|
|
1313
|
-
def on_hci_le_remote_connection_parameter_request_event(
|
|
1337
|
+
def on_hci_le_remote_connection_parameter_request_event(
|
|
1338
|
+
self, event: hci.HCI_LE_Remote_Connection_Parameter_Request_Event
|
|
1339
|
+
):
|
|
1314
1340
|
if event.connection_handle not in self.connections:
|
|
1315
1341
|
logger.warning('!!! REMOTE CONNECTION PARAMETER REQUEST: unknown handle')
|
|
1316
1342
|
return
|
|
@@ -1329,7 +1355,9 @@ class Host(utils.EventEmitter):
|
|
|
1329
1355
|
)
|
|
1330
1356
|
)
|
|
1331
1357
|
|
|
1332
|
-
def on_hci_le_long_term_key_request_event(
|
|
1358
|
+
def on_hci_le_long_term_key_request_event(
|
|
1359
|
+
self, event: hci.HCI_LE_Long_Term_Key_Request_Event
|
|
1360
|
+
):
|
|
1333
1361
|
if (connection := self.connections.get(event.connection_handle)) is None:
|
|
1334
1362
|
logger.warning('!!! LE LONG TERM KEY REQUEST: unknown handle')
|
|
1335
1363
|
return
|
|
@@ -1363,7 +1391,9 @@ class Host(utils.EventEmitter):
|
|
|
1363
1391
|
|
|
1364
1392
|
asyncio.create_task(send_long_term_key())
|
|
1365
1393
|
|
|
1366
|
-
def on_hci_synchronous_connection_complete_event(
|
|
1394
|
+
def on_hci_synchronous_connection_complete_event(
|
|
1395
|
+
self, event: hci.HCI_Synchronous_Connection_Complete_Event
|
|
1396
|
+
):
|
|
1367
1397
|
if event.status == hci.HCI_SUCCESS:
|
|
1368
1398
|
# Create/update the connection
|
|
1369
1399
|
logger.debug(
|
|
@@ -1389,7 +1419,9 @@ class Host(utils.EventEmitter):
|
|
|
1389
1419
|
# Notify the client
|
|
1390
1420
|
self.emit('sco_connection_failure', event.bd_addr, event.status)
|
|
1391
1421
|
|
|
1392
|
-
def on_hci_synchronous_connection_changed_event(
|
|
1422
|
+
def on_hci_synchronous_connection_changed_event(
|
|
1423
|
+
self, event: hci.HCI_Synchronous_Connection_Changed_Event
|
|
1424
|
+
):
|
|
1393
1425
|
pass
|
|
1394
1426
|
|
|
1395
1427
|
def on_hci_mode_change_event(self, event: hci.HCI_Mode_Change_Event):
|
|
@@ -1401,7 +1433,7 @@ class Host(utils.EventEmitter):
|
|
|
1401
1433
|
event.interval,
|
|
1402
1434
|
)
|
|
1403
1435
|
|
|
1404
|
-
def on_hci_role_change_event(self, event):
|
|
1436
|
+
def on_hci_role_change_event(self, event: hci.HCI_Role_Change_Event):
|
|
1405
1437
|
if event.status == hci.HCI_SUCCESS:
|
|
1406
1438
|
logger.debug(
|
|
1407
1439
|
f'role change for {event.bd_addr}: '
|
|
@@ -1415,7 +1447,9 @@ class Host(utils.EventEmitter):
|
|
|
1415
1447
|
)
|
|
1416
1448
|
self.emit('role_change_failure', event.bd_addr, event.status)
|
|
1417
1449
|
|
|
1418
|
-
def on_hci_le_data_length_change_event(
|
|
1450
|
+
def on_hci_le_data_length_change_event(
|
|
1451
|
+
self, event: hci.HCI_LE_Data_Length_Change_Event
|
|
1452
|
+
):
|
|
1419
1453
|
if (connection := self.connections.get(event.connection_handle)) is None:
|
|
1420
1454
|
logger.warning('!!! DATA LENGTH CHANGE: unknown handle')
|
|
1421
1455
|
return
|
|
@@ -1429,7 +1463,9 @@ class Host(utils.EventEmitter):
|
|
|
1429
1463
|
event.max_rx_time,
|
|
1430
1464
|
)
|
|
1431
1465
|
|
|
1432
|
-
def on_hci_authentication_complete_event(
|
|
1466
|
+
def on_hci_authentication_complete_event(
|
|
1467
|
+
self, event: hci.HCI_Authentication_Complete_Event
|
|
1468
|
+
):
|
|
1433
1469
|
# Notify the client
|
|
1434
1470
|
if event.status == hci.HCI_SUCCESS:
|
|
1435
1471
|
self.emit('connection_authentication', event.connection_handle)
|
|
@@ -1470,7 +1506,9 @@ class Host(utils.EventEmitter):
|
|
|
1470
1506
|
'connection_encryption_failure', event.connection_handle, event.status
|
|
1471
1507
|
)
|
|
1472
1508
|
|
|
1473
|
-
def on_hci_encryption_key_refresh_complete_event(
|
|
1509
|
+
def on_hci_encryption_key_refresh_complete_event(
|
|
1510
|
+
self, event: hci.HCI_Encryption_Key_Refresh_Complete_Event
|
|
1511
|
+
):
|
|
1474
1512
|
# Notify the client
|
|
1475
1513
|
if event.status == hci.HCI_SUCCESS:
|
|
1476
1514
|
self.emit('connection_encryption_key_refresh', event.connection_handle)
|
|
@@ -1481,7 +1519,7 @@ class Host(utils.EventEmitter):
|
|
|
1481
1519
|
event.status,
|
|
1482
1520
|
)
|
|
1483
1521
|
|
|
1484
|
-
def on_hci_qos_setup_complete_event(self, event):
|
|
1522
|
+
def on_hci_qos_setup_complete_event(self, event: hci.HCI_QOS_Setup_Complete_Event):
|
|
1485
1523
|
if event.status == hci.HCI_SUCCESS:
|
|
1486
1524
|
self.emit(
|
|
1487
1525
|
'connection_qos_setup', event.connection_handle, event.service_type
|
|
@@ -1493,23 +1531,31 @@ class Host(utils.EventEmitter):
|
|
|
1493
1531
|
event.status,
|
|
1494
1532
|
)
|
|
1495
1533
|
|
|
1496
|
-
def on_hci_link_supervision_timeout_changed_event(
|
|
1534
|
+
def on_hci_link_supervision_timeout_changed_event(
|
|
1535
|
+
self, event: hci.HCI_Link_Supervision_Timeout_Changed_Event
|
|
1536
|
+
):
|
|
1497
1537
|
pass
|
|
1498
1538
|
|
|
1499
|
-
def on_hci_max_slots_change_event(self, event):
|
|
1539
|
+
def on_hci_max_slots_change_event(self, event: hci.HCI_Max_Slots_Change_Event):
|
|
1500
1540
|
pass
|
|
1501
1541
|
|
|
1502
|
-
def on_hci_page_scan_repetition_mode_change_event(
|
|
1542
|
+
def on_hci_page_scan_repetition_mode_change_event(
|
|
1543
|
+
self, event: hci.HCI_Page_Scan_Repetition_Mode_Change_Event
|
|
1544
|
+
):
|
|
1503
1545
|
pass
|
|
1504
1546
|
|
|
1505
|
-
def on_hci_link_key_notification_event(
|
|
1547
|
+
def on_hci_link_key_notification_event(
|
|
1548
|
+
self, event: hci.HCI_Link_Key_Notification_Event
|
|
1549
|
+
):
|
|
1506
1550
|
logger.debug(
|
|
1507
1551
|
f'link key for {event.bd_addr}: {event.link_key.hex()}, '
|
|
1508
1552
|
f'type={hci.HCI_Constant.link_key_type_name(event.key_type)}'
|
|
1509
1553
|
)
|
|
1510
1554
|
self.emit('link_key', event.bd_addr, event.link_key, event.key_type)
|
|
1511
1555
|
|
|
1512
|
-
def on_hci_simple_pairing_complete_event(
|
|
1556
|
+
def on_hci_simple_pairing_complete_event(
|
|
1557
|
+
self, event: hci.HCI_Simple_Pairing_Complete_Event
|
|
1558
|
+
):
|
|
1513
1559
|
logger.debug(
|
|
1514
1560
|
f'simple pairing complete for {event.bd_addr}: '
|
|
1515
1561
|
f'status={hci.HCI_Constant.status_name(event.status)}'
|
|
@@ -1519,10 +1565,10 @@ class Host(utils.EventEmitter):
|
|
|
1519
1565
|
else:
|
|
1520
1566
|
self.emit('classic_pairing_failure', event.bd_addr, event.status)
|
|
1521
1567
|
|
|
1522
|
-
def on_hci_pin_code_request_event(self, event):
|
|
1568
|
+
def on_hci_pin_code_request_event(self, event: hci.HCI_PIN_Code_Request_Event):
|
|
1523
1569
|
self.emit('pin_code_request', event.bd_addr)
|
|
1524
1570
|
|
|
1525
|
-
def on_hci_link_key_request_event(self, event):
|
|
1571
|
+
def on_hci_link_key_request_event(self, event: hci.HCI_Link_Key_Request_Event):
|
|
1526
1572
|
async def send_link_key():
|
|
1527
1573
|
if self.link_key_provider is None:
|
|
1528
1574
|
logger.debug('no link key provider')
|
|
@@ -1547,10 +1593,14 @@ class Host(utils.EventEmitter):
|
|
|
1547
1593
|
|
|
1548
1594
|
asyncio.create_task(send_link_key())
|
|
1549
1595
|
|
|
1550
|
-
def on_hci_io_capability_request_event(
|
|
1596
|
+
def on_hci_io_capability_request_event(
|
|
1597
|
+
self, event: hci.HCI_IO_Capability_Request_Event
|
|
1598
|
+
):
|
|
1551
1599
|
self.emit('authentication_io_capability_request', event.bd_addr)
|
|
1552
1600
|
|
|
1553
|
-
def on_hci_io_capability_response_event(
|
|
1601
|
+
def on_hci_io_capability_response_event(
|
|
1602
|
+
self, event: hci.HCI_IO_Capability_Response_Event
|
|
1603
|
+
):
|
|
1554
1604
|
self.emit(
|
|
1555
1605
|
'authentication_io_capability_response',
|
|
1556
1606
|
event.bd_addr,
|
|
@@ -1558,25 +1608,33 @@ class Host(utils.EventEmitter):
|
|
|
1558
1608
|
event.authentication_requirements,
|
|
1559
1609
|
)
|
|
1560
1610
|
|
|
1561
|
-
def on_hci_user_confirmation_request_event(
|
|
1611
|
+
def on_hci_user_confirmation_request_event(
|
|
1612
|
+
self, event: hci.HCI_User_Confirmation_Request_Event
|
|
1613
|
+
):
|
|
1562
1614
|
self.emit(
|
|
1563
1615
|
'authentication_user_confirmation_request',
|
|
1564
1616
|
event.bd_addr,
|
|
1565
1617
|
event.numeric_value,
|
|
1566
1618
|
)
|
|
1567
1619
|
|
|
1568
|
-
def on_hci_user_passkey_request_event(
|
|
1620
|
+
def on_hci_user_passkey_request_event(
|
|
1621
|
+
self, event: hci.HCI_User_Passkey_Request_Event
|
|
1622
|
+
):
|
|
1569
1623
|
self.emit('authentication_user_passkey_request', event.bd_addr)
|
|
1570
1624
|
|
|
1571
|
-
def on_hci_user_passkey_notification_event(
|
|
1625
|
+
def on_hci_user_passkey_notification_event(
|
|
1626
|
+
self, event: hci.HCI_User_Passkey_Notification_Event
|
|
1627
|
+
):
|
|
1572
1628
|
self.emit(
|
|
1573
1629
|
'authentication_user_passkey_notification', event.bd_addr, event.passkey
|
|
1574
1630
|
)
|
|
1575
1631
|
|
|
1576
|
-
def on_hci_inquiry_complete_event(self, _event):
|
|
1632
|
+
def on_hci_inquiry_complete_event(self, _event: hci.HCI_Inquiry_Complete_Event):
|
|
1577
1633
|
self.emit('inquiry_complete')
|
|
1578
1634
|
|
|
1579
|
-
def on_hci_inquiry_result_with_rssi_event(
|
|
1635
|
+
def on_hci_inquiry_result_with_rssi_event(
|
|
1636
|
+
self, event: hci.HCI_Inquiry_Result_With_RSSI_Event
|
|
1637
|
+
):
|
|
1580
1638
|
for bd_addr, class_of_device, rssi in zip(
|
|
1581
1639
|
event.bd_addr, event.class_of_device, event.rssi
|
|
1582
1640
|
):
|
|
@@ -1588,7 +1646,9 @@ class Host(utils.EventEmitter):
|
|
|
1588
1646
|
rssi,
|
|
1589
1647
|
)
|
|
1590
1648
|
|
|
1591
|
-
def on_hci_extended_inquiry_result_event(
|
|
1649
|
+
def on_hci_extended_inquiry_result_event(
|
|
1650
|
+
self, event: hci.HCI_Extended_Inquiry_Result_Event
|
|
1651
|
+
):
|
|
1592
1652
|
self.emit(
|
|
1593
1653
|
'inquiry_result',
|
|
1594
1654
|
event.bd_addr,
|
|
@@ -1597,7 +1657,9 @@ class Host(utils.EventEmitter):
|
|
|
1597
1657
|
event.rssi,
|
|
1598
1658
|
)
|
|
1599
1659
|
|
|
1600
|
-
def on_hci_remote_name_request_complete_event(
|
|
1660
|
+
def on_hci_remote_name_request_complete_event(
|
|
1661
|
+
self, event: hci.HCI_Remote_Name_Request_Complete_Event
|
|
1662
|
+
):
|
|
1601
1663
|
if event.status != hci.HCI_SUCCESS:
|
|
1602
1664
|
self.emit('remote_name_failure', event.bd_addr, event.status)
|
|
1603
1665
|
else:
|
|
@@ -1608,14 +1670,18 @@ class Host(utils.EventEmitter):
|
|
|
1608
1670
|
|
|
1609
1671
|
self.emit('remote_name', event.bd_addr, utf8_name)
|
|
1610
1672
|
|
|
1611
|
-
def on_hci_remote_host_supported_features_notification_event(
|
|
1673
|
+
def on_hci_remote_host_supported_features_notification_event(
|
|
1674
|
+
self, event: hci.HCI_Remote_Host_Supported_Features_Notification_Event
|
|
1675
|
+
):
|
|
1612
1676
|
self.emit(
|
|
1613
1677
|
'remote_host_supported_features',
|
|
1614
1678
|
event.bd_addr,
|
|
1615
1679
|
event.host_supported_features,
|
|
1616
1680
|
)
|
|
1617
1681
|
|
|
1618
|
-
def on_hci_le_read_remote_features_complete_event(
|
|
1682
|
+
def on_hci_le_read_remote_features_complete_event(
|
|
1683
|
+
self, event: hci.HCI_LE_Read_Remote_Features_Complete_Event
|
|
1684
|
+
):
|
|
1619
1685
|
if event.status != hci.HCI_SUCCESS:
|
|
1620
1686
|
self.emit(
|
|
1621
1687
|
'le_remote_features_failure', event.connection_handle, event.status
|
|
@@ -1627,22 +1693,34 @@ class Host(utils.EventEmitter):
|
|
|
1627
1693
|
int.from_bytes(event.le_features, 'little'),
|
|
1628
1694
|
)
|
|
1629
1695
|
|
|
1630
|
-
def on_hci_le_cs_read_remote_supported_capabilities_complete_event(
|
|
1696
|
+
def on_hci_le_cs_read_remote_supported_capabilities_complete_event(
|
|
1697
|
+
self, event: hci.HCI_LE_CS_Read_Remote_Supported_Capabilities_Complete_Event
|
|
1698
|
+
):
|
|
1631
1699
|
self.emit('cs_remote_supported_capabilities', event)
|
|
1632
1700
|
|
|
1633
|
-
def on_hci_le_cs_security_enable_complete_event(
|
|
1701
|
+
def on_hci_le_cs_security_enable_complete_event(
|
|
1702
|
+
self, event: hci.HCI_LE_CS_Security_Enable_Complete_Event
|
|
1703
|
+
):
|
|
1634
1704
|
self.emit('cs_security', event)
|
|
1635
1705
|
|
|
1636
|
-
def on_hci_le_cs_config_complete_event(
|
|
1706
|
+
def on_hci_le_cs_config_complete_event(
|
|
1707
|
+
self, event: hci.HCI_LE_CS_Config_Complete_Event
|
|
1708
|
+
):
|
|
1637
1709
|
self.emit('cs_config', event)
|
|
1638
1710
|
|
|
1639
|
-
def on_hci_le_cs_procedure_enable_complete_event(
|
|
1711
|
+
def on_hci_le_cs_procedure_enable_complete_event(
|
|
1712
|
+
self, event: hci.HCI_LE_CS_Procedure_Enable_Complete_Event
|
|
1713
|
+
):
|
|
1640
1714
|
self.emit('cs_procedure', event)
|
|
1641
1715
|
|
|
1642
|
-
def on_hci_le_cs_subevent_result_event(
|
|
1716
|
+
def on_hci_le_cs_subevent_result_event(
|
|
1717
|
+
self, event: hci.HCI_LE_CS_Subevent_Result_Event
|
|
1718
|
+
):
|
|
1643
1719
|
self.emit('cs_subevent_result', event)
|
|
1644
1720
|
|
|
1645
|
-
def on_hci_le_cs_subevent_result_continue_event(
|
|
1721
|
+
def on_hci_le_cs_subevent_result_continue_event(
|
|
1722
|
+
self, event: hci.HCI_LE_CS_Subevent_Result_Continue_Event
|
|
1723
|
+
):
|
|
1646
1724
|
self.emit('cs_subevent_result_continue', event)
|
|
1647
1725
|
|
|
1648
1726
|
def on_hci_le_subrate_change_event(self, event: hci.HCI_LE_Subrate_Change_Event):
|
|
@@ -1655,5 +1733,5 @@ class Host(utils.EventEmitter):
|
|
|
1655
1733
|
event.supervision_timeout,
|
|
1656
1734
|
)
|
|
1657
1735
|
|
|
1658
|
-
def on_hci_vendor_event(self, event):
|
|
1736
|
+
def on_hci_vendor_event(self, event: hci.HCI_Vendor_Event):
|
|
1659
1737
|
self.emit('vendor_event', event)
|
bumble/keys.py
CHANGED
|
@@ -21,16 +21,18 @@
|
|
|
21
21
|
# Imports
|
|
22
22
|
# -----------------------------------------------------------------------------
|
|
23
23
|
from __future__ import annotations
|
|
24
|
+
|
|
24
25
|
import asyncio
|
|
25
26
|
import dataclasses
|
|
27
|
+
import json
|
|
26
28
|
import logging
|
|
27
29
|
import os
|
|
28
|
-
import
|
|
29
|
-
|
|
30
|
+
from typing import TYPE_CHECKING, Any, Optional
|
|
31
|
+
|
|
30
32
|
from typing_extensions import Self
|
|
31
33
|
|
|
32
|
-
from bumble.colors import color
|
|
33
34
|
from bumble import hci
|
|
35
|
+
from bumble.colors import color
|
|
34
36
|
|
|
35
37
|
if TYPE_CHECKING:
|
|
36
38
|
from bumble.device import Device
|