Loading tools/rootcanal/model/controller/controller_properties.cc +5 −5 Original line number Diff line number Diff line Loading @@ -106,9 +106,11 @@ static constexpr uint64_t LlFeatures() { 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, // TODO: breaks AVD boot tests with LE audio // LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_CENTRAL, Loading Loading @@ -326,10 +328,8 @@ static std::array<uint8_t, 64> SupportedCommands() { // 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_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, Loading tools/rootcanal/model/controller/controller_properties.h +13 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,19 @@ struct ControllerProperties { return (supported_commands[index / 10] & (UINT64_C(1) << (index % 10))) != 0; } /// Return a bit mask with all supported PHYs /// (0b001 = LE_1M, 0b010 = LE_2M, 0b100 = LE_CODED). uint8_t LeSupportedPhys() const { uint8_t supported_phys = 0x1; // LE_1M is always supported. if (SupportsLLFeature(bluetooth::hci::LLFeaturesBits::LE_2M_PHY)) { supported_phys |= 0x2; } if (SupportsLLFeature(bluetooth::hci::LLFeaturesBits::LE_CODED_PHY)) { supported_phys |= 0x4; } return supported_phys; } }; } // namespace rootcanal tools/rootcanal/model/controller/dual_mode_controller.cc +45 −3 Original line number Diff line number Diff line Loading @@ -2150,6 +2150,48 @@ void DualModeController::LeReadMaximumDataLength(CommandView command) { kNumCommandPackets, ErrorCode::SUCCESS, data_length)); } void DualModeController::LeReadPhy(CommandView command) { auto command_view = gd_hci::LeReadPhyView::Create( gd_hci::LeConnectionManagementCommandView::Create( gd_hci::AclCommandView::Create(command))); ASSERT(command_view.IsValid()); uint16_t connection_handle = command_view.GetConnectionHandle(); bluetooth::hci::PhyType tx_phy{}; bluetooth::hci::PhyType rx_phy{}; ErrorCode status = link_layer_controller_.LeReadPhy(connection_handle, &tx_phy, &rx_phy); send_event_(bluetooth::hci::LeReadPhyCompleteBuilder::Create( kNumCommandPackets, status, connection_handle, tx_phy, rx_phy)); } void DualModeController::LeSetDefaultPhy(CommandView command) { auto command_view = gd_hci::LeSetDefaultPhyView::Create( gd_hci::LeConnectionManagementCommandView::Create( gd_hci::AclCommandView::Create(command))); ASSERT(command_view.IsValid()); ErrorCode status = link_layer_controller_.LeSetDefaultPhy( command_view.GetAllPhysNoTransmitPreference(), command_view.GetAllPhysNoReceivePreference(), command_view.GetTxPhysBitmask(), command_view.GetRxPhysBitmask()); send_event_(bluetooth::hci::LeSetDefaultPhyCompleteBuilder::Create( kNumCommandPackets, status)); } void DualModeController::LeSetPhy(CommandView command) { auto command_view = gd_hci::LeSetPhyView::Create( gd_hci::LeConnectionManagementCommandView::Create( gd_hci::AclCommandView::Create(command))); ASSERT(command_view.IsValid()); ErrorCode status = link_layer_controller_.LeSetPhy( command_view.GetConnectionHandle(), command_view.GetAllPhysNoTransmitPreference(), command_view.GetAllPhysNoReceivePreference(), command_view.GetTxPhysBitmask(), command_view.GetRxPhysBitmask(), command_view.GetPhyOptions()); send_event_(bluetooth::hci::LeSetPhyStatusBuilder::Create( status, kNumCommandPackets)); } void DualModeController::LeReadSuggestedDefaultDataLength(CommandView command) { auto command_view = gd_hci::LeReadSuggestedDefaultDataLengthView::Create( gd_hci::LeConnectionManagementCommandView::Create( Loading Loading @@ -3827,9 +3869,9 @@ const std::unordered_map<OpCode, DualModeController::CommandHandler> &DualModeController::LeSetResolvablePrivateAddressTimeout}, {OpCode::LE_READ_MAXIMUM_DATA_LENGTH, &DualModeController::LeReadMaximumDataLength}, //{OpCode::LE_READ_PHY, &DualModeController::LeReadPhy}, //{OpCode::LE_SET_DEFAULT_PHY, &DualModeController::LeSetDefaultPhy}, //{OpCode::LE_SET_PHY, &DualModeController::LeSetPhy}, {OpCode::LE_READ_PHY, &DualModeController::LeReadPhy}, {OpCode::LE_SET_DEFAULT_PHY, &DualModeController::LeSetDefaultPhy}, {OpCode::LE_SET_PHY, &DualModeController::LeSetPhy}, //{OpCode::LE_RECEIVER_TEST_V2, &DualModeController::LeReceiverTestV2}, //{OpCode::LE_TRANSMITTER_TEST_V2, //&DualModeController::LeTransmitterTestV2}, Loading tools/rootcanal/model/controller/dual_mode_controller.h +4 −0 Original line number Diff line number Diff line Loading @@ -529,6 +529,10 @@ class DualModeController : public Device { // 7.8.46 void LeReadMaximumDataLength(CommandView command); void LeReadPhy(CommandView command); void LeSetDefaultPhy(CommandView command); void LeSetPhy(CommandView command); // 7.8.52 void LeSetAdvertisingSetRandomAddress(CommandView command); Loading tools/rootcanal/model/controller/link_layer_controller.cc +129 −1 Original line number Diff line number Diff line Loading @@ -284,6 +284,132 @@ ErrorCode LinkLayerController::LeSetResolvablePrivateAddressTimeout( return ErrorCode::SUCCESS; } // HCI LE Read Phy command (Vol 4, Part E § 7.8.47). ErrorCode LinkLayerController::LeReadPhy(uint16_t connection_handle, bluetooth::hci::PhyType* tx_phy, bluetooth::hci::PhyType* rx_phy) { // Note: no documented status code for this case. if (!connections_.HasHandle(connection_handle) || connections_.GetPhyType(connection_handle) != Phy::Type::LOW_ENERGY) { LOG_INFO("unknown or invalid connection handle"); return ErrorCode::UNKNOWN_CONNECTION; } // TODO(b/275970864) save the phy in the connection state. *tx_phy = bluetooth::hci::PhyType::LE_1M; *rx_phy = bluetooth::hci::PhyType::LE_1M; return ErrorCode::SUCCESS; } // HCI LE Set Default Phy command (Vol 4, Part E § 7.8.48). ErrorCode LinkLayerController::LeSetDefaultPhy( bool all_phys_no_transmit_preference, bool all_phys_no_receive_preference, uint8_t tx_phys, uint8_t rx_phys) { uint8_t supported_phys = properties_.LeSupportedPhys(); // If the All_PHYs parameter specifies that the Host has no preference, // the TX_PHYs parameter shall be ignored; otherwise at least one bit shall // be set to 1. if (all_phys_no_transmit_preference) { tx_phys = 0x1; // LE_1M_PHY by default. } if (tx_phys == 0) { LOG_INFO("TX_Phys does not configure any bit"); return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; } // If the All_PHYs parameter specifies that the Host has no preference, // the RX_PHYs parameter shall be ignored; otherwise at least one bit shall // be set to 1. if (all_phys_no_receive_preference) { rx_phys = 0x1; // LE_1M_PHY by default. } if (rx_phys == 0) { LOG_INFO("RX_Phys does not configure any bit"); return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; } // If the Host sets, in the TX_PHYs or RX_PHYs parameter, a bit for a PHY that // the Controller does not support, including a bit that is reserved for // future use, the Controller shall return the error code Unsupported Feature // or Parameter Value (0x11). if ((tx_phys & ~supported_phys) != 0) { LOG_INFO("TX_PhyS (%x) configures unsupported or reserved bits", tx_phys); return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; } if ((rx_phys & ~supported_phys) != 0) { LOG_INFO("RX_PhyS (%x) configures unsupported or reserved bits", rx_phys); return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; } // TODO(b/275970864) save the phy default preference. return ErrorCode::SUCCESS; } // HCI LE Set Phy command (Vol 4, Part E § 7.8.49). ErrorCode LinkLayerController::LeSetPhy( uint16_t connection_handle, bool all_phys_no_transmit_preference, bool all_phys_no_receive_preference, uint8_t tx_phys, uint8_t rx_phys, bluetooth::hci::PhyOptions phy_options) { uint8_t supported_phys = properties_.LeSupportedPhys(); // Note: no documented status code for this case. if (!connections_.HasHandle(connection_handle) || connections_.GetPhyType(connection_handle) != Phy::Type::LOW_ENERGY) { LOG_INFO("unknown or invalid connection handle"); return ErrorCode::UNKNOWN_CONNECTION; } // If the All_PHYs parameter specifies that the Host has no preference, // the TX_PHYs parameter shall be ignored; otherwise at least one bit shall // be set to 1. if (all_phys_no_transmit_preference) { tx_phys = 0x1; // LE_1M_PHY by default. } if (tx_phys == 0) { LOG_INFO("TX_Phys does not configure any bit"); return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; } // If the All_PHYs parameter specifies that the Host has no preference, // the RX_PHYs parameter shall be ignored; otherwise at least one bit shall // be set to 1. if (all_phys_no_receive_preference) { rx_phys = 0x1; // LE_1M_PHY by default. } if (rx_phys == 0) { LOG_INFO("RX_Phys does not configure any bit"); return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; } // If the Host sets, in the TX_PHYs or RX_PHYs parameter, a bit for a PHY that // the Controller does not support, including a bit that is reserved for // future use, the Controller shall return the error code Unsupported Feature // or Parameter Value (0x11). if ((tx_phys & ~supported_phys) != 0) { LOG_INFO("TX_PhyS (%x) configures unsupported or reserved bits", tx_phys); return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; } if ((rx_phys & ~supported_phys) != 0) { LOG_INFO("RX_PhyS (%x) configures unsupported or reserved bits", rx_phys); return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; } // The HCI_LE_PHY_Update_Complete event shall be generated either when one // or both PHY changes or when the Controller determines that neither PHY // will change immediately. // TODO(b/275970864) send LL_PHY_REQ to the peer. ScheduleTask(0ms, [this, connection_handle] { send_event_(bluetooth::hci::LePhyUpdateCompleteBuilder::Create( ErrorCode::SUCCESS, connection_handle, static_cast<uint8_t>(bluetooth::hci::PhyType::LE_1M), static_cast<uint8_t>(bluetooth::hci::PhyType::LE_1M))); }); // TODO(b/275970864) save the phy preference. return ErrorCode::SUCCESS; } // HCI LE Set Host Feature command (Vol 4, Part E § 7.8.115). ErrorCode LinkLayerController::LeSetHostFeature(uint8_t bit_number, uint8_t bit_value) { Loading Loading @@ -683,6 +809,8 @@ ErrorCode LinkLayerController::LeSetExtendedScanParameters( bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy, uint8_t scanning_phys, std::vector<bluetooth::hci::PhyScanParameters> scanning_phy_parameters) { uint8_t supported_phys = properties_.LeSupportedPhys(); // Extended advertising commands are disallowed when legacy advertising // commands were used since the last reset. if (!SelectExtendedAdvertising()) { Loading @@ -702,7 +830,7 @@ ErrorCode LinkLayerController::LeSetExtendedScanParameters( // If the Host specifies a PHY that is not supported by the Controller, // including a bit that is reserved for future use, it should return the // error code Unsupported Feature or Parameter Value (0x11). if ((scanning_phys & 0xfa) != 0) { if ((scanning_phys & ~supported_phys) != 0) { LOG_INFO( "scanning_phys (%02x) enables PHYs that are not supported by" " the controller", Loading Loading
tools/rootcanal/model/controller/controller_properties.cc +5 −5 Original line number Diff line number Diff line Loading @@ -106,9 +106,11 @@ static constexpr uint64_t LlFeatures() { 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, // TODO: breaks AVD boot tests with LE audio // LLFeaturesBits::CONNECTED_ISOCHRONOUS_STREAM_CENTRAL, Loading Loading @@ -326,10 +328,8 @@ static std::array<uint8_t, 64> SupportedCommands() { // 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_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, Loading
tools/rootcanal/model/controller/controller_properties.h +13 −0 Original line number Diff line number Diff line Loading @@ -137,6 +137,19 @@ struct ControllerProperties { return (supported_commands[index / 10] & (UINT64_C(1) << (index % 10))) != 0; } /// Return a bit mask with all supported PHYs /// (0b001 = LE_1M, 0b010 = LE_2M, 0b100 = LE_CODED). uint8_t LeSupportedPhys() const { uint8_t supported_phys = 0x1; // LE_1M is always supported. if (SupportsLLFeature(bluetooth::hci::LLFeaturesBits::LE_2M_PHY)) { supported_phys |= 0x2; } if (SupportsLLFeature(bluetooth::hci::LLFeaturesBits::LE_CODED_PHY)) { supported_phys |= 0x4; } return supported_phys; } }; } // namespace rootcanal
tools/rootcanal/model/controller/dual_mode_controller.cc +45 −3 Original line number Diff line number Diff line Loading @@ -2150,6 +2150,48 @@ void DualModeController::LeReadMaximumDataLength(CommandView command) { kNumCommandPackets, ErrorCode::SUCCESS, data_length)); } void DualModeController::LeReadPhy(CommandView command) { auto command_view = gd_hci::LeReadPhyView::Create( gd_hci::LeConnectionManagementCommandView::Create( gd_hci::AclCommandView::Create(command))); ASSERT(command_view.IsValid()); uint16_t connection_handle = command_view.GetConnectionHandle(); bluetooth::hci::PhyType tx_phy{}; bluetooth::hci::PhyType rx_phy{}; ErrorCode status = link_layer_controller_.LeReadPhy(connection_handle, &tx_phy, &rx_phy); send_event_(bluetooth::hci::LeReadPhyCompleteBuilder::Create( kNumCommandPackets, status, connection_handle, tx_phy, rx_phy)); } void DualModeController::LeSetDefaultPhy(CommandView command) { auto command_view = gd_hci::LeSetDefaultPhyView::Create( gd_hci::LeConnectionManagementCommandView::Create( gd_hci::AclCommandView::Create(command))); ASSERT(command_view.IsValid()); ErrorCode status = link_layer_controller_.LeSetDefaultPhy( command_view.GetAllPhysNoTransmitPreference(), command_view.GetAllPhysNoReceivePreference(), command_view.GetTxPhysBitmask(), command_view.GetRxPhysBitmask()); send_event_(bluetooth::hci::LeSetDefaultPhyCompleteBuilder::Create( kNumCommandPackets, status)); } void DualModeController::LeSetPhy(CommandView command) { auto command_view = gd_hci::LeSetPhyView::Create( gd_hci::LeConnectionManagementCommandView::Create( gd_hci::AclCommandView::Create(command))); ASSERT(command_view.IsValid()); ErrorCode status = link_layer_controller_.LeSetPhy( command_view.GetConnectionHandle(), command_view.GetAllPhysNoTransmitPreference(), command_view.GetAllPhysNoReceivePreference(), command_view.GetTxPhysBitmask(), command_view.GetRxPhysBitmask(), command_view.GetPhyOptions()); send_event_(bluetooth::hci::LeSetPhyStatusBuilder::Create( status, kNumCommandPackets)); } void DualModeController::LeReadSuggestedDefaultDataLength(CommandView command) { auto command_view = gd_hci::LeReadSuggestedDefaultDataLengthView::Create( gd_hci::LeConnectionManagementCommandView::Create( Loading Loading @@ -3827,9 +3869,9 @@ const std::unordered_map<OpCode, DualModeController::CommandHandler> &DualModeController::LeSetResolvablePrivateAddressTimeout}, {OpCode::LE_READ_MAXIMUM_DATA_LENGTH, &DualModeController::LeReadMaximumDataLength}, //{OpCode::LE_READ_PHY, &DualModeController::LeReadPhy}, //{OpCode::LE_SET_DEFAULT_PHY, &DualModeController::LeSetDefaultPhy}, //{OpCode::LE_SET_PHY, &DualModeController::LeSetPhy}, {OpCode::LE_READ_PHY, &DualModeController::LeReadPhy}, {OpCode::LE_SET_DEFAULT_PHY, &DualModeController::LeSetDefaultPhy}, {OpCode::LE_SET_PHY, &DualModeController::LeSetPhy}, //{OpCode::LE_RECEIVER_TEST_V2, &DualModeController::LeReceiverTestV2}, //{OpCode::LE_TRANSMITTER_TEST_V2, //&DualModeController::LeTransmitterTestV2}, Loading
tools/rootcanal/model/controller/dual_mode_controller.h +4 −0 Original line number Diff line number Diff line Loading @@ -529,6 +529,10 @@ class DualModeController : public Device { // 7.8.46 void LeReadMaximumDataLength(CommandView command); void LeReadPhy(CommandView command); void LeSetDefaultPhy(CommandView command); void LeSetPhy(CommandView command); // 7.8.52 void LeSetAdvertisingSetRandomAddress(CommandView command); Loading
tools/rootcanal/model/controller/link_layer_controller.cc +129 −1 Original line number Diff line number Diff line Loading @@ -284,6 +284,132 @@ ErrorCode LinkLayerController::LeSetResolvablePrivateAddressTimeout( return ErrorCode::SUCCESS; } // HCI LE Read Phy command (Vol 4, Part E § 7.8.47). ErrorCode LinkLayerController::LeReadPhy(uint16_t connection_handle, bluetooth::hci::PhyType* tx_phy, bluetooth::hci::PhyType* rx_phy) { // Note: no documented status code for this case. if (!connections_.HasHandle(connection_handle) || connections_.GetPhyType(connection_handle) != Phy::Type::LOW_ENERGY) { LOG_INFO("unknown or invalid connection handle"); return ErrorCode::UNKNOWN_CONNECTION; } // TODO(b/275970864) save the phy in the connection state. *tx_phy = bluetooth::hci::PhyType::LE_1M; *rx_phy = bluetooth::hci::PhyType::LE_1M; return ErrorCode::SUCCESS; } // HCI LE Set Default Phy command (Vol 4, Part E § 7.8.48). ErrorCode LinkLayerController::LeSetDefaultPhy( bool all_phys_no_transmit_preference, bool all_phys_no_receive_preference, uint8_t tx_phys, uint8_t rx_phys) { uint8_t supported_phys = properties_.LeSupportedPhys(); // If the All_PHYs parameter specifies that the Host has no preference, // the TX_PHYs parameter shall be ignored; otherwise at least one bit shall // be set to 1. if (all_phys_no_transmit_preference) { tx_phys = 0x1; // LE_1M_PHY by default. } if (tx_phys == 0) { LOG_INFO("TX_Phys does not configure any bit"); return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; } // If the All_PHYs parameter specifies that the Host has no preference, // the RX_PHYs parameter shall be ignored; otherwise at least one bit shall // be set to 1. if (all_phys_no_receive_preference) { rx_phys = 0x1; // LE_1M_PHY by default. } if (rx_phys == 0) { LOG_INFO("RX_Phys does not configure any bit"); return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; } // If the Host sets, in the TX_PHYs or RX_PHYs parameter, a bit for a PHY that // the Controller does not support, including a bit that is reserved for // future use, the Controller shall return the error code Unsupported Feature // or Parameter Value (0x11). if ((tx_phys & ~supported_phys) != 0) { LOG_INFO("TX_PhyS (%x) configures unsupported or reserved bits", tx_phys); return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; } if ((rx_phys & ~supported_phys) != 0) { LOG_INFO("RX_PhyS (%x) configures unsupported or reserved bits", rx_phys); return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; } // TODO(b/275970864) save the phy default preference. return ErrorCode::SUCCESS; } // HCI LE Set Phy command (Vol 4, Part E § 7.8.49). ErrorCode LinkLayerController::LeSetPhy( uint16_t connection_handle, bool all_phys_no_transmit_preference, bool all_phys_no_receive_preference, uint8_t tx_phys, uint8_t rx_phys, bluetooth::hci::PhyOptions phy_options) { uint8_t supported_phys = properties_.LeSupportedPhys(); // Note: no documented status code for this case. if (!connections_.HasHandle(connection_handle) || connections_.GetPhyType(connection_handle) != Phy::Type::LOW_ENERGY) { LOG_INFO("unknown or invalid connection handle"); return ErrorCode::UNKNOWN_CONNECTION; } // If the All_PHYs parameter specifies that the Host has no preference, // the TX_PHYs parameter shall be ignored; otherwise at least one bit shall // be set to 1. if (all_phys_no_transmit_preference) { tx_phys = 0x1; // LE_1M_PHY by default. } if (tx_phys == 0) { LOG_INFO("TX_Phys does not configure any bit"); return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; } // If the All_PHYs parameter specifies that the Host has no preference, // the RX_PHYs parameter shall be ignored; otherwise at least one bit shall // be set to 1. if (all_phys_no_receive_preference) { rx_phys = 0x1; // LE_1M_PHY by default. } if (rx_phys == 0) { LOG_INFO("RX_Phys does not configure any bit"); return ErrorCode::INVALID_HCI_COMMAND_PARAMETERS; } // If the Host sets, in the TX_PHYs or RX_PHYs parameter, a bit for a PHY that // the Controller does not support, including a bit that is reserved for // future use, the Controller shall return the error code Unsupported Feature // or Parameter Value (0x11). if ((tx_phys & ~supported_phys) != 0) { LOG_INFO("TX_PhyS (%x) configures unsupported or reserved bits", tx_phys); return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; } if ((rx_phys & ~supported_phys) != 0) { LOG_INFO("RX_PhyS (%x) configures unsupported or reserved bits", rx_phys); return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE; } // The HCI_LE_PHY_Update_Complete event shall be generated either when one // or both PHY changes or when the Controller determines that neither PHY // will change immediately. // TODO(b/275970864) send LL_PHY_REQ to the peer. ScheduleTask(0ms, [this, connection_handle] { send_event_(bluetooth::hci::LePhyUpdateCompleteBuilder::Create( ErrorCode::SUCCESS, connection_handle, static_cast<uint8_t>(bluetooth::hci::PhyType::LE_1M), static_cast<uint8_t>(bluetooth::hci::PhyType::LE_1M))); }); // TODO(b/275970864) save the phy preference. return ErrorCode::SUCCESS; } // HCI LE Set Host Feature command (Vol 4, Part E § 7.8.115). ErrorCode LinkLayerController::LeSetHostFeature(uint8_t bit_number, uint8_t bit_value) { Loading Loading @@ -683,6 +809,8 @@ ErrorCode LinkLayerController::LeSetExtendedScanParameters( bluetooth::hci::LeScanningFilterPolicy scanning_filter_policy, uint8_t scanning_phys, std::vector<bluetooth::hci::PhyScanParameters> scanning_phy_parameters) { uint8_t supported_phys = properties_.LeSupportedPhys(); // Extended advertising commands are disallowed when legacy advertising // commands were used since the last reset. if (!SelectExtendedAdvertising()) { Loading @@ -702,7 +830,7 @@ ErrorCode LinkLayerController::LeSetExtendedScanParameters( // If the Host specifies a PHY that is not supported by the Controller, // including a bit that is reserved for future use, it should return the // error code Unsupported Feature or Parameter Value (0x11). if ((scanning_phys & 0xfa) != 0) { if ((scanning_phys & ~supported_phys) != 0) { LOG_INFO( "scanning_phys (%02x) enables PHYs that are not supported by" " the controller", Loading