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/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, data):
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, data
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 = asyncio.get_running_loop().create_future()
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.hci_packet_type == HCI_COMMAND_PACKET:
286
+ if isinstance(packet, hci.HCI_Command):
276
287
  self.on_hci_command_packet(packet)
277
- elif packet.hci_packet_type == HCI_EVENT_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(self, 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, le_create_connection_command, status
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(self, disconnection_command, status):
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(self, peer_address, _rand, _ediv, _ltk):
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(self, sender_address, transport, 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(self, peer_address, link_type):
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(self, peer_address, status):
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(self, 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(self, 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
- def on_hci_accept_connection_request_command(self, command):
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(self, 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(self, 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(self, command: hci.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(self, command: hci.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(self, command: hci.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(self, 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 = command.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(self, 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(self, _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(self, _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(self, _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(self, _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(self, 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(self, _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(self, _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(self, _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(self, _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(self, 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 = command.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(self, _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(self, _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(self, 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(self, _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(self, _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(self, _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(self, 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(self, _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(self, _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(self, 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 = command.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(self, _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(self, _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(self, _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(self, 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(self, 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(self, _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(self, 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(self, 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(self, 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(self, 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(self, 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(self, 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(self, _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(self, _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(self, _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(self, _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(self, _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(self, 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(self, _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(self, 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(self, _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(self, _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(self, 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(self, _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(self, _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(self, _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(self, _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(self, 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(self, 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(self, _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(self, 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(self, 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
- 'all_phys': command.all_phys,
1679
- 'tx_phys': command.tx_phys,
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(self, _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(self, _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(self, _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(self, _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(self, _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(self, _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(self, _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(self, _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(self, _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(self, _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(self, _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(self, 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
- for handle, cis_link in self.central_cis_links.items():
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(self, 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(self, 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
- for cis_handle, cis_link in self.central_cis_links.items():
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(self, 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
  '''