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/acl_manager.h"
27 #include "hci/address.h"
28 #include "hci/controller.h"
29 #include "hci/hci_layer.h"
30 #include "hci/le_scanning_manager.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
60 protected:
Start()61 void Start() override {}
Stop()62 void Stop() override {}
ListDependencies(ModuleList * list)63 void ListDependencies(ModuleList* list) override {}
64
65 private:
66 std::set<OpCode> supported_opcodes_{};
67 };
68
69 class TestHciLayer : public HciLayer {
70 public:
EnqueueCommand(std::unique_ptr<CommandBuilder> command,common::ContextualOnceCallback<void (CommandStatusView)> on_status)71 void EnqueueCommand(
72 std::unique_ptr<CommandBuilder> command,
73 common::ContextualOnceCallback<void(CommandStatusView)> on_status) override {
74 command_queue_.push(std::move(command));
75 command_status_callbacks.push_back(std::move(on_status));
76 if (command_promise_ != nullptr) {
77 command_promise_->set_value();
78 command_promise_.reset();
79 }
80 }
81
EnqueueCommand(std::unique_ptr<CommandBuilder> command,common::ContextualOnceCallback<void (CommandCompleteView)> on_complete)82 void EnqueueCommand(
83 std::unique_ptr<CommandBuilder> command,
84 common::ContextualOnceCallback<void(CommandCompleteView)> on_complete) override {
85 command_queue_.push(std::move(command));
86 command_complete_callbacks.push_back(std::move(on_complete));
87 if (command_promise_ != nullptr) {
88 command_promise_->set_value();
89 command_promise_.reset();
90 }
91 }
92
GetCommandFuture()93 std::future<void> GetCommandFuture() {
94 ASSERT_LOG(command_promise_ == nullptr, "Promises promises ... Only one at a time");
95 command_promise_ = std::make_unique<std::promise<void>>();
96 return command_promise_->get_future();
97 }
98
GetLastCommand()99 CommandView GetLastCommand() {
100 if (command_queue_.empty()) {
101 return CommandView::Create(GetPacketView(nullptr));
102 } else {
103 auto last = std::move(command_queue_.front());
104 command_queue_.pop();
105 return CommandView::Create(GetPacketView(std::move(last)));
106 }
107 }
108
GetCommand(OpCode op_code)109 ConnectionManagementCommandView GetCommand(OpCode op_code) {
110 CommandView command_packet_view = GetLastCommand();
111 auto command = ConnectionManagementCommandView::Create(AclCommandView::Create(command_packet_view));
112 EXPECT_TRUE(command.IsValid());
113 EXPECT_EQ(command.GetOpCode(), op_code);
114 return command;
115 }
116
RegisterEventHandler(EventCode event_code,common::ContextualCallback<void (EventView)> event_handler)117 void RegisterEventHandler(EventCode event_code, common::ContextualCallback<void(EventView)> event_handler) override {
118 registered_events_[event_code] = event_handler;
119 }
120
UnregisterEventHandler(EventCode event_code)121 void UnregisterEventHandler(EventCode event_code) override {
122 registered_events_.erase(event_code);
123 }
124
RegisterLeEventHandler(SubeventCode subevent_code,common::ContextualCallback<void (LeMetaEventView)> event_handler)125 void RegisterLeEventHandler(SubeventCode subevent_code,
126 common::ContextualCallback<void(LeMetaEventView)> event_handler) override {
127 registered_le_events_[subevent_code] = event_handler;
128 }
129
UnregisterLeEventHandler(SubeventCode subevent_code)130 void UnregisterLeEventHandler(SubeventCode subevent_code) override {
131 registered_le_events_.erase(subevent_code);
132 }
133
IncomingEvent(std::unique_ptr<EventBuilder> event_builder)134 void IncomingEvent(std::unique_ptr<EventBuilder> event_builder) {
135 auto packet = GetPacketView(std::move(event_builder));
136 EventView event = EventView::Create(packet);
137 ASSERT_TRUE(event.IsValid());
138 EventCode event_code = event.GetEventCode();
139 ASSERT_NE(registered_events_.find(event_code), registered_events_.end()) << EventCodeText(event_code);
140 registered_events_[event_code].Invoke(event);
141 }
142
IncomingLeMetaEvent(std::unique_ptr<LeMetaEventBuilder> event_builder)143 void IncomingLeMetaEvent(std::unique_ptr<LeMetaEventBuilder> event_builder) {
144 auto packet = GetPacketView(std::move(event_builder));
145 EventView event = EventView::Create(packet);
146 LeMetaEventView meta_event_view = LeMetaEventView::Create(event);
147 ASSERT_TRUE(meta_event_view.IsValid());
148 SubeventCode subevent_code = meta_event_view.GetSubeventCode();
149 ASSERT_NE(registered_le_events_.find(subevent_code), registered_le_events_.end())
150 << SubeventCodeText(subevent_code);
151 registered_le_events_[subevent_code].Invoke(meta_event_view);
152 }
153
CommandCompleteCallback(EventView event)154 void CommandCompleteCallback(EventView event) {
155 CommandCompleteView complete_view = CommandCompleteView::Create(event);
156 ASSERT_TRUE(complete_view.IsValid());
157 ASSERT_NE(command_complete_callbacks.size(), 0);
158 std::move(command_complete_callbacks.front()).Invoke(complete_view);
159 command_complete_callbacks.pop_front();
160 }
161
CommandStatusCallback(EventView event)162 void CommandStatusCallback(EventView event) {
163 CommandStatusView status_view = CommandStatusView::Create(event);
164 ASSERT_TRUE(status_view.IsValid());
165 ASSERT_NE(command_status_callbacks.size(), 0);
166 std::move(command_status_callbacks.front()).Invoke(status_view);
167 command_status_callbacks.pop_front();
168 }
169
ListDependencies(ModuleList * list)170 void ListDependencies(ModuleList* list) override {}
Start()171 void Start() override {
172 RegisterEventHandler(EventCode::COMMAND_COMPLETE,
173 GetHandler()->BindOn(this, &TestHciLayer::CommandCompleteCallback));
174 RegisterEventHandler(EventCode::COMMAND_STATUS, GetHandler()->BindOn(this, &TestHciLayer::CommandStatusCallback));
175 }
Stop()176 void Stop() override {}
177
178 private:
179 std::map<EventCode, common::ContextualCallback<void(EventView)>> registered_events_;
180 std::map<SubeventCode, common::ContextualCallback<void(LeMetaEventView)>> registered_le_events_;
181 std::list<common::ContextualOnceCallback<void(CommandCompleteView)>> command_complete_callbacks;
182 std::list<common::ContextualOnceCallback<void(CommandStatusView)>> command_status_callbacks;
183
184 std::queue<std::unique_ptr<CommandBuilder>> command_queue_;
185 mutable std::mutex mutex_;
186 std::unique_ptr<std::promise<void>> command_promise_{};
187 };
188
189 class TestLeAddressManager : public LeAddressManager {
190 public:
TestLeAddressManager(common::Callback<void (std::unique_ptr<CommandBuilder>)> enqueue_command,os::Handler * handler,Address public_address,uint8_t connect_list_size,uint8_t resolving_list_size)191 TestLeAddressManager(
192 common::Callback<void(std::unique_ptr<CommandBuilder>)> enqueue_command,
193 os::Handler* handler,
194 Address public_address,
195 uint8_t connect_list_size,
196 uint8_t resolving_list_size)
197 : LeAddressManager(enqueue_command, handler, public_address, connect_list_size, resolving_list_size) {}
198
Register(LeAddressManagerCallback * callback)199 AddressPolicy Register(LeAddressManagerCallback* callback) override {
200 return AddressPolicy::USE_STATIC_ADDRESS;
201 }
202
Unregister(LeAddressManagerCallback * callback)203 void Unregister(LeAddressManagerCallback* callback) override {}
204 };
205
206 class TestAclManager : public AclManager {
207 public:
GetLeAddressManager()208 LeAddressManager* GetLeAddressManager() override {
209 return test_le_address_manager_;
210 }
211
212 protected:
Start()213 void Start() override {
214 thread_ = new os::Thread("thread", os::Thread::Priority::NORMAL);
215 handler_ = new os::Handler(thread_);
216 Address address({0x01, 0x02, 0x03, 0x04, 0x05, 0x06});
217 test_le_address_manager_ = new TestLeAddressManager(
218 common::Bind(&TestAclManager::enqueue_command, common::Unretained(this)), handler_, address, 0x3F, 0x3F);
219 }
220
Stop()221 void Stop() override {
222 delete test_le_address_manager_;
223 handler_->Clear();
224 delete handler_;
225 delete thread_;
226 }
227
ListDependencies(ModuleList * list)228 void ListDependencies(ModuleList* list) override {}
229
SetRandomAddress(Address address)230 void SetRandomAddress(Address address) {}
231
enqueue_command(std::unique_ptr<CommandBuilder> command_packet)232 void enqueue_command(std::unique_ptr<CommandBuilder> command_packet){};
233
234 os::Thread* thread_;
235 os::Handler* handler_;
236 TestLeAddressManager* test_le_address_manager_;
237 };
238
239 class LeScanningManagerTest : public ::testing::Test {
240 protected:
SetUp()241 void SetUp() override {
242 test_hci_layer_ = new TestHciLayer; // Ownership is transferred to registry
243 test_controller_ = new TestController;
244 test_controller_->AddSupported(param_opcode_);
245 if (is_filter_support_) {
246 test_controller_->AddSupported(OpCode::LE_ADV_FILTER);
247 }
248 if (is_batch_scan_support_) {
249 test_controller_->AddSupported(OpCode::LE_BATCH_SCAN);
250 }
251 test_acl_manager_ = new TestAclManager;
252 fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_);
253 fake_registry_.InjectTestModule(&Controller::Factory, test_controller_);
254 fake_registry_.InjectTestModule(&AclManager::Factory, test_acl_manager_);
255 client_handler_ = fake_registry_.GetTestModuleHandler(&HciLayer::Factory);
256 std::future<void> config_future = test_hci_layer_->GetCommandFuture();
257 fake_registry_.Start<LeScanningManager>(&thread_);
258 le_scanning_manager =
259 static_cast<LeScanningManager*>(fake_registry_.GetModuleUnderTest(&LeScanningManager::Factory));
260 auto result = config_future.wait_for(std::chrono::duration(std::chrono::milliseconds(1000)));
261 ASSERT_EQ(std::future_status::ready, result);
262 auto packet = test_hci_layer_->GetCommand(enable_opcode_);
263 test_hci_layer_->IncomingEvent(LeSetScanEnableCompleteBuilder::Create(1, ErrorCode::SUCCESS));
264 config_future.wait_for(std::chrono::duration(std::chrono::milliseconds(1000)));
265 ASSERT_EQ(std::future_status::ready, result);
266 HandleConfiguration();
267 le_scanning_manager->RegisterScanningCallback(&mock_callbacks_);
268 }
269
TearDown()270 void TearDown() override {
271 fake_registry_.SynchronizeModuleHandler(&LeScanningManager::Factory, std::chrono::milliseconds(20));
272 fake_registry_.StopAll();
273 }
274
HandleConfiguration()275 virtual void HandleConfiguration() {
276 auto packet = test_hci_layer_->GetCommand(OpCode::LE_SET_SCAN_PARAMETERS);
277 test_hci_layer_->IncomingEvent(LeSetScanParametersCompleteBuilder::Create(1, ErrorCode::SUCCESS));
278 }
279
sync_client_handler()280 void sync_client_handler() {
281 std::promise<void> promise;
282 auto future = promise.get_future();
283 client_handler_->Call(common::BindOnce(&std::promise<void>::set_value, common::Unretained(&promise)));
284 auto future_status = future.wait_for(std::chrono::seconds(1));
285 ASSERT_EQ(future_status, std::future_status::ready);
286 }
287
288 TestModuleRegistry fake_registry_;
289 TestHciLayer* test_hci_layer_ = nullptr;
290 TestController* test_controller_ = nullptr;
291 TestAclManager* test_acl_manager_ = nullptr;
292 os::Thread& thread_ = fake_registry_.GetTestThread();
293 LeScanningManager* le_scanning_manager = nullptr;
294 os::Handler* client_handler_ = nullptr;
295
296 class MockCallbacks : public bluetooth::hci::ScanningCallback {
297 public:
298 MOCK_METHOD(
299 void,
300 OnScannerRegistered,
301 (const bluetooth::hci::Uuid app_uuid, ScannerId scanner_id, ScanningStatus status),
302 (override));
303 MOCK_METHOD(
304 void,
305 OnScanResult,
306 (uint16_t event_type,
307 uint8_t address_type,
308 Address address,
309 uint8_t primary_phy,
310 uint8_t secondary_phy,
311 uint8_t advertising_sid,
312 int8_t tx_power,
313 int8_t rssi,
314 uint16_t periodic_advertising_interval,
315 std::vector<uint8_t> advertising_data),
316 (override));
317 MOCK_METHOD(
318 void,
319 OnTrackAdvFoundLost,
320 (bluetooth::hci::AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info),
321 (override));
322 MOCK_METHOD(
323 void,
324 OnBatchScanReports,
325 (int client_if, int status, int report_format, int num_records, std::vector<uint8_t> data),
326 (override));
327 MOCK_METHOD(void, OnBatchScanThresholdCrossed, (int client_if), (override));
328 MOCK_METHOD(void, OnTimeout, (), (override));
329 MOCK_METHOD(void, OnFilterEnable, (Enable enable, uint8_t status), (override));
330 MOCK_METHOD(void, OnFilterParamSetup, (uint8_t available_spaces, ApcfAction action, uint8_t status), (override));
331 MOCK_METHOD(
332 void,
333 OnFilterConfigCallback,
334 (ApcfFilterType filter_type, uint8_t available_spaces, ApcfAction action, uint8_t status),
335 (override));
336 } mock_callbacks_;
337
338 OpCode param_opcode_{OpCode::LE_SET_ADVERTISING_PARAMETERS};
339 OpCode enable_opcode_{OpCode::LE_SET_SCAN_ENABLE};
340 bool is_filter_support_ = false;
341 bool is_batch_scan_support_ = false;
342 };
343
344 class LeAndroidHciScanningManagerTest : public LeScanningManagerTest {
345 protected:
SetUp()346 void SetUp() override {
347 param_opcode_ = OpCode::LE_EXTENDED_SCAN_PARAMS;
348 is_filter_support_ = true;
349 is_batch_scan_support_ = true;
350 LeScanningManagerTest::SetUp();
351 test_controller_->AddSupported(OpCode::LE_ADV_FILTER);
352 }
353
HandleConfiguration()354 void HandleConfiguration() override {
355 auto packet = test_hci_layer_->GetCommand(OpCode::LE_EXTENDED_SCAN_PARAMS);
356 test_hci_layer_->IncomingEvent(LeExtendedScanParamsCompleteBuilder::Create(1, ErrorCode::SUCCESS));
357 }
358 };
359
360 class LeExtendedScanningManagerTest : public LeScanningManagerTest {
361 protected:
SetUp()362 void SetUp() override {
363 param_opcode_ = OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS;
364 enable_opcode_ = OpCode::LE_SET_EXTENDED_SCAN_ENABLE;
365 LeScanningManagerTest::SetUp();
366 }
367
HandleConfiguration()368 void HandleConfiguration() override {
369 auto packet = test_hci_layer_->GetCommand(OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS);
370 test_hci_layer_->IncomingEvent(LeSetExtendedScanParametersCompleteBuilder::Create(1, ErrorCode::SUCCESS));
371 }
372 };
373
TEST_F(LeScanningManagerTest,startup_teardown)374 TEST_F(LeScanningManagerTest, startup_teardown) {}
375
TEST_F(LeScanningManagerTest,start_scan_test)376 TEST_F(LeScanningManagerTest, start_scan_test) {
377 auto next_command_future = test_hci_layer_->GetCommandFuture();
378 le_scanning_manager->Scan(true);
379
380 auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
381 ASSERT_EQ(std::future_status::ready, result);
382 test_hci_layer_->IncomingEvent(LeSetScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
383
384 LeAdvertisingReport report{};
385 report.event_type_ = AdvertisingEventType::ADV_DIRECT_IND;
386 report.address_type_ = AddressType::PUBLIC_DEVICE_ADDRESS;
387 Address::FromString("12:34:56:78:9a:bc", report.address_);
388 std::vector<GapData> gap_data{};
389 GapData data_item{};
390 data_item.data_type_ = GapDataType::FLAGS;
391 data_item.data_ = {0x34};
392 gap_data.push_back(data_item);
393 data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
394 data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
395 gap_data.push_back(data_item);
396 report.advertising_data_ = gap_data;
397
398 EXPECT_CALL(mock_callbacks_, OnScanResult);
399
400 test_hci_layer_->IncomingLeMetaEvent(LeAdvertisingReportBuilder::Create({report}));
401 }
402
TEST_F(LeAndroidHciScanningManagerTest,start_scan_test)403 TEST_F(LeAndroidHciScanningManagerTest, start_scan_test) {
404 auto next_command_future = test_hci_layer_->GetCommandFuture();
405 le_scanning_manager->Scan(true);
406
407 auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
408 ASSERT_EQ(std::future_status::ready, result);
409 test_hci_layer_->IncomingEvent(LeSetScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
410
411 LeAdvertisingReport report{};
412 report.event_type_ = AdvertisingEventType::ADV_DIRECT_IND;
413 report.address_type_ = AddressType::PUBLIC_DEVICE_ADDRESS;
414 Address::FromString("12:34:56:78:9a:bc", report.address_);
415 std::vector<GapData> gap_data{};
416 GapData data_item{};
417 data_item.data_type_ = GapDataType::FLAGS;
418 data_item.data_ = {0x34};
419 gap_data.push_back(data_item);
420 data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
421 data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
422 gap_data.push_back(data_item);
423 report.advertising_data_ = gap_data;
424
425 EXPECT_CALL(mock_callbacks_, OnScanResult);
426
427 test_hci_layer_->IncomingLeMetaEvent(LeAdvertisingReportBuilder::Create({report}));
428 }
429
TEST_F(LeAndroidHciScanningManagerTest,scan_filter_enable_test)430 TEST_F(LeAndroidHciScanningManagerTest, scan_filter_enable_test) {
431 auto next_command_future = test_hci_layer_->GetCommandFuture();
432 le_scanning_manager->ScanFilterEnable(true);
433 auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
434 ASSERT_EQ(std::future_status::ready, result);
435 EXPECT_CALL(mock_callbacks_, OnFilterEnable);
436 test_hci_layer_->IncomingEvent(
437 LeAdvFilterEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS, Enable::ENABLED));
438 sync_client_handler();
439 }
440
TEST_F(LeAndroidHciScanningManagerTest,scan_filter_parameter_test)441 TEST_F(LeAndroidHciScanningManagerTest, scan_filter_parameter_test) {
442 auto next_command_future = test_hci_layer_->GetCommandFuture();
443 AdvertisingFilterParameter advertising_filter_parameter{};
444 advertising_filter_parameter.delivery_mode = DeliveryMode::IMMEDIATE;
445 le_scanning_manager->ScanFilterParameterSetup(ApcfAction::ADD, 0x01, advertising_filter_parameter);
446 auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
447 ASSERT_EQ(std::future_status::ready, result);
448 EXPECT_CALL(mock_callbacks_, OnFilterParamSetup);
449 test_hci_layer_->IncomingEvent(
450 LeAdvFilterSetFilteringParametersCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS, ApcfAction::ADD, 0x0a));
451 sync_client_handler();
452 }
453
TEST_F(LeAndroidHciScanningManagerTest,scan_filter_add_test)454 TEST_F(LeAndroidHciScanningManagerTest, scan_filter_add_test) {
455 auto next_command_future = test_hci_layer_->GetCommandFuture();
456 std::vector<AdvertisingPacketContentFilterCommand> filters = {};
457 AdvertisingPacketContentFilterCommand filter{};
458 filter.filter_type = ApcfFilterType::BROADCASTER_ADDRESS;
459 filter.address = Address::kEmpty;
460 filter.application_address_type = ApcfApplicationAddressType::RANDOM;
461 filters.push_back(filter);
462 le_scanning_manager->ScanFilterAdd(0x01, filters);
463 EXPECT_CALL(mock_callbacks_, OnFilterConfigCallback);
464 auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
465 ASSERT_EQ(std::future_status::ready, result);
466 test_hci_layer_->IncomingEvent(
467 LeAdvFilterBroadcasterAddressCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS, ApcfAction::ADD, 0x0a));
468 sync_client_handler();
469 }
470
TEST_F(LeAndroidHciScanningManagerTest,read_batch_scan_result)471 TEST_F(LeAndroidHciScanningManagerTest, read_batch_scan_result) {
472 // Enable batch scan feature
473 auto next_command_future = test_hci_layer_->GetCommandFuture();
474 le_scanning_manager->BatchScanConifgStorage(100, 0, 95, 0x00);
475 auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
476 ASSERT_EQ(std::future_status::ready, result);
477 test_hci_layer_->IncomingEvent(LeBatchScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
478 test_hci_layer_->IncomingEvent(
479 LeBatchScanSetStorageParametersCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
480
481 // Enable batch scan
482 next_command_future = test_hci_layer_->GetCommandFuture();
483 le_scanning_manager->BatchScanEnable(BatchScanMode::FULL, 2400, 2400, BatchScanDiscardRule::OLDEST);
484 result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
485 ASSERT_EQ(std::future_status::ready, result);
486 test_hci_layer_->IncomingEvent(LeBatchScanSetScanParametersCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
487
488 // Read batch scan data
489 next_command_future = test_hci_layer_->GetCommandFuture();
490 le_scanning_manager->BatchScanReadReport(0x01, BatchScanMode::FULL);
491 result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
492 ASSERT_EQ(std::future_status::ready, result);
493
494 EXPECT_CALL(mock_callbacks_, OnBatchScanReports);
495 std::vector<uint8_t> raw_data = {0x5c, 0x1f, 0xa2, 0xc3, 0x63, 0x5d, 0x01, 0xf5, 0xb3, 0x5e, 0x00, 0x0c, 0x02,
496 0x01, 0x02, 0x05, 0x09, 0x6d, 0x76, 0x38, 0x76, 0x02, 0x0a, 0xf5, 0x00};
497 next_command_future = test_hci_layer_->GetCommandFuture();
498 // We will send read command while num_of_record != 0
499 test_hci_layer_->IncomingEvent(LeBatchScanReadResultParametersCompleteRawBuilder::Create(
500 uint8_t{1}, ErrorCode::SUCCESS, BatchScanDataRead::FULL_MODE_DATA, 1, raw_data));
501 result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
502 ASSERT_EQ(std::future_status::ready, result);
503
504 // OnBatchScanReports will be trigger when num_of_record == 0
505 test_hci_layer_->IncomingEvent(LeBatchScanReadResultParametersCompleteRawBuilder::Create(
506 uint8_t{1}, ErrorCode::SUCCESS, BatchScanDataRead::FULL_MODE_DATA, 0, {}));
507 }
508
TEST_F(LeExtendedScanningManagerTest,start_scan_test)509 TEST_F(LeExtendedScanningManagerTest, start_scan_test) {
510 auto next_command_future = test_hci_layer_->GetCommandFuture();
511 le_scanning_manager->Scan(true);
512
513 auto result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
514 ASSERT_EQ(std::future_status::ready, result);
515 test_hci_layer_->GetCommand(OpCode::LE_SET_EXTENDED_SCAN_ENABLE);
516 test_hci_layer_->IncomingEvent(LeSetScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
517
518 result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
519 ASSERT_EQ(std::future_status::ready, result);
520 test_hci_layer_->GetCommand(OpCode::LE_SET_EXTENDED_SCAN_PARAMETERS);
521 test_hci_layer_->IncomingEvent(LeSetExtendedScanParametersCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
522
523 result = next_command_future.wait_for(std::chrono::duration(std::chrono::milliseconds(100)));
524 ASSERT_EQ(std::future_status::ready, result);
525 test_hci_layer_->GetCommand(OpCode::LE_SET_EXTENDED_SCAN_ENABLE);
526
527 test_hci_layer_->IncomingEvent(LeSetScanEnableCompleteBuilder::Create(uint8_t{1}, ErrorCode::SUCCESS));
528
529 LeExtendedAdvertisingReport report{};
530 report.connectable_ = 1;
531 report.scannable_ = 0;
532 report.address_type_ = DirectAdvertisingAddressType::PUBLIC_DEVICE_ADDRESS;
533 Address::FromString("12:34:56:78:9a:bc", report.address_);
534 std::vector<GapData> gap_data{};
535 GapData data_item{};
536 data_item.data_type_ = GapDataType::FLAGS;
537 data_item.data_ = {0x34};
538 gap_data.push_back(data_item);
539 data_item.data_type_ = GapDataType::COMPLETE_LOCAL_NAME;
540 data_item.data_ = {'r', 'a', 'n', 'd', 'o', 'm', ' ', 'd', 'e', 'v', 'i', 'c', 'e'};
541 gap_data.push_back(data_item);
542 std::vector<uint8_t> advertising_data = {};
543 for (auto data : gap_data) {
544 advertising_data.push_back((uint8_t)data.size() - 1);
545 advertising_data.push_back((uint8_t)data.data_type_);
546 advertising_data.insert(advertising_data.end(), data.data_.begin(), data.data_.end());
547 }
548
549 report.advertising_data_ = advertising_data;
550
551 EXPECT_CALL(mock_callbacks_, OnScanResult);
552
553 test_hci_layer_->IncomingLeMetaEvent(LeExtendedAdvertisingReportBuilder::Create({report}));
554 }
555
556 } // namespace
557 } // namespace hci
558 } // namespace bluetooth
559