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