/* * Copyright 2015 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "model/controller/controller_properties.h" #include #include #include #include #include "log.h" #include "packets/hci_packets.h" #include "rootcanal/configuration.pb.h" namespace rootcanal { using namespace bluetooth::hci; static constexpr uint64_t Page0LmpFeatures() { LMPFeaturesPage0Bits features[] = { LMPFeaturesPage0Bits::LMP_3_SLOT_PACKETS, LMPFeaturesPage0Bits::LMP_5_SLOT_PACKETS, LMPFeaturesPage0Bits::ENCRYPTION, LMPFeaturesPage0Bits::SLOT_OFFSET, LMPFeaturesPage0Bits::TIMING_ACCURACY, LMPFeaturesPage0Bits::ROLE_SWITCH, LMPFeaturesPage0Bits::HOLD_MODE, LMPFeaturesPage0Bits::SNIFF_MODE, LMPFeaturesPage0Bits::POWER_CONTROL_REQUESTS, LMPFeaturesPage0Bits::CHANNEL_QUALITY_DRIVEN_DATA_RATE, LMPFeaturesPage0Bits::SCO_LINK, LMPFeaturesPage0Bits::HV2_PACKETS, LMPFeaturesPage0Bits::HV3_PACKETS, LMPFeaturesPage0Bits::M_LAW_LOG_SYNCHRONOUS_DATA, LMPFeaturesPage0Bits::A_LAW_LOG_SYNCHRONOUS_DATA, LMPFeaturesPage0Bits::CVSD_SYNCHRONOUS_DATA, LMPFeaturesPage0Bits::PAGING_PARAMETER_NEGOTIATION, LMPFeaturesPage0Bits::POWER_CONTROL, LMPFeaturesPage0Bits::TRANSPARENT_SYNCHRONOUS_DATA, LMPFeaturesPage0Bits::BROADCAST_ENCRYPTION, LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ACL_2_MB_S_MODE, LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ACL_3_MB_S_MODE, LMPFeaturesPage0Bits::ENHANCED_INQUIRY_SCAN, LMPFeaturesPage0Bits::INTERLACED_INQUIRY_SCAN, LMPFeaturesPage0Bits::INTERLACED_PAGE_SCAN, LMPFeaturesPage0Bits::RSSI_WITH_INQUIRY_RESULTS, LMPFeaturesPage0Bits::EXTENDED_SCO_LINK, LMPFeaturesPage0Bits::EV4_PACKETS, LMPFeaturesPage0Bits::EV5_PACKETS, LMPFeaturesPage0Bits::AFH_CAPABLE_PERIPHERAL, LMPFeaturesPage0Bits::AFH_CLASSIFICATION_PERIPHERAL, LMPFeaturesPage0Bits::LE_SUPPORTED_CONTROLLER, LMPFeaturesPage0Bits::LMP_3_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS, LMPFeaturesPage0Bits::LMP_5_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS, LMPFeaturesPage0Bits::SNIFF_SUBRATING, LMPFeaturesPage0Bits::PAUSE_ENCRYPTION, LMPFeaturesPage0Bits::AFH_CAPABLE_CENTRAL, LMPFeaturesPage0Bits::AFH_CLASSIFICATION_CENTRAL, LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ESCO_2_MB_S_MODE, LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ESCO_3_MB_S_MODE, LMPFeaturesPage0Bits::LMP_3_SLOT_ENHANCED_DATA_RATE_ESCO_PACKETS, LMPFeaturesPage0Bits::EXTENDED_INQUIRY_RESPONSE, LMPFeaturesPage0Bits::SIMULTANEOUS_LE_AND_BR_CONTROLLER, LMPFeaturesPage0Bits::SECURE_SIMPLE_PAIRING_CONTROLLER, LMPFeaturesPage0Bits::ENCAPSULATED_PDU, LMPFeaturesPage0Bits::HCI_LINK_SUPERVISION_TIMEOUT_CHANGED_EVENT, LMPFeaturesPage0Bits::VARIABLE_INQUIRY_TX_POWER_LEVEL, LMPFeaturesPage0Bits::ENHANCED_POWER_CONTROL, LMPFeaturesPage0Bits::EXTENDED_FEATURES}; uint64_t value = 0; for (auto feature : features) { value |= static_cast(feature); } return value; } static constexpr uint64_t Page2LmpFeatures() { LMPFeaturesPage2Bits features[] = { LMPFeaturesPage2Bits::SECURE_CONNECTIONS_CONTROLLER_SUPPORT, LMPFeaturesPage2Bits::PING, }; uint64_t value = 0; for (auto feature : features) { value |= static_cast(feature); } return value; } static constexpr uint64_t LlFeatures() { LLFeaturesBits features[] = { LLFeaturesBits::LE_ENCRYPTION, LLFeaturesBits::CONNECTION_PARAMETERS_REQUEST_PROCEDURE, LLFeaturesBits::EXTENDED_REJECT_INDICATION, LLFeaturesBits::PERIPHERAL_INITIATED_FEATURES_EXCHANGE, LLFeaturesBits::LE_PING, LLFeaturesBits::LL_PRIVACY, LLFeaturesBits::EXTENDED_SCANNER_FILTER_POLICIES, LLFeaturesBits::LE_2M_PHY, LLFeaturesBits::LE_CODED_PHY, LLFeaturesBits::LE_EXTENDED_ADVERTISING, LLFeaturesBits::LE_PERIODIC_ADVERTISING, LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_CENTRAL, LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL, }; uint64_t value = 0; for (auto feature : features) { value |= static_cast(feature); } return value; } static std::array SupportedCommands() { OpCodeIndex supported_commands[] = { // LINK_CONTROL OpCodeIndex::INQUIRY, OpCodeIndex::INQUIRY_CANCEL, // OpCodeIndex::PERIODIC_INQUIRY_MODE, // OpCodeIndex::EXIT_PERIODIC_INQUIRY_MODE, OpCodeIndex::CREATE_CONNECTION, OpCodeIndex::DISCONNECT, OpCodeIndex::ADD_SCO_CONNECTION, OpCodeIndex::CREATE_CONNECTION_CANCEL, OpCodeIndex::ACCEPT_CONNECTION_REQUEST, OpCodeIndex::REJECT_CONNECTION_REQUEST, OpCodeIndex::LINK_KEY_REQUEST_REPLY, OpCodeIndex::LINK_KEY_REQUEST_NEGATIVE_REPLY, OpCodeIndex::PIN_CODE_REQUEST_REPLY, OpCodeIndex::PIN_CODE_REQUEST_NEGATIVE_REPLY, OpCodeIndex::CHANGE_CONNECTION_PACKET_TYPE, OpCodeIndex::AUTHENTICATION_REQUESTED, OpCodeIndex::SET_CONNECTION_ENCRYPTION, OpCodeIndex::CHANGE_CONNECTION_LINK_KEY, OpCodeIndex::CENTRAL_LINK_KEY, OpCodeIndex::REMOTE_NAME_REQUEST, // OpCodeIndex::REMOTE_NAME_REQUEST_CANCEL, OpCodeIndex::READ_REMOTE_SUPPORTED_FEATURES, OpCodeIndex::READ_REMOTE_EXTENDED_FEATURES, OpCodeIndex::READ_REMOTE_VERSION_INFORMATION, OpCodeIndex::READ_CLOCK_OFFSET, OpCodeIndex::READ_LMP_HANDLE, OpCodeIndex::SETUP_SYNCHRONOUS_CONNECTION, OpCodeIndex::ACCEPT_SYNCHRONOUS_CONNECTION, OpCodeIndex::REJECT_SYNCHRONOUS_CONNECTION, OpCodeIndex::IO_CAPABILITY_REQUEST_REPLY, OpCodeIndex::USER_CONFIRMATION_REQUEST_REPLY, OpCodeIndex::USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, OpCodeIndex::USER_PASSKEY_REQUEST_REPLY, OpCodeIndex::USER_PASSKEY_REQUEST_NEGATIVE_REPLY, OpCodeIndex::REMOTE_OOB_DATA_REQUEST_REPLY, OpCodeIndex::REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY, OpCodeIndex::IO_CAPABILITY_REQUEST_NEGATIVE_REPLY, OpCodeIndex::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION, OpCodeIndex::ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION, // OpCodeIndex::TRUNCATED_PAGE, // OpCodeIndex::TRUNCATED_PAGE_CANCEL, // OpCodeIndex::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST, // OpCodeIndex::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE, // OpCodeIndex::START_SYNCHRONIZATION_TRAIN, // OpCodeIndex::RECEIVE_SYNCHRONIZATION_TRAIN, OpCodeIndex::REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY, // LINK_POLICY OpCodeIndex::HOLD_MODE, OpCodeIndex::SNIFF_MODE, OpCodeIndex::EXIT_SNIFF_MODE, OpCodeIndex::QOS_SETUP, OpCodeIndex::ROLE_DISCOVERY, OpCodeIndex::SWITCH_ROLE, OpCodeIndex::READ_LINK_POLICY_SETTINGS, OpCodeIndex::WRITE_LINK_POLICY_SETTINGS, OpCodeIndex::READ_DEFAULT_LINK_POLICY_SETTINGS, OpCodeIndex::WRITE_DEFAULT_LINK_POLICY_SETTINGS, OpCodeIndex::FLOW_SPECIFICATION, OpCodeIndex::SNIFF_SUBRATING, // CONTROLLER_AND_BASEBAND OpCodeIndex::SET_EVENT_MASK, OpCodeIndex::RESET, OpCodeIndex::SET_EVENT_FILTER, OpCodeIndex::FLUSH, // OpCodeIndex::READ_PIN_TYPE, // OpCodeIndex::WRITE_PIN_TYPE, // OpCodeIndex::READ_STORED_LINK_KEY, // OpCodeIndex::WRITE_STORED_LINK_KEY, OpCodeIndex::DELETE_STORED_LINK_KEY, OpCodeIndex::WRITE_LOCAL_NAME, OpCodeIndex::READ_LOCAL_NAME, OpCodeIndex::READ_CONNECTION_ACCEPT_TIMEOUT, OpCodeIndex::WRITE_CONNECTION_ACCEPT_TIMEOUT, OpCodeIndex::READ_PAGE_TIMEOUT, OpCodeIndex::WRITE_PAGE_TIMEOUT, OpCodeIndex::READ_SCAN_ENABLE, OpCodeIndex::WRITE_SCAN_ENABLE, OpCodeIndex::READ_PAGE_SCAN_ACTIVITY, OpCodeIndex::WRITE_PAGE_SCAN_ACTIVITY, OpCodeIndex::READ_INQUIRY_SCAN_ACTIVITY, OpCodeIndex::WRITE_INQUIRY_SCAN_ACTIVITY, OpCodeIndex::READ_AUTHENTICATION_ENABLE, OpCodeIndex::WRITE_AUTHENTICATION_ENABLE, OpCodeIndex::READ_CLASS_OF_DEVICE, OpCodeIndex::WRITE_CLASS_OF_DEVICE, OpCodeIndex::READ_VOICE_SETTING, OpCodeIndex::WRITE_VOICE_SETTING, OpCodeIndex::READ_AUTOMATIC_FLUSH_TIMEOUT, OpCodeIndex::WRITE_AUTOMATIC_FLUSH_TIMEOUT, // OpCodeIndex::READ_NUM_BROADCAST_RETRANSMITS, // OpCodeIndex::WRITE_NUM_BROADCAST_RETRANSMITS, OpCodeIndex::READ_HOLD_MODE_ACTIVITY, OpCodeIndex::WRITE_HOLD_MODE_ACTIVITY, OpCodeIndex::READ_TRANSMIT_POWER_LEVEL, OpCodeIndex::READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE, OpCodeIndex::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE, OpCodeIndex::SET_CONTROLLER_TO_HOST_FLOW_CONTROL, OpCodeIndex::HOST_BUFFER_SIZE, OpCodeIndex::HOST_NUMBER_OF_COMPLETED_PACKETS, OpCodeIndex::READ_LINK_SUPERVISION_TIMEOUT, OpCodeIndex::WRITE_LINK_SUPERVISION_TIMEOUT, OpCodeIndex::READ_NUMBER_OF_SUPPORTED_IAC, OpCodeIndex::READ_CURRENT_IAC_LAP, OpCodeIndex::WRITE_CURRENT_IAC_LAP, OpCodeIndex::SET_AFH_HOST_CHANNEL_CLASSIFICATION, OpCodeIndex::READ_INQUIRY_SCAN_TYPE, OpCodeIndex::WRITE_INQUIRY_SCAN_TYPE, OpCodeIndex::READ_INQUIRY_MODE, OpCodeIndex::WRITE_INQUIRY_MODE, OpCodeIndex::READ_PAGE_SCAN_TYPE, OpCodeIndex::WRITE_PAGE_SCAN_TYPE, OpCodeIndex::READ_AFH_CHANNEL_ASSESSMENT_MODE, OpCodeIndex::WRITE_AFH_CHANNEL_ASSESSMENT_MODE, OpCodeIndex::READ_EXTENDED_INQUIRY_RESPONSE, OpCodeIndex::WRITE_EXTENDED_INQUIRY_RESPONSE, OpCodeIndex::REFRESH_ENCRYPTION_KEY, OpCodeIndex::READ_SIMPLE_PAIRING_MODE, OpCodeIndex::WRITE_SIMPLE_PAIRING_MODE, OpCodeIndex::READ_LOCAL_OOB_DATA, OpCodeIndex::READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL, OpCodeIndex::WRITE_INQUIRY_TRANSMIT_POWER_LEVEL, // OpCodeIndex::READ_DEFAULT_ERRONEOUS_DATA_REPORTING, // OpCodeIndex::WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING, OpCodeIndex::ENHANCED_FLUSH, OpCodeIndex::SEND_KEYPRESS_NOTIFICATION, OpCodeIndex::SET_EVENT_MASK_PAGE_2, // OpCodeIndex::READ_FLOW_CONTROL_MODE, // OpCodeIndex::WRITE_FLOW_CONTROL_MODE, OpCodeIndex::READ_ENHANCED_TRANSMIT_POWER_LEVEL, OpCodeIndex::READ_LE_HOST_SUPPORT, OpCodeIndex::WRITE_LE_HOST_SUPPORT, // OpCodeIndex::SET_MWS_CHANNEL_PARAMETERS, // OpCodeIndex::SET_EXTERNAL_FRAME_CONFIGURATION, // OpCodeIndex::SET_MWS_SIGNALING, // OpCodeIndex::SET_MWS_TRANSPORT_LAYER, // OpCodeIndex::SET_MWS_SCAN_FREQUENCY_TABLE, // OpCodeIndex::SET_MWS_PATTERN_CONFIGURATION, // OpCodeIndex::SET_RESERVED_LT_ADDR, // OpCodeIndex::DELETE_RESERVED_LT_ADDR, // OpCodeIndex::SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA, // OpCodeIndex::READ_SYNCHRONIZATION_TRAIN_PARAMETERS, // OpCodeIndex::WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS, OpCodeIndex::READ_SECURE_CONNECTIONS_HOST_SUPPORT, OpCodeIndex::WRITE_SECURE_CONNECTIONS_HOST_SUPPORT, OpCodeIndex::READ_AUTHENTICATED_PAYLOAD_TIMEOUT, OpCodeIndex::WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT, OpCodeIndex::READ_LOCAL_OOB_EXTENDED_DATA, // OpCodeIndex::READ_EXTENDED_PAGE_TIMEOUT, // OpCodeIndex::WRITE_EXTENDED_PAGE_TIMEOUT, // OpCodeIndex::READ_EXTENDED_INQUIRY_LENGTH, // OpCodeIndex::WRITE_EXTENDED_INQUIRY_LENGTH, // OpCodeIndex::SET_ECOSYSTEM_BASE_INTERVAL, // OpCodeIndex::CONFIGURE_DATA_PATH, // OpCodeIndex::SET_MIN_ENCRYPTION_KEY_SIZE, // INFORMATIONAL_PARAMETERS OpCodeIndex::READ_LOCAL_VERSION_INFORMATION, OpCodeIndex::READ_LOCAL_SUPPORTED_FEATURES, OpCodeIndex::READ_LOCAL_EXTENDED_FEATURES, OpCodeIndex::READ_BUFFER_SIZE, OpCodeIndex::READ_BD_ADDR, // OpCodeIndex::READ_DATA_BLOCK_SIZE, OpCodeIndex::READ_LOCAL_SUPPORTED_CODECS_V1, // OpCodeIndex::READ_LOCAL_SIMPLE_PAIRING_OPTIONS, // OpCodeIndex::READ_LOCAL_SUPPORTED_CODECS_V2, // OpCodeIndex::READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES, // OpCodeIndex::READ_LOCAL_SUPPORTED_CONTROLLER_DELAY, // STATUS_PARAMETERS OpCodeIndex::READ_FAILED_CONTACT_COUNTER, OpCodeIndex::RESET_FAILED_CONTACT_COUNTER, // OpCodeIndex::READ_LINK_QUALITY, OpCodeIndex::READ_RSSI, OpCodeIndex::READ_AFH_CHANNEL_MAP, // OpCodeIndex::READ_CLOCK, OpCodeIndex::READ_ENCRYPTION_KEY_SIZE, // OpCodeIndex::GET_MWS_TRANSPORT_LAYER_CONFIGURATION, // OpCodeIndex::SET_TRIGGERED_CLOCK_CAPTURE, // TESTING OpCodeIndex::READ_LOOPBACK_MODE, OpCodeIndex::WRITE_LOOPBACK_MODE, OpCodeIndex::ENABLE_DEVICE_UNDER_TEST_MODE, OpCodeIndex::WRITE_SIMPLE_PAIRING_DEBUG_MODE, OpCodeIndex::WRITE_SECURE_CONNECTIONS_TEST_MODE, // LE_CONTROLLER OpCodeIndex::LE_SET_EVENT_MASK, OpCodeIndex::LE_READ_BUFFER_SIZE_V1, OpCodeIndex::LE_READ_LOCAL_SUPPORTED_FEATURES, OpCodeIndex::LE_SET_RANDOM_ADDRESS, OpCodeIndex::LE_SET_ADVERTISING_PARAMETERS, OpCodeIndex::LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER, OpCodeIndex::LE_SET_ADVERTISING_DATA, OpCodeIndex::LE_SET_SCAN_RESPONSE_DATA, OpCodeIndex::LE_SET_ADVERTISING_ENABLE, OpCodeIndex::LE_SET_SCAN_PARAMETERS, OpCodeIndex::LE_SET_SCAN_ENABLE, OpCodeIndex::LE_CREATE_CONNECTION, OpCodeIndex::LE_CREATE_CONNECTION_CANCEL, OpCodeIndex::LE_READ_FILTER_ACCEPT_LIST_SIZE, OpCodeIndex::LE_CLEAR_FILTER_ACCEPT_LIST, OpCodeIndex::LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST, OpCodeIndex::LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST, OpCodeIndex::LE_CONNECTION_UPDATE, OpCodeIndex::LE_SET_HOST_CHANNEL_CLASSIFICATION, OpCodeIndex::LE_READ_CHANNEL_MAP, OpCodeIndex::LE_READ_REMOTE_FEATURES, OpCodeIndex::LE_ENCRYPT, OpCodeIndex::LE_RAND, OpCodeIndex::LE_START_ENCRYPTION, OpCodeIndex::LE_LONG_TERM_KEY_REQUEST_REPLY, OpCodeIndex::LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY, OpCodeIndex::LE_READ_SUPPORTED_STATES, OpCodeIndex::LE_RECEIVER_TEST_V1, OpCodeIndex::LE_TRANSMITTER_TEST_V1, OpCodeIndex::LE_TEST_END, OpCodeIndex::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY, OpCodeIndex::LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY, // OpCodeIndex::LE_SET_DATA_LENGTH, OpCodeIndex::LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH, OpCodeIndex::LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH, // OpCodeIndex::LE_READ_LOCAL_P_256_PUBLIC_KEY, // OpCodeIndex::LE_GENERATE_DHKEY_V1, OpCodeIndex::LE_ADD_DEVICE_TO_RESOLVING_LIST, OpCodeIndex::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST, OpCodeIndex::LE_CLEAR_RESOLVING_LIST, OpCodeIndex::LE_READ_RESOLVING_LIST_SIZE, OpCodeIndex::LE_READ_PEER_RESOLVABLE_ADDRESS, OpCodeIndex::LE_READ_LOCAL_RESOLVABLE_ADDRESS, OpCodeIndex::LE_SET_ADDRESS_RESOLUTION_ENABLE, OpCodeIndex::LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT, OpCodeIndex::LE_READ_MAXIMUM_DATA_LENGTH, OpCodeIndex::LE_READ_PHY, OpCodeIndex::LE_SET_DEFAULT_PHY, OpCodeIndex::LE_SET_PHY, // OpCodeIndex::LE_RECEIVER_TEST_V2, // OpCodeIndex::LE_TRANSMITTER_TEST_V2, OpCodeIndex::LE_SET_ADVERTISING_SET_RANDOM_ADDRESS, OpCodeIndex::LE_SET_EXTENDED_ADVERTISING_PARAMETERS, OpCodeIndex::LE_SET_EXTENDED_ADVERTISING_DATA, OpCodeIndex::LE_SET_EXTENDED_SCAN_RESPONSE_DATA, OpCodeIndex::LE_SET_EXTENDED_ADVERTISING_ENABLE, OpCodeIndex::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH, OpCodeIndex::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS, OpCodeIndex::LE_REMOVE_ADVERTISING_SET, OpCodeIndex::LE_CLEAR_ADVERTISING_SETS, OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_PARAMETERS, OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_DATA, OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_ENABLE, OpCodeIndex::LE_SET_EXTENDED_SCAN_PARAMETERS, OpCodeIndex::LE_SET_EXTENDED_SCAN_ENABLE, OpCodeIndex::LE_EXTENDED_CREATE_CONNECTION, OpCodeIndex::LE_PERIODIC_ADVERTISING_CREATE_SYNC, OpCodeIndex::LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL, OpCodeIndex::LE_PERIODIC_ADVERTISING_TERMINATE_SYNC, OpCodeIndex::LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST, OpCodeIndex::LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST, OpCodeIndex::LE_CLEAR_PERIODIC_ADVERTISER_LIST, OpCodeIndex::LE_READ_PERIODIC_ADVERTISER_LIST_SIZE, // OpCodeIndex::LE_READ_TRANSMIT_POWER, OpCodeIndex::LE_READ_RF_PATH_COMPENSATION_POWER, OpCodeIndex::LE_WRITE_RF_PATH_COMPENSATION_POWER, OpCodeIndex::LE_SET_PRIVACY_MODE, // OpCodeIndex::LE_RECEIVER_TEST_V3, // OpCodeIndex::LE_TRANSMITTER_TEST_V3, // OpCodeIndex::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS, // OpCodeIndex::LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE, // OpCodeIndex::LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE, // OpCodeIndex::LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS, // OpCodeIndex::LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS, // OpCodeIndex::LE_CONNECTION_CTE_REQUEST_ENABLE, // OpCodeIndex::LE_CONNECTION_CTE_RESPONSE_ENABLE, // OpCodeIndex::LE_READ_ANTENNA_INFORMATION, // OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE, // OpCodeIndex::LE_PERIODIC_ADVERTISING_SYNC_TRANSFER, // OpCodeIndex::LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER, // OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS, // OpCodeIndex::LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS, // OpCodeIndex::LE_GENERATE_DHKEY_V2, // OpCodeIndex::LE_MODIFY_SLEEP_CLOCK_ACCURACY, OpCodeIndex::LE_READ_BUFFER_SIZE_V2, // OpCodeIndex::LE_READ_ISO_TX_SYNC, OpCodeIndex::LE_SET_CIG_PARAMETERS, OpCodeIndex::LE_SET_CIG_PARAMETERS_TEST, OpCodeIndex::LE_CREATE_CIS, OpCodeIndex::LE_REMOVE_CIG, OpCodeIndex::LE_ACCEPT_CIS_REQUEST, OpCodeIndex::LE_REJECT_CIS_REQUEST, // OpCodeIndex::LE_CREATE_BIG, // OpCodeIndex::LE_CREATE_BIG_TEST, // OpCodeIndex::LE_TERMINATE_BIG, // OpCodeIndex::LE_BIG_CREATE_SYNC, // OpCodeIndex::LE_BIG_TERMINATE_SYNC, OpCodeIndex::LE_REQUEST_PEER_SCA, OpCodeIndex::LE_SETUP_ISO_DATA_PATH, OpCodeIndex::LE_REMOVE_ISO_DATA_PATH, // OpCodeIndex::LE_ISO_TRANSMIT_TEST, // OpCodeIndex::LE_ISO_RECEIVE_TEST, // OpCodeIndex::LE_ISO_READ_TEST_COUNTERS, // OpCodeIndex::LE_ISO_TEST_END, OpCodeIndex::LE_SET_HOST_FEATURE, // OpCodeIndex::LE_READ_ISO_LINK_QUALITY, // OpCodeIndex::LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL, // OpCodeIndex::LE_READ_REMOTE_TRANSMIT_POWER_LEVEL, // OpCodeIndex::LE_SET_PATH_LOSS_REPORTING_PARAMETERS, // OpCodeIndex::LE_SET_PATH_LOSS_REPORTING_ENABLE, // OpCodeIndex::LE_SET_TRANSMIT_POWER_REPORTING_ENABLE, // OpCodeIndex::LE_TRANSMITTER_TEST_V4, // OpCodeIndex::LE_SET_DATA_RELATED_ADDRESS_CHANGES, // OpCodeIndex::LE_SET_DEFAULT_SUBRATE, // OpCodeIndex::LE_SUBRATE_REQUEST, }; std::array value{}; for (auto command : supported_commands) { int index = static_cast(command); value[index / 10] |= 1U << (index % 10); } return value; } bool ControllerProperties::CheckSupportedFeatures() const { // Vol 2, Part C § 3.3 Feature mask definition. // Check for reserved or deprecated feature bits. // // Note: the specification for v1.0 and v1.1 is no longer available for // download, the reserved feature bits are copied over from v1.2. uint64_t lmp_page_0_reserved_bits = 0; uint64_t lmp_page_2_reserved_bits = 0; switch (lmp_version) { case bluetooth::hci::LmpVersion::V_1_0B: lmp_page_0_reserved_bits = UINT64_C(0x7fffe7e407000000); lmp_page_2_reserved_bits = UINT64_C(0xffffffffffffffff); break; case bluetooth::hci::LmpVersion::V_1_1: lmp_page_0_reserved_bits = UINT64_C(0x7fffe7e407000000); lmp_page_2_reserved_bits = UINT64_C(0xffffffffffffffff); break; case bluetooth::hci::LmpVersion::V_1_2: lmp_page_0_reserved_bits = UINT64_C(0x7fffe7e407000000); lmp_page_2_reserved_bits = UINT64_C(0xffffffffffffffff); break; case bluetooth::hci::LmpVersion::V_2_0: lmp_page_0_reserved_bits = UINT64_C(0x7fff066401000000); lmp_page_2_reserved_bits = UINT64_C(0xffffffffffffffff); break; case bluetooth::hci::LmpVersion::V_2_1: lmp_page_0_reserved_bits = UINT64_C(0x7c86006401000000); lmp_page_2_reserved_bits = UINT64_C(0xffffffffffffffff); break; case bluetooth::hci::LmpVersion::V_3_0: lmp_page_0_reserved_bits = UINT64_C(0x7886006401000000); lmp_page_2_reserved_bits = UINT64_C(0xffffffffffffffff); break; case bluetooth::hci::LmpVersion::V_4_0: lmp_page_0_reserved_bits = UINT64_C(0x7884000401000000); lmp_page_2_reserved_bits = UINT64_C(0xffffffffffffffff); break; case bluetooth::hci::LmpVersion::V_4_1: lmp_page_0_reserved_bits = UINT64_C(0x7884000401000000); lmp_page_2_reserved_bits = UINT64_C(0xfffffffffffff480); break; case bluetooth::hci::LmpVersion::V_4_2: lmp_page_0_reserved_bits = UINT64_C(0x7884000401000000); lmp_page_2_reserved_bits = UINT64_C(0xfffffffffffff480); break; case bluetooth::hci::LmpVersion::V_5_0: lmp_page_0_reserved_bits = UINT64_C(0x7884000401000100); lmp_page_2_reserved_bits = UINT64_C(0xfffffffffffff480); break; case bluetooth::hci::LmpVersion::V_5_1: lmp_page_0_reserved_bits = UINT64_C(0x7884000401000100); lmp_page_2_reserved_bits = UINT64_C(0xfffffffffffff080); break; case bluetooth::hci::LmpVersion::V_5_2: lmp_page_0_reserved_bits = UINT64_C(0x7884000401000100); lmp_page_2_reserved_bits = UINT64_C(0xfffffffffffff080); break; case bluetooth::hci::LmpVersion::V_5_3: default: lmp_page_0_reserved_bits = UINT64_C(0x7884000401000100); lmp_page_2_reserved_bits = UINT64_C(0xfffffffffffff080); break; } if ((lmp_page_0_reserved_bits & lmp_features[0]) != 0) { INFO( "The page 0 feature bits 0x{:016x}" " are reserved in the specification {}", lmp_page_0_reserved_bits & lmp_features[0], LmpVersionText(lmp_version)); return false; } if ((lmp_page_2_reserved_bits & lmp_features[2]) != 0) { INFO( "The page 2 feature bits 0x{:016x}" " are reserved in the specification {}", lmp_page_2_reserved_bits & lmp_features[2], LmpVersionText(lmp_version)); return false; } // Vol 2, Part C § 3.5 Feature requirements. // RootCanal always support BR/EDR mode, this function implements // the feature requirements from the subsection 1. Devices supporting BR/EDR. // // Note: the feature requirements were introduced in version v5.1 of the // specification, for previous versions it is assumed that the same // requirements apply for the subset of defined feature bits. // The features listed in Table 3.5 are mandatory in this version of the // specification (see Section 3.1) and these feature bits shall be set. if (!SupportsLMPFeature(LMPFeaturesPage0Bits::ENCRYPTION) || !SupportsLMPFeature( LMPFeaturesPage0Bits::SECURE_SIMPLE_PAIRING_CONTROLLER) || !SupportsLMPFeature(LMPFeaturesPage0Bits::ENCAPSULATED_PDU)) { INFO("Table 3.5 validation failed"); return false; } // The features listed in Table 3.6 are forbidden in this version of the // specification and these feature bits shall not be set. if (SupportsLMPFeature(LMPFeaturesPage0Bits::BR_EDR_NOT_SUPPORTED)) { INFO("Table 3.6 validation failed"); return false; } // For each row of Table 3.7, either every feature named in that row shall be // supported or none of the features named in that row shall be supported. if (SupportsLMPFeature(LMPFeaturesPage0Bits::SNIFF_MODE) != SupportsLMPFeature(LMPFeaturesPage0Bits::SNIFF_SUBRATING)) { INFO("Table 3.7 validation failed"); return false; } // For each row of Table 3.8, not more than one feature in that row shall be // supported. if (SupportsLMPFeature(LMPFeaturesPage0Bits::BROADCAST_ENCRYPTION) && SupportsLMPFeature(LMPFeaturesPage2Bits::COARSE_CLOCK_ADJUSTMENT)) { INFO("Table 3.8 validation failed"); return false; } // For each row of Table 3.9, if the feature named in the first column is // supported then the feature named in the second column shall be supported. if (SupportsLMPFeature(LMPFeaturesPage0Bits::ROLE_SWITCH) && !SupportsLMPFeature(LMPFeaturesPage0Bits::SLOT_OFFSET)) { INFO("Table 3.9 validation failed; expected Slot Offset"); return false; } if (SupportsLMPFeature(LMPFeaturesPage0Bits::HV2_PACKETS) && !SupportsLMPFeature(LMPFeaturesPage0Bits::SCO_LINK)) { INFO("Table 3.9 validation failed; expected Sco Link"); return false; } if (SupportsLMPFeature(LMPFeaturesPage0Bits::HV3_PACKETS) && !SupportsLMPFeature(LMPFeaturesPage0Bits::SCO_LINK)) { INFO("Table 3.9 validation failed; expected Sco Link"); return false; } if (SupportsLMPFeature(LMPFeaturesPage0Bits::M_LAW_LOG_SYNCHRONOUS_DATA) && !SupportsLMPFeature(LMPFeaturesPage0Bits::SCO_LINK) && !SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_SCO_LINK)) { INFO("Table 3.9 validation failed; expected Sco Link or Extended Sco Link"); return false; } if (SupportsLMPFeature(LMPFeaturesPage0Bits::A_LAW_LOG_SYNCHRONOUS_DATA) && !SupportsLMPFeature(LMPFeaturesPage0Bits::SCO_LINK) && !SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_SCO_LINK)) { INFO("Table 3.9 validation failed; expected Sco Link or Extended Sco Link"); return false; } if (SupportsLMPFeature(LMPFeaturesPage0Bits::CVSD_SYNCHRONOUS_DATA) && !SupportsLMPFeature(LMPFeaturesPage0Bits::SCO_LINK) && !SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_SCO_LINK)) { INFO("Table 3.9 validation failed; expected Sco Link or Extended Sco Link"); return false; } if (SupportsLMPFeature(LMPFeaturesPage0Bits::TRANSPARENT_SYNCHRONOUS_DATA) && !SupportsLMPFeature(LMPFeaturesPage0Bits::SCO_LINK) && !SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_SCO_LINK)) { INFO("Table 3.9 validation failed; expected Sco Link or Extended Sco Link"); return false; } if (SupportsLMPFeature( LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ACL_3_MB_S_MODE) && !SupportsLMPFeature( LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ACL_2_MB_S_MODE)) { INFO( "Table 3.9 validation failed; expected Enhanced Data Rate ACL 2Mb/s " "mode"); return false; } if (SupportsLMPFeature(LMPFeaturesPage0Bits::EV4_PACKETS) && !SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_SCO_LINK)) { INFO("Table 3.9 validation failed; expected Extended Sco Link"); return false; } if (SupportsLMPFeature(LMPFeaturesPage0Bits::EV5_PACKETS) && !SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_SCO_LINK)) { INFO("Table 3.9 validation failed; expected Extended Sco Link"); return false; } if (SupportsLMPFeature(LMPFeaturesPage0Bits::AFH_CLASSIFICATION_PERIPHERAL) && !SupportsLMPFeature(LMPFeaturesPage0Bits::AFH_CAPABLE_PERIPHERAL)) { INFO("Table 3.9 validation failed; expected AFH Capable Peripheral"); return false; } if (SupportsLMPFeature( LMPFeaturesPage0Bits::LMP_3_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS) && !SupportsLMPFeature( LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ACL_2_MB_S_MODE)) { INFO( "Table 3.9 validation failed; expected Enhanced Data Rate ACL 2Mb/s " "mode"); return false; } if (SupportsLMPFeature( LMPFeaturesPage0Bits::LMP_5_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS) && !SupportsLMPFeature( LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ACL_2_MB_S_MODE)) { INFO( "Table 3.9 validation failed; expected Enhanced Data Rate ACL 2Mb/s " "mode"); return false; } if (SupportsLMPFeature(LMPFeaturesPage0Bits::AFH_CLASSIFICATION_CENTRAL) && !SupportsLMPFeature(LMPFeaturesPage0Bits::AFH_CAPABLE_CENTRAL)) { INFO("Table 3.9 validation failed; expected AFH Capable Central"); return false; } if (SupportsLMPFeature( LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ESCO_2_MB_S_MODE) && !SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_SCO_LINK)) { INFO("Table 3.9 validation failed; expected Extended Sco Link"); return false; } if (SupportsLMPFeature( LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ESCO_3_MB_S_MODE) && !SupportsLMPFeature( LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ESCO_2_MB_S_MODE)) { INFO( "Table 3.9 validation failed; expected Enhanced Data Rate eSCO 2Mb/s " "mode"); return false; } if (SupportsLMPFeature( LMPFeaturesPage0Bits::LMP_3_SLOT_ENHANCED_DATA_RATE_ESCO_PACKETS) && !SupportsLMPFeature( LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ESCO_2_MB_S_MODE)) { INFO( "Table 3.9 validation failed; expected Enhanced Data Rate eSCO 2Mb/s " "mode"); return false; } if (SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_INQUIRY_RESPONSE) && !SupportsLMPFeature(LMPFeaturesPage0Bits::RSSI_WITH_INQUIRY_RESULTS)) { INFO("Table 3.9 validation failed; expected RSSI with Inquiry Results"); return false; } if (SupportsLMPFeature( LMPFeaturesPage0Bits::SIMULTANEOUS_LE_AND_BR_CONTROLLER) && !SupportsLMPFeature(LMPFeaturesPage0Bits::LE_SUPPORTED_CONTROLLER)) { INFO("Table 3.9 validation failed; expected LE Supported (Controller)"); return false; } if (SupportsLMPFeature(LMPFeaturesPage0Bits::ERRONEOUS_DATA_REPORTING) && !SupportsLMPFeature(LMPFeaturesPage0Bits::SCO_LINK) && !SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_SCO_LINK)) { INFO("Table 3.9 validation failed; expected Sco Link or Extended Sco Link"); return false; } if (SupportsLMPFeature(LMPFeaturesPage0Bits::ENHANCED_POWER_CONTROL) && (!SupportsLMPFeature(LMPFeaturesPage0Bits::POWER_CONTROL_REQUESTS) || !SupportsLMPFeature(LMPFeaturesPage0Bits::POWER_CONTROL))) { INFO( "Table 3.9 validation failed; expected Power Control Request and Power " "Control"); return false; } if (SupportsLMPFeature( LMPFeaturesPage2Bits:: CONNECTIONLESS_PERIPHERAL_BROADCAST_TRANSMITTER_OPERATION) && !SupportsLMPFeature(LMPFeaturesPage2Bits::SYNCHRONIZATION_TRAIN)) { INFO("Table 3.9 validation failed; expected Synchronization Train"); return false; } if (SupportsLMPFeature( LMPFeaturesPage2Bits:: CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVER_OPERATION) && !SupportsLMPFeature(LMPFeaturesPage2Bits::SYNCHRONIZATION_SCAN)) { INFO("Table 3.9 validation failed; expected Synchronization Scan"); return false; } if (SupportsLMPFeature(LMPFeaturesPage2Bits::GENERALIZED_INTERLACED_SCAN) && !SupportsLMPFeature(LMPFeaturesPage0Bits::INTERLACED_INQUIRY_SCAN) && !SupportsLMPFeature(LMPFeaturesPage0Bits::INTERLACED_PAGE_SCAN)) { INFO( "Table 3.9 validation failed; expected Interlaced Inquiry Scan or " "Interlaced Page Scan"); return false; } if (SupportsLMPFeature(LMPFeaturesPage2Bits::COARSE_CLOCK_ADJUSTMENT) && (!SupportsLMPFeature(LMPFeaturesPage0Bits::AFH_CAPABLE_PERIPHERAL) || !SupportsLMPFeature(LMPFeaturesPage0Bits::AFH_CAPABLE_CENTRAL) || !SupportsLMPFeature(LMPFeaturesPage2Bits::SYNCHRONIZATION_TRAIN) || !SupportsLMPFeature(LMPFeaturesPage2Bits::SYNCHRONIZATION_SCAN))) { INFO( "Table 3.9 validation failed; expected AFH Capable Central/Peripheral " "and Synchronization Train/Scan"); return false; } if (SupportsLMPFeature( LMPFeaturesPage2Bits::SECURE_CONNECTIONS_CONTROLLER_SUPPORT) && (!SupportsLMPFeature(LMPFeaturesPage0Bits::PAUSE_ENCRYPTION) || !SupportsLMPFeature(LMPFeaturesPage2Bits::PING))) { INFO("Table 3.9 validation failed; expected Pause Encryption and Ping"); return false; } return true; } bool ControllerProperties::CheckSupportedCommands() const { // Vol 4, Part E § 3 Overview of commands and events. // // A Controller shall support the command or event if it is shown as mandatory // for at least one of the transports (i.e. BR/EDR or LE) that the Controller // supports, otherwise the Controller may support the command or event if it // is shown as optional for at least one of the transports that the Controller // supports, otherwise it shall not support the command or event. // // RootCanal always support BR/EDR and LE modes, this function implements // the feature requirements from both BR/EDR and LE commands. // Some controller features are always set as supported in the RootCanal // controller: // - The controller supports transmitting packets. // - The controller supports receiving packets. // - The controller supports Connection State. // - The controller supports Initiating State. // - The controller supports Synchronization State. // - The controller supports Scanning State. // - The controller supports Advertising State. // - The controller supports Central Role. // - The controller supports Peripheral Role. // - The controller supports LE transport. // - The controller supports Inquiry. // Some controller features are always set as not supported in the RootCanal // controller: // - The controller can not change its sleep clock accuracy. // - The controller does not support Test Mode. // - The controller does not support Data block based flow control. // - The controller does not support Truncated Page State. enum Requirement { kMandatory, kOptional, kExcluded, }; constexpr auto mandatory = kMandatory; constexpr auto optional = kOptional; constexpr auto excluded = kExcluded; auto mandatory_or_excluded = [](bool cond) { return cond ? kMandatory : kExcluded; }; auto mandatory_or_optional = [](bool cond) { return cond ? kMandatory : kOptional; }; auto optional_or_excluded = [](bool cond) { return cond ? kMandatory : kExcluded; }; auto mandatory_or_optional_or_excluded = [](bool cond1, bool cond2) { return cond1 ? kMandatory : cond2 ? kOptional : kExcluded; }; // A Controller shall support the command or event if it is shown as // mandatory for at least one of the transports (i.e. BR/EDR or LE) that // the Controller supports, otherwise the Controller may support the command // or event if it is shown as optional for at least one of the transports // that the Controller supports, otherwise it shall not support the // command or event. auto check_command_requirement = [](bool br_supported, Requirement br_requirement, bool le_supported, Requirement le_requirement, bool command_supported) { Requirement command_requirement = !br_supported ? le_requirement : !le_supported ? br_requirement : le_requirement == kMandatory || br_requirement == kMandatory ? kMandatory : le_requirement == kOptional || br_requirement == kOptional ? kOptional : kExcluded; if (command_requirement == kMandatory && !command_supported) { return false; } if (command_requirement == kExcluded && command_supported) { return false; } return true; }; // C1: Mandatory if the LE Controller supports transmitting packets, otherwise // excluded. auto c1 = mandatory; // C2: Mandatory if the LE Controller supports receiving packets, otherwise // excluded. auto c2 = mandatory; // C3: Mandatory if the LE Controller supports Connection State, otherwise // excluded. auto c3 = mandatory; // C4: Mandatory if LE Feature (LE Encryption) is supported, otherwise // excluded. auto c4 = mandatory_or_excluded(SupportsLLFeature(LLFeaturesBits::LE_ENCRYPTION)); // C6: Mandatory if LE Feature (Connection Parameters Request procedure) is // supported, otherwise excluded. auto c6 = mandatory_or_excluded(SupportsLLFeature( LLFeaturesBits::CONNECTION_PARAMETERS_REQUEST_PROCEDURE)); // C7: Mandatory if LE Feature (LE Encryption) and LE Feature (LE Ping) are // supported, otherwise excluded. auto c7 = mandatory_or_excluded(SupportsLLFeature(LLFeaturesBits::LE_ENCRYPTION) && SupportsLLFeature(LLFeaturesBits::LE_PING)); // C8: Mandatory if LE Feature (LE Data Packet Length Extension) is supported, // otherwise optional. auto c8 = mandatory_or_optional( SupportsLLFeature(LLFeaturesBits::LE_DATA_PACKET_LENGTH_EXTENSION)); // C9: Mandatory if LE Feature (LL Privacy) is supported, otherwise excluded. auto c9 = mandatory_or_excluded(SupportsLLFeature(LLFeaturesBits::LL_PRIVACY)); // C10: Optional if LE Feature (LL Privacy) is supported, otherwise excluded. auto c10 = optional_or_excluded(SupportsLLFeature(LLFeaturesBits::LL_PRIVACY)); // C11: Mandatory if LE Feature (LE 2M PHY) or LE Feature (LE Coded PHY) is // supported, otherwise optional. auto c11 = mandatory_or_optional(SupportsLLFeature(LLFeaturesBits::LE_2M_PHY) || SupportsLLFeature(LLFeaturesBits::LE_CODED_PHY)); // C12: Mandatory if LE Feature (LE 2M PHY) or LE Feature (LE Coded PHY) or // LE Feature (Stable Modulation Index - Transmitter) is supported, otherwise // optional if the LE Controller supports transmitting packets, otherwise // excluded. auto c12 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::LE_2M_PHY) || SupportsLLFeature(LLFeaturesBits::LE_CODED_PHY) || SupportsLLFeature(LLFeaturesBits::STABLE_MODULATION_INDEX_TRANSMITTER)); // C13: Mandatory if LE Feature (LE 2M PHY) or LE Feature (LE Coded PHY) or LE // Feature (Stable Modulation Index - Receiver) is supported, otherwise // optional if the LE Controller supports receiving packets, otherwise // excluded. auto c13 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::LE_2M_PHY) || SupportsLLFeature(LLFeaturesBits::LE_CODED_PHY) || SupportsLLFeature(LLFeaturesBits::STABLE_MODULATION_INDEX_RECEIVER)); // C15: Mandatory if LE Controller supports transmitting scannable // advertisements, otherwise excluded. auto c15 = mandatory; // C16: Mandatory if LE Feature (Periodic Advertising) is supported and the LE // Controller supports both Scanning State and Synchronization State, // otherwise excluded. auto c16 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::LE_PERIODIC_ADVERTISING)); // C17: Mandatory if LE Feature (Extended Advertising) is supported and the LE // Controller supports Advertising State, otherwise excluded. auto c17 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::LE_EXTENDED_ADVERTISING)); // C18: Mandatory if LE Feature (Periodic Advertising) is supported and the LE // Controller supports Advertising State, otherwise excluded. auto c18 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::LE_PERIODIC_ADVERTISING)); // C19: Mandatory if LE Feature (Extended Advertising) is supported and the LE // Controller supports Scanning State, otherwise excluded. auto c19 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::LE_EXTENDED_ADVERTISING)); // C20: Mandatory if LE Feature (Extended Advertising) is supported and the LE // Controller supports Initiating State, otherwise excluded. auto c20 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::LE_EXTENDED_ADVERTISING)); // C21: Mandatory if LE Feature (Periodic Advertising) is supported and the LE // Controller supports Synchronization State, otherwise excluded. auto c21 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::LE_PERIODIC_ADVERTISING)); // C22: Mandatory if the LE Controller supports sending Transmit Power in // advertisements or if LE Feature (LE Power Control Request) is supported, // otherwise optional. auto c22 = mandatory; // C23: Mandatory if LE Feature (LE Channel Selection Algorithm #2) is // supported, otherwise excluded. // // C24: Mandatory if the LE Controller supports // Connection State and either LE Feature (LL Privacy) or LE Feature (Extended // Advertising) is supported, otherwise optional if the LE Controller supports // Connection State, otherwise excluded. // // C25: Mandatory if LE Feature // (Connection CTE Request) is supported, otherwise excluded. auto c25 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::CONNECTION_CTE_REQUEST)); // C26: Mandatory if LE Feature (Connection CTE Response) is supported, // otherwise excluded. auto c26 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::CONNECTION_CTE_RESPONSE)); // C27: Mandatory if LE Feature (Connectionless CTE Transmitter) is supported, // otherwise excluded. auto c27 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::CONNECTIONLESS_CTE_TRANSMITTER)); // C28: Mandatory if LE Feature (Connectionless CTE Receiver) is supported, // otherwise excluded. auto c28 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::CONNECTIONLESS_CTE_RECEIVER)); // C29: Mandatory if LE Feature (Connection CTE Response) or LE Feature // (Connectionless CTE Transmitter) is supported, otherwise optional if the LE // Controller supports transmitting packets, otherwise excluded. auto c29 = mandatory_or_optional( SupportsLLFeature(LLFeaturesBits::CONNECTION_CTE_RESPONSE) || SupportsLLFeature(LLFeaturesBits::CONNECTIONLESS_CTE_TRANSMITTER)); // C30: Mandatory if LE Feature (Connection CTE Request) or LE Feature // (Connectionless CTE Receiver) is supported, otherwise optional if the LE // Controller supports receiving packets, otherwise excluded. auto c30 = mandatory_or_optional( SupportsLLFeature(LLFeaturesBits::CONNECTION_CTE_REQUEST) || SupportsLLFeature(LLFeaturesBits::CONNECTIONLESS_CTE_RECEIVER)); // C31: Mandatory if LE Feature (Connection CTE Request) or LE Feature // (Connection CTE Response) or LE Feature (Connectionless CTE Transmitter) or // LE Feature (Connectionless CTE Receiver) is supported, otherwise excluded. auto c31 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::CONNECTION_CTE_REQUEST) || SupportsLLFeature(LLFeaturesBits::CONNECTION_CTE_RESPONSE) || SupportsLLFeature(LLFeaturesBits::CONNECTIONLESS_CTE_TRANSMITTER) || SupportsLLFeature(LLFeaturesBits::CONNECTIONLESS_CTE_RECEIVER)); // C32: Mandatory if LE Feature (Periodic Advertising Sync Transfer – // Recipient) is supported, otherwise optional if LE Feature (Periodic // Advertising) is supported and the LE Controller supports Synchronization // State, otherwise excluded. auto c32 = mandatory_or_optional_or_excluded( SupportsLLFeature( LLFeaturesBits::PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT), SupportsLLFeature(LLFeaturesBits::LE_PERIODIC_ADVERTISING)); // C33: Mandatory if LE Feature (Periodic Advertising Sync Transfer – Sender) // is supported and the LE Controller supports Scanning State, otherwise // excluded. auto c33 = mandatory_or_excluded(SupportsLLFeature( LLFeaturesBits::PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER)); // C34: Mandatory if LE Feature (Periodic Advertising Sync Transfer – Sender) // is supported and the LE Controller supports Advertising State, otherwise // excluded. auto c34 = mandatory_or_excluded(SupportsLLFeature( LLFeaturesBits::PERIODIC_ADVERTISING_SYNC_TRANSFER_SENDER)); // C35: Mandatory if LE Feature (Periodic Advertising Sync Transfer – // Recipient) is supported, otherwise excluded. auto c35 = mandatory_or_excluded(SupportsLLFeature( LLFeaturesBits::PERIODIC_ADVERTISING_SYNC_TRANSFER_RECIPIENT)); // C36: Mandatory if the LE Controller supports Central role or supports both // Peripheral role and LE Feature (Channel Classification), otherwise optional // if LE Feature (Extended Advertising) is supported and the LE Controller // supports Advertising State or if LE Feature (Isochronous Broadcaster) is // supported, otherwise excluded. auto c36 = mandatory; // C37: Mandatory if the LE Controller can change its sleep clock accuracy, // otherwise excluded. auto c37 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::SLEEP_CLOCK_ACCURACY_UPDATES)); // C38: Mandatory if LE Feature (Connected Isochronous Stream - Central) or // LE Feature (Connected Isochronous Stream - Peripheral) is supported, // otherwise excluded. // // C39: Mandatory if LE Feature (Connected Isochronous // Stream - Central) is supported, otherwise excluded. auto c39 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_CENTRAL)); // C40: Mandatory if LE Feature (Connected Isochronous Stream - Peripheral) is // supported, otherwise excluded. auto c40 = mandatory_or_excluded(SupportsLLFeature( LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL)); // C41: Mandatory if LE Feature (Isochronous Broadcaster) is supported, // otherwise excluded. auto c41 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::ISOCHRONOUS_BROADCASTER)); // C42: Mandatory if LE Feature (Synchronized Receiver role) is supported, // otherwise excluded. auto c42 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::SYNCHRONIZED_RECEIVER)); // C44: Mandatory if LE Feature (Sleep Clock Accuracy Updates) and either LE // Feature (Connected Isochronous Stream - Central) or LE Feature (Connected // Isochronous Stream - Peripheral) are supported, otherwise optional if LE // Feature (Sleep Clock Accuracy Updates) is supported, otherwise excluded. auto c44 = mandatory_or_optional_or_excluded( SupportsLLFeature(LLFeaturesBits::SLEEP_CLOCK_ACCURACY_UPDATES) && (SupportsLLFeature( LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_CENTRAL) || SupportsLLFeature( LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL)), SupportsLLFeature(LLFeaturesBits::SLEEP_CLOCK_ACCURACY_UPDATES)); // C45: Mandatory if LE Feature (Connected Isochronous Stream - Central), or // LE Feature (Connected Isochronous Stream - Peripheral), or // LE Feature (Isochronous Broadcaster) is supported, otherwise excluded. auto c45 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_CENTRAL) || SupportsLLFeature( LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL) || SupportsLLFeature(LLFeaturesBits::ISOCHRONOUS_BROADCASTER)); // C46: Mandatory if LE Feature (Connected Isochronous Stream - Central), or // LE Feature (Connected Isochronous Stream - Peripheral), or // LE Feature (Synchronized Receiver role) is supported, otherwise excluded. auto c46 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_CENTRAL) || SupportsLLFeature( LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL) || SupportsLLFeature(LLFeaturesBits::SYNCHRONIZED_RECEIVER)); // C47: Mandatory if LE Feature (Connected Isochronous Stream - Central), or // LE Feature (Connected Isochronous Stream - Peripheral), or // LE Feature (Isochronous Broadcaster), or // LE Feature (Synchronized Receiver role) is supported, otherwise excluded. auto c47 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_CENTRAL) || SupportsLLFeature( LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL) || SupportsLLFeature(LLFeaturesBits::ISOCHRONOUS_BROADCASTER) || SupportsLLFeature(LLFeaturesBits::SYNCHRONIZED_RECEIVER)); // C49: Mandatory if LE Feature (Connected Isochronous Stream - Central) or // LE Feature (Connected Isochronous Stream - Peripheral) or // LE Feature (Connection Subrating) is supported, otherwise optional. auto c49 = mandatory_or_optional( SupportsLLFeature(LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_CENTRAL) || SupportsLLFeature( LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL) || SupportsLLFeature(LLFeaturesBits::CONNECTION_SUBRATING)); // C50: Optional if LE Feature (Connected Isochronous Stream - Central), or // LE Feature (Connected Isochronous Stream - Peripheral), or // LE Feature (Synchronized Receiver role) is supported, otherwise excluded. auto c50 = optional_or_excluded( SupportsLLFeature(LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_CENTRAL) || SupportsLLFeature( LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL) || SupportsLLFeature(LLFeaturesBits::SYNCHRONIZED_RECEIVER)); // C51: Mandatory if LE Feature (LE Power Control Request) is supported, // otherwise excluded. auto c51 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::LE_POWER_CONTROL_REQUEST)); // C52: Mandatory if LE Feature (LE Path Loss Monitoring) is supported, // otherwise excluded. auto c52 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::LE_PATH_LOSS_MONITORING)); // C53: Mandatory if LE Feature (LE Power Control Request) is supported, // otherwise optional if the LE Controller supports transmitting packets, // otherwise excluded. auto c53 = mandatory_or_optional( SupportsLLFeature(LLFeaturesBits::LE_POWER_CONTROL_REQUEST)); // C54: Mandatory if LE Feature (Synchronized Receiver) is supported, // otherwise optional. // // C55: Mandatory if LE Feature (Connected Isochronous // Stream - Central), or LE Feature (Connected Isochronous Stream - // Peripheral), or LE Feature (Isochronous Broadcaster) is supported, // otherwise optional if the LE Controller supports Connection State, // otherwise excluded. auto c55 = mandatory_or_optional( SupportsLLFeature(LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_CENTRAL) || SupportsLLFeature( LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL) || SupportsLLFeature(LLFeaturesBits::ISOCHRONOUS_BROADCASTER)); // C56: Optional if LE Feature (LE Encryption) is supported, otherwise // excluded. // // C57: Mandatory if LE Feature (Connection Subrating) is supported, // otherwise excluded. auto c57 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::CONNECTION_SUBRATING)); // C58: Mandatory if LE Feature (Channel Classification) is supported, // otherwise excluded. auto c58 = mandatory_or_excluded( SupportsLLFeature(LLFeaturesBits::CHANNEL_CLASSIFICATION)); // C59: Mandatory if the LE Controller supports Central role, otherwise // excluded. auto c59 = mandatory; // C60: Mandatory if the LE Controller supports Central role and LE Feature // (LE Encryption), otherwise excluded. auto c60 = mandatory_or_excluded(SupportsLLFeature(LLFeaturesBits::LE_ENCRYPTION)); // C61: Mandatory if the LE Controller supports Peripheral role and LE Feature // (LE Encryption), otherwise excluded. auto c61 = mandatory_or_excluded(SupportsLLFeature(LLFeaturesBits::LE_ENCRYPTION)); // C62: Mandatory if the LE Controller supports Central role or supports both // Peripheral role and LE Feature (Connection Parameters Request Procedure), // otherwise excluded. auto c62 = mandatory; // C63: Mandatory if the LE Controller supports Scanning state and LE Feature // (LL Privacy), otherwise excluded. // // C64: Optional if the Controller supports // transmitting packets, otherwise excluded. auto c64 = optional; // C94: Mandatory if the LE Create Connection or LE Extended Create Connection // command is supported, otherwise excluded. auto c94 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::LE_CREATE_CONNECTION) || SupportsCommand(OpCodeIndex::LE_EXTENDED_CREATE_CONNECTION)); // C95: Mandatory if the LE Request Peer SCA command is supported, otherwise // excluded. // // C96: Optional if the LE Controller supports Connection State, // otherwise excluded. auto c96 = optional; // C97: Mandatory if Advertising State is supported, otherwise excluded. auto c97 = mandatory; // C98: Mandatory if Scanning State is supported, otherwise excluded. auto c98 = mandatory; // C99: Mandatory if LE Generate DHKey command [v2] is supported, otherwise // optional. auto c99 = mandatory_or_optional(SupportsCommand(OpCodeIndex::LE_GENERATE_DHKEY_V2)); // C101: Mandatory if the Authentication Requested command is supported, // otherwise excluded. // // C102: Mandatory if the Change Connection Link Key command is supported, // otherwise excluded. // // C103: Mandatory if the Periodic // Inquiry Mode command is supported, otherwise excluded. auto c103 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::PERIODIC_INQUIRY_MODE)); // C104: Mandatory if the Read Clock Offset command is supported, otherwise // excluded. // // C105: Mandatory if the Read Remote Version Information command is // supported, otherwise excluded. // // C106: Mandatory if the Remote Name Request // command is supported, otherwise excluded. auto c106 = mandatory_or_excluded(SupportsCommand(OpCodeIndex::REMOTE_NAME_REQUEST)); // C107: Mandatory if the Set Controller To Host Flow Control command is // supported, otherwise excluded. auto c107 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::SET_CONTROLLER_TO_HOST_FLOW_CONTROL)); // C108: Mandatory if the Set MWS_PATTERN Configuration command is supported, // otherwise optional. auto c108 = mandatory_or_optional( SupportsCommand(OpCodeIndex::SET_MWS_PATTERN_CONFIGURATION)); // C109: Mandatory if the Set MWS Signaling command is supported, otherwise // excluded. auto c109 = mandatory_or_excluded(SupportsCommand(OpCodeIndex::SET_MWS_SIGNALING)); // C110: Mandatory if the Set Triggered Clock Capture command is supported, // otherwise excluded. // // C111: Mandatory if the Write Authentication Enable // command is supported, otherwise excluded. auto c111 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::WRITE_AUTHENTICATION_ENABLE)); // C112: Mandatory if the Write Default Erroneous Data Reporting command is // supported, otherwise excluded. auto c112 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING)); // C113: Mandatory if the Write Extended Inquiry Length command is supported, // otherwise excluded. auto c113 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::WRITE_EXTENDED_INQUIRY_LENGTH)); // C114: Mandatory if the Write Extended Page Timeout command is supported, // otherwise excluded. auto c114 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::WRITE_EXTENDED_PAGE_TIMEOUT)); // C115: Mandatory if the Write Inquiry Mode command is supported, otherwise // excluded. auto c115 = mandatory_or_excluded(SupportsCommand(OpCodeIndex::WRITE_INQUIRY_MODE)); // C116: Mandatory if the Write LE Host Support command is supported, // otherwise excluded. auto c116 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::WRITE_LE_HOST_SUPPORT)); // C117: Mandatory if the Write Link Supervision Timeout command is supported, // otherwise excluded. auto c117 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::WRITE_LINK_SUPERVISION_TIMEOUT)); // C118: Mandatory if the Write Num Broadcast Retransmissions command is // supported, otherwise excluded. auto c118 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::WRITE_NUM_BROADCAST_RETRANSMITS)); // C119: Mandatory if the Write Page Scan Type command is supported, otherwise // excluded. auto c119 = mandatory_or_excluded(SupportsCommand(OpCodeIndex::WRITE_PAGE_SCAN_TYPE)); // C120: Mandatory if the Write PIN Type command is supported, otherwise // excluded. auto c120 = mandatory_or_excluded(SupportsCommand(OpCodeIndex::WRITE_PIN_TYPE)); // C121: Mandatory if the Write Stored Link Key command is supported, // otherwise excluded. auto c121 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::WRITE_STORED_LINK_KEY)); // C122: Mandatory if the Write Synchronous Flow Control Enable command is // supported, otherwise excluded. auto c122 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE)); // C123: Mandatory if BR/EDR test mode is supported, otherwise excluded. auto c123 = mandatory; // C124: Mandatory if Data block based flow control is supported, otherwise // excluded. auto c124 = excluded; // C125: Mandatory if Inquiry Scan is supported, otherwise excluded. auto c125 = mandatory; // C126: Optional if Inquiry Scan is supported, otherwise excluded. // // C127: Mandatory if Inquiry is supported, otherwise excluded. auto c127 = mandatory; // C128: Optional if Inquiry is supported, otherwise excluded. auto c128 = optional; // C129: Mandatory if Truncated page state is supported, otherwise excluded. auto c129 = excluded; // C132: Mandatory if multi-slot ACL packets are is supported, otherwise // excluded. // // C133: Mandatory if HV2, HV3, or multi-slot or EDR ACL packets are // supported, otherwise excluded. auto c133 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::HV2_PACKETS) || SupportsLMPFeature(LMPFeaturesPage0Bits::HV3_PACKETS) || SupportsLMPFeature( LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ACL_2_MB_S_MODE) || SupportsLMPFeature( LMPFeaturesPage0Bits::ENHANCED_DATA_RATE_ACL_3_MB_S_MODE) || SupportsLMPFeature( LMPFeaturesPage0Bits::LMP_3_SLOT_ENHANCED_DATA_RATE_ACL_PACKETS)); // C134: Mandatory if SCO or eSCO is supported, otherwise excluded. auto c134 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::SCO_LINK) || SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_SCO_LINK)); // C135: Optional if SCO or eSCO is supported, otherwise excluded. auto c135 = optional_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::SCO_LINK) || SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_SCO_LINK)); // C136: Optional if Slot Availability Mask is supported, otherwise excluded. auto c136 = optional_or_excluded( SupportsLMPFeature(LMPFeaturesPage2Bits::SLOT_AVAILABILITY_MASK)); // C138: Mandatory if Secure Connections (Controller) is supported, otherwise // optional if eSCO is supported, otherwise excluded. auto c138 = mandatory_or_optional_or_excluded( SupportsLMPFeature( LMPFeaturesPage2Bits::SECURE_CONNECTIONS_CONTROLLER_SUPPORT), SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_SCO_LINK)); // C139: Mandatory if the Controller is AFH capable in either role, otherwise // excluded. auto c139 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::AFH_CAPABLE_CENTRAL) || SupportsLMPFeature(LMPFeaturesPage0Bits::AFH_CAPABLE_PERIPHERAL)); // C140: Mandatory if the Controller supports AFH classification in either // role or is an AFH capable Central, otherwise excluded. auto c140 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::AFH_CLASSIFICATION_CENTRAL) || SupportsLMPFeature(LMPFeaturesPage0Bits::AFH_CLASSIFICATION_PERIPHERAL) || SupportsLMPFeature(LMPFeaturesPage0Bits::AFH_CAPABLE_CENTRAL)); // C141: Mandatory if Role Switch, Hold mode, or Sniff mode is supported, // otherwise excluded. auto c141 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::ROLE_SWITCH) || SupportsLMPFeature(LMPFeaturesPage0Bits::HOLD_MODE) || SupportsLMPFeature(LMPFeaturesPage0Bits::SNIFF_MODE)); // C142: Mandatory if Secure Connections (Host) is supported, otherwise // excluded. auto c142 = mandatory; // C143: Mandatory if Secure Connections (both Host and Controller) is // supported, otherwise excluded. auto c143 = mandatory_or_excluded(SupportsLMPFeature( LMPFeaturesPage2Bits::SECURE_CONNECTIONS_CONTROLLER_SUPPORT)); // C144: Mandatory if Hold Mode or Sniff Mode is supported, otherwise // excluded. // // C145: Mandatory if any event in event mask page 2 is supported, // otherwise optional. auto c145 = mandatory; // C146: Mandatory if the Extended Inquiry Result event or the IO Capability // Request event is supported, otherwise optional if Inquiry is supported, // otherwise excluded. auto c146 = mandatory; // C147: Optional if the Inquiry Result with RSSI event is supported, // otherwise excluded. // // C148: Optional if any of the Connection Complete, // Connection Request, Extended Inquiry Result, Inquiry Result with RSSI, IO // Capability Request, or Synchronous Connection Complete events is supported, // otherwise excluded. auto c148 = mandatory; // C151: Mandatory if Secure Connections (Controller) and Ping are supported, // otherwise excluded. auto c151 = mandatory_or_excluded( SupportsLMPFeature( LMPFeaturesPage2Bits::SECURE_CONNECTIONS_CONTROLLER_SUPPORT) && SupportsLMPFeature(LMPFeaturesPage2Bits::PING)); // C152: Mandatory if Power Control is supported, otherwise optional. auto c152 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::POWER_CONTROL)); // C153: Mandatory if LE supported in the Controller, otherwise optional. auto c153 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::LE_SUPPORTED_CONTROLLER)); // C154: Mandatory if Interlaced Page Scan is supported, otherwise optional. auto c154 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::INTERLACED_PAGE_SCAN)); // C155: Mandatory if the Write Authenticated Payload Timeout command is // supported, otherwise excluded. auto c155 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT)); // C156: Mandatory if the Read Local Supported Codecs command [v2] is // supported, otherwise excluded. auto c156 = mandatory_or_excluded( SupportsCommand(OpCodeIndex::READ_LOCAL_SUPPORTED_CODECS_V2)); // C157: Mandatory if the Read Local Supported Codecs command [v2] is // supported, otherwise optional. auto c157 = mandatory_or_optional( SupportsCommand(OpCodeIndex::READ_LOCAL_SUPPORTED_CODECS_V2)); // C158: Mandatory if the Set Min Encryption Key Size command is supported, // otherwise optional. // // C201: Mandatory if Connectionless Peripheral Broadcast - Transmitter is // supported, otherwise excluded. auto c201 = mandatory_or_excluded(SupportsLMPFeature( LMPFeaturesPage2Bits:: CONNECTIONLESS_PERIPHERAL_BROADCAST_TRANSMITTER_OPERATION)); // C202: Mandatory if Connectionless Peripheral Broadcast - Receiver is // supported, otherwise excluded. auto c202 = mandatory_or_excluded(SupportsLMPFeature( LMPFeaturesPage2Bits:: CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVER_OPERATION)); // C203: Mandatory if Synchronization Train is supported, otherwise excluded. auto c203 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage2Bits::SYNCHRONIZATION_TRAIN)); // C204: Mandatory if Synchronization Scan is supported, otherwise excluded. auto c204 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage2Bits::SYNCHRONIZATION_SCAN)); // C205: Mandatory if Extended Inquiry Response is supported, otherwise // excluded. auto c205 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_INQUIRY_RESPONSE)); // C212: Mandatory if Role Switch is supported, otherwise excluded. auto c212 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::ROLE_SWITCH)); // C213: Mandatory if Hold mode is supported, otherwise excluded. auto c213 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::HOLD_MODE)); // C214: Mandatory if Sniff mode is supported, otherwise excluded. auto c214 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::SNIFF_MODE)); // C215: Mandatory if Broadcast Encryption is supported, otherwise excluded. auto c215 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::BROADCAST_ENCRYPTION)); // C217: Mandatory if BR/EDR Enhanced Power Control is supported, otherwise // excluded. auto c217 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::ENHANCED_POWER_CONTROL)); // C218: Mandatory if Secure Connections (Controller) is supported, otherwise // excluded. auto c218 = mandatory_or_excluded(SupportsLMPFeature( LMPFeaturesPage2Bits::SECURE_CONNECTIONS_CONTROLLER_SUPPORT)); // C219: Mandatory if Slot Availability Mask is supported, otherwise excluded. // C220: Mandatory if LMP Extended Features mask is supported, otherwise // excluded. auto c220 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::EXTENDED_FEATURES)); // C221: Mandatory if Sniff subrating is supported, otherwise excluded. auto c221 = mandatory_or_excluded( SupportsLMPFeature(LMPFeaturesPage0Bits::SNIFF_SUBRATING)); #define check_command_(op_code, br_requirement, le_requirement) \ { \ bool command_supported = \ SupportsCommand(bluetooth::hci::OpCodeIndex::op_code); \ if (!check_command_requirement(br_supported, br_requirement, le_supported, \ le_requirement, command_supported)) { \ INFO(#op_code " command validation failed (" #br_requirement \ "," #le_requirement ")"); \ } \ } // Table 3.1: Alphabetical list of commands and events (Sheet 1 of 49) check_command_(ACCEPT_CONNECTION_REQUEST, mandatory, excluded); check_command_(ACCEPT_SYNCHRONOUS_CONNECTION, c134, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 2 of 49) check_command_(CHANGE_CONNECTION_PACKET_TYPE, c133, excluded); check_command_(CONFIGURE_DATA_PATH, c156, c156); // Table 3.1: Alphabetical list of commands and events (Sheet 3 of 49) check_command_(CREATE_CONNECTION_CANCEL, mandatory, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 4 of 49) check_command_(CREATE_CONNECTION, mandatory, excluded); check_command_(DELETE_RESERVED_LT_ADDR, c201, excluded); check_command_(DELETE_STORED_LINK_KEY, c121, excluded); check_command_(DISCONNECT, mandatory, c3); check_command_(ENABLE_DEVICE_UNDER_TEST_MODE, c123, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 5 of 49) check_command_(ENHANCED_ACCEPT_SYNCHRONOUS_CONNECTION, c135, excluded); check_command_(ENHANCED_FLUSH, mandatory, excluded); check_command_(ENHANCED_SETUP_SYNCHRONOUS_CONNECTION, c135, excluded); check_command_(EXIT_PERIODIC_INQUIRY_MODE, c103, excluded); check_command_(EXIT_SNIFF_MODE, c214, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 6 of 49) check_command_(FLOW_SPECIFICATION, mandatory, excluded); check_command_(FLUSH, mandatory, excluded); check_command_(GET_MWS_TRANSPORT_LAYER_CONFIGURATION, c109, c109); check_command_(HOLD_MODE, c213, excluded); check_command_(HOST_BUFFER_SIZE, c107, c107); // Table 3.1: Alphabetical list of commands and events (Sheet 7 of 49) check_command_(HOST_NUMBER_OF_COMPLETED_PACKETS, c107, c107); check_command_(INQUIRY_CANCEL, c127, excluded); check_command_(INQUIRY, c127, excluded); check_command_(IO_CAPABILITY_REQUEST_NEGATIVE_REPLY, mandatory, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 8 of 49) check_command_(IO_CAPABILITY_REQUEST_REPLY, mandatory, excluded); check_command_(LE_ACCEPT_CIS_REQUEST, excluded, c40); check_command_(LE_ADD_DEVICE_TO_FILTER_ACCEPT_LIST, excluded, mandatory); check_command_(LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST, excluded, c21); check_command_(LE_ADD_DEVICE_TO_RESOLVING_LIST, excluded, c9); // Table 3.1: Alphabetical list of commands and events (Sheet 9 of 49) check_command_(LE_BIG_CREATE_SYNC, excluded, c42); check_command_(LE_BIG_TERMINATE_SYNC, excluded, c42); check_command_(LE_CLEAR_ADVERTISING_SETS, excluded, c17); check_command_(LE_CLEAR_FILTER_ACCEPT_LIST, excluded, mandatory); check_command_(LE_CLEAR_PERIODIC_ADVERTISER_LIST, excluded, c21); check_command_(LE_CLEAR_RESOLVING_LIST, excluded, c9); // Table 3.1: Alphabetical list of commands and events (Sheet 10 of 49) check_command_(LE_CONNECTION_CTE_REQUEST_ENABLE, excluded, c25); check_command_(LE_CONNECTION_CTE_RESPONSE_ENABLE, excluded, c26); check_command_(LE_CONNECTION_UPDATE, excluded, c62); check_command_(LE_CREATE_BIG, excluded, c41); // Table 3.1: Alphabetical list of commands and events (Sheet 11 of 49) check_command_(LE_CREATE_BIG_TEST, excluded, c41); check_command_(LE_CREATE_CIS, excluded, c39); check_command_(LE_CREATE_CONNECTION_CANCEL, excluded, c94); check_command_(LE_CREATE_CONNECTION, excluded, c59); check_command_(LE_START_ENCRYPTION, excluded, c60); check_command_(LE_ENCRYPT, excluded, c4); // Table 3.1: Alphabetical list of commands and events (Sheet 12 of 49) check_command_(LE_ENHANCED_READ_TRANSMIT_POWER_LEVEL, excluded, c51); check_command_(LE_EXTENDED_CREATE_CONNECTION, excluded, c20); check_command_(LE_GENERATE_DHKEY_V1, excluded, c99); check_command_(LE_GENERATE_DHKEY_V2, excluded, optional); check_command_(LE_ISO_READ_TEST_COUNTERS, excluded, c46); check_command_(LE_ISO_RECEIVE_TEST, excluded, c46); check_command_(LE_ISO_TEST_END, excluded, c47); // Table 3.1: Alphabetical list of commands and events (Sheet 13 of 49) check_command_(LE_ISO_TRANSMIT_TEST, excluded, c45); check_command_(LE_LONG_TERM_KEY_REQUEST_NEGATIVE_REPLY, excluded, c61); check_command_(LE_LONG_TERM_KEY_REQUEST_REPLY, excluded, c61); check_command_(LE_MODIFY_SLEEP_CLOCK_ACCURACY, excluded, c37); check_command_(LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL, excluded, c16); check_command_(LE_PERIODIC_ADVERTISING_CREATE_SYNC, excluded, c16); // Table 3.1: Alphabetical list of commands and events (Sheet 14 of 49) check_command_(LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER, excluded, c34); check_command_(LE_PERIODIC_ADVERTISING_SYNC_TRANSFER, excluded, c33); check_command_(LE_PERIODIC_ADVERTISING_TERMINATE_SYNC, excluded, c21); check_command_(LE_RAND, excluded, c4); check_command_(LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER, excluded, c97); // Table 3.1: Alphabetical list of commands and events (Sheet 15 of 49) check_command_(LE_READ_ANTENNA_INFORMATION, excluded, c31); check_command_(LE_READ_BUFFER_SIZE_V1, excluded, c3); check_command_(LE_READ_BUFFER_SIZE_V2, excluded, c55); check_command_(LE_READ_CHANNEL_MAP, excluded, c3); check_command_(LE_READ_FILTER_ACCEPT_LIST_SIZE, excluded, mandatory); check_command_(LE_READ_ISO_LINK_QUALITY, excluded, c50); check_command_(LE_READ_ISO_TX_SYNC, excluded, c45); check_command_(LE_READ_LOCAL_RESOLVABLE_ADDRESS, excluded, c10); // Table 3.1: Alphabetical list of commands and events (Sheet 16 of 49) check_command_(LE_READ_LOCAL_SUPPORTED_FEATURES, excluded, mandatory); check_command_(LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH, excluded, c17); check_command_(LE_READ_MAXIMUM_DATA_LENGTH, excluded, c8); check_command_(LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS, excluded, c17); check_command_(LE_READ_PEER_RESOLVABLE_ADDRESS, excluded, c10); check_command_(LE_READ_PERIODIC_ADVERTISER_LIST_SIZE, excluded, c21); check_command_(LE_READ_PHY, excluded, c11); check_command_(LE_READ_REMOTE_FEATURES, excluded, c3); // Table 3.1: Alphabetical list of commands and events (Sheet 17 of 49) check_command_(LE_READ_REMOTE_TRANSMIT_POWER_LEVEL, excluded, c51); check_command_(LE_READ_RESOLVING_LIST_SIZE, excluded, c9); check_command_(LE_READ_RF_PATH_COMPENSATION_POWER, excluded, c22); check_command_(LE_READ_SUGGESTED_DEFAULT_DATA_LENGTH, excluded, c8); check_command_(LE_READ_SUPPORTED_STATES, excluded, mandatory); check_command_(LE_READ_TRANSMIT_POWER, excluded, c64); check_command_(LE_RECEIVER_TEST_V1, excluded, c2); check_command_(LE_RECEIVER_TEST_V2, excluded, c13); check_command_(LE_RECEIVER_TEST_V3, excluded, c30); // Table 3.1: Alphabetical list of commands and events (Sheet 18 of 49) check_command_(LE_REJECT_CIS_REQUEST, excluded, c40); check_command_(LE_REMOTE_CONNECTION_PARAMETER_REQUEST_NEGATIVE_REPLY, excluded, c6); check_command_(LE_REMOTE_CONNECTION_PARAMETER_REQUEST_REPLY, excluded, c6); check_command_(LE_REMOVE_ADVERTISING_SET, excluded, c17); check_command_(LE_REMOVE_CIG, excluded, c39); check_command_(LE_REMOVE_DEVICE_FROM_FILTER_ACCEPT_LIST, excluded, mandatory); check_command_(LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST, excluded, c21); check_command_(LE_REMOVE_DEVICE_FROM_RESOLVING_LIST, excluded, c9); // Table 3.1: Alphabetical list of commands and events (Sheet 19 of 49) check_command_(LE_REMOVE_ISO_DATA_PATH, excluded, c47); check_command_(LE_REQUEST_PEER_SCA, excluded, c44); check_command_(LE_SET_ADDRESS_RESOLUTION_ENABLE, excluded, c9); check_command_(LE_SET_ADVERTISING_DATA, excluded, c97); check_command_(LE_SET_ADVERTISING_ENABLE, excluded, c97); check_command_(LE_SET_ADVERTISING_PARAMETERS, excluded, c97); check_command_(LE_SET_ADVERTISING_SET_RANDOM_ADDRESS, excluded, c17); check_command_(LE_SET_CIG_PARAMETERS, excluded, c39); // Table 3.1: Alphabetical list of commands and events (Sheet 20 of 49) check_command_(LE_SET_CIG_PARAMETERS_TEST, excluded, c39); check_command_(LE_SET_CONNECTION_CTE_RECEIVE_PARAMETERS, excluded, c25); check_command_(LE_SET_CONNECTION_CTE_TRANSMIT_PARAMETERS, excluded, c26); check_command_(LE_SET_CONNECTIONLESS_CTE_TRANSMIT_ENABLE, excluded, c27); check_command_(LE_SET_CONNECTIONLESS_CTE_TRANSMIT_PARAMETERS, excluded, c27); check_command_(LE_SET_CONNECTIONLESS_IQ_SAMPLING_ENABLE, excluded, c28); check_command_(LE_SET_DATA_LENGTH, excluded, c8); // Table 3.1: Alphabetical list of commands and events (Sheet 21 of 49) check_command_(LE_SET_DATA_RELATED_ADDRESS_CHANGES, excluded, c10); check_command_(LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS, excluded, c35); check_command_(LE_SET_DEFAULT_PHY, excluded, c11); check_command_(LE_SET_DEFAULT_SUBRATE, excluded, c57); check_command_(LE_SET_EVENT_MASK, excluded, mandatory); check_command_(LE_SET_EXTENDED_ADVERTISING_DATA, excluded, c17); check_command_(LE_SET_EXTENDED_ADVERTISING_ENABLE, excluded, c17); check_command_(LE_SET_EXTENDED_ADVERTISING_PARAMETERS, excluded, c17); check_command_(LE_SET_EXTENDED_SCAN_ENABLE, excluded, c19); // Table 3.1: Alphabetical list of commands and events (Sheet 22 of 49) check_command_(LE_SET_EXTENDED_SCAN_PARAMETERS, excluded, c19); check_command_(LE_SET_EXTENDED_SCAN_RESPONSE_DATA, excluded, c17); check_command_(LE_SET_HOST_CHANNEL_CLASSIFICATION, excluded, c36); check_command_(LE_SET_HOST_FEATURE, excluded, c49); check_command_(LE_SET_PATH_LOSS_REPORTING_ENABLE, excluded, c52); check_command_(LE_SET_PATH_LOSS_REPORTING_PARAMETERS, excluded, c52); check_command_(LE_SET_PERIODIC_ADVERTISING_DATA, excluded, c18); check_command_(LE_SET_PERIODIC_ADVERTISING_ENABLE, excluded, c18); check_command_(LE_SET_PERIODIC_ADVERTISING_PARAMETERS, excluded, c18); // Table 3.1: Alphabetical list of commands and events (Sheet 23 of 49) check_command_(LE_SET_PERIODIC_ADVERTISING_RECEIVE_ENABLE, excluded, c32); check_command_(LE_SET_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS, excluded, c35); check_command_(LE_SET_PHY, excluded, c11); check_command_(LE_SET_PRIVACY_MODE, excluded, c9); check_command_(LE_SET_RANDOM_ADDRESS, excluded, c1); check_command_(LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT, excluded, c9); check_command_(LE_SET_SCAN_ENABLE, excluded, c98); check_command_(LE_SET_SCAN_PARAMETERS, excluded, c98); check_command_(LE_SET_SCAN_RESPONSE_DATA, excluded, c15); // Table 3.1: Alphabetical list of commands and events (Sheet 24 of 49) check_command_(LE_SET_TRANSMIT_POWER_REPORTING_ENABLE, excluded, c51); check_command_(LE_SETUP_ISO_DATA_PATH, excluded, c47); check_command_(LE_SUBRATE_REQUEST, excluded, c57); check_command_(LE_TERMINATE_BIG, excluded, c41); check_command_(LE_TEST_END, excluded, mandatory); check_command_(LE_TRANSMITTER_TEST_V1, excluded, c1); check_command_(LE_TRANSMITTER_TEST_V2, excluded, c12); check_command_(LE_TRANSMITTER_TEST_V3, excluded, c29); check_command_(LE_TRANSMITTER_TEST_V4, excluded, c53); // Table 3.1: Alphabetical list of commands and events (Sheet 25 of 49) check_command_(LE_WRITE_RF_PATH_COMPENSATION_POWER, excluded, c22); check_command_(LE_WRITE_SUGGESTED_DEFAULT_DATA_LENGTH, excluded, c8); check_command_(LINK_KEY_REQUEST_NEGATIVE_REPLY, mandatory, excluded); check_command_(LINK_KEY_REQUEST_REPLY, mandatory, excluded); check_command_(CENTRAL_LINK_KEY, c215, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 26 of 49) // Table 3.1: Alphabetical list of commands and events (Sheet 27 of 49) check_command_(PERIODIC_INQUIRY_MODE, c128, excluded); check_command_(PIN_CODE_REQUEST_NEGATIVE_REPLY, mandatory, excluded); check_command_(PIN_CODE_REQUEST_REPLY, mandatory, excluded); check_command_(QOS_SETUP, mandatory, excluded); check_command_(READ_AFH_CHANNEL_ASSESSMENT_MODE, c140, c58); // Table 3.1: Alphabetical list of commands and events (Sheet 28 of 49) check_command_(READ_AFH_CHANNEL_MAP, c139, excluded); check_command_(READ_AUTHENTICATED_PAYLOAD_TIMEOUT, c155, c155); check_command_(READ_AUTHENTICATION_ENABLE, c111, excluded); check_command_(READ_AUTOMATIC_FLUSH_TIMEOUT, mandatory, excluded); check_command_(READ_BD_ADDR, mandatory, mandatory); check_command_(READ_BUFFER_SIZE, mandatory, excluded); check_command_(READ_CLASS_OF_DEVICE, mandatory, excluded); check_command_(READ_CLOCK, optional, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 29 of 49) check_command_(READ_CLOCK_OFFSET, optional, excluded); check_command_(READ_CONNECTION_ACCEPT_TIMEOUT, mandatory, c40); check_command_(READ_CURRENT_IAC_LAP, c125, excluded); check_command_(READ_DATA_BLOCK_SIZE, c124, excluded); check_command_(READ_DEFAULT_ERRONEOUS_DATA_REPORTING, c112, excluded); check_command_(READ_DEFAULT_LINK_POLICY_SETTINGS, c141, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 30 of 49) check_command_(READ_ENCRYPTION_KEY_SIZE, mandatory, excluded); check_command_(READ_ENHANCED_TRANSMIT_POWER_LEVEL, c217, excluded); check_command_(READ_EXTENDED_INQUIRY_LENGTH, c113, excluded); check_command_(READ_EXTENDED_INQUIRY_RESPONSE, c205, excluded); check_command_(READ_EXTENDED_PAGE_TIMEOUT, c114, excluded); check_command_(READ_FAILED_CONTACT_COUNTER, mandatory, excluded); check_command_(READ_FLOW_CONTROL_MODE, c124, excluded); check_command_(READ_HOLD_MODE_ACTIVITY, c213, excluded); check_command_(READ_INQUIRY_MODE, c115, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 31 of 49) check_command_(READ_INQUIRY_RESPONSE_TRANSMIT_POWER_LEVEL, c125, excluded); check_command_(READ_INQUIRY_SCAN_ACTIVITY, c125, excluded); check_command_(READ_INQUIRY_SCAN_TYPE, c125, excluded); check_command_(READ_LE_HOST_SUPPORT, c116, c116); check_command_(READ_LINK_POLICY_SETTINGS, c141, excluded); check_command_(READ_LINK_QUALITY, optional, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 32 of 49) check_command_(READ_LINK_SUPERVISION_TIMEOUT, c117, excluded); check_command_(READ_LMP_HANDLE, c134, excluded); check_command_(READ_LOCAL_EXTENDED_FEATURES, c220, excluded); check_command_(READ_LOCAL_NAME, mandatory, excluded); check_command_(READ_LOCAL_OOB_DATA, mandatory, excluded); check_command_(READ_LOCAL_OOB_EXTENDED_DATA, c142, excluded); check_command_(READ_LOCAL_SIMPLE_PAIRING_OPTIONS, optional, excluded); check_command_(READ_LOCAL_SUPPORTED_CODEC_CAPABILITIES, c156, c156); check_command_(READ_LOCAL_SUPPORTED_CODECS_V1, c157, excluded); check_command_(READ_LOCAL_SUPPORTED_CODECS_V2, optional, optional); // Table 3.1: Alphabetical list of commands and events (Sheet 33 of 49) // check_command_(READ_LOCAL_SUPPORTED_COMMANDS, mandatory, mandatory); check_command_(READ_LOCAL_SUPPORTED_CONTROLLER_DELAY, c156, c156); check_command_(READ_LOCAL_SUPPORTED_FEATURES, mandatory, mandatory); check_command_(READ_LOCAL_VERSION_INFORMATION, mandatory, mandatory); check_command_(READ_LOOPBACK_MODE, c123, excluded); check_command_(READ_NUM_BROADCAST_RETRANSMITS, c118, excluded); check_command_(READ_NUMBER_OF_SUPPORTED_IAC, c125, excluded); check_command_(READ_PAGE_SCAN_ACTIVITY, mandatory, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 34 of 49) check_command_(READ_PAGE_SCAN_TYPE, c119, excluded); check_command_(READ_PAGE_TIMEOUT, mandatory, excluded); check_command_(READ_PIN_TYPE, c120, excluded); check_command_(READ_REMOTE_EXTENDED_FEATURES, c220, excluded); check_command_(READ_REMOTE_SUPPORTED_FEATURES, mandatory, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 35 of 49) check_command_(READ_REMOTE_VERSION_INFORMATION, optional, c3); check_command_(READ_RSSI, optional, c3); check_command_(READ_SCAN_ENABLE, mandatory, excluded); check_command_(READ_SECURE_CONNECTIONS_HOST_SUPPORT, c218, excluded); check_command_(READ_SIMPLE_PAIRING_MODE, mandatory, excluded); check_command_(READ_STORED_LINK_KEY, c121, excluded); check_command_(READ_SYNCHRONIZATION_TRAIN_PARAMETERS, c203, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 36 of 49) check_command_(READ_SYNCHRONOUS_FLOW_CONTROL_ENABLE, c122, excluded); check_command_(READ_TRANSMIT_POWER_LEVEL, c152, c3); check_command_(READ_VOICE_SETTING, c134, excluded); check_command_(RECEIVE_SYNCHRONIZATION_TRAIN, c204, excluded); check_command_(REFRESH_ENCRYPTION_KEY, mandatory, excluded); check_command_(REJECT_CONNECTION_REQUEST, mandatory, excluded); check_command_(REJECT_SYNCHRONOUS_CONNECTION, c134, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 37 of 49) check_command_(REMOTE_NAME_REQUEST_CANCEL, c106, excluded); check_command_(REMOTE_NAME_REQUEST, optional, excluded); check_command_(REMOTE_OOB_DATA_REQUEST_NEGATIVE_REPLY, mandatory, excluded); check_command_(REMOTE_OOB_DATA_REQUEST_REPLY, mandatory, excluded); check_command_(REMOTE_OOB_EXTENDED_DATA_REQUEST_REPLY, c143, excluded); check_command_(RESET, mandatory, mandatory); // Table 3.1: Alphabetical list of commands and events (Sheet 38 of 49) check_command_(RESET_FAILED_CONTACT_COUNTER, mandatory, excluded); check_command_(ROLE_DISCOVERY, optional, excluded); check_command_(SEND_KEYPRESS_NOTIFICATION, mandatory, excluded); check_command_(SET_AFH_HOST_CHANNEL_CLASSIFICATION, c140, excluded); check_command_(SET_CONNECTION_ENCRYPTION, mandatory, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 39 of 49) check_command_(SET_CONNECTIONLESS_PERIPHERAL_BROADCAST, c201, excluded); check_command_(SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_DATA, c201, excluded); check_command_(SET_CONNECTIONLESS_PERIPHERAL_BROADCAST_RECEIVE, c202, excluded); check_command_(SET_CONTROLLER_TO_HOST_FLOW_CONTROL, optional, c96); check_command_(SET_ECOSYSTEM_BASE_INTERVAL, optional, optional); check_command_(SET_EVENT_FILTER, c148, excluded); check_command_(SET_EVENT_MASK, mandatory, mandatory); check_command_(SET_EVENT_MASK_PAGE_2, c145, c145); // Table 3.1: Alphabetical list of commands and events (Sheet 40 of 49) check_command_(SET_EXTERNAL_FRAME_CONFIGURATION, c108, optional); check_command_(SET_MIN_ENCRYPTION_KEY_SIZE, optional, excluded); check_command_(SET_MWS_CHANNEL_PARAMETERS, optional, optional); check_command_(SET_MWS_SCAN_FREQUENCY_TABLE, optional, optional); check_command_(SET_MWS_SIGNALING, optional, optional); check_command_(SET_MWS_TRANSPORT_LAYER, c109, c109); check_command_(SET_MWS_PATTERN_CONFIGURATION, c136, excluded); check_command_(SET_RESERVED_LT_ADDR, c201, excluded); check_command_(SET_TRIGGERED_CLOCK_CAPTURE, optional, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 41 of 49) check_command_(SETUP_SYNCHRONOUS_CONNECTION, c134, excluded); check_command_(SNIFF_MODE, c214, excluded); check_command_(SNIFF_SUBRATING, c221, excluded); check_command_(START_SYNCHRONIZATION_TRAIN, c203, excluded); check_command_(SWITCH_ROLE, c212, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 42 of 49) check_command_(TRUNCATED_PAGE_CANCEL, c129, excluded); check_command_(TRUNCATED_PAGE, c129, excluded); check_command_(USER_CONFIRMATION_REQUEST_NEGATIVE_REPLY, mandatory, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 43 of 49) check_command_(USER_CONFIRMATION_REQUEST_REPLY, mandatory, excluded); check_command_(USER_PASSKEY_REQUEST_NEGATIVE_REPLY, mandatory, excluded); check_command_(USER_PASSKEY_REQUEST_REPLY, mandatory, excluded); check_command_(WRITE_AFH_CHANNEL_ASSESSMENT_MODE, c140, c58); // Table 3.1: Alphabetical list of commands and events (Sheet 44 of 49) check_command_(WRITE_AUTHENTICATED_PAYLOAD_TIMEOUT, c151, c7); check_command_(WRITE_AUTHENTICATION_ENABLE, optional, excluded); check_command_(WRITE_AUTOMATIC_FLUSH_TIMEOUT, mandatory, excluded); check_command_(WRITE_CLASS_OF_DEVICE, mandatory, excluded); check_command_(WRITE_CONNECTION_ACCEPT_TIMEOUT, mandatory, c40); check_command_(WRITE_CURRENT_IAC_LAP, c125, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 45 of 49) check_command_(WRITE_DEFAULT_ERRONEOUS_DATA_REPORTING, c135, excluded); check_command_(WRITE_DEFAULT_LINK_POLICY_SETTINGS, c141, excluded); check_command_(WRITE_EXTENDED_INQUIRY_LENGTH, c128, excluded); check_command_(WRITE_EXTENDED_INQUIRY_RESPONSE, c205, excluded); check_command_(WRITE_EXTENDED_PAGE_TIMEOUT, optional, excluded); check_command_(WRITE_FLOW_CONTROL_MODE, c124, excluded); check_command_(WRITE_HOLD_MODE_ACTIVITY, c213, excluded); check_command_(WRITE_INQUIRY_MODE, c146, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 46 of 49) check_command_(WRITE_INQUIRY_SCAN_ACTIVITY, c125, excluded); check_command_(WRITE_INQUIRY_SCAN_TYPE, c125, excluded); check_command_(WRITE_INQUIRY_TRANSMIT_POWER_LEVEL, c127, excluded); check_command_(WRITE_LE_HOST_SUPPORT, c153, optional); check_command_(WRITE_LINK_POLICY_SETTINGS, c141, excluded); check_command_(WRITE_LINK_SUPERVISION_TIMEOUT, optional, excluded); check_command_(WRITE_LOCAL_NAME, mandatory, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 47 of 49) check_command_(WRITE_LOOPBACK_MODE, c123, excluded); check_command_(WRITE_NUM_BROADCAST_RETRANSMITS, optional, excluded); check_command_(WRITE_PAGE_SCAN_ACTIVITY, mandatory, excluded); check_command_(WRITE_PAGE_SCAN_TYPE, c154, excluded); check_command_(WRITE_PAGE_TIMEOUT, mandatory, excluded); check_command_(WRITE_PIN_TYPE, optional, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 48 of 49) check_command_(WRITE_SCAN_ENABLE, mandatory, excluded); check_command_(WRITE_SECURE_CONNECTIONS_HOST_SUPPORT, c218, excluded); check_command_(WRITE_SECURE_CONNECTIONS_TEST_MODE, c138, excluded); check_command_(WRITE_SIMPLE_PAIRING_DEBUG_MODE, mandatory, excluded); check_command_(WRITE_SIMPLE_PAIRING_MODE, mandatory, excluded); check_command_(WRITE_STORED_LINK_KEY, optional, excluded); check_command_(WRITE_SYNCHRONIZATION_TRAIN_PARAMETERS, c203, excluded); // Table 3.1: Alphabetical list of commands and events (Sheet 49 of 49) check_command_(WRITE_SYNCHRONOUS_FLOW_CONTROL_ENABLE, c135, excluded); check_command_(WRITE_VOICE_SETTING, c134, excluded); return true; } ControllerProperties::ControllerProperties() : supported_commands(std::move(SupportedCommands())), lmp_features({Page0LmpFeatures(), 0, Page2LmpFeatures()}), le_features(LlFeatures()) { if (!CheckSupportedFeatures()) { INFO( "Warning: initial LMP and/or LE are not consistent. Please make sure" " that the features are correct w.r.t. the rules described" " in Vol 2, Part C 3.5 Feature requirements"); } if (!CheckSupportedCommands()) { INFO( "Warning: initial supported commands are not consistent. Please make" " sure that the supported commands are correct w.r.t. the rules" " described in Vol 4, Part E § 3 Overview of commands and events"); } } // Commands enabled by the LE Extended Advertising feature bit. static std::vector le_extended_advertising_commands_ = { OpCodeIndex::LE_CLEAR_ADVERTISING_SETS, OpCodeIndex::LE_EXTENDED_CREATE_CONNECTION, OpCodeIndex::LE_READ_MAXIMUM_ADVERTISING_DATA_LENGTH, OpCodeIndex::LE_READ_NUMBER_OF_SUPPORTED_ADVERTISING_SETS, OpCodeIndex::LE_RECEIVER_TEST_V2, OpCodeIndex::LE_REMOVE_ADVERTISING_SET, OpCodeIndex::LE_SET_ADVERTISING_SET_RANDOM_ADDRESS, OpCodeIndex::LE_SET_DATA_RELATED_ADDRESS_CHANGES, OpCodeIndex::LE_SET_EXTENDED_ADVERTISING_DATA, OpCodeIndex::LE_SET_EXTENDED_ADVERTISING_ENABLE, OpCodeIndex::LE_SET_EXTENDED_ADVERTISING_PARAMETERS, OpCodeIndex::LE_SET_EXTENDED_SCAN_ENABLE, OpCodeIndex::LE_SET_EXTENDED_SCAN_PARAMETERS, OpCodeIndex::LE_SET_EXTENDED_SCAN_RESPONSE_DATA, }; // Commands enabled by the LE Periodic Advertising feature bit. static std::vector le_periodic_advertising_commands_ = { OpCodeIndex::LE_ADD_DEVICE_TO_PERIODIC_ADVERTISER_LIST, OpCodeIndex::LE_CLEAR_PERIODIC_ADVERTISER_LIST, OpCodeIndex::LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL, OpCodeIndex::LE_PERIODIC_ADVERTISING_CREATE_SYNC, OpCodeIndex::LE_PERIODIC_ADVERTISING_TERMINATE_SYNC, OpCodeIndex::LE_READ_PERIODIC_ADVERTISER_LIST_SIZE, OpCodeIndex::LE_RECEIVER_TEST_V2, OpCodeIndex::LE_REMOVE_DEVICE_FROM_PERIODIC_ADVERTISER_LIST, OpCodeIndex::LE_SET_DATA_RELATED_ADDRESS_CHANGES, OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_DATA, OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_ENABLE, OpCodeIndex::LE_SET_PERIODIC_ADVERTISING_PARAMETERS, }; // Commands enabled by the LL Privacy feature bit. static std::vector ll_privacy_commands_ = { OpCodeIndex::LE_ADD_DEVICE_TO_RESOLVING_LIST, OpCodeIndex::LE_CLEAR_RESOLVING_LIST, OpCodeIndex::LE_READ_LOCAL_RESOLVABLE_ADDRESS, OpCodeIndex::LE_READ_PEER_RESOLVABLE_ADDRESS, OpCodeIndex::LE_READ_RESOLVING_LIST_SIZE, OpCodeIndex::LE_RECEIVER_TEST_V2, OpCodeIndex::LE_REMOVE_DEVICE_FROM_RESOLVING_LIST, OpCodeIndex::LE_SET_ADDRESS_RESOLUTION_ENABLE, OpCodeIndex::LE_SET_PRIVACY_MODE, OpCodeIndex::LE_SET_RESOLVABLE_PRIVATE_ADDRESS_TIMEOUT, }; // Commands enabled by the LL Connected Isochronous Stream feature bit. // Central and Peripheral support bits are enabled together. static std::vector ll_connected_isochronous_stream_commands_ = { OpCodeIndex::LE_SET_CIG_PARAMETERS, OpCodeIndex::LE_SET_CIG_PARAMETERS_TEST, OpCodeIndex::LE_CREATE_CIS, OpCodeIndex::LE_REMOVE_CIG, OpCodeIndex::LE_ACCEPT_CIS_REQUEST, OpCodeIndex::LE_REJECT_CIS_REQUEST, OpCodeIndex::LE_SETUP_ISO_DATA_PATH, OpCodeIndex::LE_REMOVE_ISO_DATA_PATH, OpCodeIndex::LE_REQUEST_PEER_SCA, }; static void SetLLFeatureBit(uint64_t& le_features, LLFeaturesBits bit, bool set) { if (set) { le_features |= static_cast(bit); } else { le_features &= ~static_cast(bit); } } static void SetSupportedCommandBits(std::array& supported_commands, std::vector const& commands, bool set) { for (auto command : commands) { int index = static_cast(command); if (set) { supported_commands[index / 10] |= 1U << (index % 10); } else { supported_commands[index / 10] &= ~(1U << (index % 10)); } } } ControllerProperties::ControllerProperties( rootcanal::configuration::Controller const& config) : strict(!config.has_strict() || config.strict()), supported_commands(std::move(SupportedCommands())), lmp_features({Page0LmpFeatures(), 0, Page2LmpFeatures()}), le_features(LlFeatures()) { using namespace rootcanal::configuration; // Set the base configuration. if (config.has_preset()) { switch (config.preset()) { case ControllerPreset::DEFAULT: break; case ControllerPreset::LAIRD_BL654: // Configuration extracted with the helper script controller_info.py br_supported = false; le_supported = true; hci_version = bluetooth::hci::HciVersion::V_5_4; hci_subversion = 0x5ad2; lmp_version = bluetooth::hci::LmpVersion::V_5_4; lmp_subversion = 0x5ad2; company_identifier = 0x7e8; supported_commands = std::array{ 0x20, 0x00, 0x80, 0x00, 0x00, 0xc0, 0x00, 0x0c, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x28, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xf7, 0xff, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x30, 0xf0, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1f, 0xe0, 0xf7, 0xff, 0xff, 0xff, 0xc1, 0xe3, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; lmp_features = std::array { 0x6000000000, 0x0, 0x0 }; le_features = 0x19beff017fff; le_acl_data_packet_length = 512; total_num_le_acl_data_packets = 4; iso_data_packet_length = 512; total_num_iso_data_packets = 5; le_filter_accept_list_size = 4; le_resolving_list_size = 4; le_supported_states = 0x3ffffffffff; le_max_advertising_data_length = 256; le_num_supported_advertising_sets = 4; le_periodic_advertiser_list_size = 4; break; case ControllerPreset::CSR_RCK_PTS_DONGLE: // Configuration extracted with the helper script controller_info.py supports_csr_vendor_command = true; br_supported = true; le_supported = true; hci_version = bluetooth::hci::HciVersion::V_4_2; hci_subversion = 0x30e8; lmp_version = bluetooth::hci::LmpVersion::V_4_2; lmp_subversion = 0x30e8; company_identifier = 0xa; supported_commands = std::array { 0xff, 0xff, 0xff, 0x03, 0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xf3, 0x0f, 0xe8, 0xfe, 0x3f, 0xf7, 0x83, 0xff, 0x1c, 0x00, 0x04, 0x00, 0x61, 0xf7, 0xff, 0xff, 0x7f, 0x00, 0xc0, 0xff, 0xff, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, }; lmp_features = std::array { 0x875b1fd87e8fffff, 0x0, 0x30f }; acl_data_packet_length = 310; total_num_acl_data_packets = 10; sco_data_packet_length = 64; total_num_sco_data_packets = 8; num_supported_iac = 2; le_features = 0x1f; le_acl_data_packet_length = 0; total_num_le_acl_data_packets = 0; le_filter_accept_list_size = 25; le_supported_states = 0x3ffffffffff; break; default: break; } } // Apply selected features. if (config.has_features()) { ControllerFeatures const& features = config.features(); if (features.has_le_extended_advertising()) { SetLLFeatureBit(le_features, LLFeaturesBits::LE_EXTENDED_ADVERTISING, features.le_extended_advertising()); SetSupportedCommandBits(supported_commands, le_extended_advertising_commands_, features.le_extended_advertising()); } if (features.has_le_periodic_advertising()) { SetLLFeatureBit(le_features, LLFeaturesBits::LE_PERIODIC_ADVERTISING, features.le_periodic_advertising()); SetSupportedCommandBits(supported_commands, le_periodic_advertising_commands_, features.le_periodic_advertising()); } if (features.has_ll_privacy()) { SetLLFeatureBit(le_features, LLFeaturesBits::LL_PRIVACY, features.ll_privacy()); SetSupportedCommandBits(supported_commands, ll_privacy_commands_, features.ll_privacy()); } if (features.has_le_2m_phy()) { SetLLFeatureBit(le_features, LLFeaturesBits::LE_2M_PHY, features.le_2m_phy()); } if (features.has_le_coded_phy()) { SetLLFeatureBit(le_features, LLFeaturesBits::LE_CODED_PHY, features.le_coded_phy()); } if (features.has_le_connected_isochronous_stream()) { SetLLFeatureBit(le_features, LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_CENTRAL, features.le_connected_isochronous_stream()); SetLLFeatureBit(le_features, LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_PERIPHERAL, features.le_connected_isochronous_stream()); SetSupportedCommandBits(supported_commands, ll_connected_isochronous_stream_commands_, features.le_connected_isochronous_stream()); } } // Apply selected quirks. if (config.has_quirks()) { if (config.quirks().has_has_default_random_address()) { quirks.has_default_random_address = config.quirks().has_default_random_address(); } if (config.quirks().has_hardware_error_before_reset()) { quirks.hardware_error_before_reset = config.quirks().hardware_error_before_reset(); } // TODO(b/270606199): support send_acl_data_before_connection_complete } // Apply selected vendor features. if (config.has_vendor()) { if (config.vendor().has_csr()) { supports_csr_vendor_command = config.vendor().csr(); } if (config.vendor().has_android()) { supports_le_get_vendor_capabilities_command = config.vendor().android(); supports_le_apcf_vendor_command = config.vendor().android(); } } if (!CheckSupportedFeatures()) { INFO( "Warning: LMP and/or LE features are not consistent. Please make sure" " that the features are correct w.r.t. the rules described" " in Vol 2, Part C 3.5 Feature requirements"); } if (!CheckSupportedCommands()) { INFO( "Warning: supported commands are not consistent. Please make" " sure that the supported commands are correct w.r.t. the rules" " described in Vol 4, Part E § 3 Overview of commands and events"); } } } // namespace rootcanal