1 /*
2 * Copyright (C) 2025 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/distance_measurement_manager.h"
18
19 #include <bluetooth/log.h>
20 #include <flag_macros.h>
21 #include <gmock/gmock.h>
22 #include <gtest/gtest.h>
23
24 #include "common/bind.h"
25 #include "common/strings.h"
26 #include "hal/ranging_hal.h"
27 #include "hal/ranging_hal_mock.h"
28 #include "hci/acl_manager_mock.h"
29 #include "hci/address.h"
30 #include "hci/controller.h"
31 #include "hci/controller_mock.h"
32 #include "hci/distance_measurement_manager_mock.h"
33 #include "hci/hci_layer.h"
34 #include "hci/hci_layer_fake.h"
35 #include "module.h"
36 #include "os/fake_timer/fake_timerfd.h"
37 #include "packet/packet_view.h"
38 #include "ras/ras_packets.h"
39
40 using bluetooth::os::fake_timer::fake_timerfd_advance;
41 using bluetooth::os::fake_timer::fake_timerfd_reset;
42 using testing::_;
43 using testing::AtLeast;
44 using testing::Return;
45
46 namespace {
47 static constexpr auto kTimeout = std::chrono::seconds(1);
48 static constexpr uint8_t kMaxRetryCounterForCreateConfig = 0x03;
49 static constexpr uint8_t kMaxRetryCounterForCsEnable = 0x03;
50 static constexpr uint8_t kConnInterval = 24;
51 }
52
53 namespace bluetooth {
54 namespace hci {
55 namespace {
56 class TestController : public testing::MockController {
57 protected:
Start()58 void Start() override {}
Stop()59 void Stop() override {}
ListDependencies(ModuleList *) const60 void ListDependencies(ModuleList* /* list */) const override {}
61 };
62
63 class TestAclManager : public testing::MockAclManager {
64 public:
AddDeviceToRelaxedConnectionIntervalList(const Address)65 void AddDeviceToRelaxedConnectionIntervalList(const Address /*address*/) override {}
66
67 protected:
Start()68 void Start() override {}
Stop()69 void Stop() override {}
ListDependencies(ModuleList *) const70 void ListDependencies(ModuleList* /* list */) const override {}
71 };
72
73 struct CsReadCapabilitiesCompleteEvent {
74 ErrorCode error_code = ErrorCode::SUCCESS;
75 uint8_t num_config_supported = 4;
76 uint16_t max_consecutive_procedures_supported = 0;
77 uint8_t num_antennas_supported = 2;
78 uint8_t max_antenna_paths_supported = 4;
79 CsRoleSupported roles_supported = {/*initiator=*/1, /*reflector=*/1};
80 unsigned char modes_supported = {/*mode_3=*/1};
81 CsRttCapability rtt_capability = {/*rtt_aa_only_n=*/1, /*rtt_sounding_n=*/1,
82 /*rtt_random_payload_n=*/1};
83 uint8_t rtt_aa_only_n = 1;
84 uint8_t rtt_sounding_n = 1;
85 uint8_t rtt_random_payload_n = 1;
86 CsOptionalNadmSoundingCapability nadm_sounding_capability = {
87 /*normalized_attack_detector_metric=*/1};
88 CsOptionalNadmRandomCapability nadm_random_capability = {/*normalized_attack_detector_metric=*/1};
89 CsOptionalCsSyncPhysSupported cs_sync_phys_supported = {/*le_2m_phy=*/1, /*le_2m_2bt_phy=*/0};
90 CsOptionalSubfeaturesSupported subfeatures_supported = {/*no_frequency_actuation_error=*/1,
91 /*channel_selection_algorithm=*/1,
92 /*phase_based_ranging=*/1};
93 CsOptionalTIp1TimesSupported t_ip1_times_supported = {
94 /*support_10_microsecond=*/1, /*support_20_microsecond=*/1,
95 /*support_30_microsecond=*/1, /*support_40_microsecond=*/1,
96 /*support_50_microsecond=*/1, /*support_60_microsecond=*/1,
97 /*support_80_microsecond=*/1};
98 CsOptionalTIp2TimesSupported t_ip2_times_supported = {
99 /*support_10_microsecond=*/1, /*support_20_microsecond=*/1,
100 /*support_30_microsecond=*/1,
101 /*support_40_microsecond=*/1, /*support_50_microsecond=*/1,
102 /*support_60_microsecond=*/1, /*support_80_microsecond=*/1};
103 CsOptionalTFcsTimesSupported t_fcs_times_supported = {
104 /*support_15_microsecond=*/1, /*support_20_microsecond=*/1,
105 /*support_30_microsecond=*/1, /*support_40_microsecond=*/1,
106 /*support_50_microsecond=*/1,
107 /*support_60_microsecond=*/1, /*support_80_microsecond=*/1,
108 /*support_100_microsecond=*/1,
109 /*support_120_microsecond=*/1};
110 CsOptionalTPmTimesSupported t_pm_times_supported = {/*support_10_microsecond=*/1,
111 /*support_20_microsecond=*/1};
112 uint8_t t_sw_time_supported = 1;
113 uint8_t tx_snr_capability = 1;
114 };
115
116 struct CsConfigCompleteEvent {
117 ErrorCode status = ErrorCode::SUCCESS;
118 uint8_t config_id = 0;
119 CsAction action = CsAction::CONFIG_CREATED;
120 CsMainModeType main_mode_type = CsMainModeType::MODE_2;
121 CsSubModeType sub_mode_type = CsSubModeType::UNUSED;
122 uint8_t min_main_mode_steps = 3; // 0x02 to 0xFF
123 uint8_t max_main_mode_steps = 100; // 0x02 to 0xFF
124 uint8_t main_mode_repetition = 0; // 0x00 to 0x03
125 uint8_t mode_0_steps = 1; // 0x01 to 0x03
126 CsRole cs_role = CsRole::INITIATOR;
127 CsRttType rtt_type = CsRttType::RTT_AA_ONLY;
128 CsSyncPhy sync_phy = CsSyncPhy::LE_2M_PHY;
129 std::array<uint8_t, 10> channel_map = GetChannelMap("1FFFFFFFFFFFFC7FFFFC");
130 uint8_t channel_map_repetition = 1; // 0x01 to 0xFF
131 CsChannelSelectionType channel_selection_type = CsChannelSelectionType::TYPE_3C;
132 CsCh3cShape ch3c_shape = CsCh3cShape::HAT_SHAPE;
133 uint8_t ch3c_jump = 2; // 0x02 to 0x08
134 uint8_t t_ip1_time = 0x0A; // 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x50, or 0x91
135 uint8_t t_ip2_time = 0x0A; // 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x50, or 0x91
136 uint8_t t_fcs_time = 0x0F; // 0x0F, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x50, 0x64, 0x78, or 0x96
137 uint8_t t_pm_time = 0x0A; // 0x0A, 0x14, or 0x28
138
GetChannelMapbluetooth::hci::__anoncada9abe0211::CsConfigCompleteEvent139 static const std::array<uint8_t, 10> GetChannelMap(const std::string& hex_string) {
140 assert(hex_stinrg.length() == 20);
141 auto channel_vector = common::FromHexString(hex_string);
142 std::array<uint8_t, 10> channel_map{};
143 std::copy(channel_vector->begin(), channel_vector->end(), channel_map.begin());
144 std::reverse(channel_map.begin(), channel_map.end());
145 return channel_map;
146 }
147 };
148
149 struct CsProcedureEnableCompleteEvent {
150 ErrorCode status = ErrorCode::SUCCESS;
151 uint8_t config_id = 0;
152 uint8_t tone_antenna_config_selection = 0;
153 uint8_t selected_tx_power = 0; // -127 to 20 dBm
154 uint32_t subevent_len = 2500; // 1250us to 4s
155 uint8_t subevents_per_event = 1; // 0x01 to 0x20
156 uint16_t subevent_interval = 1; // N x 0.625ms
157 uint16_t event_interval = 0; // number of acl conn interval
158 uint16_t procedure_interval = 2; // number of acl conn interval
159 uint16_t procedure_count = 5; // 0x0001 to 0xFFFF
160 uint16_t max_procedure_len = 10; // N x 0.625 ms
161 };
162
163 struct StartMeasurementParameters {
164 Address remote_address = Address::FromString("12:34:56:78:9a:bc").value();
165 uint16_t connection_handle = 64;
166 Role local_hci_role = Role::CENTRAL;
167 uint16_t interval = 200; // 200ms
168 DistanceMeasurementMethod method = DistanceMeasurementMethod::METHOD_CS;
169 };
170
171 class DistanceMeasurementManagerTest : public ::testing::Test {
172 protected:
SetUp()173 void SetUp() override {
174 test_hci_layer_ = new HciLayerFake; // Ownership is transferred to registry
175 mock_controller_ = new TestController; // Ownership is transferred to registry
176 mock_ranging_hal_ = new hal::testing::MockRangingHal; // Ownership is transferred to registry
177 mock_acl_manager_ = new TestAclManager; // Ownership is transferred to registry
178 fake_registry_.InjectTestModule(&hal::RangingHal::Factory, mock_ranging_hal_);
179 fake_registry_.InjectTestModule(&Controller::Factory, mock_controller_);
180 fake_registry_.InjectTestModule(&HciLayer::Factory, test_hci_layer_);
181 fake_registry_.InjectTestModule(&AclManager::Factory, mock_acl_manager_);
182
183 client_handler_ = fake_registry_.GetTestModuleHandler(&HciLayer::Factory);
184 ASSERT_NE(client_handler_, nullptr);
185
186 EXPECT_CALL(*mock_controller_, SupportsBleChannelSounding()).WillOnce(Return(true));
187 EXPECT_CALL(*mock_ranging_hal_, IsBound()).Times(AtLeast(1)).WillRepeatedly(Return(true));
188 EXPECT_CALL(*mock_ranging_hal_, GetRangingHalVersion).WillRepeatedly(Return(hal::V_2));
189
190 handler_ = fake_registry_.GetTestHandler();
191 dm_manager_ = fake_registry_.Start<DistanceMeasurementManager>(&thread_, handler_);
192
193 dm_manager_->RegisterDistanceMeasurementCallbacks(&mock_dm_callbacks_);
194 }
195
TearDown()196 void TearDown() override {
197 fake_registry_.SynchronizeModuleHandler(&DistanceMeasurementManager::Factory,
198 std::chrono::milliseconds(20));
199 fake_registry_.StopAll();
200 }
201
GetDmSessionFuture()202 std::future<void> GetDmSessionFuture() {
203 log::assert_that(dm_session_promise_ == nullptr, "Promises promises ... Only one at a time");
204 dm_session_promise_ = std::make_unique<std::promise<void>>();
205 return dm_session_promise_->get_future();
206 }
207
fake_timer_advance(uint64_t ms)208 std::future<void> fake_timer_advance(uint64_t ms) {
209 std::promise<void> promise;
210 auto future = promise.get_future();
211 handler_->Post(common::BindOnce(
212 [](std::promise<void> promise, uint64_t ms) {
213 fake_timerfd_advance(ms);
214 promise.set_value();
215 },
216 common::Passed(std::move(promise)), ms));
217
218 return future;
219 }
220
sync_client_handler()221 void sync_client_handler() {
222 log::assert_that(thread_.GetReactor()->WaitForIdle(kTimeout),
223 "assert failed: thread_.GetReactor()->WaitForIdle(kTimeout)");
224 }
225
226 static std::unique_ptr<LeCsReadLocalSupportedCapabilitiesCompleteBuilder>
GetLocalSupportedCapabilitiesCompleteEvent(const CsReadCapabilitiesCompleteEvent & cs_cap_complete_event)227 GetLocalSupportedCapabilitiesCompleteEvent(
228 const CsReadCapabilitiesCompleteEvent& cs_cap_complete_event) {
229 return LeCsReadLocalSupportedCapabilitiesCompleteBuilder::Create(
230 /*num_hci_command_packets=*/0xFF, cs_cap_complete_event.error_code,
231 cs_cap_complete_event.num_config_supported,
232 cs_cap_complete_event.max_consecutive_procedures_supported,
233 cs_cap_complete_event.num_antennas_supported,
234 cs_cap_complete_event.max_antenna_paths_supported,
235 cs_cap_complete_event.roles_supported, cs_cap_complete_event.modes_supported,
236 cs_cap_complete_event.rtt_capability, cs_cap_complete_event.rtt_aa_only_n,
237 cs_cap_complete_event.rtt_sounding_n, cs_cap_complete_event.rtt_random_payload_n,
238 cs_cap_complete_event.nadm_sounding_capability,
239 cs_cap_complete_event.nadm_random_capability,
240 cs_cap_complete_event.cs_sync_phys_supported,
241 cs_cap_complete_event.subfeatures_supported,
242 cs_cap_complete_event.t_ip1_times_supported,
243 cs_cap_complete_event.t_ip2_times_supported,
244 cs_cap_complete_event.t_fcs_times_supported, cs_cap_complete_event.t_pm_times_supported,
245 cs_cap_complete_event.t_sw_time_supported, cs_cap_complete_event.tx_snr_capability);
246 }
247
248 static std::unique_ptr<LeCsReadRemoteSupportedCapabilitiesCompleteBuilder>
GetRemoteSupportedCapabilitiesCompleteEvent(uint16_t connection_handle,const CsReadCapabilitiesCompleteEvent & cs_cap_complete_event)249 GetRemoteSupportedCapabilitiesCompleteEvent(
250 uint16_t connection_handle,
251 const CsReadCapabilitiesCompleteEvent& cs_cap_complete_event) {
252 return LeCsReadRemoteSupportedCapabilitiesCompleteBuilder::Create(
253 cs_cap_complete_event.error_code, connection_handle,
254 cs_cap_complete_event.num_config_supported,
255 cs_cap_complete_event.max_consecutive_procedures_supported,
256 cs_cap_complete_event.num_antennas_supported,
257 cs_cap_complete_event.max_antenna_paths_supported,
258 cs_cap_complete_event.roles_supported, cs_cap_complete_event.modes_supported,
259 cs_cap_complete_event.rtt_capability, cs_cap_complete_event.rtt_aa_only_n,
260 cs_cap_complete_event.rtt_sounding_n, cs_cap_complete_event.rtt_random_payload_n,
261 cs_cap_complete_event.nadm_sounding_capability,
262 cs_cap_complete_event.nadm_random_capability,
263 cs_cap_complete_event.cs_sync_phys_supported,
264 cs_cap_complete_event.subfeatures_supported,
265 cs_cap_complete_event.t_ip1_times_supported,
266 cs_cap_complete_event.t_ip2_times_supported,
267 cs_cap_complete_event.t_fcs_times_supported, cs_cap_complete_event.t_pm_times_supported,
268 cs_cap_complete_event.t_sw_time_supported, cs_cap_complete_event.tx_snr_capability);
269 }
270
GetConfigCompleteEvent(uint16_t connection_handle,CsConfigCompleteEvent complete_event)271 static std::unique_ptr<LeCsConfigCompleteBuilder> GetConfigCompleteEvent(
272 uint16_t connection_handle, CsConfigCompleteEvent complete_event) {
273 return LeCsConfigCompleteBuilder::Create(
274 complete_event.status, connection_handle, complete_event.config_id,
275 complete_event.action, complete_event.main_mode_type, complete_event.sub_mode_type,
276 complete_event.min_main_mode_steps, complete_event.max_main_mode_steps,
277 complete_event.main_mode_repetition, complete_event.mode_0_steps,
278 complete_event.cs_role, complete_event.rtt_type, complete_event.sync_phy,
279 complete_event.channel_map, complete_event.channel_map_repetition,
280 complete_event.channel_selection_type, complete_event.ch3c_shape,
281 complete_event.ch3c_jump, complete_event.t_ip1_time, complete_event.t_ip2_time,
282 complete_event.t_fcs_time, complete_event.t_pm_time);
283 }
284
GetProcedureEnableCompleteEvent(uint16_t connection_handle,Enable enable,CsProcedureEnableCompleteEvent complete_event)285 static std::unique_ptr<LeCsProcedureEnableCompleteBuilder> GetProcedureEnableCompleteEvent(
286 uint16_t connection_handle, Enable enable,
287 CsProcedureEnableCompleteEvent complete_event) {
288 return LeCsProcedureEnableCompleteBuilder::Create(
289 complete_event.status, connection_handle, complete_event.config_id, enable,
290 complete_event.tone_antenna_config_selection, complete_event.selected_tx_power,
291 complete_event.subevent_len, complete_event.subevents_per_event,
292 complete_event.subevent_interval, complete_event.event_interval,
293 complete_event.procedure_interval, complete_event.procedure_count,
294 complete_event.max_procedure_len);
295 }
296
StartMeasurement(const StartMeasurementParameters & params)297 void StartMeasurement(const StartMeasurementParameters& params) {
298 dm_manager_->StartDistanceMeasurement(params.remote_address, params.connection_handle,
299 params.local_hci_role, params.interval, params.method);
300 }
301
ReceivedReadLocalCapabilitiesComplete()302 void ReceivedReadLocalCapabilitiesComplete() {
303 CsReadCapabilitiesCompleteEvent read_cs_complete_event;
304 test_hci_layer_->IncomingEvent(
305 GetLocalSupportedCapabilitiesCompleteEvent(read_cs_complete_event));
306 }
307
StartMeasurementTillRasConnectedEvent(const StartMeasurementParameters & params)308 void StartMeasurementTillRasConnectedEvent(const StartMeasurementParameters& params) {
309 ReceivedReadLocalCapabilitiesComplete();
310 EXPECT_CALL(*mock_ranging_hal_, OpenSession(_, _, _))
311 .WillOnce([this](uint16_t connection_handle, uint16_t /*att_handle*/,
312 const std::vector<hal::VendorSpecificCharacteristic>&
313 vendor_specific_data) {
314 mock_ranging_hal_->GetRangingHalCallback()->OnOpened(connection_handle,
315 vendor_specific_data);
316 });
317 StartMeasurement(params);
318 dm_manager_->HandleRasClientConnectedEvent(
319 params.remote_address, params.connection_handle,
320 /*att_handle=*/0,
321 /*vendor_specific_data=*/std::vector<hal::VendorSpecificCharacteristic>(),
322 /*conn_interval=*/kConnInterval);
323 }
324
StartMeasurementTillReadRemoteCaps(const StartMeasurementParameters & params)325 void StartMeasurementTillReadRemoteCaps(const StartMeasurementParameters& params) {
326 StartMeasurementTillRasConnectedEvent(params);
327
328 test_hci_layer_->GetCommand(OpCode::LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES);
329 CsReadCapabilitiesCompleteEvent read_cs_complete_event;
330 test_hci_layer_->IncomingEvent(LeCsReadRemoteSupportedCapabilitiesStatusBuilder::Create(
331 /*status=*/ErrorCode::SUCCESS,
332 /*num_hci_command_packets=*/0xFF));
333 test_hci_layer_->IncomingLeMetaEvent(GetRemoteSupportedCapabilitiesCompleteEvent(
334 params.connection_handle, read_cs_complete_event));
335
336 test_hci_layer_->GetCommand(OpCode::LE_CS_SET_DEFAULT_SETTINGS);
337 test_hci_layer_->IncomingEvent(LeCsSetDefaultSettingsCompleteBuilder::Create(
338 /*num_hci_command_packets=*/static_cast<uint8_t>(0xEE), ErrorCode::SUCCESS,
339 params.connection_handle));
340 }
341
StartMeasurementTillCreateConfig(const StartMeasurementParameters & params)342 void StartMeasurementTillCreateConfig(const StartMeasurementParameters& params) {
343 StartMeasurementTillReadRemoteCaps(params);
344
345 CsConfigCompleteEvent cs_config_complete_event;
346 test_hci_layer_->GetCommand(OpCode::LE_CS_CREATE_CONFIG);
347 test_hci_layer_->IncomingEvent(LeCsCreateConfigStatusBuilder::Create(
348 /*status=*/ErrorCode::SUCCESS,
349 /*num_hci_command_packets=*/0xFF));
350 test_hci_layer_->IncomingLeMetaEvent(
351 GetConfigCompleteEvent(params.connection_handle, cs_config_complete_event));
352 }
353
StartMeasurementTillSecurityEnable(const StartMeasurementParameters & params)354 void StartMeasurementTillSecurityEnable(const StartMeasurementParameters& params) {
355 StartMeasurementTillCreateConfig(params);
356
357 test_hci_layer_->GetCommand(OpCode::LE_CS_SECURITY_ENABLE);
358 test_hci_layer_->IncomingEvent(LeCsSecurityEnableStatusBuilder::Create(
359 /*status=*/ErrorCode::SUCCESS,
360 /*num_hci_command_packets=*/0xFF));
361 test_hci_layer_->IncomingLeMetaEvent(LeCsSecurityEnableCompleteBuilder::Create(
362 ErrorCode::SUCCESS, params.connection_handle));
363 }
364
StartMeasurementTillSetProcedureParameters(const StartMeasurementParameters & params)365 void StartMeasurementTillSetProcedureParameters(const StartMeasurementParameters& params) {
366 StartMeasurementTillSecurityEnable(params);
367
368 auto command_view =
369 LeCsSetProcedureParametersView::Create(DistanceMeasurementCommandView::Create(
370 test_hci_layer_->GetCommand(OpCode::LE_CS_SET_PROCEDURE_PARAMETERS)));
371 EXPECT_EQ(command_view.IsValid(), true);
372 auto expected_min_procedure_interval =
373 static_cast<uint16_t>(std::round(params.interval / (kConnInterval * 1.25)));
374 EXPECT_EQ(command_view.GetMinProcedureInterval(), expected_min_procedure_interval);
375 test_hci_layer_->IncomingEvent(LeCsSetProcedureParametersCompleteBuilder::Create(
376 /*num_hci_command_packets=*/static_cast<uint8_t>(0xEE), ErrorCode::SUCCESS,
377 params.connection_handle));
378 }
379
380 protected:
381 TestModuleRegistry fake_registry_;
382 HciLayerFake* test_hci_layer_ = nullptr;
383 TestController* mock_controller_ = nullptr;
384 TestAclManager* mock_acl_manager_ = nullptr;
385 hal::testing::MockRangingHal* mock_ranging_hal_ = nullptr;
386 os::Thread& thread_ = fake_registry_.GetTestThread();
387 os::Handler* client_handler_ = nullptr;
388 os::Handler* handler_ = nullptr;
389
390 DistanceMeasurementManager* dm_manager_ = nullptr;
391 testing::MockDistanceMeasurementCallbacks mock_dm_callbacks_;
392 std::unique_ptr<std::promise<void>> dm_session_promise_;
393 };
394
TEST_F(DistanceMeasurementManagerTest,setup_teardown)395 TEST_F(DistanceMeasurementManagerTest, setup_teardown) {
396 EXPECT_NE(mock_ranging_hal_->GetRangingHalCallback(), nullptr);
397 }
398
TEST_F(DistanceMeasurementManagerTest,fail_read_local_cs_capabilities)399 TEST_F(DistanceMeasurementManagerTest, fail_read_local_cs_capabilities) {
400 StartMeasurementParameters params;
401 auto dm_session_future = GetDmSessionFuture();
402 EXPECT_CALL(mock_dm_callbacks_,
403 OnDistanceMeasurementStopped(params.remote_address,
404 DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
405 DistanceMeasurementMethod::METHOD_CS))
406 .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
407 DistanceMeasurementMethod /*method*/) {
408 ASSERT_NE(dm_session_promise_, nullptr);
409 dm_session_promise_->set_value();
410 dm_session_promise_.reset();
411 });
412
413 CsReadCapabilitiesCompleteEvent read_cs_complete_event;
414 read_cs_complete_event.error_code = ErrorCode::COMMAND_DISALLOWED;
415 test_hci_layer_->IncomingEvent(
416 GetLocalSupportedCapabilitiesCompleteEvent(read_cs_complete_event));
417
418 StartMeasurement(params);
419
420 dm_session_future.wait_for(kTimeout);
421 sync_client_handler();
422 }
423
TEST_F(DistanceMeasurementManagerTest,ras_remote_not_support)424 TEST_F(DistanceMeasurementManagerTest, ras_remote_not_support) {
425 ReceivedReadLocalCapabilitiesComplete();
426 StartMeasurementParameters params;
427 auto dm_session_future = GetDmSessionFuture();
428 EXPECT_CALL(mock_dm_callbacks_,
429 OnDistanceMeasurementStopped(
430 params.remote_address,
431 DistanceMeasurementErrorCode::REASON_FEATURE_NOT_SUPPORTED_REMOTE,
432 DistanceMeasurementMethod::METHOD_CS))
433 .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
434 DistanceMeasurementMethod /*method*/) {
435 ASSERT_NE(dm_session_promise_, nullptr);
436 dm_session_promise_->set_value();
437 dm_session_promise_.reset();
438 });
439
440 StartMeasurement(params);
441 dm_manager_->HandleRasClientDisconnectedEvent(params.remote_address,
442 ras::RasDisconnectReason::SERVER_NOT_AVAILABLE);
443
444 dm_session_future.wait_for(kTimeout);
445 sync_client_handler();
446 }
447
TEST_F(DistanceMeasurementManagerTest,error_read_remote_cs_caps_command)448 TEST_F(DistanceMeasurementManagerTest, error_read_remote_cs_caps_command) {
449 auto dm_session_future = GetDmSessionFuture();
450 StartMeasurementParameters params;
451 StartMeasurementTillRasConnectedEvent(params);
452
453 EXPECT_CALL(mock_dm_callbacks_,
454 OnDistanceMeasurementStopped(params.remote_address,
455 DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
456 DistanceMeasurementMethod::METHOD_CS))
457 .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
458 DistanceMeasurementMethod /*method*/) {
459 ASSERT_NE(dm_session_promise_, nullptr);
460 dm_session_promise_->set_value();
461 dm_session_promise_.reset();
462 });
463
464 test_hci_layer_->GetCommand(OpCode::LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES);
465 test_hci_layer_->IncomingEvent(LeCsReadRemoteSupportedCapabilitiesStatusBuilder::Create(
466 /*status=*/ErrorCode::COMMAND_DISALLOWED,
467 /*num_hci_command_packets=*/0xff));
468 sync_client_handler();
469 }
470
TEST_F(DistanceMeasurementManagerTest,fail_read_remote_cs_caps_complete)471 TEST_F(DistanceMeasurementManagerTest, fail_read_remote_cs_caps_complete) {
472 auto dm_session_future = GetDmSessionFuture();
473 StartMeasurementParameters params;
474 StartMeasurementTillRasConnectedEvent(params);
475
476 EXPECT_CALL(mock_dm_callbacks_,
477 OnDistanceMeasurementStopped(params.remote_address,
478 DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
479 DistanceMeasurementMethod::METHOD_CS))
480 .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
481 DistanceMeasurementMethod /*method*/) {
482 ASSERT_NE(dm_session_promise_, nullptr);
483 dm_session_promise_->set_value();
484 dm_session_promise_.reset();
485 });
486
487 test_hci_layer_->GetCommand(OpCode::LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES);
488 CsReadCapabilitiesCompleteEvent read_cs_complete_event;
489 read_cs_complete_event.error_code = ErrorCode::COMMAND_DISALLOWED;
490 test_hci_layer_->IncomingLeMetaEvent(GetRemoteSupportedCapabilitiesCompleteEvent(
491 params.connection_handle, read_cs_complete_event));
492 sync_client_handler();
493 }
494
TEST_F(DistanceMeasurementManagerTest,error_create_config_command)495 TEST_F(DistanceMeasurementManagerTest, error_create_config_command) {
496 auto dm_session_future = GetDmSessionFuture();
497 StartMeasurementParameters params;
498 StartMeasurementTillReadRemoteCaps(params);
499
500 EXPECT_CALL(mock_dm_callbacks_,
501 OnDistanceMeasurementStopped(params.remote_address,
502 DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
503 DistanceMeasurementMethod::METHOD_CS))
504 .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
505 DistanceMeasurementMethod /*method*/) {
506 ASSERT_NE(dm_session_promise_, nullptr);
507 dm_session_promise_->set_value();
508 dm_session_promise_.reset();
509 });
510
511 test_hci_layer_->GetCommand(OpCode::LE_CS_CREATE_CONFIG);
512 test_hci_layer_->IncomingEvent(LeCsCreateConfigStatusBuilder::Create(
513 /*status=*/ErrorCode::COMMAND_DISALLOWED,
514 /*num_hci_command_packets=*/0xff));
515 sync_client_handler();
516 }
517
TEST_F(DistanceMeasurementManagerTest,fail_create_config_complete)518 TEST_F(DistanceMeasurementManagerTest, fail_create_config_complete) {
519 auto dm_session_future = GetDmSessionFuture();
520 StartMeasurementParameters params;
521 StartMeasurementTillReadRemoteCaps(params);
522
523 EXPECT_CALL(mock_dm_callbacks_,
524 OnDistanceMeasurementStopped(params.remote_address,
525 DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
526 DistanceMeasurementMethod::METHOD_CS))
527 .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
528 DistanceMeasurementMethod /*method*/) {
529 ASSERT_NE(dm_session_promise_, nullptr);
530 dm_session_promise_->set_value();
531 dm_session_promise_.reset();
532 });
533
534 CsConfigCompleteEvent cs_config_complete_event;
535 cs_config_complete_event.status = ErrorCode::COMMAND_DISALLOWED;
536 for (int i = 0; i <= kMaxRetryCounterForCreateConfig; i++) {
537 test_hci_layer_->GetCommand(OpCode::LE_CS_CREATE_CONFIG);
538 test_hci_layer_->IncomingLeMetaEvent(
539 GetConfigCompleteEvent(params.connection_handle, cs_config_complete_event));
540 }
541 sync_client_handler();
542 }
543
TEST_F(DistanceMeasurementManagerTest,retry_fail_procedure_enable_command)544 TEST_F(DistanceMeasurementManagerTest, retry_fail_procedure_enable_command) {
545 auto dm_session_future = GetDmSessionFuture();
546 StartMeasurementParameters params;
547 StartMeasurementTillSetProcedureParameters(params);
548
549 EXPECT_CALL(mock_dm_callbacks_,
550 OnDistanceMeasurementStopped(params.remote_address,
551 DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
552 DistanceMeasurementMethod::METHOD_CS))
553 .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
554 DistanceMeasurementMethod /*method*/) {
555 ASSERT_NE(dm_session_promise_, nullptr);
556 dm_session_promise_->set_value();
557 dm_session_promise_.reset();
558 });
559
560 for (int i = 0; i <= kMaxRetryCounterForCsEnable; i++) {
561 test_hci_layer_->GetCommand(OpCode::LE_CS_PROCEDURE_ENABLE);
562 test_hci_layer_->IncomingEvent(LeCsProcedureEnableStatusBuilder::Create(
563 /*status=*/ErrorCode::COMMAND_DISALLOWED,
564 /*num_hci_command_packets=*/0xff));
565 auto future = fake_timer_advance(params.interval + 10);
566 future.wait_for(kTimeout);
567 sync_client_handler();
568 }
569 fake_timerfd_reset();
570 sync_client_handler();
571 }
572
TEST_F(DistanceMeasurementManagerTest,retry_fail_procedure_enable_complete)573 TEST_F(DistanceMeasurementManagerTest, retry_fail_procedure_enable_complete) {
574 auto dm_session_future = GetDmSessionFuture();
575 StartMeasurementParameters params;
576 StartMeasurementTillSetProcedureParameters(params);
577
578 EXPECT_CALL(mock_dm_callbacks_,
579 OnDistanceMeasurementStopped(params.remote_address,
580 DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
581 DistanceMeasurementMethod::METHOD_CS))
582 .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
583 DistanceMeasurementMethod /*method*/) {
584 ASSERT_NE(dm_session_promise_, nullptr);
585 dm_session_promise_->set_value();
586 dm_session_promise_.reset();
587 });
588
589 CsProcedureEnableCompleteEvent complete_event;
590 complete_event.status = ErrorCode::LINK_LAYER_COLLISION;
591 for (int i = 0; i <= kMaxRetryCounterForCsEnable; i++) {
592 test_hci_layer_->GetCommand(OpCode::LE_CS_PROCEDURE_ENABLE);
593 test_hci_layer_->IncomingEvent(LeCsProcedureEnableStatusBuilder::Create(
594 /*status=*/ErrorCode::SUCCESS,
595 /*num_hci_command_packets=*/0xff));
596 test_hci_layer_->IncomingLeMetaEvent(GetProcedureEnableCompleteEvent(
597 params.connection_handle, Enable::ENABLED, complete_event));
598 auto future = fake_timer_advance(params.interval + 10);
599 future.wait_for(kTimeout);
600 sync_client_handler();
601 }
602 fake_timerfd_reset();
603 sync_client_handler();
604 }
605
TEST_F(DistanceMeasurementManagerTest,unexpected_procedure_enable_complete_as_disable)606 TEST_F(DistanceMeasurementManagerTest, unexpected_procedure_enable_complete_as_disable) {
607 auto dm_session_future = GetDmSessionFuture();
608 StartMeasurementParameters params;
609 StartMeasurementTillSetProcedureParameters(params);
610
611 EXPECT_CALL(mock_dm_callbacks_,
612 OnDistanceMeasurementStopped(params.remote_address,
613 DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
614 DistanceMeasurementMethod::METHOD_CS))
615 .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
616 DistanceMeasurementMethod /*method*/) {
617 ASSERT_NE(dm_session_promise_, nullptr);
618 dm_session_promise_->set_value();
619 dm_session_promise_.reset();
620 });
621
622 test_hci_layer_->GetCommand(OpCode::LE_CS_PROCEDURE_ENABLE);
623 test_hci_layer_->IncomingEvent(LeCsProcedureEnableStatusBuilder::Create(
624 /*status=*/ErrorCode::SUCCESS,
625 /*num_hci_command_packets=*/0xff));
626 CsProcedureEnableCompleteEvent complete_event;
627 complete_event.status = ErrorCode::LINK_LAYER_COLLISION;
628 test_hci_layer_->IncomingLeMetaEvent(GetProcedureEnableCompleteEvent(
629 params.connection_handle, Enable::DISABLED, complete_event));
630
631 sync_client_handler();
632 }
633
634 } // namespace
635 } // namespace hci
636 } // namespace bluetooth
637