• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet)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:
IsSupported(OpCode op_code) const52   bool IsSupported(OpCode op_code) const override {
53     return supported_opcodes_.count(op_code) == 1;
54   }
55 
AddSupported(OpCode op_code)56   void AddSupported(OpCode op_code) {
57     supported_opcodes_.insert(op_code);
58   }
59 
GetControllerLeNumberOfSupportedAdverisingSets() const60   uint8_t GetControllerLeNumberOfSupportedAdverisingSets() const override {
61     return num_advertisers;
62   }
63 
64   uint8_t num_advertisers{0};
65 
66  protected:
Start()67   void Start() override {}
Stop()68   void Stop() override {}
ListDependencies(ModuleList * list)69   void ListDependencies(ModuleList* list) override {}
70 
71  private:
72   std::set<OpCode> supported_opcodes_{};
73 };
74 
75 class TestHciLayer : public HciLayer {
76  public:
TestHciLayer()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 
EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,common::OnceCallback<void (CommandStatusView)> on_status,os::Handler * handler)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 
EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,common::OnceCallback<void (CommandCompleteView)> on_complete,os::Handler * handler)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 
GetCommandFuture(OpCode op_code=OpCode::NONE)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 
GetSubCommandFuture(SubOcf sub_ocf)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 
GetCommandPacket(OpCode op_code)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 
RegisterEventHandler(EventCode event_code,common::Callback<void (EventPacketView)> event_handler,os::Handler * handler)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 
RegisterLeEventHandler(SubeventCode subevent_code,common::Callback<void (LeMetaEventView)> event_handler,os::Handler * handler)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 
IncomingEvent(std::unique_ptr<EventPacketBuilder> event_builder)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 
IncomingLeMetaEvent(std::unique_ptr<LeMetaEventBuilder> event_builder)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 
CommandCompleteCallback(EventPacketView event)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 
CommandStatusCallback(EventPacketView event)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 
ListDependencies(ModuleList * list)190   void ListDependencies(ModuleList* list) override {}
Start()191   void Start() override {}
Stop()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:
SetUp()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 
TearDown()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 
GetOnScanPromise()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   }
on_scan(Address address,AddressType address_type)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 
GetSetTerminatedPromise()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   }
on_set_terminated(ErrorCode error_code,uint8_t,uint8_t)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:
SetUp()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:
SetUp()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 
TEST_F(LeAdvertisingManagerTest,startup_teardown)290 TEST_F(LeAdvertisingManagerTest, startup_teardown) {}
291 
TEST_F(LeAndroidHciAdvertisingManagerTest,startup_teardown)292 TEST_F(LeAndroidHciAdvertisingManagerTest, startup_teardown) {}
293 
TEST_F(LeExtendedAdvertisingManagerTest,startup_teardown)294 TEST_F(LeExtendedAdvertisingManagerTest, startup_teardown) {}
295 
TEST_F(LeAdvertisingManagerTest,create_advertiser_test)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 
TEST_F(LeAndroidHciAdvertisingManagerTest,create_advertiser_test)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 
TEST_F(LeExtendedAdvertisingManagerTest,create_advertiser_test)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