• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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