bumble 0.0.218__py3-none-any.whl → 0.0.219__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/a2dp.py +57 -18
- bumble/avctp.py +8 -12
- bumble/avdtp.py +584 -533
- bumble/avrcp.py +20 -20
- bumble/controller.py +429 -229
- bumble/drivers/rtk.py +3 -1
- bumble/hci.py +38 -0
- bumble/hid.py +1 -1
- bumble/rfcomm.py +7 -3
- bumble/transport/common.py +6 -3
- bumble/transport/ws_client.py +2 -2
- bumble/transport/ws_server.py +16 -8
- {bumble-0.0.218.dist-info → bumble-0.0.219.dist-info}/METADATA +2 -2
- {bumble-0.0.218.dist-info → bumble-0.0.219.dist-info}/RECORD +19 -19
- {bumble-0.0.218.dist-info → bumble-0.0.219.dist-info}/WHEEL +0 -0
- {bumble-0.0.218.dist-info → bumble-0.0.219.dist-info}/entry_points.txt +0 -0
- {bumble-0.0.218.dist-info → bumble-0.0.219.dist-info}/licenses/LICENSE +0 -0
- {bumble-0.0.218.dist-info → bumble-0.0.219.dist-info}/top_level.txt +0 -0
bumble/controller.py
CHANGED
|
@@ -101,10 +101,10 @@ class Connection:
|
|
|
101
101
|
transport: int
|
|
102
102
|
link_type: int
|
|
103
103
|
|
|
104
|
-
def __post_init__(self):
|
|
104
|
+
def __post_init__(self) -> None:
|
|
105
105
|
self.assembler = HCI_AclDataPacketAssembler(self.on_acl_pdu)
|
|
106
106
|
|
|
107
|
-
def on_hci_acl_data_packet(self, packet):
|
|
107
|
+
def on_hci_acl_data_packet(self, packet: hci.HCI_AclDataPacket) -> None:
|
|
108
108
|
self.assembler.feed_packet(packet)
|
|
109
109
|
self.controller.send_hci_packet(
|
|
110
110
|
HCI_Number_Of_Completed_Packets_Event(
|
|
@@ -112,15 +112,81 @@ class Connection:
|
|
|
112
112
|
)
|
|
113
113
|
)
|
|
114
114
|
|
|
115
|
-
def on_acl_pdu(self,
|
|
115
|
+
def on_acl_pdu(self, pdu: bytes) -> None:
|
|
116
116
|
if self.link:
|
|
117
117
|
self.link.send_acl_data(
|
|
118
|
-
self.controller, self.peer_address, self.transport,
|
|
118
|
+
self.controller, self.peer_address, self.transport, pdu
|
|
119
119
|
)
|
|
120
120
|
|
|
121
121
|
|
|
122
122
|
# -----------------------------------------------------------------------------
|
|
123
123
|
class Controller:
|
|
124
|
+
hci_sink: Optional[TransportSink] = None
|
|
125
|
+
|
|
126
|
+
central_connections: dict[
|
|
127
|
+
Address, Connection
|
|
128
|
+
] # Connections where this controller is the central
|
|
129
|
+
peripheral_connections: dict[
|
|
130
|
+
Address, Connection
|
|
131
|
+
] # Connections where this controller is the peripheral
|
|
132
|
+
classic_connections: dict[Address, Connection] # Connections in BR/EDR
|
|
133
|
+
central_cis_links: dict[int, CisLink] # CIS links by handle
|
|
134
|
+
peripheral_cis_links: dict[int, CisLink] # CIS links by handle
|
|
135
|
+
|
|
136
|
+
hci_version: int = HCI_VERSION_BLUETOOTH_CORE_5_0
|
|
137
|
+
hci_revision: int = 0
|
|
138
|
+
lmp_version: int = HCI_VERSION_BLUETOOTH_CORE_5_0
|
|
139
|
+
lmp_subversion: int = 0
|
|
140
|
+
lmp_features: bytes = bytes.fromhex(
|
|
141
|
+
'0000000060000000'
|
|
142
|
+
) # BR/EDR Not Supported, LE Supported (Controller)
|
|
143
|
+
manufacturer_name: int = 0xFFFF
|
|
144
|
+
acl_data_packet_length: int = 27
|
|
145
|
+
total_num_acl_data_packets: int = 64
|
|
146
|
+
le_acl_data_packet_length: int = 27
|
|
147
|
+
total_num_le_acl_data_packets: int = 64
|
|
148
|
+
iso_data_packet_length: int = 960
|
|
149
|
+
total_num_iso_data_packets: int = 64
|
|
150
|
+
event_mask: int = 0
|
|
151
|
+
event_mask_page_2: int = 0
|
|
152
|
+
supported_commands: bytes = bytes.fromhex(
|
|
153
|
+
'2000800000c000000000e4000000a822000000000000040000f7ffff7f000000'
|
|
154
|
+
'30f0f9ff01008004002000000000000000000000000000000000000000000000'
|
|
155
|
+
)
|
|
156
|
+
le_event_mask: int = 0
|
|
157
|
+
advertising_parameters: Optional[hci.HCI_LE_Set_Advertising_Parameters_Command] = (
|
|
158
|
+
None
|
|
159
|
+
)
|
|
160
|
+
le_features: bytes = bytes.fromhex('ff49010000000000')
|
|
161
|
+
le_states: bytes = bytes.fromhex('ffff3fffff030000')
|
|
162
|
+
advertising_channel_tx_power: int = 0
|
|
163
|
+
filter_accept_list_size: int = 8
|
|
164
|
+
filter_duplicates: bool = False
|
|
165
|
+
resolving_list_size: int = 8
|
|
166
|
+
supported_max_tx_octets: int = 27
|
|
167
|
+
supported_max_tx_time: int = 10000
|
|
168
|
+
supported_max_rx_octets: int = 27
|
|
169
|
+
supported_max_rx_time: int = 10000
|
|
170
|
+
suggested_max_tx_octets: int = 27
|
|
171
|
+
suggested_max_tx_time: int = 0x0148
|
|
172
|
+
default_phy: dict[str, int]
|
|
173
|
+
le_scan_type: int = 0
|
|
174
|
+
le_scan_interval: int = 0x10
|
|
175
|
+
le_scan_window: int = 0x10
|
|
176
|
+
le_scan_enable: int = 0
|
|
177
|
+
le_scan_own_address_type: int = Address.RANDOM_DEVICE_ADDRESS
|
|
178
|
+
le_scanning_filter_policy: int = 0
|
|
179
|
+
le_scan_response_data: Optional[bytes] = None
|
|
180
|
+
le_address_resolution: bool = False
|
|
181
|
+
le_rpa_timeout: int = 0
|
|
182
|
+
sync_flow_control: bool = False
|
|
183
|
+
local_name: str = 'Bumble'
|
|
184
|
+
advertising_interval: int = 2000
|
|
185
|
+
advertising_data: Optional[bytes] = None
|
|
186
|
+
advertising_timer_handle: Optional[asyncio.Handle] = None
|
|
187
|
+
|
|
188
|
+
_random_address: 'Address' = Address('00:00:00:00:00:00')
|
|
189
|
+
|
|
124
190
|
def __init__(
|
|
125
191
|
self,
|
|
126
192
|
name: str,
|
|
@@ -128,75 +194,20 @@ class Controller:
|
|
|
128
194
|
host_sink: Optional[TransportSink] = None,
|
|
129
195
|
link: Optional[LocalLink] = None,
|
|
130
196
|
public_address: Optional[Union[bytes, str, Address]] = None,
|
|
131
|
-
):
|
|
197
|
+
) -> None:
|
|
132
198
|
self.name = name
|
|
133
|
-
self.hci_sink = None
|
|
134
199
|
self.link = link
|
|
200
|
+
self.central_connections = {}
|
|
201
|
+
self.peripheral_connections = {}
|
|
202
|
+
self.classic_connections = {}
|
|
203
|
+
self.central_cis_links = {}
|
|
204
|
+
self.peripheral_cis_links = {}
|
|
205
|
+
self.default_phy = {
|
|
206
|
+
'all_phys': 0,
|
|
207
|
+
'tx_phys': 0,
|
|
208
|
+
'rx_phys': 0,
|
|
209
|
+
}
|
|
135
210
|
|
|
136
|
-
self.central_connections: dict[Address, Connection] = (
|
|
137
|
-
{}
|
|
138
|
-
) # Connections where this controller is the central
|
|
139
|
-
self.peripheral_connections: dict[Address, Connection] = (
|
|
140
|
-
{}
|
|
141
|
-
) # Connections where this controller is the peripheral
|
|
142
|
-
self.classic_connections: dict[Address, Connection] = (
|
|
143
|
-
{}
|
|
144
|
-
) # Connections in BR/EDR
|
|
145
|
-
self.central_cis_links: dict[int, CisLink] = {} # CIS links by handle
|
|
146
|
-
self.peripheral_cis_links: dict[int, CisLink] = {} # CIS links by handle
|
|
147
|
-
|
|
148
|
-
self.hci_version = HCI_VERSION_BLUETOOTH_CORE_5_0
|
|
149
|
-
self.hci_revision = 0
|
|
150
|
-
self.lmp_version = HCI_VERSION_BLUETOOTH_CORE_5_0
|
|
151
|
-
self.lmp_subversion = 0
|
|
152
|
-
self.lmp_features = bytes.fromhex(
|
|
153
|
-
'0000000060000000'
|
|
154
|
-
) # BR/EDR Not Supported, LE Supported (Controller)
|
|
155
|
-
self.manufacturer_name = 0xFFFF
|
|
156
|
-
self.acl_data_packet_length = 27
|
|
157
|
-
self.total_num_acl_data_packets = 64
|
|
158
|
-
self.le_acl_data_packet_length = 27
|
|
159
|
-
self.total_num_le_acl_data_packets = 64
|
|
160
|
-
self.iso_data_packet_length = 960
|
|
161
|
-
self.total_num_iso_data_packets = 64
|
|
162
|
-
self.event_mask = 0
|
|
163
|
-
self.event_mask_page_2 = 0
|
|
164
|
-
self.supported_commands = bytes.fromhex(
|
|
165
|
-
'2000800000c000000000e4000000a822000000000000040000f7ffff7f000000'
|
|
166
|
-
'30f0f9ff01008004002000000000000000000000000000000000000000000000'
|
|
167
|
-
)
|
|
168
|
-
self.le_event_mask = 0
|
|
169
|
-
self.advertising_parameters = None
|
|
170
|
-
self.le_features = bytes.fromhex('ff49010000000000')
|
|
171
|
-
self.le_states = bytes.fromhex('ffff3fffff030000')
|
|
172
|
-
self.advertising_channel_tx_power = 0
|
|
173
|
-
self.filter_accept_list_size = 8
|
|
174
|
-
self.filter_duplicates = False
|
|
175
|
-
self.resolving_list_size = 8
|
|
176
|
-
self.supported_max_tx_octets = 27
|
|
177
|
-
self.supported_max_tx_time = 10000 # microseconds
|
|
178
|
-
self.supported_max_rx_octets = 27
|
|
179
|
-
self.supported_max_rx_time = 10000 # microseconds
|
|
180
|
-
self.suggested_max_tx_octets = 27
|
|
181
|
-
self.suggested_max_tx_time = 0x0148 # microseconds
|
|
182
|
-
self.default_phy = bytes([0, 0, 0])
|
|
183
|
-
self.le_scan_type = 0
|
|
184
|
-
self.le_scan_interval = 0x10
|
|
185
|
-
self.le_scan_window = 0x10
|
|
186
|
-
self.le_scan_enable = 0
|
|
187
|
-
self.le_scan_own_address_type = Address.RANDOM_DEVICE_ADDRESS
|
|
188
|
-
self.le_scanning_filter_policy = 0
|
|
189
|
-
self.le_scan_response_data = None
|
|
190
|
-
self.le_address_resolution = False
|
|
191
|
-
self.le_rpa_timeout = 0
|
|
192
|
-
self.sync_flow_control = False
|
|
193
|
-
self.local_name = 'Bumble'
|
|
194
|
-
|
|
195
|
-
self.advertising_interval = 2000 # Fixed for now
|
|
196
|
-
self.advertising_data = None
|
|
197
|
-
self.advertising_timer_handle = None
|
|
198
|
-
|
|
199
|
-
self._random_address = Address('00:00:00:00:00:00')
|
|
200
211
|
if isinstance(public_address, Address):
|
|
201
212
|
self._public_address = public_address
|
|
202
213
|
elif public_address is not None:
|
|
@@ -215,44 +226,44 @@ class Controller:
|
|
|
215
226
|
if link:
|
|
216
227
|
link.add_controller(self)
|
|
217
228
|
|
|
218
|
-
self.terminated =
|
|
229
|
+
self.terminated: asyncio.Future[Any] = (
|
|
230
|
+
asyncio.get_running_loop().create_future()
|
|
231
|
+
)
|
|
219
232
|
|
|
220
233
|
@property
|
|
221
|
-
def host(self):
|
|
234
|
+
def host(self) -> Optional[TransportSink]:
|
|
222
235
|
return self.hci_sink
|
|
223
236
|
|
|
224
237
|
@host.setter
|
|
225
|
-
def host(self, host):
|
|
238
|
+
def host(self, host: Optional[TransportSink]) -> None:
|
|
226
239
|
'''
|
|
227
240
|
Sets the host (sink) for this controller, and set this controller as the
|
|
228
241
|
controller (sink) for the host
|
|
229
242
|
'''
|
|
230
243
|
self.set_packet_sink(host)
|
|
231
|
-
if host:
|
|
232
|
-
host.controller = self
|
|
233
244
|
|
|
234
|
-
def set_packet_sink(self, sink):
|
|
245
|
+
def set_packet_sink(self, sink: Optional[TransportSink]) -> None:
|
|
235
246
|
'''
|
|
236
247
|
Method from the Packet Source interface
|
|
237
248
|
'''
|
|
238
249
|
self.hci_sink = sink
|
|
239
250
|
|
|
240
251
|
@property
|
|
241
|
-
def public_address(self):
|
|
252
|
+
def public_address(self) -> Address:
|
|
242
253
|
return self._public_address
|
|
243
254
|
|
|
244
255
|
@public_address.setter
|
|
245
|
-
def public_address(self, address):
|
|
256
|
+
def public_address(self, address: Union[Address, str]) -> None:
|
|
246
257
|
if isinstance(address, str):
|
|
247
258
|
address = Address(address)
|
|
248
259
|
self._public_address = address
|
|
249
260
|
|
|
250
261
|
@property
|
|
251
|
-
def random_address(self):
|
|
262
|
+
def random_address(self) -> Address:
|
|
252
263
|
return self._random_address
|
|
253
264
|
|
|
254
265
|
@random_address.setter
|
|
255
|
-
def random_address(self, address):
|
|
266
|
+
def random_address(self, address: Union[Address, str]) -> None:
|
|
256
267
|
if isinstance(address, str):
|
|
257
268
|
address = Address(address)
|
|
258
269
|
self._random_address = address
|
|
@@ -262,29 +273,29 @@ class Controller:
|
|
|
262
273
|
self.link.on_address_changed(self)
|
|
263
274
|
|
|
264
275
|
# Packet Sink protocol (packets coming from the host via HCI)
|
|
265
|
-
def on_packet(self, packet):
|
|
276
|
+
def on_packet(self, packet: bytes) -> None:
|
|
266
277
|
self.on_hci_packet(HCI_Packet.from_bytes(packet))
|
|
267
278
|
|
|
268
|
-
def on_hci_packet(self, packet):
|
|
279
|
+
def on_hci_packet(self, packet: HCI_Packet) -> None:
|
|
269
280
|
logger.debug(
|
|
270
281
|
f'{color("<<<", "blue")} [{self.name}] '
|
|
271
282
|
f'{color("HOST -> CONTROLLER", "blue")}: {packet}'
|
|
272
283
|
)
|
|
273
284
|
|
|
274
285
|
# If the packet is a command, invoke the handler for this packet
|
|
275
|
-
if packet.
|
|
286
|
+
if isinstance(packet, hci.HCI_Command):
|
|
276
287
|
self.on_hci_command_packet(packet)
|
|
277
|
-
elif packet.
|
|
278
|
-
self.on_hci_event_packet(packet)
|
|
279
|
-
elif packet.hci_packet_type == HCI_ACL_DATA_PACKET:
|
|
288
|
+
elif isinstance(packet, hci.HCI_AclDataPacket):
|
|
280
289
|
self.on_hci_acl_data_packet(packet)
|
|
290
|
+
elif isinstance(packet, hci.HCI_Event):
|
|
291
|
+
self.on_hci_event_packet(packet)
|
|
281
292
|
else:
|
|
282
293
|
logger.warning(f'!!! unknown packet type {packet.hci_packet_type}')
|
|
283
294
|
|
|
284
|
-
def on_hci_command_packet(self, command):
|
|
295
|
+
def on_hci_command_packet(self, command: hci.HCI_Command) -> None:
|
|
285
296
|
handler_name = f'on_{command.name.lower()}'
|
|
286
297
|
handler = getattr(self, handler_name, self.on_hci_command)
|
|
287
|
-
result = handler(command)
|
|
298
|
+
result: Optional[bytes] = handler(command)
|
|
288
299
|
if isinstance(result, bytes):
|
|
289
300
|
self.send_hci_packet(
|
|
290
301
|
HCI_Command_Complete_Event(
|
|
@@ -294,10 +305,10 @@ class Controller:
|
|
|
294
305
|
)
|
|
295
306
|
)
|
|
296
307
|
|
|
297
|
-
def on_hci_event_packet(self, _event):
|
|
308
|
+
def on_hci_event_packet(self, _event: HCI_Packet) -> None:
|
|
298
309
|
logger.warning('!!! unexpected event packet')
|
|
299
310
|
|
|
300
|
-
def on_hci_acl_data_packet(self, packet):
|
|
311
|
+
def on_hci_acl_data_packet(self, packet: hci.HCI_AclDataPacket) -> None:
|
|
301
312
|
# Look for the connection to which this data belongs
|
|
302
313
|
connection = self.find_connection_by_handle(packet.connection_handle)
|
|
303
314
|
if connection is None:
|
|
@@ -309,7 +320,7 @@ class Controller:
|
|
|
309
320
|
# Pass the packet to the connection
|
|
310
321
|
connection.on_hci_acl_data_packet(packet)
|
|
311
322
|
|
|
312
|
-
def send_hci_packet(self, packet):
|
|
323
|
+
def send_hci_packet(self, packet: HCI_Packet) -> None:
|
|
313
324
|
logger.debug(
|
|
314
325
|
f'{color(">>>", "green")} [{self.name}] '
|
|
315
326
|
f'{color("CONTROLLER -> HOST", "green")}: {packet}'
|
|
@@ -318,7 +329,7 @@ class Controller:
|
|
|
318
329
|
self.host.on_packet(bytes(packet))
|
|
319
330
|
|
|
320
331
|
# This method allows the controller to emulate the same API as a transport source
|
|
321
|
-
async def wait_for_termination(self):
|
|
332
|
+
async def wait_for_termination(self) -> None:
|
|
322
333
|
await self.terminated
|
|
323
334
|
|
|
324
335
|
############################################################
|
|
@@ -345,15 +356,17 @@ class Controller:
|
|
|
345
356
|
handle = max_handle + 1
|
|
346
357
|
return handle
|
|
347
358
|
|
|
348
|
-
def find_le_connection_by_address(self, address):
|
|
359
|
+
def find_le_connection_by_address(self, address: Address) -> Optional[Connection]:
|
|
349
360
|
return self.central_connections.get(address) or self.peripheral_connections.get(
|
|
350
361
|
address
|
|
351
362
|
)
|
|
352
363
|
|
|
353
|
-
def find_classic_connection_by_address(
|
|
364
|
+
def find_classic_connection_by_address(
|
|
365
|
+
self, address: Address
|
|
366
|
+
) -> Optional[Connection]:
|
|
354
367
|
return self.classic_connections.get(address)
|
|
355
368
|
|
|
356
|
-
def find_connection_by_handle(self, handle):
|
|
369
|
+
def find_connection_by_handle(self, handle: int) -> Optional[Connection]:
|
|
357
370
|
for connection in itertools.chain(
|
|
358
371
|
self.central_connections.values(),
|
|
359
372
|
self.peripheral_connections.values(),
|
|
@@ -363,19 +376,19 @@ class Controller:
|
|
|
363
376
|
return connection
|
|
364
377
|
return None
|
|
365
378
|
|
|
366
|
-
def find_central_connection_by_handle(self, handle):
|
|
379
|
+
def find_central_connection_by_handle(self, handle: int) -> Optional[Connection]:
|
|
367
380
|
for connection in self.central_connections.values():
|
|
368
381
|
if connection.handle == handle:
|
|
369
382
|
return connection
|
|
370
383
|
return None
|
|
371
384
|
|
|
372
|
-
def find_peripheral_connection_by_handle(self, handle):
|
|
385
|
+
def find_peripheral_connection_by_handle(self, handle: int) -> Optional[Connection]:
|
|
373
386
|
for connection in self.peripheral_connections.values():
|
|
374
387
|
if connection.handle == handle:
|
|
375
388
|
return connection
|
|
376
389
|
return None
|
|
377
390
|
|
|
378
|
-
def find_classic_connection_by_handle(self, handle):
|
|
391
|
+
def find_classic_connection_by_handle(self, handle: int) -> Optional[Connection]:
|
|
379
392
|
for connection in self.classic_connections.values():
|
|
380
393
|
if connection.handle == handle:
|
|
381
394
|
return connection
|
|
@@ -386,7 +399,7 @@ class Controller:
|
|
|
386
399
|
handle
|
|
387
400
|
)
|
|
388
401
|
|
|
389
|
-
def on_link_central_connected(self, central_address):
|
|
402
|
+
def on_link_central_connected(self, central_address: Address) -> None:
|
|
390
403
|
'''
|
|
391
404
|
Called when an incoming connection occurs from a central on the link
|
|
392
405
|
'''
|
|
@@ -424,7 +437,7 @@ class Controller:
|
|
|
424
437
|
)
|
|
425
438
|
)
|
|
426
439
|
|
|
427
|
-
def on_link_disconnected(self, peer_address, reason):
|
|
440
|
+
def on_link_disconnected(self, peer_address: Address, reason: int) -> None:
|
|
428
441
|
'''
|
|
429
442
|
Called when an active disconnection occurs from a peer
|
|
430
443
|
'''
|
|
@@ -456,8 +469,10 @@ class Controller:
|
|
|
456
469
|
logger.warning(f'!!! No peripheral connection found for {peer_address}')
|
|
457
470
|
|
|
458
471
|
def on_link_peripheral_connection_complete(
|
|
459
|
-
self,
|
|
460
|
-
|
|
472
|
+
self,
|
|
473
|
+
le_create_connection_command: hci.HCI_LE_Create_Connection_Command,
|
|
474
|
+
status: int,
|
|
475
|
+
) -> None:
|
|
461
476
|
'''
|
|
462
477
|
Called by the link when a connection has been made or has failed to be made
|
|
463
478
|
'''
|
|
@@ -500,7 +515,9 @@ class Controller:
|
|
|
500
515
|
)
|
|
501
516
|
)
|
|
502
517
|
|
|
503
|
-
def on_link_disconnection_complete(
|
|
518
|
+
def on_link_disconnection_complete(
|
|
519
|
+
self, disconnection_command: hci.HCI_Disconnect_Command, status: int
|
|
520
|
+
) -> None:
|
|
504
521
|
'''
|
|
505
522
|
Called when a disconnection has been completed
|
|
506
523
|
'''
|
|
@@ -526,7 +543,9 @@ class Controller:
|
|
|
526
543
|
logger.debug(f'PERIPHERAL Connection removed: {connection}')
|
|
527
544
|
del self.peripheral_connections[connection.peer_address]
|
|
528
545
|
|
|
529
|
-
def on_link_encrypted(
|
|
546
|
+
def on_link_encrypted(
|
|
547
|
+
self, peer_address: Address, _rand: int, _ediv: int, _ltk: bytes
|
|
548
|
+
) -> None:
|
|
530
549
|
# For now, just setup the encryption without asking the host
|
|
531
550
|
if connection := self.find_le_connection_by_address(peer_address):
|
|
532
551
|
self.send_hci_packet(
|
|
@@ -535,7 +554,9 @@ class Controller:
|
|
|
535
554
|
)
|
|
536
555
|
)
|
|
537
556
|
|
|
538
|
-
def on_link_acl_data(
|
|
557
|
+
def on_link_acl_data(
|
|
558
|
+
self, sender_address: Address, transport: PhysicalTransport, data: bytes
|
|
559
|
+
) -> None:
|
|
539
560
|
# Look for the connection to which this data belongs
|
|
540
561
|
if transport == PhysicalTransport.LE:
|
|
541
562
|
connection = self.find_le_connection_by_address(sender_address)
|
|
@@ -550,7 +571,7 @@ class Controller:
|
|
|
550
571
|
acl_packet = HCI_AclDataPacket(connection.handle, 2, 0, len(data), data)
|
|
551
572
|
self.send_hci_packet(acl_packet)
|
|
552
573
|
|
|
553
|
-
def on_link_advertising_data(self, sender_address: Address, data: bytes):
|
|
574
|
+
def on_link_advertising_data(self, sender_address: Address, data: bytes) -> None:
|
|
554
575
|
# Ignore if we're not scanning
|
|
555
576
|
if self.le_scan_enable == 0:
|
|
556
577
|
return
|
|
@@ -677,7 +698,9 @@ class Controller:
|
|
|
677
698
|
# Classic link connections
|
|
678
699
|
############################################################
|
|
679
700
|
|
|
680
|
-
def on_classic_connection_request(
|
|
701
|
+
def on_classic_connection_request(
|
|
702
|
+
self, peer_address: Address, link_type: int
|
|
703
|
+
) -> None:
|
|
681
704
|
self.send_hci_packet(
|
|
682
705
|
HCI_Connection_Request_Event(
|
|
683
706
|
bd_addr=peer_address,
|
|
@@ -686,7 +709,9 @@ class Controller:
|
|
|
686
709
|
)
|
|
687
710
|
)
|
|
688
711
|
|
|
689
|
-
def on_classic_connection_complete(
|
|
712
|
+
def on_classic_connection_complete(
|
|
713
|
+
self, peer_address: Address, status: int
|
|
714
|
+
) -> None:
|
|
690
715
|
if status == HCI_SUCCESS:
|
|
691
716
|
# Allocate (or reuse) a connection handle
|
|
692
717
|
peer_address = peer_address
|
|
@@ -730,7 +755,7 @@ class Controller:
|
|
|
730
755
|
)
|
|
731
756
|
)
|
|
732
757
|
|
|
733
|
-
def on_classic_disconnected(self, peer_address, reason):
|
|
758
|
+
def on_classic_disconnected(self, peer_address: Address, reason: int) -> None:
|
|
734
759
|
# Send a disconnection complete event
|
|
735
760
|
if connection := self.classic_connections.get(peer_address):
|
|
736
761
|
self.send_hci_packet(
|
|
@@ -746,7 +771,7 @@ class Controller:
|
|
|
746
771
|
else:
|
|
747
772
|
logger.warning(f'!!! No classic connection found for {peer_address}')
|
|
748
773
|
|
|
749
|
-
def on_classic_role_change(self, peer_address, new_role):
|
|
774
|
+
def on_classic_role_change(self, peer_address: Address, new_role: int) -> None:
|
|
750
775
|
self.send_hci_packet(
|
|
751
776
|
HCI_Role_Change_Event(
|
|
752
777
|
status=HCI_SUCCESS,
|
|
@@ -757,7 +782,7 @@ class Controller:
|
|
|
757
782
|
|
|
758
783
|
def on_classic_sco_connection_complete(
|
|
759
784
|
self, peer_address: Address, status: int, link_type: int
|
|
760
|
-
):
|
|
785
|
+
) -> None:
|
|
761
786
|
if status == HCI_SUCCESS:
|
|
762
787
|
# Allocate (or reuse) a connection handle
|
|
763
788
|
connection_handle = self.allocate_connection_handle()
|
|
@@ -794,13 +819,13 @@ class Controller:
|
|
|
794
819
|
############################################################
|
|
795
820
|
# Advertising support
|
|
796
821
|
############################################################
|
|
797
|
-
def on_advertising_timer_fired(self):
|
|
822
|
+
def on_advertising_timer_fired(self) -> None:
|
|
798
823
|
self.send_advertising_data()
|
|
799
824
|
self.advertising_timer_handle = asyncio.get_running_loop().call_later(
|
|
800
825
|
self.advertising_interval / 1000.0, self.on_advertising_timer_fired
|
|
801
826
|
)
|
|
802
827
|
|
|
803
|
-
def start_advertising(self):
|
|
828
|
+
def start_advertising(self) -> None:
|
|
804
829
|
# Stop any ongoing advertising before we start again
|
|
805
830
|
self.stop_advertising()
|
|
806
831
|
|
|
@@ -809,33 +834,35 @@ class Controller:
|
|
|
809
834
|
self.on_advertising_timer_fired
|
|
810
835
|
)
|
|
811
836
|
|
|
812
|
-
def stop_advertising(self):
|
|
837
|
+
def stop_advertising(self) -> None:
|
|
813
838
|
if self.advertising_timer_handle is not None:
|
|
814
839
|
self.advertising_timer_handle.cancel()
|
|
815
840
|
self.advertising_timer_handle = None
|
|
816
841
|
|
|
817
|
-
def send_advertising_data(self):
|
|
842
|
+
def send_advertising_data(self) -> None:
|
|
818
843
|
if self.link and self.advertising_data:
|
|
819
844
|
self.link.send_advertising_data(self.random_address, self.advertising_data)
|
|
820
845
|
|
|
821
846
|
@property
|
|
822
|
-
def is_advertising(self):
|
|
847
|
+
def is_advertising(self) -> bool:
|
|
823
848
|
return self.advertising_timer_handle is not None
|
|
824
849
|
|
|
825
850
|
############################################################
|
|
826
851
|
# HCI handlers
|
|
827
852
|
############################################################
|
|
828
|
-
def on_hci_command(self, command):
|
|
853
|
+
def on_hci_command(self, command: hci.HCI_Command) -> Optional[bytes]:
|
|
829
854
|
logger.warning(color(f'--- Unsupported command {command}', 'red'))
|
|
830
855
|
return bytes([HCI_UNKNOWN_HCI_COMMAND_ERROR])
|
|
831
856
|
|
|
832
|
-
def on_hci_create_connection_command(
|
|
857
|
+
def on_hci_create_connection_command(
|
|
858
|
+
self, command: hci.HCI_Create_Connection_Command
|
|
859
|
+
) -> Optional[bytes]:
|
|
833
860
|
'''
|
|
834
861
|
See Bluetooth spec Vol 4, Part E - 7.1.5 Create Connection command
|
|
835
862
|
'''
|
|
836
863
|
|
|
837
864
|
if self.link is None:
|
|
838
|
-
return
|
|
865
|
+
return None
|
|
839
866
|
logger.debug(f'Connection request to {command.bd_addr}')
|
|
840
867
|
|
|
841
868
|
# Check that we don't already have a pending connection
|
|
@@ -847,7 +874,7 @@ class Controller:
|
|
|
847
874
|
command_opcode=command.op_code,
|
|
848
875
|
)
|
|
849
876
|
)
|
|
850
|
-
return
|
|
877
|
+
return None
|
|
851
878
|
|
|
852
879
|
self.link.classic_connect(self, command.bd_addr)
|
|
853
880
|
|
|
@@ -859,8 +886,11 @@ class Controller:
|
|
|
859
886
|
command_opcode=command.op_code,
|
|
860
887
|
)
|
|
861
888
|
)
|
|
889
|
+
return None
|
|
862
890
|
|
|
863
|
-
def on_hci_disconnect_command(
|
|
891
|
+
def on_hci_disconnect_command(
|
|
892
|
+
self, command: hci.HCI_Disconnect_Command
|
|
893
|
+
) -> Optional[bytes]:
|
|
864
894
|
'''
|
|
865
895
|
See Bluetooth spec Vol 4, Part E - 7.1.6 Disconnect Command
|
|
866
896
|
'''
|
|
@@ -904,7 +934,7 @@ class Controller:
|
|
|
904
934
|
elif cis_link := (
|
|
905
935
|
self.central_cis_links.get(handle) or self.peripheral_cis_links.get(handle)
|
|
906
936
|
):
|
|
907
|
-
if self.link:
|
|
937
|
+
if self.link and cis_link.acl_connection:
|
|
908
938
|
self.link.disconnect_cis(
|
|
909
939
|
initiator_controller=self,
|
|
910
940
|
peer_address=cis_link.acl_connection.peer_address,
|
|
@@ -913,13 +943,17 @@ class Controller:
|
|
|
913
943
|
)
|
|
914
944
|
# Spec requires handle to be kept after disconnection.
|
|
915
945
|
|
|
916
|
-
|
|
946
|
+
return None
|
|
947
|
+
|
|
948
|
+
def on_hci_accept_connection_request_command(
|
|
949
|
+
self, command: hci.HCI_Accept_Connection_Request_Command
|
|
950
|
+
) -> Optional[bytes]:
|
|
917
951
|
'''
|
|
918
952
|
See Bluetooth spec Vol 4, Part E - 7.1.8 Accept Connection Request command
|
|
919
953
|
'''
|
|
920
954
|
|
|
921
955
|
if self.link is None:
|
|
922
|
-
return
|
|
956
|
+
return None
|
|
923
957
|
self.send_hci_packet(
|
|
924
958
|
HCI_Command_Status_Event(
|
|
925
959
|
status=HCI_SUCCESS,
|
|
@@ -928,14 +962,17 @@ class Controller:
|
|
|
928
962
|
)
|
|
929
963
|
)
|
|
930
964
|
self.link.classic_accept_connection(self, command.bd_addr, command.role)
|
|
965
|
+
return None
|
|
931
966
|
|
|
932
|
-
def on_hci_enhanced_setup_synchronous_connection_command(
|
|
967
|
+
def on_hci_enhanced_setup_synchronous_connection_command(
|
|
968
|
+
self, command: hci.HCI_Enhanced_Setup_Synchronous_Connection_Command
|
|
969
|
+
) -> Optional[bytes]:
|
|
933
970
|
'''
|
|
934
971
|
See Bluetooth spec Vol 4, Part E - 7.1.45 Enhanced Setup Synchronous Connection command
|
|
935
972
|
'''
|
|
936
973
|
|
|
937
974
|
if self.link is None:
|
|
938
|
-
return
|
|
975
|
+
return None
|
|
939
976
|
|
|
940
977
|
if not (
|
|
941
978
|
connection := self.find_classic_connection_by_handle(
|
|
@@ -949,7 +986,7 @@ class Controller:
|
|
|
949
986
|
command_opcode=command.op_code,
|
|
950
987
|
)
|
|
951
988
|
)
|
|
952
|
-
return
|
|
989
|
+
return None
|
|
953
990
|
|
|
954
991
|
self.send_hci_packet(
|
|
955
992
|
HCI_Command_Status_Event(
|
|
@@ -961,14 +998,17 @@ class Controller:
|
|
|
961
998
|
self.link.classic_sco_connect(
|
|
962
999
|
self, connection.peer_address, HCI_Connection_Complete_Event.LinkType.ESCO
|
|
963
1000
|
)
|
|
1001
|
+
return None
|
|
964
1002
|
|
|
965
|
-
def on_hci_enhanced_accept_synchronous_connection_request_command(
|
|
1003
|
+
def on_hci_enhanced_accept_synchronous_connection_request_command(
|
|
1004
|
+
self, command: hci.HCI_Enhanced_Accept_Synchronous_Connection_Request_Command
|
|
1005
|
+
) -> Optional[bytes]:
|
|
966
1006
|
'''
|
|
967
1007
|
See Bluetooth spec Vol 4, Part E - 7.1.46 Enhanced Accept Synchronous Connection Request command
|
|
968
1008
|
'''
|
|
969
1009
|
|
|
970
1010
|
if self.link is None:
|
|
971
|
-
return
|
|
1011
|
+
return None
|
|
972
1012
|
|
|
973
1013
|
if not (connection := self.find_classic_connection_by_address(command.bd_addr)):
|
|
974
1014
|
self.send_hci_packet(
|
|
@@ -978,7 +1018,7 @@ class Controller:
|
|
|
978
1018
|
command_opcode=command.op_code,
|
|
979
1019
|
)
|
|
980
1020
|
)
|
|
981
|
-
return
|
|
1021
|
+
return None
|
|
982
1022
|
|
|
983
1023
|
self.send_hci_packet(
|
|
984
1024
|
HCI_Command_Status_Event(
|
|
@@ -990,8 +1030,11 @@ class Controller:
|
|
|
990
1030
|
self.link.classic_accept_sco_connection(
|
|
991
1031
|
self, connection.peer_address, HCI_Connection_Complete_Event.LinkType.ESCO
|
|
992
1032
|
)
|
|
1033
|
+
return None
|
|
993
1034
|
|
|
994
|
-
def on_hci_sniff_mode_command(
|
|
1035
|
+
def on_hci_sniff_mode_command(
|
|
1036
|
+
self, command: hci.HCI_Sniff_Mode_Command
|
|
1037
|
+
) -> Optional[bytes]:
|
|
995
1038
|
'''
|
|
996
1039
|
See Bluetooth spec Vol 4, Part E - 7.2.2 Sniff Mode command
|
|
997
1040
|
'''
|
|
@@ -1003,7 +1046,7 @@ class Controller:
|
|
|
1003
1046
|
command_opcode=command.op_code,
|
|
1004
1047
|
)
|
|
1005
1048
|
)
|
|
1006
|
-
return
|
|
1049
|
+
return None
|
|
1007
1050
|
|
|
1008
1051
|
self.send_hci_packet(
|
|
1009
1052
|
hci.HCI_Command_Status_Event(
|
|
@@ -1020,8 +1063,11 @@ class Controller:
|
|
|
1020
1063
|
interval=2,
|
|
1021
1064
|
)
|
|
1022
1065
|
)
|
|
1066
|
+
return None
|
|
1023
1067
|
|
|
1024
|
-
def on_hci_exit_sniff_mode_command(
|
|
1068
|
+
def on_hci_exit_sniff_mode_command(
|
|
1069
|
+
self, command: hci.HCI_Exit_Sniff_Mode_Command
|
|
1070
|
+
) -> Optional[bytes]:
|
|
1025
1071
|
'''
|
|
1026
1072
|
See Bluetooth spec Vol 4, Part E - 7.2.3 Exit Sniff Mode command
|
|
1027
1073
|
'''
|
|
@@ -1034,7 +1080,7 @@ class Controller:
|
|
|
1034
1080
|
command_opcode=command.op_code,
|
|
1035
1081
|
)
|
|
1036
1082
|
)
|
|
1037
|
-
return
|
|
1083
|
+
return None
|
|
1038
1084
|
|
|
1039
1085
|
self.send_hci_packet(
|
|
1040
1086
|
hci.HCI_Command_Status_Event(
|
|
@@ -1051,14 +1097,17 @@ class Controller:
|
|
|
1051
1097
|
interval=2,
|
|
1052
1098
|
)
|
|
1053
1099
|
)
|
|
1100
|
+
return None
|
|
1054
1101
|
|
|
1055
|
-
def on_hci_switch_role_command(
|
|
1102
|
+
def on_hci_switch_role_command(
|
|
1103
|
+
self, command: hci.HCI_Switch_Role_Command
|
|
1104
|
+
) -> Optional[bytes]:
|
|
1056
1105
|
'''
|
|
1057
1106
|
See Bluetooth spec Vol 4, Part E - 7.2.8 Switch Role command
|
|
1058
1107
|
'''
|
|
1059
1108
|
|
|
1060
1109
|
if self.link is None:
|
|
1061
|
-
return
|
|
1110
|
+
return None
|
|
1062
1111
|
self.send_hci_packet(
|
|
1063
1112
|
HCI_Command_Status_Event(
|
|
1064
1113
|
status=HCI_SUCCESS,
|
|
@@ -1067,22 +1116,29 @@ class Controller:
|
|
|
1067
1116
|
)
|
|
1068
1117
|
)
|
|
1069
1118
|
self.link.classic_switch_role(self, command.bd_addr, command.role)
|
|
1119
|
+
return None
|
|
1070
1120
|
|
|
1071
|
-
def on_hci_set_event_mask_command(
|
|
1121
|
+
def on_hci_set_event_mask_command(
|
|
1122
|
+
self, command: hci.HCI_Set_Event_Mask_Command
|
|
1123
|
+
) -> Optional[bytes]:
|
|
1072
1124
|
'''
|
|
1073
1125
|
See Bluetooth spec Vol 4, Part E - 7.3.1 Set Event Mask Command
|
|
1074
1126
|
'''
|
|
1075
|
-
self.event_mask =
|
|
1127
|
+
self.event_mask = int.from_bytes(
|
|
1128
|
+
command.event_mask, byteorder='little', signed=False
|
|
1129
|
+
)
|
|
1076
1130
|
return bytes([HCI_SUCCESS])
|
|
1077
1131
|
|
|
1078
|
-
def on_hci_reset_command(self, _command):
|
|
1132
|
+
def on_hci_reset_command(self, _command: hci.HCI_Reset_Command) -> Optional[bytes]:
|
|
1079
1133
|
'''
|
|
1080
1134
|
See Bluetooth spec Vol 4, Part E - 7.3.2 Reset Command
|
|
1081
1135
|
'''
|
|
1082
1136
|
# TODO: cleanup what needs to be reset
|
|
1083
1137
|
return bytes([HCI_SUCCESS])
|
|
1084
1138
|
|
|
1085
|
-
def on_hci_write_local_name_command(
|
|
1139
|
+
def on_hci_write_local_name_command(
|
|
1140
|
+
self, command: hci.HCI_Write_Local_Name_Command
|
|
1141
|
+
) -> Optional[bytes]:
|
|
1086
1142
|
'''
|
|
1087
1143
|
See Bluetooth spec Vol 4, Part E - 7.3.11 Write Local Name Command
|
|
1088
1144
|
'''
|
|
@@ -1097,7 +1153,9 @@ class Controller:
|
|
|
1097
1153
|
pass
|
|
1098
1154
|
return bytes([HCI_SUCCESS])
|
|
1099
1155
|
|
|
1100
|
-
def on_hci_read_local_name_command(
|
|
1156
|
+
def on_hci_read_local_name_command(
|
|
1157
|
+
self, _command: hci.HCI_Read_Local_Name_Command
|
|
1158
|
+
) -> Optional[bytes]:
|
|
1101
1159
|
'''
|
|
1102
1160
|
See Bluetooth spec Vol 4, Part E - 7.3.12 Read Local Name Command
|
|
1103
1161
|
'''
|
|
@@ -1107,19 +1165,25 @@ class Controller:
|
|
|
1107
1165
|
|
|
1108
1166
|
return bytes([HCI_SUCCESS]) + local_name
|
|
1109
1167
|
|
|
1110
|
-
def on_hci_read_class_of_device_command(
|
|
1168
|
+
def on_hci_read_class_of_device_command(
|
|
1169
|
+
self, _command: hci.HCI_Read_Class_Of_Device_Command
|
|
1170
|
+
) -> Optional[bytes]:
|
|
1111
1171
|
'''
|
|
1112
1172
|
See Bluetooth spec Vol 4, Part E - 7.3.25 Read Class of Device Command
|
|
1113
1173
|
'''
|
|
1114
1174
|
return bytes([HCI_SUCCESS, 0, 0, 0])
|
|
1115
1175
|
|
|
1116
|
-
def on_hci_write_class_of_device_command(
|
|
1176
|
+
def on_hci_write_class_of_device_command(
|
|
1177
|
+
self, _command: hci.HCI_Write_Class_Of_Device_Command
|
|
1178
|
+
) -> Optional[bytes]:
|
|
1117
1179
|
'''
|
|
1118
1180
|
See Bluetooth spec Vol 4, Part E - 7.3.26 Write Class of Device Command
|
|
1119
1181
|
'''
|
|
1120
1182
|
return bytes([HCI_SUCCESS])
|
|
1121
1183
|
|
|
1122
|
-
def on_hci_read_synchronous_flow_control_enable_command(
|
|
1184
|
+
def on_hci_read_synchronous_flow_control_enable_command(
|
|
1185
|
+
self, _command: hci.HCI_Read_Synchronous_Flow_Control_Enable_Command
|
|
1186
|
+
) -> Optional[bytes]:
|
|
1123
1187
|
'''
|
|
1124
1188
|
See Bluetooth spec Vol 4, Part E - 7.3.36 Read Synchronous Flow Control Enable
|
|
1125
1189
|
Command
|
|
@@ -1130,7 +1194,9 @@ class Controller:
|
|
|
1130
1194
|
ret = 0
|
|
1131
1195
|
return bytes([HCI_SUCCESS, ret])
|
|
1132
1196
|
|
|
1133
|
-
def on_hci_write_synchronous_flow_control_enable_command(
|
|
1197
|
+
def on_hci_write_synchronous_flow_control_enable_command(
|
|
1198
|
+
self, command: hci.HCI_Write_Synchronous_Flow_Control_Enable_Command
|
|
1199
|
+
) -> Optional[bytes]:
|
|
1134
1200
|
'''
|
|
1135
1201
|
See Bluetooth spec Vol 4, Part E - 7.3.37 Write Synchronous Flow Control Enable
|
|
1136
1202
|
Command
|
|
@@ -1144,7 +1210,9 @@ class Controller:
|
|
|
1144
1210
|
ret = HCI_INVALID_HCI_COMMAND_PARAMETERS_ERROR
|
|
1145
1211
|
return bytes([ret])
|
|
1146
1212
|
|
|
1147
|
-
def on_hci_set_controller_to_host_flow_control_command(
|
|
1213
|
+
def on_hci_set_controller_to_host_flow_control_command(
|
|
1214
|
+
self, _command: hci.HCI_Set_Controller_To_Host_Flow_Control_Command
|
|
1215
|
+
) -> Optional[bytes]:
|
|
1148
1216
|
'''
|
|
1149
1217
|
See Bluetooth spec Vol 4, Part E - 7.3.38 Set Controller To Host Flow Control
|
|
1150
1218
|
Command
|
|
@@ -1153,7 +1221,9 @@ class Controller:
|
|
|
1153
1221
|
# TODO: respect the passed in values.
|
|
1154
1222
|
return bytes([HCI_SUCCESS])
|
|
1155
1223
|
|
|
1156
|
-
def on_hci_host_buffer_size_command(
|
|
1224
|
+
def on_hci_host_buffer_size_command(
|
|
1225
|
+
self, _command: hci.HCI_Host_Buffer_Size_Command
|
|
1226
|
+
) -> Optional[bytes]:
|
|
1157
1227
|
'''
|
|
1158
1228
|
See Bluetooth spec Vol 4, Part E - 7.3.39 Host Buffer Size Command
|
|
1159
1229
|
'''
|
|
@@ -1161,40 +1231,54 @@ class Controller:
|
|
|
1161
1231
|
# TODO: respect the passed in values.
|
|
1162
1232
|
return bytes([HCI_SUCCESS])
|
|
1163
1233
|
|
|
1164
|
-
def on_hci_write_extended_inquiry_response_command(
|
|
1234
|
+
def on_hci_write_extended_inquiry_response_command(
|
|
1235
|
+
self, _command: hci.HCI_Write_Extended_Inquiry_Response_Command
|
|
1236
|
+
) -> Optional[bytes]:
|
|
1165
1237
|
'''
|
|
1166
1238
|
See Bluetooth spec Vol 4, Part E - 7.3.56 Write Extended Inquiry Response
|
|
1167
1239
|
Command
|
|
1168
1240
|
'''
|
|
1169
1241
|
return bytes([HCI_SUCCESS])
|
|
1170
1242
|
|
|
1171
|
-
def on_hci_write_simple_pairing_mode_command(
|
|
1243
|
+
def on_hci_write_simple_pairing_mode_command(
|
|
1244
|
+
self, _command: hci.HCI_Write_Simple_Pairing_Mode_Command
|
|
1245
|
+
) -> Optional[bytes]:
|
|
1172
1246
|
'''
|
|
1173
1247
|
See Bluetooth spec Vol 4, Part E - 7.3.59 Write Simple Pairing Mode Command
|
|
1174
1248
|
'''
|
|
1175
1249
|
return bytes([HCI_SUCCESS])
|
|
1176
1250
|
|
|
1177
|
-
def on_hci_set_event_mask_page_2_command(
|
|
1251
|
+
def on_hci_set_event_mask_page_2_command(
|
|
1252
|
+
self, command: hci.HCI_Set_Event_Mask_Page_2_Command
|
|
1253
|
+
) -> Optional[bytes]:
|
|
1178
1254
|
'''
|
|
1179
1255
|
See Bluetooth spec Vol 4, Part E - 7.3.69 Set Event Mask Page 2 Command
|
|
1180
1256
|
'''
|
|
1181
|
-
self.event_mask_page_2 =
|
|
1257
|
+
self.event_mask_page_2 = int.from_bytes(
|
|
1258
|
+
command.event_mask_page_2, byteorder='little', signed=False
|
|
1259
|
+
)
|
|
1182
1260
|
return bytes([HCI_SUCCESS])
|
|
1183
1261
|
|
|
1184
|
-
def on_hci_read_le_host_support_command(
|
|
1262
|
+
def on_hci_read_le_host_support_command(
|
|
1263
|
+
self, _command: hci.HCI_Read_LE_Host_Support_Command
|
|
1264
|
+
) -> Optional[bytes]:
|
|
1185
1265
|
'''
|
|
1186
1266
|
See Bluetooth spec Vol 4, Part E - 7.3.78 Write LE Host Support Command
|
|
1187
1267
|
'''
|
|
1188
1268
|
return bytes([HCI_SUCCESS, 1, 0])
|
|
1189
1269
|
|
|
1190
|
-
def on_hci_write_le_host_support_command(
|
|
1270
|
+
def on_hci_write_le_host_support_command(
|
|
1271
|
+
self, _command: hci.HCI_Write_LE_Host_Support_Command
|
|
1272
|
+
) -> Optional[bytes]:
|
|
1191
1273
|
'''
|
|
1192
1274
|
See Bluetooth spec Vol 4, Part E - 7.3.79 Write LE Host Support Command
|
|
1193
1275
|
'''
|
|
1194
1276
|
# TODO / Just ignore for now
|
|
1195
1277
|
return bytes([HCI_SUCCESS])
|
|
1196
1278
|
|
|
1197
|
-
def on_hci_write_authenticated_payload_timeout_command(
|
|
1279
|
+
def on_hci_write_authenticated_payload_timeout_command(
|
|
1280
|
+
self, command: hci.HCI_Write_Authenticated_Payload_Timeout_Command
|
|
1281
|
+
) -> Optional[bytes]:
|
|
1198
1282
|
'''
|
|
1199
1283
|
See Bluetooth spec Vol 4, Part E - 7.3.94 Write Authenticated Payload Timeout
|
|
1200
1284
|
Command
|
|
@@ -1202,7 +1286,9 @@ class Controller:
|
|
|
1202
1286
|
# TODO
|
|
1203
1287
|
return struct.pack('<BH', HCI_SUCCESS, command.connection_handle)
|
|
1204
1288
|
|
|
1205
|
-
def on_hci_read_local_version_information_command(
|
|
1289
|
+
def on_hci_read_local_version_information_command(
|
|
1290
|
+
self, _command: hci.HCI_Read_Local_Version_Information_Command
|
|
1291
|
+
) -> Optional[bytes]:
|
|
1206
1292
|
'''
|
|
1207
1293
|
See Bluetooth spec Vol 4, Part E - 7.4.1 Read Local Version Information Command
|
|
1208
1294
|
'''
|
|
@@ -1216,19 +1302,25 @@ class Controller:
|
|
|
1216
1302
|
self.lmp_subversion,
|
|
1217
1303
|
)
|
|
1218
1304
|
|
|
1219
|
-
def on_hci_read_local_supported_commands_command(
|
|
1305
|
+
def on_hci_read_local_supported_commands_command(
|
|
1306
|
+
self, _command: hci.HCI_Read_Local_Supported_Commands_Command
|
|
1307
|
+
) -> Optional[bytes]:
|
|
1220
1308
|
'''
|
|
1221
1309
|
See Bluetooth spec Vol 4, Part E - 7.4.2 Read Local Supported Commands Command
|
|
1222
1310
|
'''
|
|
1223
1311
|
return bytes([HCI_SUCCESS]) + self.supported_commands
|
|
1224
1312
|
|
|
1225
|
-
def on_hci_read_local_supported_features_command(
|
|
1313
|
+
def on_hci_read_local_supported_features_command(
|
|
1314
|
+
self, _command: hci.HCI_Read_Local_Supported_Features_Command
|
|
1315
|
+
) -> Optional[bytes]:
|
|
1226
1316
|
'''
|
|
1227
1317
|
See Bluetooth spec Vol 4, Part E - 7.4.3 Read Local Supported Features Command
|
|
1228
1318
|
'''
|
|
1229
1319
|
return bytes([HCI_SUCCESS]) + self.lmp_features[:8]
|
|
1230
1320
|
|
|
1231
|
-
def on_hci_read_local_extended_features_command(
|
|
1321
|
+
def on_hci_read_local_extended_features_command(
|
|
1322
|
+
self, command: hci.HCI_Read_Local_Extended_Features_Command
|
|
1323
|
+
) -> Optional[bytes]:
|
|
1232
1324
|
'''
|
|
1233
1325
|
See Bluetooth spec Vol 4, Part E - 7.4.4 Read Local Extended Features Command
|
|
1234
1326
|
'''
|
|
@@ -1249,7 +1341,9 @@ class Controller:
|
|
|
1249
1341
|
+ self.lmp_features[command.page_number * 8 : (command.page_number + 1) * 8]
|
|
1250
1342
|
)
|
|
1251
1343
|
|
|
1252
|
-
def on_hci_read_buffer_size_command(
|
|
1344
|
+
def on_hci_read_buffer_size_command(
|
|
1345
|
+
self, _command: hci.HCI_Read_Buffer_Size_Command
|
|
1346
|
+
) -> Optional[bytes]:
|
|
1253
1347
|
'''
|
|
1254
1348
|
See Bluetooth spec Vol 4, Part E - 7.4.5 Read Buffer Size Command
|
|
1255
1349
|
'''
|
|
@@ -1262,7 +1356,9 @@ class Controller:
|
|
|
1262
1356
|
0,
|
|
1263
1357
|
)
|
|
1264
1358
|
|
|
1265
|
-
def on_hci_read_bd_addr_command(
|
|
1359
|
+
def on_hci_read_bd_addr_command(
|
|
1360
|
+
self, _command: hci.HCI_Read_BD_ADDR_Command
|
|
1361
|
+
) -> Optional[bytes]:
|
|
1266
1362
|
'''
|
|
1267
1363
|
See Bluetooth spec Vol 4, Part E - 7.4.6 Read BD_ADDR Command
|
|
1268
1364
|
'''
|
|
@@ -1275,7 +1371,7 @@ class Controller:
|
|
|
1275
1371
|
|
|
1276
1372
|
def on_hci_le_set_default_subrate_command(
|
|
1277
1373
|
self, command: hci.HCI_LE_Set_Default_Subrate_Command
|
|
1278
|
-
):
|
|
1374
|
+
) -> Optional[bytes]:
|
|
1279
1375
|
'''
|
|
1280
1376
|
See Bluetooth spec Vol 6, Part E - 7.8.123 LE Set Event Mask Command
|
|
1281
1377
|
'''
|
|
@@ -1291,7 +1387,7 @@ class Controller:
|
|
|
1291
1387
|
|
|
1292
1388
|
def on_hci_le_subrate_request_command(
|
|
1293
1389
|
self, command: hci.HCI_LE_Subrate_Request_Command
|
|
1294
|
-
):
|
|
1390
|
+
) -> Optional[bytes]:
|
|
1295
1391
|
'''
|
|
1296
1392
|
See Bluetooth spec Vol 6, Part E - 7.8.124 LE Subrate Request command
|
|
1297
1393
|
'''
|
|
@@ -1323,14 +1419,20 @@ class Controller:
|
|
|
1323
1419
|
)
|
|
1324
1420
|
return None
|
|
1325
1421
|
|
|
1326
|
-
def on_hci_le_set_event_mask_command(
|
|
1422
|
+
def on_hci_le_set_event_mask_command(
|
|
1423
|
+
self, command: hci.HCI_LE_Set_Event_Mask_Command
|
|
1424
|
+
) -> Optional[bytes]:
|
|
1327
1425
|
'''
|
|
1328
1426
|
See Bluetooth spec Vol 4, Part E - 7.8.1 LE Set Event Mask Command
|
|
1329
1427
|
'''
|
|
1330
|
-
self.le_event_mask =
|
|
1428
|
+
self.le_event_mask = int.from_bytes(
|
|
1429
|
+
command.le_event_mask, byteorder='little', signed=False
|
|
1430
|
+
)
|
|
1331
1431
|
return bytes([HCI_SUCCESS])
|
|
1332
1432
|
|
|
1333
|
-
def on_hci_le_read_buffer_size_command(
|
|
1433
|
+
def on_hci_le_read_buffer_size_command(
|
|
1434
|
+
self, _command: hci.HCI_LE_Read_Buffer_Size_Command
|
|
1435
|
+
) -> Optional[bytes]:
|
|
1334
1436
|
'''
|
|
1335
1437
|
See Bluetooth spec Vol 4, Part E - 7.8.2 LE Read Buffer Size Command
|
|
1336
1438
|
'''
|
|
@@ -1341,7 +1443,9 @@ class Controller:
|
|
|
1341
1443
|
self.total_num_le_acl_data_packets,
|
|
1342
1444
|
)
|
|
1343
1445
|
|
|
1344
|
-
def on_hci_le_read_buffer_size_v2_command(
|
|
1446
|
+
def on_hci_le_read_buffer_size_v2_command(
|
|
1447
|
+
self, _command: hci.HCI_LE_Read_Buffer_Size_V2_Command
|
|
1448
|
+
) -> Optional[bytes]:
|
|
1345
1449
|
'''
|
|
1346
1450
|
See Bluetooth spec Vol 4, Part E - 7.8.2 LE Read Buffer Size Command
|
|
1347
1451
|
'''
|
|
@@ -1354,49 +1458,63 @@ class Controller:
|
|
|
1354
1458
|
self.total_num_iso_data_packets,
|
|
1355
1459
|
)
|
|
1356
1460
|
|
|
1357
|
-
def on_hci_le_read_local_supported_features_command(
|
|
1461
|
+
def on_hci_le_read_local_supported_features_command(
|
|
1462
|
+
self, _command: hci.HCI_LE_Read_Local_Supported_Features_Command
|
|
1463
|
+
) -> Optional[bytes]:
|
|
1358
1464
|
'''
|
|
1359
1465
|
See Bluetooth spec Vol 4, Part E - 7.8.3 LE Read Local Supported Features
|
|
1360
1466
|
Command
|
|
1361
1467
|
'''
|
|
1362
1468
|
return bytes([HCI_SUCCESS]) + self.le_features
|
|
1363
1469
|
|
|
1364
|
-
def on_hci_le_set_random_address_command(
|
|
1470
|
+
def on_hci_le_set_random_address_command(
|
|
1471
|
+
self, command: hci.HCI_LE_Set_Random_Address_Command
|
|
1472
|
+
) -> Optional[bytes]:
|
|
1365
1473
|
'''
|
|
1366
1474
|
See Bluetooth spec Vol 4, Part E - 7.8.4 LE Set Random Address Command
|
|
1367
1475
|
'''
|
|
1368
1476
|
self.random_address = command.random_address
|
|
1369
1477
|
return bytes([HCI_SUCCESS])
|
|
1370
1478
|
|
|
1371
|
-
def on_hci_le_set_advertising_parameters_command(
|
|
1479
|
+
def on_hci_le_set_advertising_parameters_command(
|
|
1480
|
+
self, command: hci.HCI_LE_Set_Advertising_Parameters_Command
|
|
1481
|
+
) -> Optional[bytes]:
|
|
1372
1482
|
'''
|
|
1373
1483
|
See Bluetooth spec Vol 4, Part E - 7.8.5 LE Set Advertising Parameters Command
|
|
1374
1484
|
'''
|
|
1375
1485
|
self.advertising_parameters = command
|
|
1376
1486
|
return bytes([HCI_SUCCESS])
|
|
1377
1487
|
|
|
1378
|
-
def on_hci_le_read_advertising_physical_channel_tx_power_command(
|
|
1488
|
+
def on_hci_le_read_advertising_physical_channel_tx_power_command(
|
|
1489
|
+
self, _command: hci.HCI_LE_Read_Advertising_Physical_Channel_Tx_Power_Command
|
|
1490
|
+
) -> Optional[bytes]:
|
|
1379
1491
|
'''
|
|
1380
1492
|
See Bluetooth spec Vol 4, Part E - 7.8.6 LE Read Advertising Physical Channel
|
|
1381
1493
|
Tx Power Command
|
|
1382
1494
|
'''
|
|
1383
1495
|
return bytes([HCI_SUCCESS, self.advertising_channel_tx_power])
|
|
1384
1496
|
|
|
1385
|
-
def on_hci_le_set_advertising_data_command(
|
|
1497
|
+
def on_hci_le_set_advertising_data_command(
|
|
1498
|
+
self, command: hci.HCI_LE_Set_Advertising_Data_Command
|
|
1499
|
+
) -> Optional[bytes]:
|
|
1386
1500
|
'''
|
|
1387
1501
|
See Bluetooth spec Vol 4, Part E - 7.8.7 LE Set Advertising Data Command
|
|
1388
1502
|
'''
|
|
1389
1503
|
self.advertising_data = command.advertising_data
|
|
1390
1504
|
return bytes([HCI_SUCCESS])
|
|
1391
1505
|
|
|
1392
|
-
def on_hci_le_set_scan_response_data_command(
|
|
1506
|
+
def on_hci_le_set_scan_response_data_command(
|
|
1507
|
+
self, command: hci.HCI_LE_Set_Scan_Response_Data_Command
|
|
1508
|
+
) -> Optional[bytes]:
|
|
1393
1509
|
'''
|
|
1394
1510
|
See Bluetooth spec Vol 4, Part E - 7.8.8 LE Set Scan Response Data Command
|
|
1395
1511
|
'''
|
|
1396
1512
|
self.le_scan_response_data = command.scan_response_data
|
|
1397
1513
|
return bytes([HCI_SUCCESS])
|
|
1398
1514
|
|
|
1399
|
-
def on_hci_le_set_advertising_enable_command(
|
|
1515
|
+
def on_hci_le_set_advertising_enable_command(
|
|
1516
|
+
self, command: hci.HCI_LE_Set_Advertising_Enable_Command
|
|
1517
|
+
) -> Optional[bytes]:
|
|
1400
1518
|
'''
|
|
1401
1519
|
See Bluetooth spec Vol 4, Part E - 7.8.9 LE Set Advertising Enable Command
|
|
1402
1520
|
'''
|
|
@@ -1407,7 +1525,9 @@ class Controller:
|
|
|
1407
1525
|
|
|
1408
1526
|
return bytes([HCI_SUCCESS])
|
|
1409
1527
|
|
|
1410
|
-
def on_hci_le_set_scan_parameters_command(
|
|
1528
|
+
def on_hci_le_set_scan_parameters_command(
|
|
1529
|
+
self, command: hci.HCI_LE_Set_Scan_Parameters_Command
|
|
1530
|
+
) -> Optional[bytes]:
|
|
1411
1531
|
'''
|
|
1412
1532
|
See Bluetooth spec Vol 4, Part E - 7.8.10 LE Set Scan Parameters Command
|
|
1413
1533
|
'''
|
|
@@ -1417,25 +1537,29 @@ class Controller:
|
|
|
1417
1537
|
self.le_scan_type = command.le_scan_type
|
|
1418
1538
|
self.le_scan_interval = command.le_scan_interval
|
|
1419
1539
|
self.le_scan_window = command.le_scan_window
|
|
1420
|
-
self.le_scan_own_address_type = command.own_address_type
|
|
1540
|
+
self.le_scan_own_address_type = hci.AddressType(command.own_address_type)
|
|
1421
1541
|
self.le_scanning_filter_policy = command.scanning_filter_policy
|
|
1422
1542
|
return bytes([HCI_SUCCESS])
|
|
1423
1543
|
|
|
1424
|
-
def on_hci_le_set_scan_enable_command(
|
|
1544
|
+
def on_hci_le_set_scan_enable_command(
|
|
1545
|
+
self, command: hci.HCI_LE_Set_Scan_Enable_Command
|
|
1546
|
+
) -> Optional[bytes]:
|
|
1425
1547
|
'''
|
|
1426
1548
|
See Bluetooth spec Vol 4, Part E - 7.8.11 LE Set Scan Enable Command
|
|
1427
1549
|
'''
|
|
1428
|
-
self.le_scan_enable = command.le_scan_enable
|
|
1429
|
-
self.filter_duplicates = command.filter_duplicates
|
|
1550
|
+
self.le_scan_enable = bool(command.le_scan_enable)
|
|
1551
|
+
self.filter_duplicates = bool(command.filter_duplicates)
|
|
1430
1552
|
return bytes([HCI_SUCCESS])
|
|
1431
1553
|
|
|
1432
|
-
def on_hci_le_create_connection_command(
|
|
1554
|
+
def on_hci_le_create_connection_command(
|
|
1555
|
+
self, command: hci.HCI_LE_Create_Connection_Command
|
|
1556
|
+
) -> Optional[bytes]:
|
|
1433
1557
|
'''
|
|
1434
1558
|
See Bluetooth spec Vol 4, Part E - 7.8.12 LE Create Connection Command
|
|
1435
1559
|
'''
|
|
1436
1560
|
|
|
1437
1561
|
if not self.link:
|
|
1438
|
-
return
|
|
1562
|
+
return None
|
|
1439
1563
|
|
|
1440
1564
|
logger.debug(f'Connection request to {command.peer_address}')
|
|
1441
1565
|
|
|
@@ -1448,7 +1572,7 @@ class Controller:
|
|
|
1448
1572
|
command_opcode=command.op_code,
|
|
1449
1573
|
)
|
|
1450
1574
|
)
|
|
1451
|
-
return
|
|
1575
|
+
return None
|
|
1452
1576
|
|
|
1453
1577
|
# Initiate the connection
|
|
1454
1578
|
self.link.connect(self.random_address, command)
|
|
@@ -1461,41 +1585,54 @@ class Controller:
|
|
|
1461
1585
|
command_opcode=command.op_code,
|
|
1462
1586
|
)
|
|
1463
1587
|
)
|
|
1588
|
+
return None
|
|
1464
1589
|
|
|
1465
|
-
def on_hci_le_create_connection_cancel_command(
|
|
1590
|
+
def on_hci_le_create_connection_cancel_command(
|
|
1591
|
+
self, _command: hci.HCI_LE_Create_Connection_Cancel_Command
|
|
1592
|
+
) -> Optional[bytes]:
|
|
1466
1593
|
'''
|
|
1467
1594
|
See Bluetooth spec Vol 4, Part E - 7.8.13 LE Create Connection Cancel Command
|
|
1468
1595
|
'''
|
|
1469
1596
|
return bytes([HCI_SUCCESS])
|
|
1470
1597
|
|
|
1471
|
-
def on_hci_le_read_filter_accept_list_size_command(
|
|
1598
|
+
def on_hci_le_read_filter_accept_list_size_command(
|
|
1599
|
+
self, _command: hci.HCI_LE_Read_Filter_Accept_List_Size_Command
|
|
1600
|
+
) -> Optional[bytes]:
|
|
1472
1601
|
'''
|
|
1473
1602
|
See Bluetooth spec Vol 4, Part E - 7.8.14 LE Read Filter Accept List Size
|
|
1474
1603
|
Command
|
|
1475
1604
|
'''
|
|
1476
1605
|
return bytes([HCI_SUCCESS, self.filter_accept_list_size])
|
|
1477
1606
|
|
|
1478
|
-
def on_hci_le_clear_filter_accept_list_command(
|
|
1607
|
+
def on_hci_le_clear_filter_accept_list_command(
|
|
1608
|
+
self, _command: hci.HCI_LE_Clear_Filter_Accept_List_Command
|
|
1609
|
+
) -> Optional[bytes]:
|
|
1479
1610
|
'''
|
|
1480
1611
|
See Bluetooth spec Vol 4, Part E - 7.8.15 LE Clear Filter Accept List Command
|
|
1481
1612
|
'''
|
|
1482
1613
|
return bytes([HCI_SUCCESS])
|
|
1483
1614
|
|
|
1484
|
-
def on_hci_le_add_device_to_filter_accept_list_command(
|
|
1615
|
+
def on_hci_le_add_device_to_filter_accept_list_command(
|
|
1616
|
+
self, _command: hci.HCI_LE_Add_Device_To_Filter_Accept_List_Command
|
|
1617
|
+
) -> Optional[bytes]:
|
|
1485
1618
|
'''
|
|
1486
1619
|
See Bluetooth spec Vol 4, Part E - 7.8.16 LE Add Device To Filter Accept List
|
|
1487
1620
|
Command
|
|
1488
1621
|
'''
|
|
1489
1622
|
return bytes([HCI_SUCCESS])
|
|
1490
1623
|
|
|
1491
|
-
def on_hci_le_remove_device_from_filter_accept_list_command(
|
|
1624
|
+
def on_hci_le_remove_device_from_filter_accept_list_command(
|
|
1625
|
+
self, _command: hci.HCI_LE_Remove_Device_From_Filter_Accept_List_Command
|
|
1626
|
+
) -> Optional[bytes]:
|
|
1492
1627
|
'''
|
|
1493
1628
|
See Bluetooth spec Vol 4, Part E - 7.8.17 LE Remove Device From Filter Accept
|
|
1494
1629
|
List Command
|
|
1495
1630
|
'''
|
|
1496
1631
|
return bytes([HCI_SUCCESS])
|
|
1497
1632
|
|
|
1498
|
-
def on_hci_le_read_remote_features_command(
|
|
1633
|
+
def on_hci_le_read_remote_features_command(
|
|
1634
|
+
self, command: hci.HCI_LE_Read_Remote_Features_Command
|
|
1635
|
+
) -> Optional[bytes]:
|
|
1499
1636
|
'''
|
|
1500
1637
|
See Bluetooth spec Vol 4, Part E - 7.8.21 LE Read Remote Features Command
|
|
1501
1638
|
'''
|
|
@@ -1510,7 +1647,7 @@ class Controller:
|
|
|
1510
1647
|
command_opcode=command.op_code,
|
|
1511
1648
|
)
|
|
1512
1649
|
)
|
|
1513
|
-
return
|
|
1650
|
+
return None
|
|
1514
1651
|
|
|
1515
1652
|
# First, say that the command is pending
|
|
1516
1653
|
self.send_hci_packet(
|
|
@@ -1529,17 +1666,24 @@ class Controller:
|
|
|
1529
1666
|
le_features=bytes.fromhex('dd40000000000000'),
|
|
1530
1667
|
)
|
|
1531
1668
|
)
|
|
1669
|
+
return None
|
|
1532
1670
|
|
|
1533
|
-
def on_hci_le_rand_command(
|
|
1671
|
+
def on_hci_le_rand_command(
|
|
1672
|
+
self, _command: hci.HCI_LE_Rand_Command
|
|
1673
|
+
) -> Optional[bytes]:
|
|
1534
1674
|
'''
|
|
1535
1675
|
See Bluetooth spec Vol 4, Part E - 7.8.23 LE Rand Command
|
|
1536
1676
|
'''
|
|
1537
1677
|
return bytes([HCI_SUCCESS]) + struct.pack('Q', random.randint(0, 1 << 64))
|
|
1538
1678
|
|
|
1539
|
-
def on_hci_le_enable_encryption_command(
|
|
1679
|
+
def on_hci_le_enable_encryption_command(
|
|
1680
|
+
self, command: hci.HCI_LE_Enable_Encryption_Command
|
|
1681
|
+
) -> Optional[bytes]:
|
|
1540
1682
|
'''
|
|
1541
1683
|
See Bluetooth spec Vol 4, Part E - 7.8.24 LE Enable Encryption Command
|
|
1542
1684
|
'''
|
|
1685
|
+
if not self.link:
|
|
1686
|
+
return None
|
|
1543
1687
|
|
|
1544
1688
|
# Check the parameters
|
|
1545
1689
|
if not (
|
|
@@ -1569,13 +1713,17 @@ class Controller:
|
|
|
1569
1713
|
|
|
1570
1714
|
return None
|
|
1571
1715
|
|
|
1572
|
-
def on_hci_le_read_supported_states_command(
|
|
1716
|
+
def on_hci_le_read_supported_states_command(
|
|
1717
|
+
self, _command: hci.HCI_LE_Read_Supported_States_Command
|
|
1718
|
+
) -> Optional[bytes]:
|
|
1573
1719
|
'''
|
|
1574
1720
|
See Bluetooth spec Vol 4, Part E - 7.8.27 LE Read Supported States Command
|
|
1575
1721
|
'''
|
|
1576
1722
|
return bytes([HCI_SUCCESS]) + self.le_states
|
|
1577
1723
|
|
|
1578
|
-
def on_hci_le_read_suggested_default_data_length_command(
|
|
1724
|
+
def on_hci_le_read_suggested_default_data_length_command(
|
|
1725
|
+
self, _command: hci.HCI_LE_Read_Suggested_Default_Data_Length_Command
|
|
1726
|
+
) -> Optional[bytes]:
|
|
1579
1727
|
'''
|
|
1580
1728
|
See Bluetooth spec Vol 4, Part E - 7.8.34 LE Read Suggested Default Data Length
|
|
1581
1729
|
Command
|
|
@@ -1587,7 +1735,9 @@ class Controller:
|
|
|
1587
1735
|
self.suggested_max_tx_time,
|
|
1588
1736
|
)
|
|
1589
1737
|
|
|
1590
|
-
def on_hci_le_write_suggested_default_data_length_command(
|
|
1738
|
+
def on_hci_le_write_suggested_default_data_length_command(
|
|
1739
|
+
self, command: hci.HCI_LE_Write_Suggested_Default_Data_Length_Command
|
|
1740
|
+
) -> Optional[bytes]:
|
|
1591
1741
|
'''
|
|
1592
1742
|
See Bluetooth spec Vol 4, Part E - 7.8.35 LE Write Suggested Default Data Length
|
|
1593
1743
|
Command
|
|
@@ -1597,33 +1747,43 @@ class Controller:
|
|
|
1597
1747
|
)
|
|
1598
1748
|
return bytes([HCI_SUCCESS])
|
|
1599
1749
|
|
|
1600
|
-
def on_hci_le_read_local_p_256_public_key_command(
|
|
1750
|
+
def on_hci_le_read_local_p_256_public_key_command(
|
|
1751
|
+
self, _command: hci.HCI_LE_Read_Local_P_256_Public_Key_Command
|
|
1752
|
+
) -> Optional[bytes]:
|
|
1601
1753
|
'''
|
|
1602
1754
|
See Bluetooth spec Vol 4, Part E - 7.8.36 LE Read P-256 Public Key Command
|
|
1603
1755
|
'''
|
|
1604
1756
|
# TODO create key and send HCI_LE_Read_Local_P-256_Public_Key_Complete event
|
|
1605
1757
|
return bytes([HCI_SUCCESS])
|
|
1606
1758
|
|
|
1607
|
-
def on_hci_le_add_device_to_resolving_list_command(
|
|
1759
|
+
def on_hci_le_add_device_to_resolving_list_command(
|
|
1760
|
+
self, _command: hci.HCI_LE_Add_Device_To_Resolving_List_Command
|
|
1761
|
+
) -> Optional[bytes]:
|
|
1608
1762
|
'''
|
|
1609
1763
|
See Bluetooth spec Vol 4, Part E - 7.8.38 LE Add Device To Resolving List
|
|
1610
1764
|
Command
|
|
1611
1765
|
'''
|
|
1612
1766
|
return bytes([HCI_SUCCESS])
|
|
1613
1767
|
|
|
1614
|
-
def on_hci_le_clear_resolving_list_command(
|
|
1768
|
+
def on_hci_le_clear_resolving_list_command(
|
|
1769
|
+
self, _command: hci.HCI_LE_Clear_Resolving_List_Command
|
|
1770
|
+
) -> Optional[bytes]:
|
|
1615
1771
|
'''
|
|
1616
1772
|
See Bluetooth spec Vol 4, Part E - 7.8.40 LE Clear Resolving List Command
|
|
1617
1773
|
'''
|
|
1618
1774
|
return bytes([HCI_SUCCESS])
|
|
1619
1775
|
|
|
1620
|
-
def on_hci_le_read_resolving_list_size_command(
|
|
1776
|
+
def on_hci_le_read_resolving_list_size_command(
|
|
1777
|
+
self, _command: hci.HCI_LE_Read_Resolving_List_Size_Command
|
|
1778
|
+
) -> Optional[bytes]:
|
|
1621
1779
|
'''
|
|
1622
1780
|
See Bluetooth spec Vol 4, Part E - 7.8.41 LE Read Resolving List Size Command
|
|
1623
1781
|
'''
|
|
1624
1782
|
return bytes([HCI_SUCCESS, self.resolving_list_size])
|
|
1625
1783
|
|
|
1626
|
-
def on_hci_le_set_address_resolution_enable_command(
|
|
1784
|
+
def on_hci_le_set_address_resolution_enable_command(
|
|
1785
|
+
self, command: hci.HCI_LE_Set_Address_Resolution_Enable_Command
|
|
1786
|
+
) -> Optional[bytes]:
|
|
1627
1787
|
'''
|
|
1628
1788
|
See Bluetooth spec Vol 4, Part E - 7.8.44 LE Set Address Resolution Enable
|
|
1629
1789
|
Command
|
|
@@ -1637,7 +1797,9 @@ class Controller:
|
|
|
1637
1797
|
ret = HCI_INVALID_HCI_COMMAND_PARAMETERS_ERROR
|
|
1638
1798
|
return bytes([ret])
|
|
1639
1799
|
|
|
1640
|
-
def on_hci_le_set_resolvable_private_address_timeout_command(
|
|
1800
|
+
def on_hci_le_set_resolvable_private_address_timeout_command(
|
|
1801
|
+
self, command: hci.HCI_LE_Set_Resolvable_Private_Address_Timeout_Command
|
|
1802
|
+
) -> Optional[bytes]:
|
|
1641
1803
|
'''
|
|
1642
1804
|
See Bluetooth spec Vol 4, Part E - 7.8.45 LE Set Resolvable Private Address
|
|
1643
1805
|
Timeout Command
|
|
@@ -1645,7 +1807,9 @@ class Controller:
|
|
|
1645
1807
|
self.le_rpa_timeout = command.rpa_timeout
|
|
1646
1808
|
return bytes([HCI_SUCCESS])
|
|
1647
1809
|
|
|
1648
|
-
def on_hci_le_read_maximum_data_length_command(
|
|
1810
|
+
def on_hci_le_read_maximum_data_length_command(
|
|
1811
|
+
self, _command: hci.HCI_LE_Read_Maximum_Data_Length_Command
|
|
1812
|
+
) -> Optional[bytes]:
|
|
1649
1813
|
'''
|
|
1650
1814
|
See Bluetooth spec Vol 4, Part E - 7.8.46 LE Read Maximum Data Length Command
|
|
1651
1815
|
'''
|
|
@@ -1658,7 +1822,9 @@ class Controller:
|
|
|
1658
1822
|
self.supported_max_rx_time,
|
|
1659
1823
|
)
|
|
1660
1824
|
|
|
1661
|
-
def on_hci_le_read_phy_command(
|
|
1825
|
+
def on_hci_le_read_phy_command(
|
|
1826
|
+
self, command: hci.HCI_LE_Read_PHY_Command
|
|
1827
|
+
) -> Optional[bytes]:
|
|
1662
1828
|
'''
|
|
1663
1829
|
See Bluetooth spec Vol 4, Part E - 7.8.47 LE Read PHY Command
|
|
1664
1830
|
'''
|
|
@@ -1670,100 +1836,125 @@ class Controller:
|
|
|
1670
1836
|
HCI_LE_1M_PHY,
|
|
1671
1837
|
)
|
|
1672
1838
|
|
|
1673
|
-
def on_hci_le_set_default_phy_command(
|
|
1839
|
+
def on_hci_le_set_default_phy_command(
|
|
1840
|
+
self, command: hci.HCI_LE_Set_Default_PHY_Command
|
|
1841
|
+
) -> Optional[bytes]:
|
|
1674
1842
|
'''
|
|
1675
1843
|
See Bluetooth spec Vol 4, Part E - 7.8.48 LE Set Default PHY Command
|
|
1676
1844
|
'''
|
|
1677
|
-
self.default_phy =
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
'rx_phys': command.rx_phys,
|
|
1681
|
-
}
|
|
1845
|
+
self.default_phy['all_phys'] = command.all_phys
|
|
1846
|
+
self.default_phy['tx_phys'] = command.tx_phys
|
|
1847
|
+
self.default_phy['rx_phys'] = command.rx_phys
|
|
1682
1848
|
return bytes([HCI_SUCCESS])
|
|
1683
1849
|
|
|
1684
|
-
def on_hci_le_set_advertising_set_random_address_command(
|
|
1850
|
+
def on_hci_le_set_advertising_set_random_address_command(
|
|
1851
|
+
self, _command: hci.HCI_LE_Set_Advertising_Set_Random_Address_Command
|
|
1852
|
+
) -> Optional[bytes]:
|
|
1685
1853
|
'''
|
|
1686
1854
|
See Bluetooth spec Vol 4, Part E - 7.8.52 LE Set Advertising Set Random Address
|
|
1687
1855
|
Command
|
|
1688
1856
|
'''
|
|
1689
1857
|
return bytes([HCI_SUCCESS])
|
|
1690
1858
|
|
|
1691
|
-
def on_hci_le_set_extended_advertising_parameters_command(
|
|
1859
|
+
def on_hci_le_set_extended_advertising_parameters_command(
|
|
1860
|
+
self, _command: hci.HCI_LE_Set_Extended_Advertising_Parameters_Command
|
|
1861
|
+
) -> Optional[bytes]:
|
|
1692
1862
|
'''
|
|
1693
1863
|
See Bluetooth spec Vol 4, Part E - 7.8.53 LE Set Extended Advertising Parameters
|
|
1694
1864
|
Command
|
|
1695
1865
|
'''
|
|
1696
1866
|
return bytes([HCI_SUCCESS, 0])
|
|
1697
1867
|
|
|
1698
|
-
def on_hci_le_set_extended_advertising_data_command(
|
|
1868
|
+
def on_hci_le_set_extended_advertising_data_command(
|
|
1869
|
+
self, _command: hci.HCI_LE_Set_Extended_Advertising_Data_Command
|
|
1870
|
+
) -> Optional[bytes]:
|
|
1699
1871
|
'''
|
|
1700
1872
|
See Bluetooth spec Vol 4, Part E - 7.8.54 LE Set Extended Advertising Data
|
|
1701
1873
|
Command
|
|
1702
1874
|
'''
|
|
1703
1875
|
return bytes([HCI_SUCCESS])
|
|
1704
1876
|
|
|
1705
|
-
def on_hci_le_set_extended_scan_response_data_command(
|
|
1877
|
+
def on_hci_le_set_extended_scan_response_data_command(
|
|
1878
|
+
self, _command: hci.HCI_LE_Set_Extended_Scan_Response_Data_Command
|
|
1879
|
+
) -> Optional[bytes]:
|
|
1706
1880
|
'''
|
|
1707
1881
|
See Bluetooth spec Vol 4, Part E - 7.8.55 LE Set Extended Scan Response Data
|
|
1708
1882
|
Command
|
|
1709
1883
|
'''
|
|
1710
1884
|
return bytes([HCI_SUCCESS])
|
|
1711
1885
|
|
|
1712
|
-
def on_hci_le_set_extended_advertising_enable_command(
|
|
1886
|
+
def on_hci_le_set_extended_advertising_enable_command(
|
|
1887
|
+
self, _command: hci.HCI_LE_Set_Extended_Advertising_Enable_Command
|
|
1888
|
+
) -> Optional[bytes]:
|
|
1713
1889
|
'''
|
|
1714
1890
|
See Bluetooth spec Vol 4, Part E - 7.8.56 LE Set Extended Advertising Enable
|
|
1715
1891
|
Command
|
|
1716
1892
|
'''
|
|
1717
1893
|
return bytes([HCI_SUCCESS])
|
|
1718
1894
|
|
|
1719
|
-
def on_hci_le_read_maximum_advertising_data_length_command(
|
|
1895
|
+
def on_hci_le_read_maximum_advertising_data_length_command(
|
|
1896
|
+
self, _command: hci.HCI_LE_Read_Maximum_Advertising_Data_Length_Command
|
|
1897
|
+
) -> Optional[bytes]:
|
|
1720
1898
|
'''
|
|
1721
1899
|
See Bluetooth spec Vol 4, Part E - 7.8.57 LE Read Maximum Advertising Data
|
|
1722
1900
|
Length Command
|
|
1723
1901
|
'''
|
|
1724
1902
|
return struct.pack('<BH', HCI_SUCCESS, 0x0672)
|
|
1725
1903
|
|
|
1726
|
-
def on_hci_le_read_number_of_supported_advertising_sets_command(
|
|
1904
|
+
def on_hci_le_read_number_of_supported_advertising_sets_command(
|
|
1905
|
+
self, _command: hci.HCI_LE_Read_Number_Of_Supported_Advertising_Sets_Command
|
|
1906
|
+
) -> Optional[bytes]:
|
|
1727
1907
|
'''
|
|
1728
1908
|
See Bluetooth spec Vol 4, Part E - 7.8.58 LE Read Number of Supported
|
|
1729
1909
|
Advertising Set Command
|
|
1730
1910
|
'''
|
|
1731
1911
|
return struct.pack('<BB', HCI_SUCCESS, 0xF0)
|
|
1732
1912
|
|
|
1733
|
-
def on_hci_le_set_periodic_advertising_parameters_command(
|
|
1913
|
+
def on_hci_le_set_periodic_advertising_parameters_command(
|
|
1914
|
+
self, _command: hci.HCI_LE_Set_Periodic_Advertising_Parameters_Command
|
|
1915
|
+
) -> Optional[bytes]:
|
|
1734
1916
|
'''
|
|
1735
1917
|
See Bluetooth spec Vol 4, Part E - 7.8.61 LE Set Periodic Advertising Parameters
|
|
1736
1918
|
Command
|
|
1737
1919
|
'''
|
|
1738
1920
|
return bytes([HCI_SUCCESS])
|
|
1739
1921
|
|
|
1740
|
-
def on_hci_le_set_periodic_advertising_data_command(
|
|
1922
|
+
def on_hci_le_set_periodic_advertising_data_command(
|
|
1923
|
+
self, _command: hci.HCI_LE_Set_Periodic_Advertising_Data_Command
|
|
1924
|
+
) -> Optional[bytes]:
|
|
1741
1925
|
'''
|
|
1742
1926
|
See Bluetooth spec Vol 4, Part E - 7.8.62 LE Set Periodic Advertising Data
|
|
1743
1927
|
Command
|
|
1744
1928
|
'''
|
|
1745
1929
|
return bytes([HCI_SUCCESS])
|
|
1746
1930
|
|
|
1747
|
-
def on_hci_le_set_periodic_advertising_enable_command(
|
|
1931
|
+
def on_hci_le_set_periodic_advertising_enable_command(
|
|
1932
|
+
self, _command: hci.HCI_LE_Set_Periodic_Advertising_Enable_Command
|
|
1933
|
+
) -> Optional[bytes]:
|
|
1748
1934
|
'''
|
|
1749
1935
|
See Bluetooth spec Vol 4, Part E - 7.8.63 LE Set Periodic Advertising Enable
|
|
1750
1936
|
Command
|
|
1751
1937
|
'''
|
|
1752
1938
|
return bytes([HCI_SUCCESS])
|
|
1753
1939
|
|
|
1754
|
-
def on_hci_le_read_transmit_power_command(
|
|
1940
|
+
def on_hci_le_read_transmit_power_command(
|
|
1941
|
+
self, _command: hci.HCI_LE_Read_Transmit_Power_Command
|
|
1942
|
+
) -> Optional[bytes]:
|
|
1755
1943
|
'''
|
|
1756
1944
|
See Bluetooth spec Vol 4, Part E - 7.8.74 LE Read Transmit Power Command
|
|
1757
1945
|
'''
|
|
1758
1946
|
return struct.pack('<BBB', HCI_SUCCESS, 0, 0)
|
|
1759
1947
|
|
|
1760
|
-
def on_hci_le_set_cig_parameters_command(
|
|
1948
|
+
def on_hci_le_set_cig_parameters_command(
|
|
1949
|
+
self, command: hci.HCI_LE_Set_CIG_Parameters_Command
|
|
1950
|
+
) -> Optional[bytes]:
|
|
1761
1951
|
'''
|
|
1762
1952
|
See Bluetooth spec Vol 4, Part E - 7.8.97 LE Set CIG Parameter Command
|
|
1763
1953
|
'''
|
|
1764
1954
|
|
|
1765
1955
|
# Remove old CIG implicitly.
|
|
1766
|
-
|
|
1956
|
+
cis_links = list(self.central_cis_links.items())
|
|
1957
|
+
for handle, cis_link in cis_links:
|
|
1767
1958
|
if cis_link.cig_id == command.cig_id:
|
|
1768
1959
|
self.central_cis_links.pop(handle)
|
|
1769
1960
|
|
|
@@ -1780,12 +1971,14 @@ class Controller:
|
|
|
1780
1971
|
'<BBB', HCI_SUCCESS, command.cig_id, len(handles)
|
|
1781
1972
|
) + b''.join([struct.pack('<H', handle) for handle in handles])
|
|
1782
1973
|
|
|
1783
|
-
def on_hci_le_create_cis_command(
|
|
1974
|
+
def on_hci_le_create_cis_command(
|
|
1975
|
+
self, command: hci.HCI_LE_Create_CIS_Command
|
|
1976
|
+
) -> Optional[bytes]:
|
|
1784
1977
|
'''
|
|
1785
1978
|
See Bluetooth spec Vol 4, Part E - 7.8.99 LE Create CIS Command
|
|
1786
1979
|
'''
|
|
1787
1980
|
if not self.link:
|
|
1788
|
-
return
|
|
1981
|
+
return None
|
|
1789
1982
|
|
|
1790
1983
|
for cis_handle, acl_handle in zip(
|
|
1791
1984
|
command.cis_connection_handle, command.acl_connection_handle
|
|
@@ -1814,27 +2007,33 @@ class Controller:
|
|
|
1814
2007
|
command_opcode=command.op_code,
|
|
1815
2008
|
)
|
|
1816
2009
|
)
|
|
2010
|
+
return None
|
|
1817
2011
|
|
|
1818
|
-
def on_hci_le_remove_cig_command(
|
|
2012
|
+
def on_hci_le_remove_cig_command(
|
|
2013
|
+
self, command: hci.HCI_LE_Remove_CIG_Command
|
|
2014
|
+
) -> Optional[bytes]:
|
|
1819
2015
|
'''
|
|
1820
2016
|
See Bluetooth spec Vol 4, Part E - 7.8.100 LE Remove CIG Command
|
|
1821
2017
|
'''
|
|
1822
2018
|
|
|
1823
2019
|
status = HCI_UNKNOWN_CONNECTION_IDENTIFIER_ERROR
|
|
1824
2020
|
|
|
1825
|
-
|
|
2021
|
+
cis_links = list(self.central_cis_links.items())
|
|
2022
|
+
for cis_handle, cis_link in cis_links:
|
|
1826
2023
|
if cis_link.cig_id == command.cig_id:
|
|
1827
2024
|
self.central_cis_links.pop(cis_handle)
|
|
1828
2025
|
status = HCI_SUCCESS
|
|
1829
2026
|
|
|
1830
2027
|
return struct.pack('<BH', status, command.cig_id)
|
|
1831
2028
|
|
|
1832
|
-
def on_hci_le_accept_cis_request_command(
|
|
2029
|
+
def on_hci_le_accept_cis_request_command(
|
|
2030
|
+
self, command: hci.HCI_LE_Accept_CIS_Request_Command
|
|
2031
|
+
) -> Optional[bytes]:
|
|
1833
2032
|
'''
|
|
1834
2033
|
See Bluetooth spec Vol 4, Part E - 7.8.101 LE Accept CIS Request Command
|
|
1835
2034
|
'''
|
|
1836
2035
|
if not self.link:
|
|
1837
|
-
return
|
|
2036
|
+
return None
|
|
1838
2037
|
|
|
1839
2038
|
if not (
|
|
1840
2039
|
pending_cis_link := self.peripheral_cis_links.get(command.connection_handle)
|
|
@@ -1857,10 +2056,11 @@ class Controller:
|
|
|
1857
2056
|
command_opcode=command.op_code,
|
|
1858
2057
|
)
|
|
1859
2058
|
)
|
|
2059
|
+
return None
|
|
1860
2060
|
|
|
1861
2061
|
def on_hci_le_setup_iso_data_path_command(
|
|
1862
2062
|
self, command: hci.HCI_LE_Setup_ISO_Data_Path_Command
|
|
1863
|
-
) -> bytes:
|
|
2063
|
+
) -> Optional[bytes]:
|
|
1864
2064
|
'''
|
|
1865
2065
|
See Bluetooth spec Vol 4, Part E - 7.8.109 LE Setup ISO Data Path Command
|
|
1866
2066
|
'''
|
|
@@ -1881,7 +2081,7 @@ class Controller:
|
|
|
1881
2081
|
|
|
1882
2082
|
def on_hci_le_remove_iso_data_path_command(
|
|
1883
2083
|
self, command: hci.HCI_LE_Remove_ISO_Data_Path_Command
|
|
1884
|
-
) -> bytes:
|
|
2084
|
+
) -> Optional[bytes]:
|
|
1885
2085
|
'''
|
|
1886
2086
|
See Bluetooth spec Vol 4, Part E - 7.8.110 LE Remove ISO Data Path Command
|
|
1887
2087
|
'''
|
|
@@ -1907,7 +2107,7 @@ class Controller:
|
|
|
1907
2107
|
|
|
1908
2108
|
def on_hci_le_set_host_feature_command(
|
|
1909
2109
|
self, _command: hci.HCI_LE_Set_Host_Feature_Command
|
|
1910
|
-
):
|
|
2110
|
+
) -> Optional[bytes]:
|
|
1911
2111
|
'''
|
|
1912
2112
|
See Bluetooth spec Vol 4, Part E - 7.8.115 LE Set Host Feature command
|
|
1913
2113
|
'''
|