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 <com_android_bluetooth_flags.h>
20 #include <flag_macros.h>
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23
24 #include "hci/le_scanning_callback.h"
25 #include "hci/le_scanning_interface.h"
26 #include "hci/le_scanning_manager_mock.h"
27 #include "os/handler.h"
28
29 #define TEST_BT com::android::bluetooth::flags
30
31 using namespace std::chrono_literals;
32
33 using testing::_;
34
35 namespace bluetooth {
36 namespace hci {
37 namespace {
38
GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet)39 PacketView<kLittleEndian> GetPacketView(std::unique_ptr<packet::BasePacketBuilder> packet) {
40 auto bytes = std::make_shared<std::vector<uint8_t>>();
41 BitInserter i(*bytes);
42 bytes->reserve(packet->size());
43 packet->Serialize(i);
44 return packet::PacketView<packet::kLittleEndian>(bytes);
45 }
46
47 class TestLeScanningInterface : public LeScanningInterface {
48 public:
EnqueueCommand(std::unique_ptr<LeScanningCommandBuilder> command,common::ContextualOnceCallback<void (CommandCompleteView)> on_complete)49 void EnqueueCommand(
50 std::unique_ptr<LeScanningCommandBuilder> command,
51 common::ContextualOnceCallback<void(CommandCompleteView)> on_complete) override {
52 std::lock_guard<std::mutex> lock(mutex_);
53 command_queue_.push(std::move(command));
54 command_complete_callbacks.push_back(std::move(on_complete));
55 if (command_promise_ != nullptr) {
56 std::promise<void>* prom = command_promise_.release();
57 prom->set_value();
58 delete prom;
59 }
60 }
61
EnqueueCommand(std::unique_ptr<LeScanningCommandBuilder> command,common::ContextualOnceCallback<void (CommandStatusView)> on_status)62 void EnqueueCommand(
63 std::unique_ptr<LeScanningCommandBuilder> command,
64 common::ContextualOnceCallback<void(CommandStatusView)> on_status) override {
65 command_queue_.push(std::move(command));
66 command_status_callbacks.push_back(std::move(on_status));
67 if (command_promise_ != nullptr) {
68 std::promise<void>* prom = command_promise_.release();
69 prom->set_value();
70 delete prom;
71 }
72 }
73
SetCommandFuture()74 void SetCommandFuture() {
75 ASSERT_EQ(command_promise_, nullptr) << "Promises, Promises, ... Only one at a time.";
76 command_promise_ = std::make_unique<std::promise<void>>();
77 command_future_ = std::make_unique<std::future<void>>(command_promise_->get_future());
78 }
79
GetLastCommand()80 CommandView GetLastCommand() {
81 if (command_queue_.empty()) {
82 return CommandView::Create(PacketView<kLittleEndian>(std::make_shared<std::vector<uint8_t>>()));
83 }
84 auto last = std::move(command_queue_.front());
85 command_queue_.pop();
86 return CommandView::Create(GetPacketView(std::move(last)));
87 }
88
GetCommand(OpCode op_code)89 CommandView GetCommand(OpCode op_code) {
90 if (!command_queue_.empty()) {
91 std::lock_guard<std::mutex> lock(mutex_);
92 if (command_future_ != nullptr) {
93 command_future_.reset();
94 command_promise_.reset();
95 }
96 } else if (command_future_ != nullptr) {
97 auto result = command_future_->wait_for(std::chrono::milliseconds(1000));
98 EXPECT_NE(std::future_status::timeout, result);
99 }
100 std::lock_guard<std::mutex> lock(mutex_);
101 log::assert_that(
102 !command_queue_.empty(),
103 "Expecting command {} but command queue was empty",
104 OpCodeText(op_code));
105 CommandView command_packet_view = GetLastCommand();
106 EXPECT_TRUE(command_packet_view.IsValid());
107 EXPECT_EQ(command_packet_view.GetOpCode(), op_code);
108 return command_packet_view;
109 }
110
CommandCompleteCallback(std::unique_ptr<EventBuilder> event_builder)111 void CommandCompleteCallback(std::unique_ptr<EventBuilder> event_builder) {
112 auto event = EventView::Create(GetPacketView(std::move(event_builder)));
113 CommandCompleteView complete_view = CommandCompleteView::Create(event);
114 ASSERT_TRUE(complete_view.IsValid());
115 ASSERT_NE((uint16_t)command_complete_callbacks.size(), 0);
116 std::move(command_complete_callbacks.front())(complete_view);
117 command_complete_callbacks.pop_front();
118 }
119
CommandStatusCallback(std::unique_ptr<EventBuilder> event_builder)120 void CommandStatusCallback(std::unique_ptr<EventBuilder> event_builder) {
121 auto event = EventView::Create(GetPacketView(std::move(event_builder)));
122 CommandStatusView status_view = CommandStatusView::Create(event);
123 ASSERT_TRUE(status_view.IsValid());
124 ASSERT_NE((uint16_t)command_status_callbacks.size(), 0);
125 std::move(command_status_callbacks.front())(status_view);
126 command_status_callbacks.pop_front();
127 }
128
129 private:
130 std::list<common::ContextualOnceCallback<void(CommandCompleteView)>> command_complete_callbacks;
131 std::list<common::ContextualOnceCallback<void(CommandStatusView)>> command_status_callbacks;
132 std::queue<std::unique_ptr<CommandBuilder>> command_queue_;
133 std::unique_ptr<std::promise<void>> command_promise_;
134 std::unique_ptr<std::future<void>> command_future_;
135 mutable std::mutex mutex_;
136 };
137
138 class PeriodicSyncManagerTest : public ::testing::Test {
139 protected:
SetUp()140 void SetUp() override {
141 thread_ = new os::Thread("thread", os::Thread::Priority::NORMAL);
142 handler_ = new os::Handler(thread_);
143 test_le_scanning_interface_ = new TestLeScanningInterface();
144 periodic_sync_manager_ = new PeriodicSyncManager(&mock_callbacks_);
145 periodic_sync_manager_->Init(test_le_scanning_interface_, handler_);
146 }
147
TearDown()148 void TearDown() override {
149 delete periodic_sync_manager_;
150 periodic_sync_manager_ = nullptr;
151 delete test_le_scanning_interface_;
152 test_le_scanning_interface_ = nullptr;
153 handler_->Clear();
154 delete handler_;
155 handler_ = nullptr;
156 delete thread_;
157 thread_ = nullptr;
158 }
159
sync_handler()160 void sync_handler() {
161 log::assert_that(thread_ != nullptr, "assert failed: thread_ != nullptr");
162 log::assert_that(
163 thread_->GetReactor()->WaitForIdle(2s),
164 "assert failed: thread_->GetReactor()->WaitForIdle(2s)");
165 }
166
167 class MockCallbacks : public bluetooth::hci::ScanningCallback {
168 public:
169 MOCK_METHOD(
170 void,
171 OnScannerRegistered,
172 (const bluetooth::hci::Uuid app_uuid, ScannerId scanner_id, ScanningStatus status),
173 (override));
174 MOCK_METHOD(void, OnSetScannerParameterComplete, (ScannerId scanner_id, ScanningStatus status), (override));
175 MOCK_METHOD(
176 void,
177 OnScanResult,
178 (uint16_t event_type,
179 uint8_t address_type,
180 Address address,
181 uint8_t primary_phy,
182 uint8_t secondary_phy,
183 uint8_t advertising_sid,
184 int8_t tx_power,
185 int8_t rssi,
186 uint16_t periodic_advertising_interval,
187 std::vector<uint8_t> advertising_data),
188 (override));
189 MOCK_METHOD(
190 void,
191 OnTrackAdvFoundLost,
192 (bluetooth::hci::AdvertisingFilterOnFoundOnLostInfo on_found_on_lost_info),
193 (override));
194 MOCK_METHOD(
195 void,
196 OnBatchScanReports,
197 (int client_if, int status, int report_format, int num_records, std::vector<uint8_t> data),
198 (override));
199 MOCK_METHOD(void, OnBatchScanThresholdCrossed, (int client_if), (override));
200 MOCK_METHOD(void, OnTimeout, (), (override));
201 MOCK_METHOD(void, OnFilterEnable, (Enable enable, uint8_t status), (override));
202 MOCK_METHOD(void, OnFilterParamSetup, (uint8_t available_spaces, ApcfAction action, uint8_t status), (override));
203 MOCK_METHOD(
204 void,
205 OnFilterConfigCallback,
206 (ApcfFilterType filter_type, uint8_t available_spaces, ApcfAction action, uint8_t status),
207 (override));
208 MOCK_METHOD(void, OnPeriodicSyncStarted, (int, uint8_t, uint16_t, uint8_t, AddressWithType, uint8_t, uint16_t));
209 MOCK_METHOD(void, OnPeriodicSyncReport, (uint16_t, int8_t, int8_t, uint8_t, std::vector<uint8_t>));
210 MOCK_METHOD(void, OnPeriodicSyncLost, (uint16_t));
211 MOCK_METHOD(void, OnPeriodicSyncTransferred, (int, uint8_t, Address));
212 MOCK_METHOD(void, OnBigInfoReport, (uint16_t, bool));
213 } mock_callbacks_;
214
215 os::Thread* thread_;
216 os::Handler* handler_;
217 TestLeScanningInterface* test_le_scanning_interface_;
218 PeriodicSyncManager* periodic_sync_manager_ = nullptr;
219 };
220
TEST_F(PeriodicSyncManagerTest,startup_teardown)221 TEST_F(PeriodicSyncManagerTest, startup_teardown) {}
222
TEST_F(PeriodicSyncManagerTest,start_sync_test)223 TEST_F(PeriodicSyncManagerTest, start_sync_test) {
224 Address address;
225 Address::FromString("00:11:22:33:44:55", address);
226 int request_id = 0x01;
227 uint8_t advertiser_sid = 0x02;
228 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
229 uint16_t sync_handle = 0x03;
230 PeriodicSyncStates request{
231 .request_id = request_id,
232 .advertiser_sid = advertiser_sid,
233 .address_with_type = address_with_type,
234 .sync_handle = sync_handle,
235 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
236 };
237 uint16_t skip = 0x04;
238 uint16_t sync_timeout = 0x0A;
239 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
240 periodic_sync_manager_->StartSync(request, skip, sync_timeout);
241 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
242 auto packet_view = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
243 ASSERT_TRUE(packet_view.IsValid());
244 ASSERT_EQ(advertiser_sid, packet_view.GetAdvertisingSid());
245 ASSERT_EQ(
246 AdvertisingAddressType::PUBLIC_DEVICE_OR_IDENTITY_ADDRESS,
247 packet_view.GetAdvertiserAddressType());
248 ASSERT_EQ(address, packet_view.GetAdvertiserAddress());
249 ASSERT_EQ(skip, packet_view.GetSkip());
250 ASSERT_EQ(sync_timeout, packet_view.GetSyncTimeout());
251 sync_handler();
252 }
253
TEST_F(PeriodicSyncManagerTest,handle_advertising_sync_established_test)254 TEST_F(PeriodicSyncManagerTest, handle_advertising_sync_established_test) {
255 uint16_t sync_handle = 0x12;
256 uint8_t advertiser_sid = 0x02;
257 // start scan
258 Address address;
259 Address::FromString("00:11:22:33:44:55", address);
260 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
261 PeriodicSyncStates request{
262 .request_id = 0x01,
263 .advertiser_sid = advertiser_sid,
264 .address_with_type = address_with_type,
265 .sync_handle = sync_handle,
266 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
267 };
268 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
269 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
270 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
271 auto temp_view = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
272 ASSERT_TRUE(temp_view.IsValid());
273
274 // Get command status
275 test_le_scanning_interface_->CommandStatusCallback(
276 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
277
278 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncStarted);
279
280 // Get LePeriodicAdvertisingSyncEstablished
281 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
282 ErrorCode::SUCCESS,
283 sync_handle,
284 advertiser_sid,
285 address_with_type.GetAddressType(),
286 address_with_type.GetAddress(),
287 SecondaryPhyType::LE_1M,
288 0xFF,
289 ClockAccuracy::PPM_250);
290 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
291 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
292 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
293 sync_handler();
294 }
295
TEST_F(PeriodicSyncManagerTest,handle_advertising_sync_established_with_public_identity_address_test)296 TEST_F(PeriodicSyncManagerTest, handle_advertising_sync_established_with_public_identity_address_test) {
297 uint16_t sync_handle = 0x12;
298 uint8_t advertiser_sid = 0x02;
299 // start scan
300 Address address;
301 Address::FromString("00:11:22:33:44:55", address);
302 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
303 PeriodicSyncStates request{
304 .request_id = 0x01,
305 .advertiser_sid = advertiser_sid,
306 .address_with_type = address_with_type,
307 .sync_handle = sync_handle,
308 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
309 };
310 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
311 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
312 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
313 auto temp_view = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
314 ASSERT_TRUE(temp_view.IsValid());
315
316 // Get command status
317 test_le_scanning_interface_->CommandStatusCallback(
318 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
319
320 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncStarted);
321
322 // Get LePeriodicAdvertisingSyncEstablished with AddressType::PUBLIC_IDENTITY_ADDRESS
323 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
324 ErrorCode::SUCCESS,
325 sync_handle,
326 advertiser_sid,
327 AddressType::PUBLIC_IDENTITY_ADDRESS,
328 address_with_type.GetAddress(),
329 SecondaryPhyType::LE_1M,
330 0xFF,
331 ClockAccuracy::PPM_250);
332 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
333 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
334 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
335 sync_handler();
336 }
337
TEST_F(PeriodicSyncManagerTest,stop_sync_test)338 TEST_F(PeriodicSyncManagerTest, stop_sync_test) {
339 uint16_t sync_handle = 0x12;
340 uint8_t advertiser_sid = 0x02;
341 // start scan
342 Address address;
343 Address::FromString("00:11:22:33:44:55", address);
344 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
345 PeriodicSyncStates request{
346 .request_id = 0x01,
347 .advertiser_sid = advertiser_sid,
348 .address_with_type = address_with_type,
349 .sync_handle = sync_handle,
350 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
351 };
352 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
353 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
354 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
355 auto temp_view =
356 LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
357 ASSERT_TRUE(temp_view.IsValid());
358
359 // Get command status
360 test_le_scanning_interface_->CommandStatusCallback(
361 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
362
363 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncStarted);
364
365 // Get LePeriodicAdvertisingSyncEstablished
366 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
367 ErrorCode::SUCCESS,
368 sync_handle,
369 advertiser_sid,
370 address_with_type.GetAddressType(),
371 address_with_type.GetAddress(),
372 SecondaryPhyType::LE_1M,
373 0xFF,
374 ClockAccuracy::PPM_250);
375 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
376 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
377 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
378
379 // StopSync
380 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
381 periodic_sync_manager_->StopSync(sync_handle);
382 packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_TERMINATE_SYNC);
383 auto packet_view = LePeriodicAdvertisingTerminateSyncView::Create(LeScanningCommandView::Create(packet));
384 ASSERT_TRUE(packet_view.IsValid());
385 ASSERT_EQ(sync_handle, packet_view.GetSyncHandle());
386 sync_handler();
387 }
388
TEST_F(PeriodicSyncManagerTest,cancel_create_sync_test)389 TEST_F(PeriodicSyncManagerTest, cancel_create_sync_test) {
390 uint16_t sync_handle = 0x12;
391 uint8_t advertiser_sid = 0x02;
392 // start scan
393 Address address;
394 Address::FromString("00:11:22:33:44:55", address);
395 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
396 PeriodicSyncStates request{
397 .request_id = 0x01,
398 .advertiser_sid = advertiser_sid,
399 .address_with_type = address_with_type,
400 .sync_handle = sync_handle,
401 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
402 };
403 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
404 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
405 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
406 auto temp_view =
407 LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
408 ASSERT_TRUE(temp_view.IsValid());
409
410 // Get command status
411 test_le_scanning_interface_->CommandStatusCallback(
412 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
413
414 // Cancel crate sync
415 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
416 periodic_sync_manager_->CancelCreateSync(advertiser_sid, address_with_type.GetAddress());
417 packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL);
418 auto packet_view = LePeriodicAdvertisingCreateSyncCancelView::Create(LeScanningCommandView::Create(packet));
419 ASSERT_TRUE(packet_view.IsValid());
420 sync_handler();
421 }
422
TEST_F(PeriodicSyncManagerTest,transfer_sync_test)423 TEST_F(PeriodicSyncManagerTest, transfer_sync_test) {
424 Address address;
425 Address::FromString("00:11:22:33:44:55", address);
426 uint16_t service_data = 0x10;
427 uint16_t sync_handle = 0x11;
428 uint16_t connection_handle = 0x12;
429 int pa_source = 0x01;
430 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
431 periodic_sync_manager_->TransferSync(address, service_data, sync_handle, pa_source, connection_handle);
432 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_SYNC_TRANSFER);
433 auto packet_view = LePeriodicAdvertisingSyncTransferView::Create(LeScanningCommandView::Create(packet));
434 ASSERT_TRUE(packet_view.IsValid());
435 ASSERT_EQ(connection_handle, packet_view.GetConnectionHandle());
436 ASSERT_EQ(service_data, packet_view.GetServiceData());
437 ASSERT_EQ(sync_handle, packet_view.GetSyncHandle());
438
439 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncTransferred);
440
441 // Get command complete
442 test_le_scanning_interface_->CommandCompleteCallback(
443 LePeriodicAdvertisingSyncTransferCompleteBuilder::Create(0x00, ErrorCode::SUCCESS, connection_handle));
444
445 sync_handler();
446 }
447
TEST_F(PeriodicSyncManagerTest,sync_set_info_test)448 TEST_F(PeriodicSyncManagerTest, sync_set_info_test) {
449 Address address;
450 Address::FromString("00:11:22:33:44:55", address);
451 uint16_t service_data = 0x10;
452 uint16_t advertising_handle = 0x11;
453 uint16_t connection_handle = 0x12;
454 int pa_source = 0x01;
455 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
456 periodic_sync_manager_->SyncSetInfo(address, service_data, advertising_handle, pa_source, connection_handle);
457 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_SET_INFO_TRANSFER);
458 auto packet_view = LePeriodicAdvertisingSetInfoTransferView::Create(LeScanningCommandView::Create(packet));
459 ASSERT_TRUE(packet_view.IsValid());
460 ASSERT_EQ(connection_handle, packet_view.GetConnectionHandle());
461 ASSERT_EQ(service_data, packet_view.GetServiceData());
462 ASSERT_EQ(advertising_handle, packet_view.GetAdvertisingHandle());
463
464 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncTransferred);
465
466 // Get command complete
467 test_le_scanning_interface_->CommandCompleteCallback(
468 LePeriodicAdvertisingSetInfoTransferCompleteBuilder::Create(0x00, ErrorCode::SUCCESS, connection_handle));
469
470 sync_handler();
471 }
472
TEST_F(PeriodicSyncManagerTest,sync_tx_parameters_test)473 TEST_F(PeriodicSyncManagerTest, sync_tx_parameters_test) {
474 Address address;
475 Address::FromString("00:11:22:33:44:55", address);
476 uint8_t mode = 0x00;
477 uint16_t skip = 0x11;
478 uint16_t timout = 0x12;
479 int reg_id = 0x01;
480 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
481 periodic_sync_manager_->SyncTxParameters(address, mode, skip, timout, reg_id);
482 auto packet =
483 test_le_scanning_interface_->GetCommand(OpCode::LE_SET_DEFAULT_PERIODIC_ADVERTISING_SYNC_TRANSFER_PARAMETERS);
484 auto packet_view =
485 LeSetDefaultPeriodicAdvertisingSyncTransferParametersView::Create(LeScanningCommandView::Create(packet));
486
487 ASSERT_TRUE(packet_view.IsValid());
488 ASSERT_EQ(mode, (uint8_t)packet_view.GetMode());
489 ASSERT_EQ(skip, packet_view.GetSkip());
490 ASSERT_EQ(timout, packet_view.GetSyncTimeout());
491
492 sync_handler();
493 }
494
TEST_F(PeriodicSyncManagerTest,handle_sync_lost_test)495 TEST_F(PeriodicSyncManagerTest, handle_sync_lost_test) {
496 uint16_t sync_handle = 0x12;
497 uint8_t advertiser_sid = 0x02;
498 // start scan
499 Address address;
500 Address::FromString("00:11:22:33:44:55", address);
501 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
502 PeriodicSyncStates request{
503 .request_id = 0x01,
504 .advertiser_sid = advertiser_sid,
505 .address_with_type = address_with_type,
506 .sync_handle = sync_handle,
507 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
508 };
509 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
510 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
511 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
512 auto temp_view =
513 LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
514 ASSERT_TRUE(temp_view.IsValid());
515
516 // Get command status
517 test_le_scanning_interface_->CommandStatusCallback(
518 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
519
520 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncStarted);
521
522 // Get LePeriodicAdvertisingSyncEstablished
523 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
524 ErrorCode::SUCCESS,
525 sync_handle,
526 advertiser_sid,
527 address_with_type.GetAddressType(),
528 address_with_type.GetAddress(),
529 SecondaryPhyType::LE_1M,
530 0xFF,
531 ClockAccuracy::PPM_250);
532 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
533 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
534 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
535
536 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncLost);
537
538 // Get LePeriodicAdvertisingSyncLost
539 auto builder2 = LePeriodicAdvertisingSyncLostBuilder::Create(sync_handle);
540
541 auto event_view2 = LePeriodicAdvertisingSyncLostView::Create(
542 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder2)))));
543 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncLost(event_view2);
544
545 sync_handler();
546 }
547
TEST_F_WITH_FLAGS(PeriodicSyncManagerTest,handle_advertising_sync_established_after_error_test,REQUIRES_FLAGS_ENABLED (ACONFIG_FLAG (TEST_BT,leaudio_broadcast_feature_support)))548 TEST_F_WITH_FLAGS(
549 PeriodicSyncManagerTest,
550 handle_advertising_sync_established_after_error_test,
551 REQUIRES_FLAGS_ENABLED(ACONFIG_FLAG(TEST_BT, leaudio_broadcast_feature_support))) {
552 uint16_t sync_handle = 0x12;
553 uint8_t advertiser_sid = 0x02;
554 // start scan
555 Address address;
556 Address::FromString("00:11:22:33:44:55", address);
557 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
558
559 // First request which will finish with error
560 int request_id_1 = 0x01;
561 PeriodicSyncStates request{
562 .request_id = request_id_1,
563 .advertiser_sid = advertiser_sid,
564 .address_with_type = address_with_type,
565 .sync_handle = sync_handle,
566 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
567 };
568 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
569 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
570 auto packet =
571 test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
572 auto temp_view =
573 LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
574 ASSERT_TRUE(temp_view.IsValid());
575
576 // Get command status
577 test_le_scanning_interface_->CommandStatusCallback(
578 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
579
580 EXPECT_CALL(
581 mock_callbacks_,
582 OnPeriodicSyncStarted(
583 request_id_1,
584 static_cast<uint8_t>(ErrorCode::CONNECTION_FAILED_ESTABLISHMENT),
585 _,
586 _,
587 _,
588 _,
589 _))
590 .Times(1);
591
592 // Get LePeriodicAdvertisingSyncEstablished
593 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
594 ErrorCode::CONNECTION_FAILED_ESTABLISHMENT,
595 sync_handle,
596 advertiser_sid,
597 address_with_type.GetAddressType(),
598 address_with_type.GetAddress(),
599 SecondaryPhyType::LE_1M,
600 0xFF,
601 ClockAccuracy::PPM_250);
602 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
603 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
604 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
605
606 // Second request with the same data but different id
607 int request_id_2 = 0x02;
608 request.request_id = request_id_2;
609 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
610 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
611 packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
612 temp_view = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
613 ASSERT_TRUE(temp_view.IsValid());
614
615 // Get command status
616 test_le_scanning_interface_->CommandStatusCallback(
617 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
618
619 EXPECT_CALL(
620 mock_callbacks_,
621 OnPeriodicSyncStarted(request_id_2, static_cast<uint8_t>(ErrorCode::SUCCESS), _, _, _, _, _))
622 .Times(1);
623
624 // Get LePeriodicAdvertisingSyncEstablished
625 auto builder2 = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
626 ErrorCode::SUCCESS,
627 sync_handle,
628 advertiser_sid,
629 address_with_type.GetAddressType(),
630 address_with_type.GetAddress(),
631 SecondaryPhyType::LE_1M,
632 0xFF,
633 ClockAccuracy::PPM_250);
634 event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
635 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder2)))));
636 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
637
638 sync_handler();
639 }
640
TEST_F_WITH_FLAGS(PeriodicSyncManagerTest,handle_advertising_sync_established_after_create_command_error_test,REQUIRES_FLAGS_ENABLED (ACONFIG_FLAG (TEST_BT,leaudio_broadcast_assistant_handle_command_statuses)))641 TEST_F_WITH_FLAGS(
642 PeriodicSyncManagerTest,
643 handle_advertising_sync_established_after_create_command_error_test,
644 REQUIRES_FLAGS_ENABLED(
645 ACONFIG_FLAG(TEST_BT, leaudio_broadcast_assistant_handle_command_statuses))) {
646 uint16_t sync_handle = 0x12;
647 Address address;
648 Address::FromString("00:11:22:33:44:55", address);
649 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
650
651 // First request which will finish with error
652 int request_id_1 = 0x01;
653 uint8_t advertiser_sid_1 = 0x02;
654 PeriodicSyncStates request{
655 .request_id = request_id_1,
656 .advertiser_sid = advertiser_sid_1,
657 .address_with_type = address_with_type,
658 .sync_handle = sync_handle,
659 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
660 };
661 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
662 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
663 auto packet =
664 test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
665 auto temp_view =
666 LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
667 ASSERT_TRUE(temp_view.IsValid());
668
669 EXPECT_CALL(
670 mock_callbacks_,
671 OnPeriodicSyncStarted(
672 request_id_1,
673 static_cast<uint8_t>(ErrorCode::MEMORY_CAPACITY_EXCEEDED),
674 _,
675 advertiser_sid_1,
676 _,
677 _,
678 _))
679 .Times(1);
680
681 // Get command status
682 test_le_scanning_interface_->CommandStatusCallback(
683 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(
684 ErrorCode::MEMORY_CAPACITY_EXCEEDED, 0x00));
685
686 // Second request
687 int request_id_2 = 0x02;
688 uint8_t advertiser_sid_2 = 0x03;
689 request.request_id = request_id_2;
690 request.advertiser_sid = advertiser_sid_2;
691 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
692 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
693 packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
694 temp_view = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
695 ASSERT_TRUE(temp_view.IsValid());
696
697 // Get command status
698 test_le_scanning_interface_->CommandStatusCallback(
699 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
700
701 EXPECT_CALL(
702 mock_callbacks_,
703 OnPeriodicSyncStarted(
704 request_id_2, static_cast<uint8_t>(ErrorCode::SUCCESS), _, advertiser_sid_2, _, _, _))
705 .Times(1);
706
707 // Get LePeriodicAdvertisingSyncEstablished
708 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
709 ErrorCode::SUCCESS,
710 sync_handle,
711 advertiser_sid_2,
712 address_with_type.GetAddressType(),
713 address_with_type.GetAddress(),
714 SecondaryPhyType::LE_1M,
715 0xFF,
716 ClockAccuracy::PPM_250);
717 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
718 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
719 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
720
721 sync_handler();
722 }
723
TEST_F_WITH_FLAGS(PeriodicSyncManagerTest,handle_advertising_sync_established_after_cancel_command_error_test,REQUIRES_FLAGS_ENABLED (ACONFIG_FLAG (TEST_BT,leaudio_broadcast_assistant_handle_command_statuses)))724 TEST_F_WITH_FLAGS(
725 PeriodicSyncManagerTest,
726 handle_advertising_sync_established_after_cancel_command_error_test,
727 REQUIRES_FLAGS_ENABLED(
728 ACONFIG_FLAG(TEST_BT, leaudio_broadcast_assistant_handle_command_statuses))) {
729 uint16_t sync_handle = 0x12;
730 Address address;
731 Address::FromString("00:11:22:33:44:55", address);
732 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
733
734 // First request which will finish with timeout error
735 uint8_t advertiser_sid_1 = 0x02;
736 int request_id_1 = 0x01;
737 PeriodicSyncStates request{
738 .request_id = request_id_1,
739 .advertiser_sid = advertiser_sid_1,
740 .address_with_type = address_with_type,
741 .sync_handle = sync_handle,
742 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
743 };
744 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
745 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
746 auto packet =
747 test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
748 auto temp_view =
749 LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
750 ASSERT_TRUE(temp_view.IsValid());
751
752 // Get command status
753 test_le_scanning_interface_->CommandStatusCallback(
754 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
755
756 EXPECT_CALL(
757 mock_callbacks_,
758 OnPeriodicSyncStarted(
759 request_id_1,
760 static_cast<uint8_t>(ErrorCode::ADVERTISING_TIMEOUT),
761 _,
762 advertiser_sid_1,
763 _,
764 _,
765 _))
766 .Times(1);
767
768 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
769 periodic_sync_manager_->OnStartSyncTimeout();
770 packet =
771 test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC_CANCEL);
772 auto temp_view2 =
773 LePeriodicAdvertisingCreateSyncCancelView::Create(LeScanningCommandView::Create(packet));
774 ASSERT_TRUE(temp_view2.IsValid());
775
776 // Get command status
777 test_le_scanning_interface_->CommandCompleteCallback(
778 LePeriodicAdvertisingCreateSyncCancelCompleteBuilder::Create(
779 0x00, ErrorCode::COMMAND_DISALLOWED));
780
781 // Second request
782 int request_id_2 = 0x02;
783 uint8_t advertiser_sid_2 = 0x03;
784 request.request_id = request_id_2;
785 request.advertiser_sid = advertiser_sid_2;
786 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
787 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
788 packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
789 temp_view = LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
790 ASSERT_TRUE(temp_view.IsValid());
791
792 // Get command status
793 test_le_scanning_interface_->CommandStatusCallback(
794 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
795
796 EXPECT_CALL(
797 mock_callbacks_,
798 OnPeriodicSyncStarted(
799 request_id_2, static_cast<uint8_t>(ErrorCode::SUCCESS), _, advertiser_sid_2, _, _, _))
800 .Times(1);
801
802 // Get LePeriodicAdvertisingSyncEstablished
803 auto builder2 = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
804 ErrorCode::SUCCESS,
805 sync_handle,
806 advertiser_sid_2,
807 address_with_type.GetAddressType(),
808 address_with_type.GetAddress(),
809 SecondaryPhyType::LE_1M,
810 0xFF,
811 ClockAccuracy::PPM_250);
812 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
813 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder2)))));
814 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
815
816 sync_handler();
817 }
818
TEST_F(PeriodicSyncManagerTest,handle_periodic_advertising_report_test)819 TEST_F(PeriodicSyncManagerTest, handle_periodic_advertising_report_test) {
820 uint16_t sync_handle = 0x12;
821 uint8_t advertiser_sid = 0x02;
822 // start scan
823 Address address;
824 Address::FromString("00:11:22:33:44:55", address);
825 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
826 PeriodicSyncStates request{
827 .request_id = 0x01,
828 .advertiser_sid = advertiser_sid,
829 .address_with_type = address_with_type,
830 .sync_handle = sync_handle,
831 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
832 };
833 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
834 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
835 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
836 auto temp_view =
837 LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
838 ASSERT_TRUE(temp_view.IsValid());
839
840 // Get command status
841 test_le_scanning_interface_->CommandStatusCallback(
842 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
843
844 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncStarted);
845
846 // Get LePeriodicAdvertisingSyncEstablished
847 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
848 ErrorCode::SUCCESS,
849 sync_handle,
850 advertiser_sid,
851 address_with_type.GetAddressType(),
852 address_with_type.GetAddress(),
853 SecondaryPhyType::LE_1M,
854 0xFF,
855 ClockAccuracy::PPM_250);
856 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
857 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
858 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
859
860 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncReport);
861
862 // Get LePeriodicAdvertisingReport
863 std::vector<uint8_t> data = {0x01, 0x02, 0x03};
864 auto builder2 = LePeriodicAdvertisingReportBuilder::Create(
865 sync_handle, 0x1a, 0x1a, CteType::AOA_CONSTANT_TONE_EXTENSION, DataStatus::COMPLETE, data);
866
867 auto event_view2 = LePeriodicAdvertisingReportView::Create(
868 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder2)))));
869 periodic_sync_manager_->HandleLePeriodicAdvertisingReport(event_view2);
870
871 sync_handler();
872 }
873
TEST_F(PeriodicSyncManagerTest,handle_biginfo_advertising_report_test)874 TEST_F(PeriodicSyncManagerTest, handle_biginfo_advertising_report_test) {
875 uint16_t sync_handle = 0x12;
876 uint8_t advertiser_sid = 0x02;
877 // start scan
878 Address address;
879 Address::FromString("00:11:22:33:44:55", address);
880 AddressWithType address_with_type = AddressWithType(address, AddressType::PUBLIC_DEVICE_ADDRESS);
881 PeriodicSyncStates request{
882 .request_id = 0x01,
883 .advertiser_sid = advertiser_sid,
884 .address_with_type = address_with_type,
885 .sync_handle = sync_handle,
886 .sync_state = PeriodicSyncState::PERIODIC_SYNC_STATE_IDLE,
887 };
888 ASSERT_NO_FATAL_FAILURE(test_le_scanning_interface_->SetCommandFuture());
889 periodic_sync_manager_->StartSync(request, 0x04, 0x0A);
890 auto packet = test_le_scanning_interface_->GetCommand(OpCode::LE_PERIODIC_ADVERTISING_CREATE_SYNC);
891 auto temp_view =
892 LePeriodicAdvertisingCreateSyncView::Create(LeScanningCommandView::Create(packet));
893 ASSERT_TRUE(temp_view.IsValid());
894
895 // Get command status
896 test_le_scanning_interface_->CommandStatusCallback(
897 LePeriodicAdvertisingCreateSyncStatusBuilder::Create(ErrorCode::SUCCESS, 0x00));
898
899 EXPECT_CALL(mock_callbacks_, OnPeriodicSyncStarted);
900
901 // Get LePeriodicAdvertisingSyncEstablished
902 auto builder = LePeriodicAdvertisingSyncEstablishedBuilder::Create(
903 ErrorCode::SUCCESS,
904 sync_handle,
905 advertiser_sid,
906 address_with_type.GetAddressType(),
907 address_with_type.GetAddress(),
908 SecondaryPhyType::LE_1M,
909 0xFF,
910 ClockAccuracy::PPM_250);
911 auto event_view = LePeriodicAdvertisingSyncEstablishedView::Create(
912 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder)))));
913 periodic_sync_manager_->HandleLePeriodicAdvertisingSyncEstablished(event_view);
914
915 EXPECT_CALL(mock_callbacks_, OnBigInfoReport);
916
917 // Get LeBigInfoAdvertisingReport
918 auto builder2 = LeBigInfoAdvertisingReportBuilder::Create(
919 sync_handle, 2, 9, 24, 3, 1, 2, 100, 10000, 100, static_cast<SecondaryPhyType>(2),
920 static_cast<Enable> (0), static_cast<Enable> (1));
921
922 auto event_view2 = LeBigInfoAdvertisingReportView::Create(
923 LeMetaEventView::Create(EventView::Create(GetPacketView(std::move(builder2)))));
924 periodic_sync_manager_->HandleLeBigInfoAdvertisingReport(event_view2);
925
926 sync_handler();
927 }
928
929 } // namespace
930 } // namespace hci
931 } // namespace bluetooth
932