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 <gmock/gmock.h>
18 #include <gtest/gtest.h>
19
20 #include <algorithm>
21 #include <chrono>
22 #include <future>
23 #include <map>
24
25 #include "common/bind.h"
26 #include "hci/address.h"
27 #include "hci/controller.h"
28 #include "hci/hci_layer.h"
29 #include "hci/le_scanning_manager.h"
30 #include "os/thread.h"
31 #include "packet/raw_builder.h"
32
33 namespace bluetooth {
34 namespace hci {
35 namespace {
36
37 using packet::kLittleEndian;
38 using packet::PacketView;
39 using packet::RawBuilder;
40
GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet)41 PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
42 auto bytes = std::make_shared<std::vector<uint8_t>>();
43 BitInserter i(*bytes);
44 bytes->reserve(packet->size());
45 packet->Serialize(i);
46 return packet::PacketView<packet::kLittleEndian>(bytes);
47 }
48
49 class TestController : public Controller {
50 public:
IsSupported(OpCode op_code) const51 bool IsSupported(OpCode op_code) const override {
52 return supported_opcodes_.count(op_code) == 1;
53 }
54
AddSupported(OpCode op_code)55 void AddSupported(OpCode op_code) {
56 supported_opcodes_.insert(op_code);
57 }
58
59 protected:
Start()60 void Start() override {}
Stop()61 void Stop() override {}
ListDependencies(ModuleList * list)62 void ListDependencies(ModuleList* list) override {}
63
64 private:
65 std::set<OpCode> supported_opcodes_{};
66 };
67
68 class TestHciLayer : public HciLayer {
69 public:
TestHciLayer()70 TestHciLayer() {
71 RegisterEventHandler(EventCode::COMMAND_COMPLETE,
72 base::Bind(&TestHciLayer::CommandCompleteCallback, common::Unretained(this)), nullptr);
73 RegisterEventHandler(EventCode::COMMAND_STATUS,
74 base::Bind(&TestHciLayer::CommandStatusCallback, common::Unretained(this)), nullptr);
75 }
76
EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,common::OnceCallback<void (CommandStatusView)> on_status,os::Handler * handler)77 void EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,
78 common::OnceCallback<void(CommandStatusView)> on_status, os::Handler* handler) override {
79 command_queue_.push(std::move(command));
80 command_status_callbacks.push_front(std::move(on_status));
81 if (command_promise_ != nullptr) {
82 command_promise_->set_value();
83 command_promise_.reset();
84 }
85 }
86
EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,common::OnceCallback<void (CommandCompleteView)> on_complete,os::Handler * handler)87 void EnqueueCommand(std::unique_ptr<CommandPacketBuilder> command,
88 common::OnceCallback<void(CommandCompleteView)> on_complete, os::Handler* handler) override {
89 command_queue_.push(std::move(command));
90 command_complete_callbacks.push_front(std::move(on_complete));
91 if (command_promise_ != nullptr) {
92 command_promise_->set_value();
93 command_promise_.reset();
94 }
95 }
96
GetCommandFuture()97 std::future<void> GetCommandFuture() {
98 ASSERT_LOG(command_promise_ == nullptr, "Promises promises ... Only one at a time");
99 command_promise_ = std::make_unique<std::promise<void>>();
100 return command_promise_->get_future();
101 }
102
GetLastCommand()103 std::unique_ptr<CommandPacketBuilder> GetLastCommand() {
104 ASSERT(!command_queue_.empty());
105 auto last = std::move(command_queue_.front());
106 command_queue_.pop();
107 return last;
108 }
109
GetCommandPacket(OpCode op_code)110 ConnectionManagementCommandView GetCommandPacket(OpCode op_code) {
111 auto packet_view = GetPacketView(GetLastCommand());
112 CommandPacketView command_packet_view = CommandPacketView::Create(packet_view);
113 ConnectionManagementCommandView command = ConnectionManagementCommandView::Create(command_packet_view);
114 ASSERT(command.IsValid());
115 EXPECT_EQ(command.GetOpCode(), op_code);
116
117 return command;
118 }
119
RegisterEventHandler(EventCode event_code,common::Callback<void (EventPacketView)> event_handler,os::Handler * handler)120 void RegisterEventHandler(EventCode event_code, common::Callback<void(EventPacketView)> event_handler,
121 os::Handler* handler) override {
122 registered_events_[event_code] = event_handler;
123 }
124
RegisterLeEventHandler(SubeventCode subevent_code,common::Callback<void (LeMetaEventView)> event_handler,os::Handler * handler)125 void RegisterLeEventHandler(SubeventCode subevent_code, common::Callback<void(LeMetaEventView)> event_handler,
126 os::Handler* handler) override {
127 registered_le_events_[subevent_code] = event_handler;
128 }
129
IncomingEvent(std::unique_ptr<EventPacketBuilder> event_builder)130 void IncomingEvent(std::unique_ptr<EventPacketBuilder> event_builder) {
131 auto packet = GetPacketView(std::move(event_builder));
132 EventPacketView event = EventPacketView::Create(packet);
133 ASSERT_TRUE(event.IsValid());
134 EventCode event_code = event.GetEventCode();
135 ASSERT_TRUE(registered_events_.find(event_code) != registered_events_.end()) << EventCodeText(event_code);
136 registered_events_[event_code].Run(event);
137 }
138
IncomingLeMetaEvent(std::unique_ptr<LeMetaEventBuilder> event_builder)139 void IncomingLeMetaEvent(std::unique_ptr<LeMetaEventBuilder> event_builder) {
140 auto packet = GetPacketView(std::move(event_builder));
141 EventPacketView event = EventPacketView::Create(packet);
142 LeMetaEventView meta_event_view = LeMetaEventView::Create(event);
143 ASSERT_TRUE(meta_event_view.IsValid());
144 SubeventCode subevent_code = meta_event_view.GetSubeventCode();
145 ASSERT_TRUE(registered_le_events_.find(subevent_code) != registered_le_events_.end())
146 << SubeventCodeText(subevent_code);
147 registered_le_events_[subevent_code].Run(meta_event_view);
148 }
149
CommandCompleteCallback(EventPacketView event)150 void CommandCompleteCallback(EventPacketView event) {
151 CommandCompleteView complete_view = CommandCompleteView::Create(event);
152 ASSERT(complete_view.IsValid());
153 std::move(command_complete_callbacks.front()).Run(complete_view);
154 command_complete_callbacks.pop_front();
155 }
156
CommandStatusCallback(EventPacketView event)157 void CommandStatusCallback(EventPacketView event) {
158 CommandStatusView status_view = CommandStatusView::Create(event);
159 ASSERT(status_view.IsValid());
160 std::move(command_status_callbacks.front()).Run(status_view);
161 command_status_callbacks.pop_front();
162 }
163
ListDependencies(ModuleList * list)164 void ListDependencies(ModuleList* list) override {}
Start()165 void Start() override {}
Stop()166 void Stop() override {}
167
168 private:
169 std::map<EventCode, common::Callback<void(EventPacketView)>> registered_events_;
170 std::map<SubeventCode, common::Callback<void(LeMetaEventView)>> registered_le_events_;
171 std::list<base::OnceCallback<void(CommandCompleteView)>> command_complete_callbacks;
172 std::list<base::OnceCallback<void(CommandStatusView)>> command_status_callbacks;
173
174 std::queue<std::unique_ptr<CommandPacketBuilder>> command_queue_;
175 mutable std::mutex mutex_;
176 std::unique_ptr<std::promise<void>> command_promise_{};
177 };
178
179 class LeScanningManagerTest : public ::testing::Test {
180 protected:
SetUp()181 void SetUp() override {
182 test_hci_layer_ = new TestHciLayer; // Ownership is transferred to registry
183 test_controller_ = new TestController;
184 test_controller_->AddSupported(param_opcode_);
185 fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_);
186 fake_registry_.InjectTestModule(&Controller::Factory, test_controller_);
187 client_handler_ = fake_registry_.GetTestModuleHandler(&HciLayer::Factory);
188 ASSERT_NE(client_handler_, nullptr);
189 mock_callbacks_.handler_ = client_handler_;
190 std::future<void> config_future = test_hci_layer_->GetCommandFuture();
191 fake_registry_.Start<LeScanningManager>(&thread_);
192 le_scanning_manager =
193 static_cast<LeScanningManager*>(fake_registry_.GetModuleUnderTest(&LeScanningManager::Factory));
194 auto result = config_future.wait_for(std::chrono::duration(std::chrono::milliseconds(1000)));
195 ASSERT_EQ(std::future_status::ready, result);
196 HandleConfiguration();
197 }
198
TearDown()199 void TearDown() override {
200 fake_registry_.SynchronizeModuleHandler(&LeScanningManager::Factory, std::chrono::milliseconds(20));
201 fake_registry_.StopAll();
202 }
203
HandleConfiguration()204 virtual void HandleConfiguration() {
205 auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_SET_SCAN_PARAMETERS);
206 test_hci_layer_->IncomingEvent(LeSetScanParametersCompleteBuilder::Create(1, ErrorCode::SUCCESS));
207 }
208
209 TestModuleRegistry fake_registry_;
210 TestHciLayer* test_hci_layer_ = nullptr;
211 TestController* test_controller_ = nullptr;
212 os::Thread& thread_ = fake_registry_.GetTestThread();
213 LeScanningManager* le_scanning_manager = nullptr;
214 os::Handler* client_handler_ = nullptr;
215
216 class MockLeScanningManagerCallbacks : public LeScanningManagerCallbacks {
217 public:
218 MOCK_METHOD(void, on_advertisements, (std::vector<std::shared_ptr<LeReport>>), (override));
219 MOCK_METHOD(void, on_timeout, (), (override));
Handler()220 os::Handler* Handler() {
221 return handler_;
222 }
223 os::Handler* handler_{nullptr};
224 } mock_callbacks_;
225
226 OpCode param_opcode_{OpCode::LE_SET_ADVERTISING_PARAMETERS};
227 };
228
229 class LeAndroidHciScanningManagerTest : public LeScanningManagerTest {
230 protected:
SetUp()231 void SetUp() override {
232 param_opcode_ = OpCode::LE_EXTENDED_SCAN_PARAMS;
233 LeScanningManagerTest::SetUp();
234 }
235
HandleConfiguration()236 void HandleConfiguration() override {
237 auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_EXTENDED_SCAN_PARAMS);
238 test_hci_layer_->IncomingEvent(LeExtendedScanParamsCompleteBuilder::Create(1, ErrorCode::SUCCESS));
239 }
240 };
241
242 class LeExtendedScanningManagerTest : public LeScanningManagerTest {
243 protected:
SetUp()244 void SetUp() override {
245 param_opcode_ = OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS;
246 LeScanningManagerTest::SetUp();
247 }
248
HandleConfiguration()249 void HandleConfiguration() override {
250 auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS);
251 test_hci_layer_->IncomingEvent(LeSetExtendedScanParametersCompleteBuilder::Create(1, ErrorCode::SUCCESS));
252 }
253 };
254
TEST_F(LeScanningManagerTest,startup_teardown)255 TEST_F(LeScanningManagerTest, startup_teardown) {}
256
TEST_F(LeScanningManagerTest,start_scan_test)257 TEST_F(LeScanningManagerTest, start_scan_test) {
258 auto next_command_future = test_hci_layer_->GetCommandFuture();
259 le_scanning_manager->StartScan(&mock_callbacks_);
260
261 auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
262 ASSERT_EQ(std::future_status::ready, result);
263 test_hci_layer_->IncomingEvent(LeSetScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
264
265 LeAdvertisingReport report{};
266 report.event_type_ = AdvertisingEventType::ADV_IND;
267 report.address_type_ = AddressType::PUBLIC_DEVICE_ADDRESS;
268 Address::FromString("12:34:56:78:9a:bc", report.address_);
269 std::vector<GapData> gap_data{};
270 GapData data_item{};
271 data_item.data_type_ = GapDataType::FLAGS;
272 data_item.data_ = {0x34};
273 gap_data.push_back(data_item);
274 data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
275 data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
276 gap_data.push_back(data_item);
277 report.advertising_data_ = gap_data;
278
279 EXPECT_CALL(mock_callbacks_, on_advertisements);
280
281 test_hci_layer_->IncomingLeMetaEvent(LeAdvertisingReportBuilder::Create({report}));
282 }
283
TEST_F(LeAndroidHciScanningManagerTest,start_scan_test)284 TEST_F(LeAndroidHciScanningManagerTest, start_scan_test) {
285 auto next_command_future = test_hci_layer_->GetCommandFuture();
286 le_scanning_manager->StartScan(&mock_callbacks_);
287
288 auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
289 ASSERT_EQ(std::future_status::ready, result);
290 test_hci_layer_->IncomingEvent(LeSetScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
291
292 LeAdvertisingReport report{};
293 report.event_type_ = AdvertisingEventType::ADV_IND;
294 report.address_type_ = AddressType::PUBLIC_DEVICE_ADDRESS;
295 Address::FromString("12:34:56:78:9a:bc", report.address_);
296 std::vector<GapData> gap_data{};
297 GapData data_item{};
298 data_item.data_type_ = GapDataType::FLAGS;
299 data_item.data_ = {0x34};
300 gap_data.push_back(data_item);
301 data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
302 data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
303 gap_data.push_back(data_item);
304 report.advertising_data_ = gap_data;
305
306 EXPECT_CALL(mock_callbacks_, on_advertisements);
307
308 test_hci_layer_->IncomingLeMetaEvent(LeAdvertisingReportBuilder::Create({report}));
309 }
310
TEST_F(LeExtendedScanningManagerTest,start_scan_test)311 TEST_F(LeExtendedScanningManagerTest, start_scan_test) {
312 auto next_command_future = test_hci_layer_->GetCommandFuture();
313 le_scanning_manager->StartScan(&mock_callbacks_);
314
315 auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
316 ASSERT_EQ(std::future_status::ready, result);
317 auto packet = test_hci_layer_->GetCommandPacket(OpCode::LE_SET_EXTENDED_SCAN_ENABLE);
318
319 test_hci_layer_->IncomingEvent(LeSetScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
320
321 LeExtendedAdvertisingReport report{};
322 report.connectable_ = 1;
323 report.scannable_ = 1;
324 report.address_type_ = DirectAdvertisingAddressType::PUBLIC_DEVICE_ADDRESS;
325 Address::FromString("12:34:56:78:9a:bc", report.address_);
326 std::vector<GapData> gap_data{};
327 GapData data_item{};
328 data_item.data_type_ = GapDataType::FLAGS;
329 data_item.data_ = {0x34};
330 gap_data.push_back(data_item);
331 data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
332 data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
333 gap_data.push_back(data_item);
334 report.advertising_data_ = gap_data;
335
336 EXPECT_CALL(mock_callbacks_, on_advertisements);
337
338 test_hci_layer_->IncomingLeMetaEvent(LeExtendedAdvertisingReportBuilder::Create({report}));
339 }
340
341 } // namespace
342 } // namespace hci
343 } // namespace bluetooth
344