1 /* 2 * Copyright 2019 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "hci/le_advertising_manager.h" 18 19 #include <algorithm> 20 #include <chrono> 21 #include <future> 22 #include <map> 23 24 #include <gmock/gmock.h> 25 #include <gtest/gtest.h> 26 27 #include "common/bind.h" 28 #include "hci/address.h" 29 #include "hci/controller.h" 30 #include "hci/hci_layer.h" 31 #include "os/thread.h" 32 #include "packet/raw_builder.h" 33 34 namespace bluetooth { 35 namespace hci { 36 namespace { 37 38 using packet::kLittleEndian; 39 using packet::PacketView; 40 using packet::RawBuilder; 41 42 PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) { 43 auto bytes = std::make_shared<std::vector<uint8_t>>(); 44 BitInserter i(*bytes); 45 bytes->reserve(packet->size()); 46 packet->Serialize(i); 47 return packet::PacketView<packet::kLittleEndian>(bytes); 48 } 49 50 class TestController : public Controller { 51 public: 52 bool IsSupported(OpCode op_code) const override { 53 return supported_opcodes_.count(op_code) == 1; 54 } 55 56 void AddSupported(OpCode op_code) { 57 supported_opcodes_.insert(op_code); 58 } 59 60 uint8_t GetControllerLeNumberOfSupportedAdverisingSets() const override { 61 return num_advertisers; 62 } 63 64 uint8_t num_advertisers{0}; 65 66 protected: 67 void Start() override {} 68 void Stop() override {} 69 void ListDependencies(ModuleList* list) override {} 70 71 private: 72 std::set<OpCode> supported_opcodes_{}; 73 }; 74 75 class TestHciLayer : public HciLayer { 76 public: 77 TestHciLayer() { 78 RegisterEventHandler(EventCode::COMMAND_COMPLETE, 79 base::Bind(&TestHciLayer::CommandCompleteCallback, common::Unretained(this)), nullptr); 80 RegisterEventHandler(EventCode::COMMAND_STATUS, 81 base::Bind(&TestHciLayer::CommandStatusCallback, common::Unretained(this)), nullptr); 82 } 83 84 void EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command, 85 common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override { 86 auto packet_view = CommandPacketView::Create(GetPacketView(std::move(command))); 87 ASSERT(packet_view.IsValid()); 88 command_queue_.push_back(packet_view); 89 command_status_callbacks.push_back(std::move(on_status)); 90 if (command_promise_ != nullptr && 91 (command_op_code_ == OpCode::NONE || command_op_code_ == packet_view.GetOpCode())) { 92 if (command_op_code_ == OpCode::LE_MULTI_ADVT && command_sub_ocf_ != SubOcf::SET_ENABLE) { 93 return; 94 } 95 command_promise_->set_value(command_queue_.size()); 96 command_promise_.reset(); 97 } 98 } 99 100 void EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command, 101 common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) override { 102 auto packet_view = CommandPacketView::Create(GetPacketView(std::move(command))); 103 ASSERT(packet_view.IsValid()); 104 command_queue_.push_back(packet_view); 105 command_complete_callbacks.push_back(std::move(on_complete)); 106 if (command_promise_ != nullptr && 107 (command_op_code_ == OpCode::NONE || command_op_code_ == packet_view.GetOpCode())) { 108 if (command_op_code_ == OpCode::LE_MULTI_ADVT) { 109 auto sub_view = LeMultiAdvtView::Create(LeAdvertisingCommandView::Create(packet_view)); 110 ASSERT(sub_view.IsValid()); 111 if (sub_view.GetSubCmd() != command_sub_ocf_) { 112 return; 113 } 114 } 115 command_promise_->set_value(command_queue_.size()); 116 command_promise_.reset(); 117 } 118 } 119 120 std::future<size_t> GetCommandFuture(OpCode op_code = OpCode::NONE) { 121 ASSERT_LOG(command_promise_ == nullptr, "Promises promises ... Only one at a time"); 122 command_op_code_ = op_code; 123 command_promise_ = std::make_unique<std::promise<size_t>>(); 124 return command_promise_->get_future(); 125 } 126 127 std::future<size_t> GetSubCommandFuture(SubOcf sub_ocf) { 128 ASSERT_LOG(command_promise_ == nullptr, "Promises promises ... Only one at a time"); 129 command_op_code_ = OpCode::LE_MULTI_ADVT; 130 command_sub_ocf_ = sub_ocf; 131 command_promise_ = std::make_unique<std::promise<size_t>>(); 132 return command_promise_->get_future(); 133 } 134 135 ConnectionManagementCommandView GetCommandPacket(OpCode op_code) { 136 ASSERT(!command_queue_.empty()); 137 CommandPacketView command_packet_view = CommandPacketView::Create(command_queue_.front()); 138 command_queue_.pop_front(); 139 ConnectionManagementCommandView command = ConnectionManagementCommandView::Create(command_packet_view); 140 ASSERT(command.IsValid()); 141 EXPECT_EQ(command.GetOpCode(), op_code); 142 143 return command; 144 } 145 146 void RegisterEventHandler(EventCode event_code, common::Callback<void(EventPacketView)> event_handler, 147 os::Handler* handler) override { 148 registered_events_[event_code] = event_handler; 149 } 150 151 void RegisterLeEventHandler(SubeventCode subevent_code, common::Callback<void(LeMetaEventView)> event_handler, 152 os::Handler* handler) override { 153 registered_le_events_[subevent_code] = event_handler; 154 } 155 156 void IncomingEvent(std::unique_ptr<EventPacketBuilder> event_builder) { 157 auto packet = GetPacketView(std::move(event_builder)); 158 EventPacketView event = EventPacketView::Create(packet); 159 ASSERT_TRUE(event.IsValid()); 160 EventCode event_code = event.GetEventCode(); 161 ASSERT_TRUE(registered_events_.find(event_code) != registered_events_.end()) << EventCodeText(event_code); 162 registered_events_[event_code].Run(event); 163 } 164 165 void IncomingLeMetaEvent(std::unique_ptr<LeMetaEventBuilder> event_builder) { 166 auto packet = GetPacketView(std::move(event_builder)); 167 EventPacketView event = EventPacketView::Create(packet); 168 LeMetaEventView meta_event_view = LeMetaEventView::Create(event); 169 ASSERT_TRUE(meta_event_view.IsValid()); 170 SubeventCode subevent_code = meta_event_view.GetSubeventCode(); 171 ASSERT_TRUE(registered_le_events_.find(subevent_code) != registered_le_events_.end()) 172 << SubeventCodeText(subevent_code); 173 registered_le_events_[subevent_code].Run(meta_event_view); 174 } 175 176 void CommandCompleteCallback(EventPacketView event) { 177 CommandCompleteView complete_view = CommandCompleteView::Create(event); 178 ASSERT(complete_view.IsValid()); 179 std::move(command_complete_callbacks.front()).Run(complete_view); 180 command_complete_callbacks.pop_front(); 181 } 182 183 void CommandStatusCallback(EventPacketView event) { 184 CommandStatusView status_view = CommandStatusView::Create(event); 185 ASSERT(status_view.IsValid()); 186 std::move(command_status_callbacks.front()).Run(status_view); 187 command_status_callbacks.pop_front(); 188 } 189 190 void ListDependencies(ModuleList* list) override {} 191 void Start() override {} 192 void Stop() override {} 193 194 private: 195 std::map<EventCode, common::Callback<void(EventPacketView)>> registered_events_; 196 std::map<SubeventCode, common::Callback<void(LeMetaEventView)>> registered_le_events_; 197 std::list<base::OnceCallback<void(CommandCompleteView)>> command_complete_callbacks; 198 std::list<base::OnceCallback<void(CommandStatusView)>> command_status_callbacks; 199 200 std::list<CommandPacketView> command_queue_; 201 mutable std::mutex mutex_; 202 std::unique_ptr<std::promise<size_t>> command_promise_{}; 203 OpCode command_op_code_; 204 SubOcf command_sub_ocf_; 205 }; 206 207 class LeAdvertisingManagerTest : public ::testing::Test { 208 protected: 209 void SetUp() override { 210 test_hci_layer_ = new TestHciLayer; // Ownership is transferred to registry 211 test_controller_ = new TestController; 212 test_controller_->AddSupported(param_opcode_); 213 fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_); 214 fake_registry_.InjectTestModule(&Controller::Factory, test_controller_); 215 client_handler_ = fake_registry_.GetTestModuleHandler(&HciLayer::Factory); 216 ASSERT_NE(client_handler_, nullptr); 217 test_controller_->num_advertisers = 1; 218 fake_registry_.Start<LeAdvertisingManager>(&thread_); 219 le_advertising_manager_ = 220 static_cast<LeAdvertisingManager*>(fake_registry_.GetModuleUnderTest(&LeAdvertisingManager::Factory)); 221 } 222 223 void TearDown() override { 224 fake_registry_.SynchronizeModuleHandler(&LeAdvertisingManager::Factory, std::chrono::milliseconds(20)); 225 fake_registry_.StopAll(); 226 } 227 228 TestModuleRegistry fake_registry_; 229 TestHciLayer* test_hci_layer_ = nullptr; 230 TestController* test_controller_ = nullptr; 231 os::Thread& thread_ = fake_registry_.GetTestThread(); 232 LeAdvertisingManager* le_advertising_manager_ = nullptr; 233 os::Handler* client_handler_ = nullptr; 234 235 const common::Callback<void(Address, AddressType)> scan_callback = 236 common::Bind(&LeAdvertisingManagerTest::on_scan, common::Unretained(this)); 237 const common::Callback<void(ErrorCode, uint8_t, uint8_t)> set_terminated_callback = 238 common::Bind(&LeAdvertisingManagerTest::on_set_terminated, common::Unretained(this)); 239 240 std::future<Address> GetOnScanPromise() { 241 ASSERT_LOG(address_promise_ == nullptr, "Promises promises ... Only one at a time"); 242 address_promise_ = std::make_unique<std::promise<Address>>(); 243 return address_promise_->get_future(); 244 } 245 void on_scan(Address address, AddressType address_type) { 246 if (address_promise_ == nullptr) { 247 return; 248 } 249 address_promise_->set_value(address); 250 address_promise_.reset(); 251 } 252 253 std::future<ErrorCode> GetSetTerminatedPromise() { 254 ASSERT_LOG(set_terminated_promise_ == nullptr, "Promises promises ... Only one at a time"); 255 set_terminated_promise_ = std::make_unique<std::promise<ErrorCode>>(); 256 return set_terminated_promise_->get_future(); 257 } 258 void on_set_terminated(ErrorCode error_code, uint8_t, uint8_t) { 259 if (set_terminated_promise_ != nullptr) { 260 return; 261 } 262 set_terminated_promise_->set_value(error_code); 263 set_terminated_promise_.reset(); 264 } 265 266 std::unique_ptr<std::promise<Address>> address_promise_{}; 267 std::unique_ptr<std::promise<ErrorCode>> set_terminated_promise_{}; 268 269 OpCode param_opcode_{OpCode::LE_SET_ADVERTISING_PARAMETERS}; 270 }; 271 272 class LeAndroidHciAdvertisingManagerTest : public LeAdvertisingManagerTest { 273 protected: 274 void SetUp() override { 275 param_opcode_ = OpCode::LE_MULTI_ADVT; 276 LeAdvertisingManagerTest::SetUp(); 277 test_controller_->num_advertisers = 3; 278 } 279 }; 280 281 class LeExtendedAdvertisingManagerTest : public LeAdvertisingManagerTest { 282 protected: 283 void SetUp() override { 284 param_opcode_ = OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS; 285 LeAdvertisingManagerTest::SetUp(); 286 test_controller_->num_advertisers = 5; 287 } 288 }; 289 290 TEST_F(LeAdvertisingManagerTest, startup_teardown) {} 291 292 TEST_F(LeAndroidHciAdvertisingManagerTest, startup_teardown) {} 293 294 TEST_F(LeExtendedAdvertisingManagerTest, startup_teardown) {} 295 296 TEST_F(LeAdvertisingManagerTest, create_advertiser_test) { 297 AdvertisingConfig advertising_config{}; 298 advertising_config.event_type = AdvertisingEventType::ADV_IND; 299 advertising_config.address_type = AddressType::PUBLIC_DEVICE_ADDRESS; 300 std::vector<GapData> gap_data{}; 301 GapData data_item{}; 302 data_item.data_type_ = GapDataType::FLAGS; 303 data_item.data_ = {0x34}; 304 gap_data.push_back(data_item); 305 data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME; 306 data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'}; 307 gap_data.push_back(data_item); 308 advertising_config.advertisement = gap_data; 309 advertising_config.scan_response = gap_data; 310 311 auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_ADVERTISING_ENABLE); 312 auto id = le_advertising_manager_->CreateAdvertiser(advertising_config, scan_callback, set_terminated_callback, 313 client_handler_); 314 ASSERT_NE(LeAdvertisingManager::kInvalidId, id); 315 std::vector<OpCode> adv_opcodes = { 316 OpCode::LE_SET_ADVERTISING_PARAMETERS, OpCode::LE_SET_RANDOM_ADDRESS, OpCode::LE_SET_SCAN_RESPONSE_DATA, 317 OpCode::LE_SET_ADVERTISING_DATA, OpCode::LE_SET_ADVERTISING_ENABLE, 318 }; 319 std::vector<uint8_t> success_vector{static_cast<uint8_t>(ErrorCode::SUCCESS)}; 320 auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); 321 ASSERT_EQ(std::future_status::ready, result); 322 for (size_t i = 0; i < adv_opcodes.size(); i++) { 323 auto packet_view = test_hci_layer_->GetCommandPacket(adv_opcodes[i]); 324 CommandPacketView command_packet_view = CommandPacketView::Create(packet_view); 325 ConnectionManagementCommandView command = ConnectionManagementCommandView::Create(command_packet_view); 326 test_hci_layer_->IncomingEvent( 327 CommandCompleteBuilder::Create(uint8_t{1}, adv_opcodes[i], std::make_unique<RawBuilder>(success_vector))); 328 } 329 // Disable the advertiser 330 last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_ADVERTISING_ENABLE); 331 le_advertising_manager_->RemoveAdvertiser(id); 332 result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); 333 ASSERT_EQ(std::future_status::ready, result); 334 test_hci_layer_->IncomingEvent(LeSetAdvertisingEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); 335 } 336 337 TEST_F(LeAndroidHciAdvertisingManagerTest, create_advertiser_test) { 338 AdvertisingConfig advertising_config{}; 339 advertising_config.event_type = AdvertisingEventType::ADV_IND; 340 advertising_config.address_type = AddressType::PUBLIC_DEVICE_ADDRESS; 341 std::vector<GapData> gap_data{}; 342 GapData data_item{}; 343 data_item.data_type_ = GapDataType::FLAGS; 344 data_item.data_ = {0x34}; 345 gap_data.push_back(data_item); 346 data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME; 347 data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'}; 348 gap_data.push_back(data_item); 349 advertising_config.advertisement = gap_data; 350 advertising_config.scan_response = gap_data; 351 352 auto next_command_future = test_hci_layer_->GetSubCommandFuture(SubOcf::SET_ENABLE); 353 auto id = le_advertising_manager_->CreateAdvertiser(advertising_config, scan_callback, set_terminated_callback, 354 client_handler_); 355 ASSERT_NE(LeAdvertisingManager::kInvalidId, id); 356 std::vector<SubOcf> sub_ocf = { 357 SubOcf::SET_PARAM, SubOcf::SET_DATA, SubOcf::SET_SCAN_RESP, SubOcf::SET_RANDOM_ADDR, SubOcf::SET_ENABLE, 358 }; 359 auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); 360 ASSERT_EQ(std::future_status::ready, result); 361 size_t num_commands = next_command_future.get(); 362 for (size_t i = 0; i < sub_ocf.size(); i++) { 363 auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_MULTI_ADVT); 364 auto sub_packet = LeMultiAdvtView::Create(LeAdvertisingCommandView::Create(packet)); 365 ASSERT(sub_packet.IsValid()); 366 test_hci_layer_->IncomingEvent(LeMultiAdvtCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS, sub_ocf[i])); 367 num_commands -= 1; 368 } 369 ASSERT_EQ(0, num_commands); 370 // Disable the advertiser 371 next_command_future = test_hci_layer_->GetSubCommandFuture(SubOcf::SET_ENABLE); 372 le_advertising_manager_->RemoveAdvertiser(id); 373 result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); 374 ASSERT_EQ(std::future_status::ready, result); 375 test_hci_layer_->IncomingEvent(LeMultiAdvtSetEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); 376 } 377 378 TEST_F(LeExtendedAdvertisingManagerTest, create_advertiser_test) { 379 ExtendedAdvertisingConfig advertising_config{}; 380 advertising_config.event_type = AdvertisingEventType::ADV_IND; 381 advertising_config.address_type = AddressType::PUBLIC_DEVICE_ADDRESS; 382 std::vector<GapData> gap_data{}; 383 GapData data_item{}; 384 data_item.data_type_ = GapDataType::FLAGS; 385 data_item.data_ = {0x34}; 386 gap_data.push_back(data_item); 387 data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME; 388 data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'}; 389 gap_data.push_back(data_item); 390 advertising_config.advertisement = gap_data; 391 advertising_config.scan_response = gap_data; 392 advertising_config.channel_map = 1; 393 394 auto last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_ENABLE); 395 auto id = le_advertising_manager_->ExtendedCreateAdvertiser(advertising_config, scan_callback, 396 set_terminated_callback, client_handler_); 397 ASSERT_NE(LeAdvertisingManager::kInvalidId, id); 398 std::vector<OpCode> adv_opcodes = { 399 OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS, OpCode::LE_SET_EXTENDED_ADVERTISING_RANDOM_ADDRESS, 400 OpCode::LE_SET_EXTENDED_ADVERTISING_SCAN_RESPONSE, OpCode::LE_SET_EXTENDED_ADVERTISING_DATA, 401 OpCode::LE_SET_EXTENDED_ADVERTISING_ENABLE, 402 }; 403 auto result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); 404 std::vector<uint8_t> success_vector{static_cast<uint8_t>(ErrorCode::SUCCESS)}; 405 ASSERT_EQ(std::future_status::ready, result); 406 for (size_t i = 0; i < adv_opcodes.size(); i++) { 407 auto packet_view = test_hci_layer_->GetCommandPacket(adv_opcodes[i]); 408 CommandPacketView command_packet_view = CommandPacketView::Create(packet_view); 409 ConnectionManagementCommandView command = ConnectionManagementCommandView::Create(command_packet_view); 410 if (adv_opcodes[i] == OpCode::LE_SET_EXTENDED_ADVERTISING_PARAMETERS) { 411 test_hci_layer_->IncomingEvent(LeSetExtendedAdvertisingParametersCompleteBuilder::Create( 412 uint8_t{1}, ErrorCode::SUCCESS, static_cast<uint8_t>(-23))); 413 } else { 414 test_hci_layer_->IncomingEvent( 415 CommandCompleteBuilder::Create(uint8_t{1}, adv_opcodes[i], std::make_unique<RawBuilder>(success_vector))); 416 } 417 } 418 // Disable the advertiser 419 last_command_future = test_hci_layer_->GetCommandFuture(OpCode::LE_SET_EXTENDED_ADVERTISING_ENABLE); 420 le_advertising_manager_->RemoveAdvertiser(id); 421 result = last_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100))); 422 ASSERT_EQ(std::future_status::ready, result); 423 test_hci_layer_->IncomingEvent(LeSetExtendedAdvertisingEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS)); 424 } 425 } // namespace 426 } // namespace hci 427 } // namespace bluetooth 428