From 0b05e8a2e8089b17e75659540da989798ac3c0f9 Mon Sep 17 00:00:00 2001
From: Myles Watson <mylesgw@google.com>
Date: Wed, 4 May 2022 10:24:48 -0700
Subject: [PATCH] RootCanal: Check connections when setting features

Bug: 228326164
Test: cert/run
Tag: #feature
Change-Id: Ibe0a988077266c1e60ee24bd5b7c6f77cc5b9173
---
 .../model/controller/dual_mode_controller.cc  | 19 ++++++++++++-------
 .../model/controller/link_layer_controller.cc |  4 ++++
 .../model/controller/link_layer_controller.h  |  2 ++
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/tools/rootcanal/model/controller/dual_mode_controller.cc b/tools/rootcanal/model/controller/dual_mode_controller.cc
index 51811fd5f41..cda45a47461 100644
--- a/tools/rootcanal/model/controller/dual_mode_controller.cc
+++ b/tools/rootcanal/model/controller/dual_mode_controller.cc
@@ -1676,13 +1676,18 @@ void DualModeController::LeSetEventMask(CommandView command) {
 void DualModeController::LeSetHostFeature(CommandView command) {
   auto command_view = gd_hci::LeSetHostFeatureView::Create(command);
   ASSERT(command_view.IsValid());
-  // TODO: if the controller has active connections, return COMMAND_DISALLOED
-  ErrorCode error_code =
-      properties_.SetLeHostFeature(
-          static_cast<uint8_t>(command_view.GetBitNumber()),
-          static_cast<uint8_t>(command_view.GetBitValue()))
-          ? ErrorCode::SUCCESS
-          : ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
+
+  ErrorCode error_code = ErrorCode::SUCCESS;
+  if (link_layer_controller_.HasAclConnection()) {
+    error_code = ErrorCode::COMMAND_DISALLOWED;
+  } else {
+    bool bit_was_set = properties_.SetLeHostFeature(
+        static_cast<uint8_t>(command_view.GetBitNumber()),
+        static_cast<uint8_t>(command_view.GetBitValue()));
+    if (!bit_was_set) {
+      error_code = ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
+    }
+  }
   send_event_(bluetooth::hci::LeSetHostFeatureCompleteBuilder::Create(
       kNumCommandPackets, error_code));
 }
diff --git a/tools/rootcanal/model/controller/link_layer_controller.cc b/tools/rootcanal/model/controller/link_layer_controller.cc
index d1e067a7295..e7066819446 100644
--- a/tools/rootcanal/model/controller/link_layer_controller.cc
+++ b/tools/rootcanal/model/controller/link_layer_controller.cc
@@ -3396,6 +3396,10 @@ ErrorCode LinkLayerController::LeResolvingListAddDevice(
   return ErrorCode::SUCCESS;
 }
 
+bool LinkLayerController::HasAclConnection() {
+  return (connections_.GetAclHandles().size() > 0);
+}
+
 void LinkLayerController::LeSetPrivacyMode(uint8_t address_type, Address addr,
                                            uint8_t mode) {
   // set mode for addr
diff --git a/tools/rootcanal/model/controller/link_layer_controller.h b/tools/rootcanal/model/controller/link_layer_controller.h
index b9d4740c28f..60a1657f96f 100644
--- a/tools/rootcanal/model/controller/link_layer_controller.h
+++ b/tools/rootcanal/model/controller/link_layer_controller.h
@@ -380,6 +380,8 @@ class LinkLayerController {
       uint8_t retransmission_effort, uint16_t packet_types);
   ErrorCode RejectSynchronousConnection(Address bd_addr, uint16_t reason);
 
+  bool HasAclConnection();
+
   void HandleIso(bluetooth::hci::IsoView iso);
 
  protected:
-- 
GitLab