bumble 0.0.198__py3-none-any.whl → 0.0.199__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/hci.py CHANGED
@@ -267,6 +267,19 @@ HCI_LE_PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED_V2_EVENT = 0X26
267
267
  HCI_LE_PERIODIC_ADVERTISING_SUBEVENT_DATA_REQUEST_EVENT = 0X27
268
268
  HCI_LE_PERIODIC_ADVERTISING_RESPONSE_REPORT_EVENT = 0X28
269
269
  HCI_LE_ENHANCED_CONNECTION_COMPLETE_V2_EVENT = 0X29
270
+ HCI_LE_READ_ALL_REMOTE_FEATURES_COMPLETE_EVENT = 0x2A
271
+ HCI_LE_CIS_ESTABLISHED_V2_EVENT = 0x2B
272
+ HCI_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMPLETE_EVENT = 0x2C
273
+ HCI_LE_CS_READ_REMOTE_FAE_TABLE_COMPLETE_EVENT = 0x2D
274
+ HCI_LE_CS_SECURITY_ENABLE_COMPLETE_EVENT = 0x2E
275
+ HCI_LE_CS_CONFIG_COMPLETE_EVENT = 0x2F
276
+ HCI_LE_CS_PROCEDURE_ENABLE_EVENT = 0x30
277
+ HCI_LE_CS_SUBEVENT_RESULT_EVENT = 0x31
278
+ HCI_LE_CS_SUBEVENT_RESULT_CONTINUE_EVENT = 0x32
279
+ HCI_LE_CS_TEST_END_COMPLETE_EVENT = 0x33
280
+ HCI_LE_MONITORED_ADVERTISERS_REPORT_EVENT = 0x34
281
+ HCI_LE_FRAME_SPACE_UPDATE_EVENT = 0x35
282
+
270
283
 
271
284
 
272
285
  # HCI Command
@@ -573,11 +586,36 @@ HCI_LE_SET_DATA_RELATED_ADDRESS_CHANGES_COMMAND = hci_c
573
586
  HCI_LE_SET_DEFAULT_SUBRATE_COMMAND = hci_command_op_code(0x08, 0x007D)
574
587
  HCI_LE_SUBRATE_REQUEST_COMMAND = hci_command_op_code(0x08, 0x007E)
575
588
  HCI_LE_SET_EXTENDED_ADVERTISING_PARAMETERS_V2_COMMAND = hci_command_op_code(0x08, 0x007F)
589
+ HCI_LE_SET_DECISION_DATA_COMMAND = hci_command_op_code(0x08, 0x0080)
590
+ HCI_LE_SET_DECISION_INSTRUCTIONS_COMMAND = hci_command_op_code(0x08, 0x0081)
576
591
  HCI_LE_SET_PERIODIC_ADVERTISING_SUBEVENT_DATA_COMMAND = hci_command_op_code(0x08, 0x0082)
577
592
  HCI_LE_SET_PERIODIC_ADVERTISING_RESPONSE_DATA_COMMAND = hci_command_op_code(0x08, 0x0083)
578
593
  HCI_LE_SET_PERIODIC_SYNC_SUBEVENT_COMMAND = hci_command_op_code(0x08, 0x0084)
579
594
  HCI_LE_EXTENDED_CREATE_CONNECTION_V2_COMMAND = hci_command_op_code(0x08, 0x0085)
580
595
  HCI_LE_SET_PERIODIC_ADVERTISING_PARAMETERS_V2_COMMAND = hci_command_op_code(0x08, 0x0086)
596
+ HCI_LE_READ_ALL_LOCAL_SUPPORTED_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0087)
597
+ HCI_LE_READ_ALL_REMOTE_FEATURES_COMMAND = hci_command_op_code(0x08, 0x0088)
598
+ HCI_LE_CS_READ_LOCAL_SUPPORTED_CAPABILITIES_COMMAND = hci_command_op_code(0x08, 0x0089)
599
+ HCI_LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES_COMMAND = hci_command_op_code(0x08, 0x008A)
600
+ HCI_LE_CS_WRITE_CACHED_REMOTE_SUPPORTED_CAPABILITIES = hci_command_op_code(0x08, 0x008B)
601
+ HCI_LE_CS_SECURITY_ENABLE_COMMAND = hci_command_op_code(0x08, 0x008C)
602
+ HCI_LE_CS_SET_DEFAULT_SETTINGS_COMMAND = hci_command_op_code(0x08, 0x008D)
603
+ HCI_LE_CS_READ_REMOTE_FAE_TABLE_COMMAND = hci_command_op_code(0x08, 0x008E)
604
+ HCI_LE_CS_WRITE_CACHED_REMOTE_FAE_TABLE_COMMAND = hci_command_op_code(0x08, 0x008F)
605
+ HCI_LE_CS_CREATE_CONFIG_COMMAND = hci_command_op_code(0x08, 0x0090)
606
+ HCI_LE_CS_REMOVE_CONFIG_COMMAND = hci_command_op_code(0x08, 0x0091)
607
+ HCI_LE_CS_SET_CHANNEL_CLASSIFICATION_COMMAND = hci_command_op_code(0x08, 0x0092)
608
+ HCI_LE_CS_SET_PROCEDURE_PARAMETERS_COMMAND = hci_command_op_code(0x08, 0x0093)
609
+ HCI_LE_CS_PROCEDURE_ENABLE_COMMAND = hci_command_op_code(0x08, 0x0094)
610
+ HCI_LE_CS_TEST_COMMAND = hci_command_op_code(0x08, 0x0095)
611
+ HCI_LE_CS_TEST_END_COMMAND = hci_command_op_code(0x08, 0x0096)
612
+ HCI_LE_SET_HOST_FEATURE_V2_COMMAND = hci_command_op_code(0x08, 0x0097)
613
+ HCI_LE_ADD_DEVICE_TO_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x0098)
614
+ HCI_LE_REMOVE_DEVICE_FROM_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x0099)
615
+ HCI_LE_CLEAR_MONITORED_ADVERTISERS_LIST_COMMAND = hci_command_op_code(0x08, 0x009A)
616
+ HCI_LE_READ_MONITORED_ADVERTISERS_LIST_SIZE_COMMAND = hci_command_op_code(0x08, 0x009B)
617
+ HCI_LE_ENABLE_MONITORING_ADVERTISERS_COMMAND = hci_command_op_code(0x08, 0x009C)
618
+ HCI_LE_FRAME_SPACE_UPDATE_COMMAND = hci_command_op_code(0x08, 0x009D)
581
619
 
582
620
 
583
621
  # HCI Error Codes
@@ -1150,8 +1188,16 @@ class LeFeature(OpenIntEnum):
1150
1188
  CHANNEL_CLASSIFICATION = 39
1151
1189
  ADVERTISING_CODING_SELECTION = 40
1152
1190
  ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 41
1191
+ DECISION_BASED_ADVERTISING_FILTERING = 42
1153
1192
  PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 43
1154
1193
  PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 44
1194
+ UNSEGMENTED_FRAMED_MODE = 45
1195
+ CHANNEL_SOUNDING = 46
1196
+ CHANNEL_SOUNDING_HOST_SUPPORT = 47
1197
+ CHANNEL_SOUNDING_TONE_QUALITY_INDICATION = 48
1198
+ LL_EXTENDED_FEATURE_SET = 63
1199
+ MONITORING_ADVERTISERS = 64
1200
+ FRAME_SPACE_UPDATE = 65
1155
1201
 
1156
1202
  class LeFeatureMask(enum.IntFlag):
1157
1203
  LE_ENCRYPTION = 1 << LeFeature.LE_ENCRYPTION
@@ -1196,8 +1242,16 @@ class LeFeatureMask(enum.IntFlag):
1196
1242
  CHANNEL_CLASSIFICATION = 1 << LeFeature.CHANNEL_CLASSIFICATION
1197
1243
  ADVERTISING_CODING_SELECTION = 1 << LeFeature.ADVERTISING_CODING_SELECTION
1198
1244
  ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 1 << LeFeature.ADVERTISING_CODING_SELECTION_HOST_SUPPORT
1245
+ DECISION_BASED_ADVERTISING_FILTERING = 1 << LeFeature.DECISION_BASED_ADVERTISING_FILTERING
1199
1246
  PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER
1200
1247
  PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER
1248
+ UNSEGMENTED_FRAMED_MODE = 1 << LeFeature.UNSEGMENTED_FRAMED_MODE
1249
+ CHANNEL_SOUNDING = 1 << LeFeature.CHANNEL_SOUNDING
1250
+ CHANNEL_SOUNDING_HOST_SUPPORT = 1 << LeFeature.CHANNEL_SOUNDING_HOST_SUPPORT
1251
+ CHANNEL_SOUNDING_TONE_QUALITY_INDICATION = 1 << LeFeature.CHANNEL_SOUNDING_TONE_QUALITY_INDICATION
1252
+ LL_EXTENDED_FEATURE_SET = 1 << LeFeature.LL_EXTENDED_FEATURE_SET
1253
+ MONITORING_ADVERTISERS = 1 << LeFeature.MONITORING_ADVERTISERS
1254
+ FRAME_SPACE_UPDATE = 1 << LeFeature.FRAME_SPACE_UPDATE
1201
1255
 
1202
1256
  class LmpFeature(enum.IntEnum):
1203
1257
  # Page 0 (Legacy LMP features)
@@ -1565,12 +1619,16 @@ class HCI_Object:
1565
1619
  # This is an array field, starting with a 1-byte item count.
1566
1620
  item_count = data[offset]
1567
1621
  offset += 1
1622
+ # Set fields first, because item_count might be 0.
1623
+ for sub_field_name, _ in field:
1624
+ result[sub_field_name] = []
1625
+
1568
1626
  for _ in range(item_count):
1569
1627
  for sub_field_name, sub_field_type in field:
1570
1628
  value, size = HCI_Object.parse_field(
1571
1629
  data, offset, sub_field_type
1572
1630
  )
1573
- result.setdefault(sub_field_name, []).append(value)
1631
+ result[sub_field_name].append(value)
1574
1632
  offset += size
1575
1633
  continue
1576
1634
 
@@ -2982,6 +3040,27 @@ class HCI_Write_Inquiry_Scan_Activity_Command(HCI_Command):
2982
3040
  '''
2983
3041
 
2984
3042
 
3043
+ # -----------------------------------------------------------------------------
3044
+ @HCI_Command.command(
3045
+ return_parameters_fields=[
3046
+ ('status', STATUS_SPEC),
3047
+ ('authentication_enable', 1),
3048
+ ]
3049
+ )
3050
+ class HCI_Read_Authentication_Enable_Command(HCI_Command):
3051
+ '''
3052
+ See Bluetooth spec @ 7.3.23 Read Authentication Enable Command
3053
+ '''
3054
+
3055
+
3056
+ # -----------------------------------------------------------------------------
3057
+ @HCI_Command.command([('authentication_enable', 1)])
3058
+ class HCI_Write_Authentication_Enable_Command(HCI_Command):
3059
+ '''
3060
+ See Bluetooth spec @ 7.3.24 Write Authentication Enable Command
3061
+ '''
3062
+
3063
+
2985
3064
  # -----------------------------------------------------------------------------
2986
3065
  @HCI_Command.command(
2987
3066
  return_parameters_fields=[
@@ -3022,7 +3101,12 @@ class HCI_Write_Voice_Setting_Command(HCI_Command):
3022
3101
 
3023
3102
 
3024
3103
  # -----------------------------------------------------------------------------
3025
- @HCI_Command.command()
3104
+ @HCI_Command.command(
3105
+ return_parameters_fields=[
3106
+ ('status', STATUS_SPEC),
3107
+ ('synchronous_flow_control_enable', 1),
3108
+ ]
3109
+ )
3026
3110
  class HCI_Read_Synchronous_Flow_Control_Enable_Command(HCI_Command):
3027
3111
  '''
3028
3112
  See Bluetooth spec @ 7.3.36 Read Synchronous Flow Control Enable Command
@@ -3191,7 +3275,13 @@ class HCI_Set_Event_Mask_Page_2_Command(HCI_Command):
3191
3275
 
3192
3276
 
3193
3277
  # -----------------------------------------------------------------------------
3194
- @HCI_Command.command()
3278
+ @HCI_Command.command(
3279
+ return_parameters_fields=[
3280
+ ('status', STATUS_SPEC),
3281
+ ('le_supported_host', 1),
3282
+ ('unused', 1),
3283
+ ]
3284
+ )
3195
3285
  class HCI_Read_LE_Host_Support_Command(HCI_Command):
3196
3286
  '''
3197
3287
  See Bluetooth spec @ 7.3.78 Read LE Host Support Command
@@ -3324,13 +3414,39 @@ class HCI_Read_BD_ADDR_Command(HCI_Command):
3324
3414
 
3325
3415
 
3326
3416
  # -----------------------------------------------------------------------------
3327
- @HCI_Command.command()
3417
+ @HCI_Command.command(
3418
+ return_parameters_fields=[
3419
+ ("status", STATUS_SPEC),
3420
+ [("standard_codec_ids", 1)],
3421
+ [("vendor_specific_codec_ids", 4)],
3422
+ ]
3423
+ )
3328
3424
  class HCI_Read_Local_Supported_Codecs_Command(HCI_Command):
3329
3425
  '''
3330
3426
  See Bluetooth spec @ 7.4.8 Read Local Supported Codecs Command
3331
3427
  '''
3332
3428
 
3333
3429
 
3430
+ # -----------------------------------------------------------------------------
3431
+ @HCI_Command.command(
3432
+ return_parameters_fields=[
3433
+ ("status", STATUS_SPEC),
3434
+ [("standard_codec_ids", 1), ("standard_codec_transports", 1)],
3435
+ [("vendor_specific_codec_ids", 4), ("vendor_specific_codec_transports", 1)],
3436
+ ]
3437
+ )
3438
+ class HCI_Read_Local_Supported_Codecs_V2_Command(HCI_Command):
3439
+ '''
3440
+ See Bluetooth spec @ 7.4.8 Read Local Supported Codecs Command
3441
+ '''
3442
+
3443
+ class Transport(OpenIntEnum):
3444
+ BR_EDR_ACL = 0x00
3445
+ BR_EDR_SCO = 0x01
3446
+ LE_CIS = 0x02
3447
+ LE_BIS = 0x03
3448
+
3449
+
3334
3450
  # -----------------------------------------------------------------------------
3335
3451
  @HCI_Command.command(
3336
3452
  fields=[('handle', 2)],
@@ -3488,7 +3604,12 @@ class HCI_LE_Set_Advertising_Parameters_Command(HCI_Command):
3488
3604
 
3489
3605
 
3490
3606
  # -----------------------------------------------------------------------------
3491
- @HCI_Command.command()
3607
+ @HCI_Command.command(
3608
+ return_parameters_fields=[
3609
+ ('status', STATUS_SPEC),
3610
+ ('tx_power_level', 1),
3611
+ ]
3612
+ )
3492
3613
  class HCI_LE_Read_Advertising_Physical_Channel_Tx_Power_Command(HCI_Command):
3493
3614
  '''
3494
3615
  See Bluetooth spec @ 7.8.6 LE Read Advertising Physical Channel Tx Power Command
@@ -3612,7 +3733,12 @@ class HCI_LE_Create_Connection_Cancel_Command(HCI_Command):
3612
3733
 
3613
3734
 
3614
3735
  # -----------------------------------------------------------------------------
3615
- @HCI_Command.command()
3736
+ @HCI_Command.command(
3737
+ return_parameters_fields=[
3738
+ ('status', STATUS_SPEC),
3739
+ ('filter_accept_list_size', 1),
3740
+ ]
3741
+ )
3616
3742
  class HCI_LE_Read_Filter_Accept_List_Size_Command(HCI_Command):
3617
3743
  '''
3618
3744
  See Bluetooth spec @ 7.8.14 LE Read Filter Accept List Size Command
@@ -3723,7 +3849,12 @@ class HCI_LE_Long_Term_Key_Request_Negative_Reply_Command(HCI_Command):
3723
3849
 
3724
3850
 
3725
3851
  # -----------------------------------------------------------------------------
3726
- @HCI_Command.command()
3852
+ @HCI_Command.command(
3853
+ return_parameters_fields=[
3854
+ ('status', STATUS_SPEC),
3855
+ ('le_states', 8),
3856
+ ]
3857
+ )
3727
3858
  class HCI_LE_Read_Supported_States_Command(HCI_Command):
3728
3859
  '''
3729
3860
  See Bluetooth spec @ 7.8.27 LE Read Supported States Command
@@ -4698,6 +4829,102 @@ class HCI_LE_Reject_CIS_Request_Command(HCI_Command):
4698
4829
  reason: int
4699
4830
 
4700
4831
 
4832
+ # -----------------------------------------------------------------------------
4833
+ @HCI_Command.command(
4834
+ fields=[
4835
+ ('big_handle', 1),
4836
+ ('advertising_handle', 1),
4837
+ ('num_bis', 1),
4838
+ ('sdu_interval', 3),
4839
+ ('max_sdu', 2),
4840
+ ('max_transport_latency', 2),
4841
+ ('rtn', 1),
4842
+ ('phy', 1),
4843
+ ('packing', 1),
4844
+ ('framing', 1),
4845
+ ('encryption', 1),
4846
+ ('broadcast_code', 16),
4847
+ ],
4848
+ )
4849
+ class HCI_LE_Create_BIG_Command(HCI_Command):
4850
+ '''
4851
+ See Bluetooth spec @ 7.8.103 LE Create BIG command
4852
+ '''
4853
+
4854
+ big_handle: int
4855
+ advertising_handle: int
4856
+ num_bis: int
4857
+ sdu_interval: int
4858
+ max_sdu: int
4859
+ max_transport_latency: int
4860
+ rtn: int
4861
+ phy: int
4862
+ packing: int
4863
+ framing: int
4864
+ encryption: int
4865
+ broadcast_code: int
4866
+
4867
+
4868
+ # -----------------------------------------------------------------------------
4869
+ @HCI_Command.command(
4870
+ fields=[
4871
+ ('big_handle', 1),
4872
+ ('reason', {'size': 1, 'mapper': HCI_Constant.error_name}),
4873
+ ],
4874
+ )
4875
+ class HCI_LE_Terminate_BIG_Command(HCI_Command):
4876
+ '''
4877
+ See Bluetooth spec @ 7.8.105 LE Terminate BIG command
4878
+ '''
4879
+
4880
+ big_handle: int
4881
+ reason: int
4882
+
4883
+
4884
+ # -----------------------------------------------------------------------------
4885
+ @HCI_Command.command(
4886
+ fields=[
4887
+ ('big_handle', 1),
4888
+ ('sync_handle', 2),
4889
+ ('encryption', 1),
4890
+ ('broadcast_code', 16),
4891
+ ('mse', 1),
4892
+ ('big_sync_timeout', 2),
4893
+ [('bis', 1)],
4894
+ ],
4895
+ )
4896
+ class HCI_LE_BIG_Create_Sync_Command(HCI_Command):
4897
+ '''
4898
+ See Bluetooth spec @ 7.8.106 LE BIG Create Sync command
4899
+ '''
4900
+
4901
+ big_handle: int
4902
+ sync_handle: int
4903
+ encryption: int
4904
+ broadcast_code: int
4905
+ mse: int
4906
+ big_sync_timeout: int
4907
+ bis: List[int]
4908
+
4909
+
4910
+ # -----------------------------------------------------------------------------
4911
+ @HCI_Command.command(
4912
+ fields=[
4913
+ ('big_handle', 1),
4914
+ ],
4915
+ return_parameters_fields=[
4916
+ ('status', STATUS_SPEC),
4917
+ ('big_handle', 2),
4918
+ ],
4919
+ )
4920
+ class HCI_LE_BIG_Terminate_Sync_Command(HCI_Command):
4921
+ '''
4922
+ See Bluetooth spec @ 7.8.107. LE BIG Terminate Sync command
4923
+ '''
4924
+
4925
+ big_handle: int
4926
+
4927
+
4701
4928
  # -----------------------------------------------------------------------------
4702
4929
  @HCI_Command.command(
4703
4930
  fields=[
@@ -5533,6 +5760,27 @@ class HCI_LE_Channel_Selection_Algorithm_Event(HCI_LE_Meta_Event):
5533
5760
  '''
5534
5761
 
5535
5762
 
5763
+ # -----------------------------------------------------------------------------
5764
+ @HCI_LE_Meta_Event.event(
5765
+ [
5766
+ ('status', STATUS_SPEC),
5767
+ ('connection_handle', 2),
5768
+ ('service_data', 2),
5769
+ ('sync_handle', 2),
5770
+ ('advertising_sid', 1),
5771
+ ('advertiser_address_type', Address.ADDRESS_TYPE_SPEC),
5772
+ ('advertiser_address', Address.parse_address_preceded_by_type),
5773
+ ('advertiser_phy', 1),
5774
+ ('periodic_advertising_interval', 2),
5775
+ ('advertiser_clock_accuracy', 1),
5776
+ ]
5777
+ )
5778
+ class HCI_LE_Periodic_Advertising_Sync_Transfer_Received_Event(HCI_LE_Meta_Event):
5779
+ '''
5780
+ See Bluetooth spec @ 7.7.65.24 LE Periodic Advertising Sync Transfer Received Event
5781
+ '''
5782
+
5783
+
5536
5784
  # -----------------------------------------------------------------------------
5537
5785
  @HCI_LE_Meta_Event.event(
5538
5786
  [
@@ -6225,6 +6473,23 @@ class HCI_Synchronous_Connection_Changed_Event(HCI_Event):
6225
6473
  '''
6226
6474
 
6227
6475
 
6476
+ # -----------------------------------------------------------------------------
6477
+ @HCI_Event.event(
6478
+ [
6479
+ ('status', STATUS_SPEC),
6480
+ ('connection_handle', 2),
6481
+ ('max_tx_latency', 2),
6482
+ ('max_rx_latency', 2),
6483
+ ('min_remote_timeout', 2),
6484
+ ('min_local_timeout', 2),
6485
+ ]
6486
+ )
6487
+ class HCI_Sniff_Subrating_Event(HCI_Event):
6488
+ '''
6489
+ See Bluetooth spec @ 7.7.37 Sniff Subrating Event
6490
+ '''
6491
+
6492
+
6228
6493
  # -----------------------------------------------------------------------------
6229
6494
  @HCI_Event.event(
6230
6495
  [
bumble/host.py CHANGED
@@ -171,7 +171,7 @@ class Host(AbortableEventEmitter):
171
171
  self.cis_links = {} # CIS links, by connection handle
172
172
  self.sco_links = {} # SCO links, by connection handle
173
173
  self.pending_command = None
174
- self.pending_response = None
174
+ self.pending_response: Optional[asyncio.Future[Any]] = None
175
175
  self.number_of_supported_advertising_sets = 0
176
176
  self.maximum_advertising_data_length = 31
177
177
  self.local_version = None
@@ -514,7 +514,9 @@ class Host(AbortableEventEmitter):
514
514
  if self.hci_sink:
515
515
  self.hci_sink.on_packet(bytes(packet))
516
516
 
517
- async def send_command(self, command, check_result=False):
517
+ async def send_command(
518
+ self, command, check_result=False, response_timeout: Optional[int] = None
519
+ ):
518
520
  # Wait until we can send (only one pending command at a time)
519
521
  async with self.command_semaphore:
520
522
  assert self.pending_command is None
@@ -526,12 +528,13 @@ class Host(AbortableEventEmitter):
526
528
 
527
529
  try:
528
530
  self.send_hci_packet(command)
529
- response = await self.pending_response
531
+ await asyncio.wait_for(self.pending_response, timeout=response_timeout)
532
+ response = self.pending_response.result()
530
533
 
531
534
  # Check the return parameters if required
532
535
  if check_result:
533
536
  if isinstance(response, hci.HCI_Command_Status_Event):
534
- status = response.status
537
+ status = response.status # type: ignore[attr-defined]
535
538
  elif isinstance(response.return_parameters, int):
536
539
  status = response.return_parameters
537
540
  elif isinstance(response.return_parameters, bytes):
@@ -625,14 +628,21 @@ class Host(AbortableEventEmitter):
625
628
 
626
629
  # Packet Sink protocol (packets coming from the controller via HCI)
627
630
  def on_packet(self, packet: bytes) -> None:
628
- hci_packet = hci.HCI_Packet.from_bytes(packet)
631
+ try:
632
+ hci_packet = hci.HCI_Packet.from_bytes(packet)
633
+ except Exception as error:
634
+ logger.warning(f'!!! error parsing packet from bytes: {error}')
635
+ return
636
+
629
637
  if self.ready or (
630
638
  isinstance(hci_packet, hci.HCI_Command_Complete_Event)
631
639
  and hci_packet.command_opcode == hci.HCI_RESET_COMMAND
632
640
  ):
633
641
  self.on_hci_packet(hci_packet)
634
642
  else:
635
- logger.debug('reset not done, ignoring packet from controller')
643
+ logger.debug(
644
+ f'reset not done, ignoring packet from controller: {hci_packet}'
645
+ )
636
646
 
637
647
  def on_transport_lost(self):
638
648
  # Called by the source when the transport has been lost.
@@ -25,8 +25,10 @@ import grpc.aio
25
25
  from .config import Config
26
26
  from .device import PandoraDevice
27
27
  from .host import HostService
28
+ from .l2cap import L2CAPService
28
29
  from .security import SecurityService, SecurityStorageService
29
30
  from pandora.host_grpc_aio import add_HostServicer_to_server
31
+ from pandora.l2cap_grpc_aio import add_L2CAPServicer_to_server
30
32
  from pandora.security_grpc_aio import (
31
33
  add_SecurityServicer_to_server,
32
34
  add_SecurityStorageServicer_to_server,
@@ -77,6 +79,7 @@ async def serve(
77
79
  add_SecurityStorageServicer_to_server(
78
80
  SecurityStorageService(bumble.device, config), server
79
81
  )
82
+ add_L2CAPServicer_to_server(L2CAPService(bumble.device, config), server)
80
83
 
81
84
  # call hooks if any.
82
85
  for hook in _SERVICERS_HOOKS: