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 
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:
51   bool IsSupported(OpCode op_code) const override {
52     return supported_opcodes_.count(op_code) == 1;
53   }
54 
55   void AddSupported(OpCode op_code) {
56     supported_opcodes_.insert(op_code);
57   }
58 
59  protected:
60   void Start() override {}
61   void Stop() override {}
62   void ListDependencies(ModuleList* list) override {}
63 
64  private:
65   std::set<OpCode> supported_opcodes_{};
66 };
67 
68 class TestHciLayer : public HciLayer {
69  public:
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
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 
164   void ListDependencies(ModuleList* list) override {}
165   void Start() override {}
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:
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 
199   void TearDown() override {
200     fake_registry_.SynchronizeModuleHandler(&LeScanningManager::Factory, std::chrono::milliseconds(20));
201     fake_registry_.StopAll();
202   }
203 
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));
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:
231   void SetUp() override {
232     param_opcode_ = OpCode::LE_EXTENDED_SCAN_PARAMS;
233     LeScanningManagerTest::SetUp();
234   }
235 
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:
244   void SetUp() override {
245     param_opcode_ = OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS;
246     LeScanningManagerTest::SetUp();
247   }
248 
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 
255 TEST_F(LeScanningManagerTest, startup_teardown) {}
256 
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 
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 
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