summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Steven Liu <steveliu@google.com> 2025-03-13 18:47:02 +0000
committer Steven Liu <steveliu@google.com> 2025-03-14 15:30:14 -0700
commite9d0c64bc947a38d6d51958359ccd38b67855cd6 (patch)
tree2f13fedc8e83e32eda1743960e85d9b8164da56e
parent96641c762aa6160a7598dc0c41ba1e0aac3cab17 (diff)
Fixes bugs about the procedure enabled.
1. scheule procedure enable command for failure retry 2. clear the procedure data only when the session is stopped. 3. work around a controller problem - got DISABLE complete for ENABLE command Flag: EXEMPT critical bug fixes, flag was in nextfood Bug: 403547016 Test: atest --host bluetooth_test_gd_unit Change-Id: Ie63cba5673e847a9d1b607c855003db77c96d075
-rw-r--r--system/gd/Android.bp3
-rw-r--r--system/gd/hci/distance_measurement_manager.cc108
-rw-r--r--system/gd/hci/distance_measurement_manager_test.cc179
3 files changed, 244 insertions, 46 deletions
diff --git a/system/gd/Android.bp b/system/gd/Android.bp
index 26f31f0b8e..6d708f1370 100644
--- a/system/gd/Android.bp
+++ b/system/gd/Android.bp
@@ -414,6 +414,9 @@ cc_test {
"storage/mutation_test.cc",
"storage/storage_module_test.cc",
],
+ cflags: [
+ "-DUSE_FAKE_TIMERS",
+ ],
static_libs: [
"bluetooth_flags_c_lib_for_test",
"libbase",
diff --git a/system/gd/hci/distance_measurement_manager.cc b/system/gd/hci/distance_measurement_manager.cc
index 6bdfde00b9..6e57f2c9d5 100644
--- a/system/gd/hci/distance_measurement_manager.cc
+++ b/system/gd/hci/distance_measurement_manager.cc
@@ -441,6 +441,8 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
it->second.measurement_ongoing = true;
it->second.waiting_for_start_callback = true;
it->second.local_hci_role = local_hci_role;
+ it->second.retry_counter_for_create_config = 0;
+ it->second.retry_counter_for_cs_enable = 0;
return true;
}
@@ -845,6 +847,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
static void reset_tracker_on_stopped(CsTracker& cs_tracker) {
cs_tracker.measurement_ongoing = false;
cs_tracker.state = CsTrackerState::STOPPED;
+ cs_tracker.procedure_data_list.clear();
}
void handle_cs_setup_failure(uint16_t connection_handle, DistanceMeasurementErrorCode errorCode) {
@@ -906,7 +909,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
if (cs_requester_trackers_.find(connection_handle) != cs_requester_trackers_.end()) {
reset_tracker_on_stopped(cs_requester_trackers_[connection_handle]);
}
- } else if (status_view.GetStatus() != ErrorCode::SUCCESS) {
+ } else if (enable == Enable::ENABLED && status_view.GetStatus() != ErrorCode::SUCCESS) {
if (cs_requester_trackers_.count(connection_handle) == 0) {
log::error("Error code {} for connection_handle {}. No request tracker found.",
ErrorCodeText(status), connection_handle);
@@ -919,6 +922,14 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
if (cs_requester_trackers_[connection_handle].retry_counter_for_cs_enable++ >=
kMaxRetryCounterForCsEnable) {
handle_cs_setup_failure(connection_handle, REASON_INTERNAL_ERROR);
+ } else {
+ cs_requester_trackers_[connection_handle].procedure_schedule_guard_alarm->Cancel();
+ log::info("schedule next procedure enable after {} ms",
+ cs_requester_trackers_[connection_handle].interval_ms);
+ cs_requester_trackers_[connection_handle].procedure_schedule_guard_alarm->Schedule(
+ common::Bind(&impl::send_le_cs_procedure_enable, common::Unretained(this),
+ connection_handle, Enable::ENABLED),
+ std::chrono::milliseconds(cs_requester_trackers_[connection_handle].interval_ms));
}
}
}
@@ -1237,25 +1248,8 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
void on_cs_procedure_enable_complete(LeCsProcedureEnableCompleteView event_view) {
log::assert_that(event_view.IsValid(), "assert failed: event_view.IsValid()");
uint16_t connection_handle = event_view.GetConnectionHandle();
- log::debug("on cs procedure enabled complete");
- if (event_view.GetStatus() != ErrorCode::SUCCESS) {
- std::string error_code = ErrorCodeText(event_view.GetStatus());
- if (cs_requester_trackers_.count(connection_handle) == 0) {
- log::warn(
- "Received LeCsProcedureEnableCompleteView with error code {}, No request tracker "
- "found",
- error_code);
- handle_cs_setup_failure(connection_handle, REASON_INTERNAL_ERROR);
- return;
- }
- log::warn("Received LeCsProcedureEnableCompleteView with error code {}. Retry counter {}",
- error_code, cs_requester_trackers_[connection_handle].retry_counter_for_cs_enable);
- if (cs_requester_trackers_[connection_handle].retry_counter_for_cs_enable++ >=
- kMaxRetryCounterForCsEnable) {
- handle_cs_setup_failure(connection_handle, REASON_INTERNAL_ERROR);
- }
- return;
- }
+ log::debug("Procedure enabled, {}", event_view.ToString());
+
uint8_t config_id = event_view.GetConfigId();
CsTracker* live_tracker = nullptr;
@@ -1272,7 +1266,7 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
live_tracker = get_live_tracker(connection_handle, config_id, valid_requester_states,
valid_responder_states);
if (live_tracker == nullptr) {
- log::error("no tracker is available for {}", connection_handle);
+ log::error("enable - no tracker is available for {}", connection_handle);
return;
}
if (live_tracker->used_config_id != config_id) {
@@ -1280,7 +1274,22 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
live_tracker->used_config_id);
return;
}
- log::debug("Procedure enabled, {}", event_view.ToString());
+
+ if (live_tracker->local_start && event_view.GetStatus() != ErrorCode::SUCCESS) {
+ log::warn("Received LeCsProcedureEnableCompleteView with error code {}. Retry counter {}",
+ ErrorCodeText(event_view.GetStatus()), live_tracker->retry_counter_for_cs_enable);
+ if (live_tracker->retry_counter_for_cs_enable++ >= kMaxRetryCounterForCsEnable) {
+ handle_cs_setup_failure(connection_handle, REASON_INTERNAL_ERROR);
+ } else {
+ live_tracker->procedure_schedule_guard_alarm->Cancel();
+ log::info("schedule next procedure enable after {} ms", live_tracker->interval_ms);
+ live_tracker->procedure_schedule_guard_alarm->Schedule(
+ common::Bind(&impl::send_le_cs_procedure_enable, common::Unretained(this),
+ connection_handle, Enable::ENABLED),
+ std::chrono::milliseconds(live_tracker->interval_ms));
+ }
+ return;
+ }
live_tracker->state = CsTrackerState::STARTED;
live_tracker->selected_tx_power = event_view.GetSelectedTxPower();
live_tracker->n_procedure_count = event_view.GetProcedureCount();
@@ -1297,38 +1306,45 @@ struct DistanceMeasurementManager::impl : bluetooth::hal::RangingHalCallback {
if (live_tracker->n_procedure_count >= 1) {
live_tracker->procedure_schedule_guard_alarm->Cancel();
log::info("schedule next procedure enable after {} ms", schedule_interval);
- cs_requester_trackers_[connection_handle].procedure_schedule_guard_alarm->Schedule(
+ live_tracker->procedure_schedule_guard_alarm->Schedule(
common::Bind(&impl::send_le_cs_procedure_enable, common::Unretained(this),
connection_handle, Enable::ENABLED),
std::chrono::milliseconds(schedule_interval));
}
- }
- if (live_tracker->local_start && live_tracker->waiting_for_start_callback) {
- live_tracker->waiting_for_start_callback = false;
- distance_measurement_callbacks_->OnDistanceMeasurementStarted(live_tracker->address,
- METHOD_CS);
- }
- if (live_tracker->local_start && is_hal_v2()) {
- // reset the procedure sequence
- live_tracker->procedure_sequence_after_enable = -1;
- ranging_hal_->UpdateProcedureEnableConfig(connection_handle, event_view);
+ if (live_tracker->waiting_for_start_callback) {
+ live_tracker->waiting_for_start_callback = false;
+ distance_measurement_callbacks_->OnDistanceMeasurementStarted(live_tracker->address,
+ METHOD_CS);
+ }
+ if (is_hal_v2()) {
+ // reset the procedure sequence
+ live_tracker->procedure_sequence_after_enable = -1;
+ ranging_hal_->UpdateProcedureEnableConfig(connection_handle, event_view);
+ }
}
} else if (event_view.GetState() == Enable::DISABLED) {
- uint8_t valid_requester_states = static_cast<uint8_t>(CsTrackerState::STARTED);
- uint8_t valid_responder_states = static_cast<uint8_t>(CsTrackerState::STARTED);
- live_tracker = get_live_tracker(connection_handle, config_id, valid_requester_states,
- valid_responder_states);
- if (live_tracker == nullptr) {
- log::error("no tracker is available for {}", connection_handle);
- return;
+ if (event_view.GetStatus() == ErrorCode::SUCCESS) {
+ // local or remote host requested it.
+ uint8_t valid_requester_states = static_cast<uint8_t>(CsTrackerState::STARTED);
+ uint8_t valid_responder_states = static_cast<uint8_t>(CsTrackerState::STARTED);
+ live_tracker = get_live_tracker(connection_handle, config_id, valid_requester_states,
+ valid_responder_states);
+ if (live_tracker == nullptr) {
+ log::error("disable - no tracker is available for {}", connection_handle);
+ return;
+ }
+ reset_tracker_on_stopped(*live_tracker);
+ } else {
+ // work around, controller may send 'DISABLE' complete with error for 'ENABLE' command
+ auto req_it = cs_requester_trackers_.find(connection_handle);
+ if (req_it != cs_requester_trackers_.end() &&
+ req_it->second.state == CsTrackerState::WAIT_FOR_PROCEDURE_ENABLED &&
+ config_id == req_it->second.used_config_id) {
+ log::warn("expect ENABLE complete, bug got DISABLE complete.");
+ handle_cs_setup_failure(connection_handle, REASON_INTERNAL_ERROR);
+ }
}
- reset_tracker_on_stopped(*live_tracker);
- }
- // reset the procedure data list.
- std::vector<CsProcedureData>& data_list = live_tracker->procedure_data_list;
- while (!data_list.empty()) {
- data_list.erase(data_list.begin());
}
}
diff --git a/system/gd/hci/distance_measurement_manager_test.cc b/system/gd/hci/distance_measurement_manager_test.cc
index 8679ec27e3..35a629c53a 100644
--- a/system/gd/hci/distance_measurement_manager_test.cc
+++ b/system/gd/hci/distance_measurement_manager_test.cc
@@ -21,6 +21,7 @@
#include <gmock/gmock.h>
#include <gtest/gtest.h>
+#include "common/bind.h"
#include "common/strings.h"
#include "hal/ranging_hal.h"
#include "hal/ranging_hal_mock.h"
@@ -32,9 +33,12 @@
#include "hci/hci_layer.h"
#include "hci/hci_layer_fake.h"
#include "module.h"
+#include "os/fake_timer/fake_timerfd.h"
#include "packet/packet_view.h"
#include "ras/ras_packets.h"
+using bluetooth::os::fake_timer::fake_timerfd_advance;
+using bluetooth::os::fake_timer::fake_timerfd_reset;
using testing::_;
using testing::AtLeast;
using testing::Return;
@@ -42,6 +46,7 @@ using testing::Return;
namespace {
static constexpr auto kTimeout = std::chrono::seconds(1);
static constexpr uint8_t kMaxRetryCounterForCreateConfig = 0x03;
+static constexpr uint8_t kMaxRetryCounterForCsEnable = 0x03;
}
namespace bluetooth {
@@ -140,6 +145,20 @@ struct CsConfigCompleteEvent {
}
};
+struct CsProcedureEnableCompleteEvent {
+ ErrorCode status = ErrorCode::SUCCESS;
+ uint8_t config_id = 0;
+ uint8_t tone_antenna_config_selection = 0;
+ uint8_t selected_tx_power = 0; // -127 to 20 dBm
+ uint32_t subevent_len = 2500; // 1250us to 4s
+ uint8_t subevents_per_event = 1; // 0x01 to 0x20
+ uint16_t subevent_interval = 1; // N x 0.625ms
+ uint16_t event_interval = 0; // number of acl conn interval
+ uint16_t procedure_interval = 2; // number of acl conn interval
+ uint16_t procedure_count = 5; // 0x0001 to 0xFFFF
+ uint16_t max_procedure_len = 10; // N x 0.625 ms
+};
+
struct StartMeasurementParameters {
Address remote_address = Address::FromString("12:34:56:78:9a:bc").value();
uint16_t connection_handle = 64;
@@ -165,6 +184,7 @@ protected:
EXPECT_CALL(*mock_controller_, SupportsBleChannelSounding()).WillOnce(Return(true));
EXPECT_CALL(*mock_ranging_hal_, IsBound()).Times(AtLeast(1)).WillRepeatedly(Return(true));
+ EXPECT_CALL(*mock_ranging_hal_, GetRangingHalVersion).WillRepeatedly(Return(hal::V_2));
handler_ = fake_registry_.GetTestHandler();
dm_manager_ = fake_registry_.Start<DistanceMeasurementManager>(&thread_, handler_);
@@ -184,6 +204,19 @@ protected:
return dm_session_promise_->get_future();
}
+ std::future<void> fake_timer_advance(uint64_t ms) {
+ std::promise<void> promise;
+ auto future = promise.get_future();
+ handler_->Post(common::BindOnce(
+ [](std::promise<void> promise, uint64_t ms) {
+ fake_timerfd_advance(ms);
+ promise.set_value();
+ },
+ common::Passed(std::move(promise)), ms));
+
+ return future;
+ }
+
void sync_client_handler() {
log::assert_that(thread_.GetReactor()->WaitForIdle(kTimeout),
"assert failed: thread_.GetReactor()->WaitForIdle(kTimeout)");
@@ -248,6 +281,18 @@ protected:
complete_event.t_fcs_time, complete_event.t_pm_time);
}
+ static std::unique_ptr<LeCsProcedureEnableCompleteBuilder> GetProcedureEnableCompleteEvent(
+ uint16_t connection_handle, Enable enable,
+ CsProcedureEnableCompleteEvent complete_event) {
+ return LeCsProcedureEnableCompleteBuilder::Create(
+ complete_event.status, connection_handle, complete_event.config_id, enable,
+ complete_event.tone_antenna_config_selection, complete_event.selected_tx_power,
+ complete_event.subevent_len, complete_event.subevents_per_event,
+ complete_event.subevent_interval, complete_event.event_interval,
+ complete_event.procedure_interval, complete_event.procedure_count,
+ complete_event.max_procedure_len);
+ }
+
void StartMeasurement(const StartMeasurementParameters& params) {
dm_manager_->StartDistanceMeasurement(params.remote_address, params.connection_handle,
params.local_hci_role, params.interval, params.method);
@@ -281,8 +326,48 @@ protected:
test_hci_layer_->GetCommand(OpCode::LE_CS_READ_REMOTE_SUPPORTED_CAPABILITIES);
CsReadCapabilitiesCompleteEvent read_cs_complete_event;
+ test_hci_layer_->IncomingEvent(LeCsReadRemoteSupportedCapabilitiesStatusBuilder::Create(
+ /*status=*/ErrorCode::SUCCESS,
+ /*num_hci_command_packets=*/0xFF));
test_hci_layer_->IncomingLeMetaEvent(GetRemoteSupportedCapabilitiesCompleteEvent(
params.connection_handle, read_cs_complete_event));
+
+ test_hci_layer_->GetCommand(OpCode::LE_CS_SET_DEFAULT_SETTINGS);
+ test_hci_layer_->IncomingEvent(LeCsSetDefaultSettingsCompleteBuilder::Create(
+ /*num_hci_command_packets=*/static_cast<uint8_t>(0xEE), ErrorCode::SUCCESS,
+ params.connection_handle));
+ }
+
+ void StartMeasurementTillCreateConfig(const StartMeasurementParameters& params) {
+ StartMeasurementTillReadRemoteCaps(params);
+
+ CsConfigCompleteEvent cs_config_complete_event;
+ test_hci_layer_->GetCommand(OpCode::LE_CS_CREATE_CONFIG);
+ test_hci_layer_->IncomingEvent(LeCsCreateConfigStatusBuilder::Create(
+ /*status=*/ErrorCode::SUCCESS,
+ /*num_hci_command_packets=*/0xFF));
+ test_hci_layer_->IncomingLeMetaEvent(
+ GetConfigCompleteEvent(params.connection_handle, cs_config_complete_event));
+ }
+
+ void StartMeasurementTillSecurityEnable(const StartMeasurementParameters& params) {
+ StartMeasurementTillCreateConfig(params);
+
+ test_hci_layer_->GetCommand(OpCode::LE_CS_SECURITY_ENABLE);
+ test_hci_layer_->IncomingEvent(LeCsSecurityEnableStatusBuilder::Create(
+ /*status=*/ErrorCode::SUCCESS,
+ /*num_hci_command_packets=*/0xFF));
+ test_hci_layer_->IncomingLeMetaEvent(LeCsSecurityEnableCompleteBuilder::Create(
+ ErrorCode::SUCCESS, params.connection_handle));
+ }
+
+ void StartMeasurementTillSetProcedureParameters(const StartMeasurementParameters& params) {
+ StartMeasurementTillSecurityEnable(params);
+
+ test_hci_layer_->GetCommand(OpCode::LE_CS_SET_PROCEDURE_PARAMETERS);
+ test_hci_layer_->IncomingEvent(LeCsSetProcedureParametersCompleteBuilder::Create(
+ /*num_hci_command_packets=*/static_cast<uint8_t>(0xEE), ErrorCode::SUCCESS,
+ params.connection_handle));
}
protected:
@@ -373,6 +458,7 @@ TEST_F(DistanceMeasurementManagerTest, error_read_remote_cs_caps_command) {
test_hci_layer_->IncomingEvent(LeCsReadRemoteSupportedCapabilitiesStatusBuilder::Create(
/*status=*/ErrorCode::COMMAND_DISALLOWED,
/*num_hci_command_packets=*/0xff));
+ sync_client_handler();
}
TEST_F(DistanceMeasurementManagerTest, fail_read_remote_cs_caps_complete) {
@@ -396,6 +482,7 @@ TEST_F(DistanceMeasurementManagerTest, fail_read_remote_cs_caps_complete) {
read_cs_complete_event.error_code = ErrorCode::COMMAND_DISALLOWED;
test_hci_layer_->IncomingLeMetaEvent(GetRemoteSupportedCapabilitiesCompleteEvent(
params.connection_handle, read_cs_complete_event));
+ sync_client_handler();
}
TEST_F(DistanceMeasurementManagerTest, error_create_config_command) {
@@ -418,6 +505,7 @@ TEST_F(DistanceMeasurementManagerTest, error_create_config_command) {
test_hci_layer_->IncomingEvent(LeCsCreateConfigStatusBuilder::Create(
/*status=*/ErrorCode::COMMAND_DISALLOWED,
/*num_hci_command_packets=*/0xff));
+ sync_client_handler();
}
TEST_F(DistanceMeasurementManagerTest, fail_create_config_complete) {
@@ -443,6 +531,97 @@ TEST_F(DistanceMeasurementManagerTest, fail_create_config_complete) {
test_hci_layer_->IncomingLeMetaEvent(
GetConfigCompleteEvent(params.connection_handle, cs_config_complete_event));
}
+ sync_client_handler();
+}
+
+TEST_F(DistanceMeasurementManagerTest, retry_fail_procedure_enable_command) {
+ auto dm_session_future = GetDmSessionFuture();
+ StartMeasurementParameters params;
+ StartMeasurementTillSetProcedureParameters(params);
+
+ EXPECT_CALL(mock_dm_callbacks_,
+ OnDistanceMeasurementStopped(params.remote_address,
+ DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
+ DistanceMeasurementMethod::METHOD_CS))
+ .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
+ DistanceMeasurementMethod /*method*/) {
+ ASSERT_NE(dm_session_promise_, nullptr);
+ dm_session_promise_->set_value();
+ dm_session_promise_.reset();
+ });
+
+ for (int i = 0; i <= kMaxRetryCounterForCsEnable; i++) {
+ test_hci_layer_->GetCommand(OpCode::LE_CS_PROCEDURE_ENABLE);
+ test_hci_layer_->IncomingEvent(LeCsProcedureEnableStatusBuilder::Create(
+ /*status=*/ErrorCode::COMMAND_DISALLOWED,
+ /*num_hci_command_packets=*/0xff));
+ auto future = fake_timer_advance(params.interval + 10);
+ future.wait_for(kTimeout);
+ sync_client_handler();
+ }
+ fake_timerfd_reset();
+ sync_client_handler();
+}
+
+TEST_F(DistanceMeasurementManagerTest, retry_fail_procedure_enable_complete) {
+ auto dm_session_future = GetDmSessionFuture();
+ StartMeasurementParameters params;
+ StartMeasurementTillSetProcedureParameters(params);
+
+ EXPECT_CALL(mock_dm_callbacks_,
+ OnDistanceMeasurementStopped(params.remote_address,
+ DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
+ DistanceMeasurementMethod::METHOD_CS))
+ .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
+ DistanceMeasurementMethod /*method*/) {
+ ASSERT_NE(dm_session_promise_, nullptr);
+ dm_session_promise_->set_value();
+ dm_session_promise_.reset();
+ });
+
+ CsProcedureEnableCompleteEvent complete_event;
+ complete_event.status = ErrorCode::LINK_LAYER_COLLISION;
+ for (int i = 0; i <= kMaxRetryCounterForCsEnable; i++) {
+ test_hci_layer_->GetCommand(OpCode::LE_CS_PROCEDURE_ENABLE);
+ test_hci_layer_->IncomingEvent(LeCsProcedureEnableStatusBuilder::Create(
+ /*status=*/ErrorCode::SUCCESS,
+ /*num_hci_command_packets=*/0xff));
+ test_hci_layer_->IncomingLeMetaEvent(GetProcedureEnableCompleteEvent(
+ params.connection_handle, Enable::ENABLED, complete_event));
+ auto future = fake_timer_advance(params.interval + 10);
+ future.wait_for(kTimeout);
+ sync_client_handler();
+ }
+ fake_timerfd_reset();
+ sync_client_handler();
+}
+
+TEST_F(DistanceMeasurementManagerTest, unexpected_procedure_enable_complete_as_disable) {
+ auto dm_session_future = GetDmSessionFuture();
+ StartMeasurementParameters params;
+ StartMeasurementTillSetProcedureParameters(params);
+
+ EXPECT_CALL(mock_dm_callbacks_,
+ OnDistanceMeasurementStopped(params.remote_address,
+ DistanceMeasurementErrorCode::REASON_INTERNAL_ERROR,
+ DistanceMeasurementMethod::METHOD_CS))
+ .WillOnce([this](const Address& /*address*/, DistanceMeasurementErrorCode /*error_code*/,
+ DistanceMeasurementMethod /*method*/) {
+ ASSERT_NE(dm_session_promise_, nullptr);
+ dm_session_promise_->set_value();
+ dm_session_promise_.reset();
+ });
+
+ test_hci_layer_->GetCommand(OpCode::LE_CS_PROCEDURE_ENABLE);
+ test_hci_layer_->IncomingEvent(LeCsProcedureEnableStatusBuilder::Create(
+ /*status=*/ErrorCode::SUCCESS,
+ /*num_hci_command_packets=*/0xff));
+ CsProcedureEnableCompleteEvent complete_event;
+ complete_event.status = ErrorCode::LINK_LAYER_COLLISION;
+ test_hci_layer_->IncomingLeMetaEvent(GetProcedureEnableCompleteEvent(
+ params.connection_handle, Enable::DISABLED, complete_event));
+
+ sync_client_handler();
}
} // namespace