1 /*
2 * Copyright 2022 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_periodic_sync_manager.h"
18
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21
22 #include "hci/le_scanning_callback.h"
23 #include "hci/le_scanning_interface.h"
24 #include "hci/le_scanning_manager_mock.h"
25 #include "os/handler.h"
26
27 using namespace std::chrono_literals;
28
29 namespace bluetooth {
30 namespace hci {
31 namespace {
32
GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet)33 PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
34 auto bytes = std::make_shared<std::vector<uint8_t>>();
35 BitInserter i(*bytes);
36 bytes->reserve(packet->size());
37 packet->Serialize(i);
38 return packet::PacketView<packet::kLittleEndian>(bytes);
39 }
40
41 class TestLeScanningInterface : public LeScanningInterface {
42 public:
EnqueueCommand(std::unique_ptr<LeScanningCommandBuilder> command,common::ContextualOnceCallback<void (CommandCompleteView)> on_complete)43 void EnqueueCommand(
44 std::unique_ptr<LeScanningCommandBuilder> command,
45 common::ContextualOnceCallback<void(CommandCompleteView)> on_complete) override {
46 std::lock_guard<std::mutex> lock(mutex_);
47 command_queue_.push(std::move(command));
48 command_complete_callbacks.push_back(std::move(on_complete));
49 if (command_promise_ != nullptr) {
50 std::promise<void>* prom = command_promise_.release();
51 prom->set_value();
52 delete prom;
53 }
54 }
55
EnqueueCommand(std::unique_ptr<LeScanningCommandBuilder> command,common::ContextualOnceCallback<void (CommandStatusView)> on_status)56 void EnqueueCommand(
57 std::unique_ptr<LeScanningCommandBuilder> command,
58 common::ContextualOnceCallback<void(CommandStatusView)> on_status) override {
59 command_queue_.push(std::move(command));
60 command_status_callbacks.push_back(std::move(on_status));
61 if (command_promise_ != nullptr) {
62 std::promise<void>* prom = command_promise_.release();
63 prom->set_value();
64 delete prom;
65 }
66 }
67
SetCommandFuture()68 void SetCommandFuture() {
69 ASSERT_EQ(command_promise_, nullptr) << "Promises, Promises, ... Only one at a time.";
70 command_promise_ = std::make_unique<std::promise<void>>();
71 command_future_ = std::make_unique<std::future<void>>(command_promise_->get_future());
72 }
73
GetLastCommand()74 CommandView GetLastCommand() {
75 if (command_queue_.empty()) {
76 return CommandView::Create(PacketView<kLittleEndian>(std::make_shared<std::vector<uint8_t>>()));
77 }
78 auto last = std::move(command_queue_.front());
79 command_queue_.pop();
80 return CommandView::Create(GetPacketView(std::move(last)));
81 }
82
GetCommand(OpCode op_code)83 CommandView GetCommand(OpCode op_code) {
84 if (!command_queue_.empty()) {
85 std::lock_guard<std::mutex> lock(mutex_);
86 if (command_future_ != nullptr) {
87 command_future_.reset();
88 command_promise_.reset();
89 }
90 } else if (command_future_ != nullptr) {
91 auto result = command_future_->wait_for(std::chrono::milliseconds(1000));
92 EXPECT_NE(std::future_status::timeout, result);
93 }
94 std::lock_guard<std::mutex> lock(mutex_);
95 ASSERT_LOG(
96 !command_queue_.empty(), "Expecting command %s but command queue was empty", OpCodeText(op_code).c_str());
97 CommandView command_packet_view = GetLastCommand();
98 EXPECT_TRUE(command_packet_view.IsValid());
99 EXPECT_EQ(command_packet_view.GetOpCode(), op_code);
100 return command_packet_view;
101 }
102
CommandCompleteCallback(std::unique_ptr<EventBuilder> event_builder)103 void CommandCompleteCallback(std::unique_ptr<EventBuilder> event_builder) {
104 auto event = EventView::Create(GetPacketView(std::move(event_builder)));
105 CommandCompleteView complete_view = CommandCompleteView::Create(event);
106 ASSERT_TRUE(complete_view.IsValid());
107 ASSERT_NE((uint16_t)command_complete_callbacks.size(), 0);
108 std::move(command_complete_callbacks.front()).Invoke(complete_view);
109 command_complete_callbacks.pop_front();
110 }
111
CommandStatusCallback(std::unique_ptr<EventBuilder> event_builder)112 void CommandStatusCallback(std::unique_ptr<EventBuilder> event_builder) {
113 auto event = EventView::Create(GetPacketView(std::move(event_builder)));
114 CommandStatusView status_view = CommandStatusView::Create(event);
115 ASSERT_TRUE(status_view.IsValid());
116 ASSERT_NE((uint16_t)command_status_callbacks.size(), 0);
117 std::move(command_status_callbacks.front()).Invoke(status_view);
118 command_status_callbacks.pop_front();
119 }
120
121 private:
122 std::list<common::ContextualOnceCallback<void(CommandCompleteView)>> command_complete_callbacks;
123 std::list<common::ContextualOnceCallback<void(CommandStatusView)>> command_status_callbacks;
124 std::queue<std::unique_ptr<CommandBuilder>> command_queue_;
125 std::unique_ptr<std::promise<void>> command_promise_;
126 std::unique_ptr<std::future<void>> command_future_;
127 mutable std::mutex mutex_;
128 };
129
130 const char* test_flags[] = {
131 "INIT_logging_debug_enabled_for_all=true",
132 nullptr,
133 };
134
135 class PeriodicSyncManagerTest : public ::testing::Test {
136 protected:
SetUp()137 void SetUp() override {
138 thread_ = new os::Thread("thread", os::Thread::Priority::NORMAL);
139 handler_ = new os::Handler(thread_);
140 test_le_scanning_interface_ = new TestLeScanningInterface();
141 periodic_sync_manager_ = new PeriodicSyncManager(&mock_callbacks_);
142 periodic_sync_manager_->Init(test_le_scanning_interface_, handler_);
143 bluetooth::common::InitFlags::Load(test_flags);
144 }
145
TearDown()146 void TearDown() override {
147 delete periodic_sync_manager_;
148 periodic_sync_manager_ = nullptr;
149 delete test_le_scanning_interface_;
150 test_le_scanning_interface_ = nullptr;
151 handler_->Clear();
152 delete handler_;
153 handler_ = nullptr;
154 delete thread_;
155 thread_ = nullptr;
156 }
157
sync_handler()158 void sync_handler() {
159 ASSERT(thread_ != nullptr);
160 ASSERT(thread_->GetReactor()->WaitForIdle(2s));
161 }
162
163 class MockCallbacks : public bluetooth::hci::ScanningCallback {
164 public:
165 MOCK_METHOD(
166 void,
167 OnScannerRegistered,
168 (const bluetooth::hci::Uuid app_uuid, ScannerId scanner_id, ScanningStatus status),
169 (override));
170 MOCK_METHOD(void, OnSetScannerParameterComplete, (ScannerId scanner_id, ScanningStatus status), (override));
171 MOCK_METHOD(
172 void,
173 OnScanResult,
174 (uint16_t event_type,
175 uint8_t address_type,
176 Address address,
177 uint8_t primary_phy,
178 uint8_t secondary_phy,
179 uint8_t advertising_sid,
180 int8_t tx_power,
181 int8_t rssi,
182 uint16_t periodic_advertising_interval,
183 std::vector<uint8_t> advertising_data),
184 (override));
185 MOCK_METHOD(
186 void,
187 OnTrackAdvFoundLost,
188 (bluetooth::hci::AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info),
189 (override));
190 MOCK_METHOD(
191 void,
192 OnBatchScanReports,
193 (int client_if, int status, int report_format, int num_records, std::vector<uint8_t> data),
194 (override));
195 MOCK_METHOD(void, OnBatchScanThresholdCrossed, (int client_if), (override));
196 MOCK_METHOD(void, OnTimeout, (), (override));
197 MOCK_METHOD(void, OnFilterEnable, (Enable enable, uint8_t status), (override));
198 MOCK_METHOD(void, OnFilterParamSetup, (uint8_t available_spaces, ApcfAction action, uint8_t status), (override));
199 MOCK_METHOD(
200 void,
201 OnFilterConfigCallback,
202 (ApcfFilterType filter_type, uint8_t available_spaces, ApcfAction action, uint8_t status),
203 (override));
204 MOCK_METHOD(void, OnPeriodicSyncStarted, (int, uint8_t, uint16_t, uint8_t, AddressWithType, uint8_t, uint16_t));
205 MOCK_METHOD(void, OnPeriodicSyncReport, (uint16_t, int8_t, int8_t, uint8_t, std::vector<uint8_t>));
206 MOCK_METHOD(void, OnPeriodicSyncLost, (uint16_t));
207 MOCK_METHOD(void, OnPeriodicSyncTransferred, (int, uint8_t, Address));
208 MOCK_METHOD(void, OnBigInfoReport, (uint16_t, bool));
209 } mock_callbacks_;
210
211 os::Thread* thread_;
212 os::Handler* handler_;
213 TestLeScanningInterface* test_le_scanning_interface_;
214 PeriodicSyncManager* periodic_sync_manager_ = nullptr;
215 };
216
TEST_F(PeriodicSyncManagerTest,startup_teardown)217 TEST_F(PeriodicSyncManagerTest, startup_teardown) {}
218
TEST_F(PeriodicSyncManagerTest,start_sync_test)219 TEST_F(PeriodicSyncManagerTest, start_sync_test) {
220 Address address;
221 Address::FromString("00:11:22:33:44:55", address);
222 int request_id = 0x01;
223 uint8_t advertiser_sid = 0x02;
224 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
225 uint16_t sync_handle = 0x03;
226 PeriodicSyncStates request{
227 .request_id = request_id,
228 .advertiser_sid = advertiser_sid,
229 .address_with_type = address_with_type,
230 .sync_handle = sync_handle,
231 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
232 };
233 uint16_t skip = 0x04;
234 uint16_t sync_timeout = 0x0A;
235 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
236 periodic_sync_manager_->StartSync(request, skip, sync_timeout);
237 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
238 auto packet_view = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
239 ASSERT_TRUE(packet_view.IsValid());
240 ASSERT_EQ(advertiser_sid, packet_view.GetAdvertisingSid());
241 ASSERT_EQ(
242 AdvertisingAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
243 packet_view.GetAdvertiserAddressType());
244 ASSERT_EQ(address, packet_view.GetAdvertiserAddress());
245 ASSERT_EQ(skip, packet_view.GetSkip());
246 ASSERT_EQ(sync_timeout, packet_view.GetSyncTimeout());
247 sync_handler();
248 }
249
TEST_F(PeriodicSyncManagerTest,handle_advertising_sync_established_test)250 TEST_F(PeriodicSyncManagerTest, handle_advertising_sync_established_test) {
251 uint16_t sync_handle = 0x12;
252 uint8_t advertiser_sid = 0x02;
253 // start scan
254 Address address;
255 Address::FromString("00:11:22:33:44:55", address);
256 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
257 PeriodicSyncStates request{
258 .request_id = 0x01,
259 .advertiser_sid = advertiser_sid,
260 .address_with_type = address_with_type,
261 .sync_handle = sync_handle,
262 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
263 };
264 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
265 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
266 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
267 auto temp_view = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
268 ASSERT_TRUE(temp_view.IsValid());
269
270 // Get command status
271 test_le_scanning_interface_->CommandStatusCallback(
272 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
273
274 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncStarted);
275
276 // Get LePeriodicAdvertisingSyncEstablished
277 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
278 ErrorCode::SUCCESS,
279 sync_handle,
280 advertiser_sid,
281 address_with_type.GetAddressType(),
282 address_with_type.GetAddress(),
283 SecondaryPhyType::LE_1M,
284 0xFF,
285 ClockAccuracy::PPM_250);
286 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
287 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
288 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
289 sync_handler();
290 }
291
TEST_F(PeriodicSyncManagerTest,handle_advertising_sync_established_with_public_identity_address_test)292 TEST_F(PeriodicSyncManagerTest, handle_advertising_sync_established_with_public_identity_address_test) {
293 uint16_t sync_handle = 0x12;
294 uint8_t advertiser_sid = 0x02;
295 // start scan
296 Address address;
297 Address::FromString("00:11:22:33:44:55", address);
298 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
299 PeriodicSyncStates request{
300 .request_id = 0x01,
301 .advertiser_sid = advertiser_sid,
302 .address_with_type = address_with_type,
303 .sync_handle = sync_handle,
304 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
305 };
306 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
307 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
308 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
309 auto temp_view = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
310 ASSERT_TRUE(temp_view.IsValid());
311
312 // Get command status
313 test_le_scanning_interface_->CommandStatusCallback(
314 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
315
316 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncStarted);
317
318 // Get LePeriodicAdvertisingSyncEstablished with AddressType::PUBLIC_IDENTITY_ADDRESS
319 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
320 ErrorCode::SUCCESS,
321 sync_handle,
322 advertiser_sid,
323 AddressType::PUBLIC_IDENTITY_ADDRESS,
324 address_with_type.GetAddress(),
325 SecondaryPhyType::LE_1M,
326 0xFF,
327 ClockAccuracy::PPM_250);
328 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
329 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
330 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
331 sync_handler();
332 }
333
TEST_F(PeriodicSyncManagerTest,stop_sync_test)334 TEST_F(PeriodicSyncManagerTest, stop_sync_test) {
335 uint16_t sync_handle = 0x12;
336 uint8_t advertiser_sid = 0x02;
337 // start scan
338 Address address;
339 Address::FromString("00:11:22:33:44:55", address);
340 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
341 PeriodicSyncStates request{
342 .request_id = 0x01,
343 .advertiser_sid = advertiser_sid,
344 .address_with_type = address_with_type,
345 .sync_handle = sync_handle,
346 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
347 };
348 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
349 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
350 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
351 auto temp_veiw = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
352 ASSERT_TRUE(temp_veiw.IsValid());
353
354 // Get command status
355 test_le_scanning_interface_->CommandStatusCallback(
356 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
357
358 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncStarted);
359
360 // Get LePeriodicAdvertisingSyncEstablished
361 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
362 ErrorCode::SUCCESS,
363 sync_handle,
364 advertiser_sid,
365 address_with_type.GetAddressType(),
366 address_with_type.GetAddress(),
367 SecondaryPhyType::LE_1M,
368 0xFF,
369 ClockAccuracy::PPM_250);
370 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
371 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
372 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
373
374 // StopSync
375 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
376 periodic_sync_manager_->StopSync(sync_handle);
377 packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_TERMINATE_SYNC);
378 auto packet_view = LePeriodicAdvertisingTerminateSyncView::Create(LeScanningCommandView::Create(packet));
379 ASSERT_TRUE(packet_view.IsValid());
380 ASSERT_EQ(sync_handle, packet_view.GetSyncHandle());
381 sync_handler();
382 }
383
TEST_F(PeriodicSyncManagerTest,cancel_create_sync_test)384 TEST_F(PeriodicSyncManagerTest, cancel_create_sync_test) {
385 uint16_t sync_handle = 0x12;
386 uint8_t advertiser_sid = 0x02;
387 // start scan
388 Address address;
389 Address::FromString("00:11:22:33:44:55", address);
390 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
391 PeriodicSyncStates request{
392 .request_id = 0x01,
393 .advertiser_sid = advertiser_sid,
394 .address_with_type = address_with_type,
395 .sync_handle = sync_handle,
396 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
397 };
398 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
399 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
400 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
401 auto temp_veiw = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
402 ASSERT_TRUE(temp_veiw.IsValid());
403
404 // Get command status
405 test_le_scanning_interface_->CommandStatusCallback(
406 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
407
408 // Cancel crate sync
409 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
410 periodic_sync_manager_->CancelCreateSync(advertiser_sid, address_with_type.GetAddress());
411 packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL);
412 auto packet_view = LePeriodicAdvertisingCreateSyncCancelView::Create(LeScanningCommandView::Create(packet));
413 ASSERT_TRUE(packet_view.IsValid());
414 sync_handler();
415 }
416
TEST_F(PeriodicSyncManagerTest,transfer_sync_test)417 TEST_F(PeriodicSyncManagerTest, transfer_sync_test) {
418 Address address;
419 Address::FromString("00:11:22:33:44:55", address);
420 uint16_t service_data = 0x10;
421 uint16_t sync_handle = 0x11;
422 uint16_t connection_handle = 0x12;
423 int pa_source = 0x01;
424 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
425 periodic_sync_manager_->TransferSync(address, service_data, sync_handle, pa_source, connection_handle);
426 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_SYNC_TRANSFER);
427 auto packet_view = LePeriodicAdvertisingSyncTransferView::Create(LeScanningCommandView::Create(packet));
428 ASSERT_TRUE(packet_view.IsValid());
429 ASSERT_EQ(connection_handle, packet_view.GetConnectionHandle());
430 ASSERT_EQ(service_data, packet_view.GetServiceData());
431 ASSERT_EQ(sync_handle, packet_view.GetSyncHandle());
432
433 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncTransferred);
434
435 // Get command complete
436 test_le_scanning_interface_->CommandCompleteCallback(
437 LePeriodicAdvertisingSyncTransferCompleteBuilder::Create(0x00, ErrorCode::SUCCESS, connection_handle));
438
439 sync_handler();
440 }
441
TEST_F(PeriodicSyncManagerTest,sync_set_info_test)442 TEST_F(PeriodicSyncManagerTest, sync_set_info_test) {
443 Address address;
444 Address::FromString("00:11:22:33:44:55", address);
445 uint16_t service_data = 0x10;
446 uint16_t advertising_handle = 0x11;
447 uint16_t connection_handle = 0x12;
448 int pa_source = 0x01;
449 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
450 periodic_sync_manager_->SyncSetInfo(address, service_data, advertising_handle, pa_source, connection_handle);
451 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER);
452 auto packet_view = LePeriodicAdvertisingSetInfoTransferView::Create(LeScanningCommandView::Create(packet));
453 ASSERT_TRUE(packet_view.IsValid());
454 ASSERT_EQ(connection_handle, packet_view.GetConnectionHandle());
455 ASSERT_EQ(service_data, packet_view.GetServiceData());
456 ASSERT_EQ(advertising_handle, packet_view.GetAdvertisingHandle());
457
458 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncTransferred);
459
460 // Get command complete
461 test_le_scanning_interface_->CommandCompleteCallback(
462 LePeriodicAdvertisingSetInfoTransferCompleteBuilder::Create(0x00, ErrorCode::SUCCESS, connection_handle));
463
464 sync_handler();
465 }
466
TEST_F(PeriodicSyncManagerTest,sync_tx_parameters_test)467 TEST_F(PeriodicSyncManagerTest, sync_tx_parameters_test) {
468 Address address;
469 Address::FromString("00:11:22:33:44:55", address);
470 uint8_t mode = 0x00;
471 uint16_t skip = 0x11;
472 uint16_t timout = 0x12;
473 int reg_id = 0x01;
474 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
475 periodic_sync_manager_->SyncTxParameters(address, mode, skip, timout, reg_id);
476 auto packet =
477 test_le_scanning_interface_->GetCommand(OpCode::LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS);
478 auto packet_view =
479 LeSetDefaultPeriodicAdvertisingSyncTransferParametersView::Create(LeScanningCommandView::Create(packet));
480
481 ASSERT_TRUE(packet_view.IsValid());
482 ASSERT_EQ(mode, (uint8_t)packet_view.GetMode());
483 ASSERT_EQ(skip, packet_view.GetSkip());
484 ASSERT_EQ(timout, packet_view.GetSyncTimeout());
485
486 sync_handler();
487 }
488
TEST_F(PeriodicSyncManagerTest,handle_sync_lost_test)489 TEST_F(PeriodicSyncManagerTest, handle_sync_lost_test) {
490 uint16_t sync_handle = 0x12;
491 uint8_t advertiser_sid = 0x02;
492 // start scan
493 Address address;
494 Address::FromString("00:11:22:33:44:55", address);
495 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
496 PeriodicSyncStates request{
497 .request_id = 0x01,
498 .advertiser_sid = advertiser_sid,
499 .address_with_type = address_with_type,
500 .sync_handle = sync_handle,
501 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
502 };
503 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
504 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
505 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
506 auto temp_veiw = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
507 ASSERT_TRUE(temp_veiw.IsValid());
508
509 // Get command status
510 test_le_scanning_interface_->CommandStatusCallback(
511 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
512
513 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncStarted);
514
515 // Get LePeriodicAdvertisingSyncEstablished
516 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
517 ErrorCode::SUCCESS,
518 sync_handle,
519 advertiser_sid,
520 address_with_type.GetAddressType(),
521 address_with_type.GetAddress(),
522 SecondaryPhyType::LE_1M,
523 0xFF,
524 ClockAccuracy::PPM_250);
525 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
526 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
527 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
528
529 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncLost);
530
531 // Get LePeriodicAdvertisingSyncLost
532 auto builder2 = LePeriodicAdvertisingSyncLostBuilder::Create(sync_handle);
533
534 auto event_view2 = LePeriodicAdvertisingSyncLostView::Create(
535 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder2)))));
536 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncLost(event_view2);
537
538 sync_handler();
539 }
540
TEST_F(PeriodicSyncManagerTest,handle_periodic_advertising_report_test)541 TEST_F(PeriodicSyncManagerTest, handle_periodic_advertising_report_test) {
542 uint16_t sync_handle = 0x12;
543 uint8_t advertiser_sid = 0x02;
544 // start scan
545 Address address;
546 Address::FromString("00:11:22:33:44:55", address);
547 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
548 PeriodicSyncStates request{
549 .request_id = 0x01,
550 .advertiser_sid = advertiser_sid,
551 .address_with_type = address_with_type,
552 .sync_handle = sync_handle,
553 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
554 };
555 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
556 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
557 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
558 auto temp_veiw = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
559 ASSERT_TRUE(temp_veiw.IsValid());
560
561 // Get command status
562 test_le_scanning_interface_->CommandStatusCallback(
563 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
564
565 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncStarted);
566
567 // Get LePeriodicAdvertisingSyncEstablished
568 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
569 ErrorCode::SUCCESS,
570 sync_handle,
571 advertiser_sid,
572 address_with_type.GetAddressType(),
573 address_with_type.GetAddress(),
574 SecondaryPhyType::LE_1M,
575 0xFF,
576 ClockAccuracy::PPM_250);
577 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
578 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
579 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
580
581 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncReport);
582
583 // Get LePeriodicAdvertisingReport
584 std::vector<uint8_t> data = {0x01, 0x02, 0x03};
585 auto builder2 = LePeriodicAdvertisingReportBuilder::Create(
586 sync_handle, 0x1a, 0x1a, CteType::AOA_CONSTANT_TONE_EXTENSION, DataStatus::COMPLETE, data);
587
588 auto event_view2 = LePeriodicAdvertisingReportView::Create(
589 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder2)))));
590 periodic_sync_manager_->HandleLePeriodicAdvertisingReport(event_view2);
591
592 sync_handler();
593 }
594
TEST_F(PeriodicSyncManagerTest,handle_biginfo_advertising_report_test)595 TEST_F(PeriodicSyncManagerTest, handle_biginfo_advertising_report_test) {
596 uint16_t sync_handle = 0x12;
597 uint8_t advertiser_sid = 0x02;
598 // start scan
599 Address address;
600 Address::FromString("00:11:22:33:44:55", address);
601 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
602 PeriodicSyncStates request{
603 .request_id = 0x01,
604 .advertiser_sid = advertiser_sid,
605 .address_with_type = address_with_type,
606 .sync_handle = sync_handle,
607 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
608 };
609 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
610 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
611 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
612 auto temp_veiw = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
613 ASSERT_TRUE(temp_veiw.IsValid());
614
615 // Get command status
616 test_le_scanning_interface_->CommandStatusCallback(
617 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
618
619 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncStarted);
620
621 // Get LePeriodicAdvertisingSyncEstablished
622 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
623 ErrorCode::SUCCESS,
624 sync_handle,
625 advertiser_sid,
626 address_with_type.GetAddressType(),
627 address_with_type.GetAddress(),
628 SecondaryPhyType::LE_1M,
629 0xFF,
630 ClockAccuracy::PPM_250);
631 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
632 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
633 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
634
635 EXPECT_CALL(mock_callbacks_, OnBigInfoReport);
636
637 // Get LeBigInfoAdvertisingReport
638 auto builder2 = LeBigInfoAdvertisingReportBuilder::Create(
639 sync_handle, 2, 9, 24, 3, 1, 2, 100, 10000, 100, static_cast<SecondaryPhyType>(2),
640 static_cast<Enable> (0), static_cast<Enable> (1));
641
642 auto event_view2 = LeBigInfoAdvertisingReportView::Create(
643 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder2)))));
644 periodic_sync_manager_->HandleLeBigInfoAdvertisingReport(event_view2);
645
646 sync_handler();
647 }
648
649 } // namespace
650 } // namespace hci
651 } // namespace bluetooth
652