summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Henri Chataing <henrichataing@google.com> 2023-06-09 14:32:53 -0700
committer Henri Chataing <henrichataing@google.com> 2023-06-12 16:23:22 +0000
commit901a2fa08b0c869b4b2c067232a41c04c49d66cb (patch)
tree70b94e01a89c409cbf94c84256066028ff037466
parent33018ef61177019f286681305af4347ac9e95d4b (diff)
RootCanal: Implement HCI LE Request Peer SCA command
Required by the LE Audio in Android which performs the command which checking the supported bit; the stack crashes when it receives a Command Complete event instead of Command Status Bug: 286588829 Test: m root-canal Change-Id: Iaecc31a9d1ab822796d6a2fb74a4be9af737ee1b
-rw-r--r--tools/rootcanal/model/controller/controller_properties.cc5
-rw-r--r--tools/rootcanal/model/controller/dual_mode_controller.cc34
-rw-r--r--tools/rootcanal/model/controller/dual_mode_controller.h3
3 files changed, 39 insertions, 3 deletions
diff --git a/tools/rootcanal/model/controller/controller_properties.cc b/tools/rootcanal/model/controller/controller_properties.cc
index dcc20006e2..b54772c2c2 100644
--- a/tools/rootcanal/model/controller/controller_properties.cc
+++ b/tools/rootcanal/model/controller/controller_properties.cc
@@ -386,8 +386,8 @@ static std::array<uint8_t, 64> SupportedCommands() {
// OpCodeIndex::LE_TERMINATE_BIG,
// OpCodeIndex::LE_BIG_CREATE_SYNC,
// OpCodeIndex::LE_BIG_TERMINATE_SYNC,
- // OpCodeIndex::LE_REQUEST_PEER_SCA,
- OpCodeIndex::LE_SETUP_ISO_DATA_PATH, OpCodeIndex::LE_REMOVE_ISO_DATA_PATH,
+ OpCodeIndex::LE_REQUEST_PEER_SCA, OpCodeIndex::LE_SETUP_ISO_DATA_PATH,
+ OpCodeIndex::LE_REMOVE_ISO_DATA_PATH,
// OpCodeIndex::LE_ISO_TRANSMIT_TEST,
// OpCodeIndex::LE_ISO_RECEIVE_TEST,
// OpCodeIndex::LE_ISO_READ_TEST_COUNTERS,
@@ -1802,6 +1802,7 @@ static std::vector<OpCodeIndex> ll_connected_isochronous_stream_commands_ = {
OpCodeIndex::LE_REJECT_CIS_REQUEST,
OpCodeIndex::LE_SETUP_ISO_DATA_PATH,
OpCodeIndex::LE_REMOVE_ISO_DATA_PATH,
+ OpCodeIndex::LE_REQUEST_PEER_SCA,
};
static void SetLLFeatureBit(uint64_t& le_features, LLFeaturesBits bit,
diff --git a/tools/rootcanal/model/controller/dual_mode_controller.cc b/tools/rootcanal/model/controller/dual_mode_controller.cc
index d96913ed40..173d466063 100644
--- a/tools/rootcanal/model/controller/dual_mode_controller.cc
+++ b/tools/rootcanal/model/controller/dual_mode_controller.cc
@@ -1816,6 +1816,38 @@ void DualModeController::LeSetEventMask(CommandView command) {
kNumCommandPackets, ErrorCode::SUCCESS));
}
+void DualModeController::LeRequestPeerSca(CommandView command) {
+ auto command_view = bluetooth::hci::LeRequestPeerScaView::Create(command);
+ ASSERT(command_view.IsValid());
+ uint16_t connection_handle = command_view.GetConnectionHandle();
+
+ DEBUG(id_, "<< LE Request Peer SCA");
+ DEBUG(id_, " connection_handle=0x{:x}", connection_handle);
+
+ // If the Host sends this command and the peer device does not support the
+ // Sleep Clock Accuracy Updates feature, the Controller shall return the error
+ // code Unsupported Feature or Parameter Value (0x11) in the HCI_LE_-
+ // Request_Peer_SCA_Complete event.
+ // TODO
+
+ // If the Host issues this command when the Controller is aware (e.g., through
+ // a previous feature exchange) that the peer device's Link Layer does not
+ // support the Sleep Clock Accuracy Updates feature, the Controller shall
+ // return the error code Unsupported Remote Feature (0x1A).
+ // TODO
+
+ if (link_layer_controller_.HasAclConnection(connection_handle)) {
+ send_event_(bluetooth::hci::LeRequestPeerScaStatusBuilder::Create(
+ ErrorCode::SUCCESS, kNumCommandPackets));
+ send_event_(bluetooth::hci::LeRequestPeerScaCompleteBuilder::Create(
+ ErrorCode::SUCCESS, connection_handle,
+ bluetooth::hci::ClockAccuracy::PPM_500));
+ } else {
+ send_event_(bluetooth::hci::LeRequestPeerScaStatusBuilder::Create(
+ ErrorCode::UNKNOWN_CONNECTION, kNumCommandPackets));
+ }
+}
+
void DualModeController::LeSetHostFeature(CommandView command) {
auto command_view = bluetooth::hci::LeSetHostFeatureView::Create(command);
ASSERT(command_view.IsValid());
@@ -4234,7 +4266,7 @@ const std::unordered_map<OpCode, DualModeController::CommandHandler>
//{OpCode::LE_BIG_CREATE_SYNC, &DualModeController::LeBigCreateSync},
//{OpCode::LE_BIG_TERMINATE_SYNC,
//&DualModeController::LeBigTerminateSync},
- //{OpCode::LE_REQUEST_PEER_SCA, &DualModeController::LeRequestPeerSca},
+ {OpCode::LE_REQUEST_PEER_SCA, &DualModeController::LeRequestPeerSca},
{OpCode::LE_SETUP_ISO_DATA_PATH, &DualModeController::ForwardToLl},
{OpCode::LE_REMOVE_ISO_DATA_PATH, &DualModeController::ForwardToLl},
//{OpCode::LE_ISO_TRANSMIT_TEST,
diff --git a/tools/rootcanal/model/controller/dual_mode_controller.h b/tools/rootcanal/model/controller/dual_mode_controller.h
index 3cdb5f3445..c591ca98ae 100644
--- a/tools/rootcanal/model/controller/dual_mode_controller.h
+++ b/tools/rootcanal/model/controller/dual_mode_controller.h
@@ -496,6 +496,9 @@ class DualModeController : public Device {
// 7.8.77
void LeSetPrivacyMode(CommandView command);
+ // 7.8.108
+ void LeRequestPeerSca(CommandView command);
+
// 7.8.115
void LeSetHostFeature(CommandView command);