diff --git a/bumble/device.py b/bumble/device.py index 3686878c..6d5c00c8 100644 --- a/bumble/device.py +++ b/bumble/device.py @@ -148,6 +148,7 @@ HCI_Write_Secure_Connections_Host_Support_Command, HCI_Write_Simple_Pairing_Mode_Command, OwnAddressType, + LeFeature, LeFeatureMask, phy_list_to_bits, ) @@ -1546,7 +1547,7 @@ async def power_on(self) -> None: if self.cis_enabled: await self.send_command( HCI_LE_Set_Host_Feature_Command( - bit_number=LeFeatureMask.CONNECTED_ISOCHRONOUS_STREAM, + bit_number=LeFeature.CONNECTED_ISOCHRONOUS_STREAM, bit_value=1, ) ) diff --git a/bumble/hci.py b/bumble/hci.py index 4e088281..850f0b19 100644 --- a/bumble/hci.py +++ b/bumble/hci.py @@ -1360,51 +1360,97 @@ class PhyBit(enum.IntFlag): # LE Supported Features # See Bluetooth spec @ Vol 6, Part B, 4.6 FEATURE SUPPORT +class LeFeature(enum.IntEnum): + LE_ENCRYPTION = 0 + CONNECTION_PARAMETERS_REQUEST_PROCEDURE = 1 + EXTENDED_REJECT_INDICATION = 2 + PERIPHERAL_INITIATED_FEATURE_EXCHANGE = 3 + LE_PING = 4 + LE_DATA_PACKET_LENGTH_EXTENSION = 5 + LL_PRIVACY = 6 + EXTENDED_SCANNER_FILTER_POLICIES = 7 + LE_2M_PHY = 8 + STABLE_MODULATION_INDEX_TRANSMITTER = 9 + STABLE_MODULATION_INDEX_RECEIVER = 10 + LE_CODED_PHY = 11 + LE_EXTENDED_ADVERTISING = 12 + LE_PERIODIC_ADVERTISING = 13 + CHANNEL_SELECTION_ALGORITHM_2 = 14 + LE_POWER_CLASS_1 = 15 + MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE = 16 + CONNECTION_CTE_REQUEST = 17 + CONNECTION_CTE_RESPONSE = 18 + CONNECTIONLESS_CTE_TRANSMITTER = 19 + CONNECTIONLESS_CTR_RECEIVER = 20 + ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION = 21 + ANTENNA_SWITCHING_DURING_CTE_RECEPTION = 22 + RECEIVING_CONSTANT_TONE_EXTENSIONS = 23 + PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER = 24 + PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT = 25 + SLEEP_CLOCK_ACCURACY_UPDATES = 26 + REMOTE_PUBLIC_KEY_VALIDATION = 27 + CONNECTED_ISOCHRONOUS_STREAM_CENTRAL = 28 + CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL = 29 + ISOCHRONOUS_BROADCASTER = 30 + SYNCHRONIZED_RECEIVER = 31 + CONNECTED_ISOCHRONOUS_STREAM = 32 + LE_POWER_CONTROL_REQUEST = 33 + LE_POWER_CONTROL_REQUEST_DUP = 34 + LE_PATH_LOSS_MONITORING = 35 + PERIODIC_ADVERTISING_ADI_SUPPORT = 36 + CONNECTION_SUBRATING = 37 + CONNECTION_SUBRATING_HOST_SUPPORT = 38 + CHANNEL_CLASSIFICATION = 39 + ADVERTISING_CODING_SELECTION = 40 + ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 41 + PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 43 + PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 44 + class LeFeatureMask(enum.IntFlag): - LE_ENCRYPTION = 1 << 0 - CONNECTION_PARAMETERS_REQUEST_PROCEDURE = 1 << 1 - EXTENDED_REJECT_INDICATION = 1 << 2 - PERIPHERAL_INITIATED_FEATURE_EXCHANGE = 1 << 3 - LE_PING = 1 << 4 - LE_DATA_PACKET_LENGTH_EXTENSION = 1 << 5 - LL_PRIVACY = 1 << 6 - EXTENDED_SCANNER_FILTER_POLICIES = 1 << 7 - LE_2M_PHY = 1 << 8 - STABLE_MODULATION_INDEX_TRANSMITTER = 1 << 9 - STABLE_MODULATION_INDEX_RECEIVER = 1 << 10 - LE_CODED_PHY = 1 << 11 - LE_EXTENDED_ADVERTISING = 1 << 12 - LE_PERIODIC_ADVERTISING = 1 << 13 - CHANNEL_SELECTION_ALGORITHM_2 = 1 << 14 - LE_POWER_CLASS_1 = 1 << 15 - MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE = 1 << 16 - CONNECTION_CTE_REQUEST = 1 << 17 - CONNECTION_CTE_RESPONSE = 1 << 18 - CONNECTIONLESS_CTE_TRANSMITTER = 1 << 19 - CONNECTIONLESS_CTR_RECEIVER = 1 << 20 - ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION = 1 << 21 - ANTENNA_SWITCHING_DURING_CTE_RECEPTION = 1 << 22 - RECEIVING_CONSTANT_TONE_EXTENSIONS = 1 << 23 - PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER = 1 << 24 - PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT = 1 << 25 - SLEEP_CLOCK_ACCURACY_UPDATES = 1 << 26 - REMOTE_PUBLIC_KEY_VALIDATION = 1 << 27 - CONNECTED_ISOCHRONOUS_STREAM_CENTRAL = 1 << 28 - CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL = 1 << 29 - ISOCHRONOUS_BROADCASTER = 1 << 30 - SYNCHRONIZED_RECEIVER = 1 << 31 - CONNECTED_ISOCHRONOUS_STREAM = 1 << 32 - LE_POWER_CONTROL_REQUEST = 1 << 33 - LE_POWER_CONTROL_REQUEST_DUP = 1 << 34 - LE_PATH_LOSS_MONITORING = 1 << 35 - PERIODIC_ADVERTISING_ADI_SUPPORT = 1 << 36 - CONNECTION_SUBRATING = 1 << 37 - CONNECTION_SUBRATING_HOST_SUPPORT = 1 << 38 - CHANNEL_CLASSIFICATION = 1 << 39 - ADVERTISING_CODING_SELECTION = 1 << 40 - ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 1 << 41 - PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 1 << 43 - PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 1 << 44 + LE_ENCRYPTION = 1 << LeFeature.LE_ENCRYPTION + CONNECTION_PARAMETERS_REQUEST_PROCEDURE = 1 << LeFeature.CONNECTION_PARAMETERS_REQUEST_PROCEDURE + EXTENDED_REJECT_INDICATION = 1 << LeFeature.EXTENDED_REJECT_INDICATION + PERIPHERAL_INITIATED_FEATURE_EXCHANGE = 1 << LeFeature.PERIPHERAL_INITIATED_FEATURE_EXCHANGE + LE_PING = 1 << LeFeature.LE_PING + LE_DATA_PACKET_LENGTH_EXTENSION = 1 << LeFeature.LE_DATA_PACKET_LENGTH_EXTENSION + LL_PRIVACY = 1 << LeFeature.LL_PRIVACY + EXTENDED_SCANNER_FILTER_POLICIES = 1 << LeFeature.EXTENDED_SCANNER_FILTER_POLICIES + LE_2M_PHY = 1 << LeFeature.LE_2M_PHY + STABLE_MODULATION_INDEX_TRANSMITTER = 1 << LeFeature.STABLE_MODULATION_INDEX_TRANSMITTER + STABLE_MODULATION_INDEX_RECEIVER = 1 << LeFeature.STABLE_MODULATION_INDEX_RECEIVER + LE_CODED_PHY = 1 << LeFeature.LE_CODED_PHY + LE_EXTENDED_ADVERTISING = 1 << LeFeature.LE_EXTENDED_ADVERTISING + LE_PERIODIC_ADVERTISING = 1 << LeFeature.LE_PERIODIC_ADVERTISING + CHANNEL_SELECTION_ALGORITHM_2 = 1 << LeFeature.CHANNEL_SELECTION_ALGORITHM_2 + LE_POWER_CLASS_1 = 1 << LeFeature.LE_POWER_CLASS_1 + MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE = 1 << LeFeature.MINIMUM_NUMBER_OF_USED_CHANNELS_PROCEDURE + CONNECTION_CTE_REQUEST = 1 << LeFeature.CONNECTION_CTE_REQUEST + CONNECTION_CTE_RESPONSE = 1 << LeFeature.CONNECTION_CTE_RESPONSE + CONNECTIONLESS_CTE_TRANSMITTER = 1 << LeFeature.CONNECTIONLESS_CTE_TRANSMITTER + CONNECTIONLESS_CTR_RECEIVER = 1 << LeFeature.CONNECTIONLESS_CTR_RECEIVER + ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION = 1 << LeFeature.ANTENNA_SWITCHING_DURING_CTE_TRANSMISSION + ANTENNA_SWITCHING_DURING_CTE_RECEPTION = 1 << LeFeature.ANTENNA_SWITCHING_DURING_CTE_RECEPTION + RECEIVING_CONSTANT_TONE_EXTENSIONS = 1 << LeFeature.RECEIVING_CONSTANT_TONE_EXTENSIONS + PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER = 1 << LeFeature.PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER + PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT = 1 << LeFeature.PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT + SLEEP_CLOCK_ACCURACY_UPDATES = 1 << LeFeature.SLEEP_CLOCK_ACCURACY_UPDATES + REMOTE_PUBLIC_KEY_VALIDATION = 1 << LeFeature.REMOTE_PUBLIC_KEY_VALIDATION + CONNECTED_ISOCHRONOUS_STREAM_CENTRAL = 1 << LeFeature.CONNECTED_ISOCHRONOUS_STREAM_CENTRAL + CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL = 1 << LeFeature.CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL + ISOCHRONOUS_BROADCASTER = 1 << LeFeature.ISOCHRONOUS_BROADCASTER + SYNCHRONIZED_RECEIVER = 1 << LeFeature.SYNCHRONIZED_RECEIVER + CONNECTED_ISOCHRONOUS_STREAM = 1 << LeFeature.CONNECTED_ISOCHRONOUS_STREAM + LE_POWER_CONTROL_REQUEST = 1 << LeFeature.LE_POWER_CONTROL_REQUEST + LE_POWER_CONTROL_REQUEST_DUP = 1 << LeFeature.LE_POWER_CONTROL_REQUEST_DUP + LE_PATH_LOSS_MONITORING = 1 << LeFeature.LE_PATH_LOSS_MONITORING + PERIODIC_ADVERTISING_ADI_SUPPORT = 1 << LeFeature.PERIODIC_ADVERTISING_ADI_SUPPORT + CONNECTION_SUBRATING = 1 << LeFeature.CONNECTION_SUBRATING + CONNECTION_SUBRATING_HOST_SUPPORT = 1 << LeFeature.CONNECTION_SUBRATING_HOST_SUPPORT + CHANNEL_CLASSIFICATION = 1 << LeFeature.CHANNEL_CLASSIFICATION + ADVERTISING_CODING_SELECTION = 1 << LeFeature.ADVERTISING_CODING_SELECTION + ADVERTISING_CODING_SELECTION_HOST_SUPPORT = 1 << LeFeature.ADVERTISING_CODING_SELECTION_HOST_SUPPORT + PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_ADVERTISER + PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER = 1 << LeFeature.PERIODIC_ADVERTISING_WITH_RESPONSES_SCANNER # fmt: on