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