From 3a9e43f5e4c09be131a8010cf3222164e83dcc55 Mon Sep 17 00:00:00 2001 From: Chienyuan Date: Wed, 2 Dec 2020 11:05:30 +0800 Subject: [PATCH] gd: Implement LE read advertising physical channel tx power Tag: #gd-refactor Bug: 169125803 Test: cert/run --host Test: atest --host bluetooth_test_gd Change-Id: Ida1ac156048c68247bd91ba929a1b70e6f26c6e9 --- gd/hci/controller.cc | 2 +- gd/hci/hci_packets.pdl | 10 +++++----- gd/hci/le_advertising_manager.cc | 20 ++++++++++++++++---- gd/hci/le_advertising_manager_test.cc | 20 ++++++++++++++++---- .../model/controller/dual_mode_controller.cc | 15 +++++++++++++++ .../model/controller/dual_mode_controller.h | 3 +++ .../model/devices/device_properties.h | 6 ++++++ 7 files changed, 62 insertions(+), 14 deletions(-) diff --git a/gd/hci/controller.cc b/gd/hci/controller.cc index 871f83a38..a8f423c27 100644 --- a/gd/hci/controller.cc +++ b/gd/hci/controller.cc @@ -651,7 +651,7 @@ struct Controller::impl { OP_CODE_MAPPING(LE_READ_LOCAL_SUPPORTED_FEATURES) OP_CODE_MAPPING(LE_SET_RANDOM_ADDRESS) OP_CODE_MAPPING(LE_SET_ADVERTISING_PARAMETERS) - OP_CODE_MAPPING(LE_READ_ADVERTISING_CHANNEL_TX_POWER) + OP_CODE_MAPPING(LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER) OP_CODE_MAPPING(LE_SET_ADVERTISING_DATA) OP_CODE_MAPPING(LE_SET_SCAN_RESPONSE_DATA) OP_CODE_MAPPING(LE_SET_ADVERTISING_ENABLE) diff --git a/gd/hci/hci_packets.pdl b/gd/hci/hci_packets.pdl index 45067d24e..3f58ab28f 100644 --- a/gd/hci/hci_packets.pdl +++ b/gd/hci/hci_packets.pdl @@ -243,7 +243,7 @@ enum OpCode : 16 { LE_READ_LOCAL_SUPPORTED_FEATURES = 0x2003, LE_SET_RANDOM_ADDRESS = 0x2005, LE_SET_ADVERTISING_PARAMETERS = 0x2006, - LE_READ_ADVERTISING_CHANNEL_TX_POWER = 0x2007, + LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER = 0x2007, LE_SET_ADVERTISING_DATA = 0x2008, LE_SET_SCAN_RESPONSE_DATA = 0x2009, LE_SET_ADVERTISING_ENABLE = 0x200A, @@ -496,7 +496,7 @@ enum OpCodeIndex : 16 { LE_READ_LOCAL_SUPPORTED_FEATURES = 252, LE_SET_RANDOM_ADDRESS = 254, LE_SET_ADVERTISING_PARAMETERS = 255, - LE_READ_ADVERTISING_CHANNEL_TX_POWER = 256, + LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER = 256, LE_SET_ADVERTISING_DATA = 257, LE_SET_SCAN_RESPONSE_DATA = 260, LE_SET_ADVERTISING_ENABLE = 261, @@ -2500,12 +2500,12 @@ packet LeSetAdvertisingParametersComplete : CommandComplete (command_op_code = L status : ErrorCode, } -packet LeReadAdvertisingChannelTxPower : LeAdvertisingCommand (op_code = LE_READ_ADVERTISING_CHANNEL_TX_POWER) { +packet LeReadAdvertisingPhysicalChannelTxPower : LeAdvertisingCommand (op_code = LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER) { } -packet LeReadAdvertisingChannelTxPowerComplete : CommandComplete (command_op_code = LE_READ_ADVERTISING_CHANNEL_TX_POWER) { +packet LeReadAdvertisingPhysicalChannelTxPowerComplete : CommandComplete (command_op_code = LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER) { status : ErrorCode, - transmit_power_level : 8, // (-20dBm to 10dBm) Accuracy: +/-4dB + transmit_power_level : 8, // (-127dBm to 20dBm) Accuracy: +/-4dB } packet LeSetAdvertisingData : LeAdvertisingCommand (op_code = LE_SET_ADVERTISING_DATA) { diff --git a/gd/hci/le_advertising_manager.cc b/gd/hci/le_advertising_manager.cc index 046440c85..9b5665e89 100644 --- a/gd/hci/le_advertising_manager.cc +++ b/gd/hci/le_advertising_manager.cc @@ -102,6 +102,9 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb advertising_api_type_ = AdvertisingApiType::ANDROID_HCI; } else { advertising_api_type_ = AdvertisingApiType::LEGACY; + hci_layer_->EnqueueCommand( + LeReadAdvertisingPhysicalChannelTxPowerBuilder::Create(), + handler->BindOnceOn(this, &impl::on_read_advertising_physical_channel_tx_power)); } } @@ -826,6 +829,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb hci::HciLayer* hci_layer_; hci::Controller* controller_; uint16_t le_maximum_advertising_data_length_; + int8_t le_physical_channel_tx_power_ = 0; hci::LeAdvertisingInterface* le_advertising_interface_; std::map advertising_sets_; hci::LeAddressManager* le_address_manager_; @@ -839,6 +843,16 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb AdvertisingApiType advertising_api_type_{0}; + void on_read_advertising_physical_channel_tx_power(CommandCompleteView view) { + auto complete_view = LeReadAdvertisingPhysicalChannelTxPowerCompleteView::Create(view); + ASSERT(complete_view.IsValid()); + if (complete_view.GetStatus() != ErrorCode::SUCCESS) { + LOG_INFO("Got a command complete with status %s", ErrorCodeText(complete_view.GetStatus()).c_str()); + return; + } + le_physical_channel_tx_power_ = complete_view.GetTransmitPowerLevel(); + } + template void on_set_advertising_enable_complete(bool enable, std::vector enabled_sets, CommandCompleteView view) { ASSERT(view.IsValid()); @@ -864,8 +878,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb } else { int reg_id = id_map_[id]; advertising_sets_[enabled_set.advertising_handle_].started = true; - // TODO read tx power - advertising_callbacks_->OnAdvertisingSetStarted(reg_id, id, 0x00, advertising_status); + advertising_callbacks_->OnAdvertisingSetStarted(reg_id, id, le_physical_channel_tx_power_, advertising_status); } } } @@ -965,8 +978,7 @@ struct LeAdvertisingManager::impl : public bluetooth::hci::LeAddressManagerCallb switch (opcode) { case OpCode::LE_SET_ADVERTISING_PARAMETERS: - // TODO read tx power - advertising_callbacks_->OnAdvertisingParametersUpdated(id, 0x00, advertising_status); + advertising_callbacks_->OnAdvertisingParametersUpdated(id, le_physical_channel_tx_power_, advertising_status); break; case OpCode::LE_SET_ADVERTISING_DATA: case OpCode::LE_SET_EXTENDED_ADVERTISING_DATA: diff --git a/gd/hci/le_advertising_manager_test.cc b/gd/hci/le_advertising_manager_test.cc index 23b952527..5f45a6e5a 100644 --- a/gd/hci/le_advertising_manager_test.cc +++ b/gd/hci/le_advertising_manager_test.cc @@ -401,6 +401,7 @@ class LeAdvertisingAPITest : public LeAdvertisingManagerTest { mock_advertising_callback_, OnAdvertisingSetStarted(0x00, advertiser_id_, 0x00, AdvertisingCallback::AdvertisingStatus::SUCCESS)); std::vector adv_opcodes = { + OpCode::LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER, OpCode::LE_SET_ADVERTISING_PARAMETERS, OpCode::LE_SET_SCAN_RESPONSE_DATA, OpCode::LE_SET_ADVERTISING_DATA, @@ -410,8 +411,13 @@ class LeAdvertisingAPITest : public LeAdvertisingManagerTest { for (size_t i = 0; i < adv_opcodes.size(); i++) { auto packet_view = test_hci_layer_->GetCommandPacket(adv_opcodes[i]); CommandPacketView command_packet_view = CommandPacketView::Create(packet_view); - test_hci_layer_->IncomingEvent( - CommandCompleteBuilder::Create(uint8_t{1}, adv_opcodes[i], std::make_unique(success_vector))); + if (adv_opcodes[i] == OpCode::LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER) { + test_hci_layer_->IncomingEvent( + LeReadAdvertisingPhysicalChannelTxPowerCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS, 0x00)); + } else { + test_hci_layer_->IncomingEvent( + CommandCompleteBuilder::Create(uint8_t{1}, adv_opcodes[i], std::make_unique(success_vector))); + } test_hci_layer_->SetCommandFuture(); } sync_client_handler(); @@ -521,6 +527,7 @@ TEST_F(LeAdvertisingManagerTest, create_advertiser_test) { 0x00, advertising_config, scan_callback, set_terminated_callback, client_handler_); ASSERT_NE(LeAdvertisingManager::kInvalidId, id); std::vector adv_opcodes = { + OpCode::LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER, OpCode::LE_SET_ADVERTISING_PARAMETERS, OpCode::LE_SET_SCAN_RESPONSE_DATA, OpCode::LE_SET_ADVERTISING_DATA, @@ -534,8 +541,13 @@ TEST_F(LeAdvertisingManagerTest, create_advertiser_test) { auto packet_view = test_hci_layer_->GetCommandPacket(adv_opcodes[i]); CommandPacketView command_packet_view = CommandPacketView::Create(packet_view); auto command = ConnectionManagementCommandView::Create(AclCommandView::Create(command_packet_view)); - test_hci_layer_->IncomingEvent( - CommandCompleteBuilder::Create(uint8_t{1}, adv_opcodes[i], std::make_unique(success_vector))); + if (adv_opcodes[i] == OpCode::LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER) { + test_hci_layer_->IncomingEvent( + LeReadAdvertisingPhysicalChannelTxPowerCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS, 0x00)); + } else { + test_hci_layer_->IncomingEvent( + CommandCompleteBuilder::Create(uint8_t{1}, adv_opcodes[i], std::make_unique(success_vector))); + } test_hci_layer_->SetCommandFuture(); } sync_client_handler(); diff --git a/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc b/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc index 45edc86b7..2dda81759 100644 --- a/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc +++ b/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.cc @@ -204,6 +204,8 @@ DualModeController::DualModeController(const std::string& properties_filename, u SET_HANDLER(OpCode::LE_SET_RANDOM_ADDRESS, LeSetRandomAddress); SET_HANDLER(OpCode::LE_SET_ADVERTISING_PARAMETERS, LeSetAdvertisingParameters); + SET_HANDLER(OpCode::LE_READ_ADVERTISING_PHYSICAL_CHANNEL_TX_POWER, + LeReadAdvertisingPhysicalChannelTxPower); SET_HANDLER(OpCode::LE_SET_ADVERTISING_DATA, LeSetAdvertisingData); SET_HANDLER(OpCode::LE_SET_SCAN_RESPONSE_DATA, LeSetScanResponseData); SET_HANDLER(OpCode::LE_SET_ADVERTISING_ENABLE, LeSetAdvertisingEnable); @@ -1592,6 +1594,19 @@ void DualModeController::LeSetAdvertisingParameters(CommandPacketView command) { send_event_(std::move(packet)); } +void DualModeController::LeReadAdvertisingPhysicalChannelTxPower( + CommandPacketView command) { + auto command_view = + gd_hci::LeReadAdvertisingPhysicalChannelTxPowerView::Create( + gd_hci::LeAdvertisingCommandView::Create(command)); + ASSERT(command_view.IsValid()); + auto packet = + bluetooth::hci::LeReadAdvertisingPhysicalChannelTxPowerCompleteBuilder:: + Create(kNumCommandPackets, ErrorCode::SUCCESS, + properties_.GetLeAdvertisingPhysicalChannelTxPower()); + send_event_(std::move(packet)); +} + void DualModeController::LeSetAdvertisingData(CommandPacketView command) { auto command_view = gd_hci::LeSetAdvertisingDataView::Create( gd_hci::LeAdvertisingCommandView::Create(command)); diff --git a/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h b/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h index 29c4d1e49..a3ae1efaf 100644 --- a/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h +++ b/vendor_libs/test_vendor_lib/model/controller/dual_mode_controller.h @@ -403,6 +403,9 @@ class DualModeController : public Device { // 7.8.5 void LeSetAdvertisingParameters(CommandPacketView args); + // 7.8.6 + void LeReadAdvertisingPhysicalChannelTxPower(CommandPacketView args); + // 7.8.7 void LeSetAdvertisingData(CommandPacketView args); diff --git a/vendor_libs/test_vendor_lib/model/devices/device_properties.h b/vendor_libs/test_vendor_lib/model/devices/device_properties.h index 9568c2bf8..0afd97c93 100644 --- a/vendor_libs/test_vendor_lib/model/devices/device_properties.h +++ b/vendor_libs/test_vendor_lib/model/devices/device_properties.h @@ -307,6 +307,11 @@ class DeviceProperties { return le_supported_features_; } + // Specification Version 5.2, Volume 4, Part E, Section 7.8.6 + int8_t GetLeAdvertisingPhysicalChannelTxPower() const { + return le_advertising_physical_channel_tx_power_; + } + void SetLeSupportedFeatures(uint64_t features) { le_supported_features_ = features; } @@ -369,6 +374,7 @@ class DeviceProperties { uint8_t le_connect_list_size_; uint8_t le_resolving_list_size_; uint64_t le_supported_features_{0x075b3fd8fe8ffeff}; + int8_t le_advertising_physical_channel_tx_power_{0x00}; uint64_t le_supported_states_; uint64_t le_event_mask_{0x01f}; std::vector le_vendor_cap_; -- 2.11.0