Root-Canal: Generate LE_Channel_Selection_Algorithm event
The 5.2 specification states in Section 7.7.8.66 that the
LE_Channel_Selection_Algorithm event shall be sent
immediately following the LE_Enhanced_Connection_Complete
event when the connection is created by the command
LE_Extend_Create_Connection.
The PTS tool relies on this behaviour to run LE Audio tests.
Bug: 241962982
Test: run VCS PTS tests against Eiffel
Ignore-AOSP-First: Cherry-picked from AOSP
Merged-In: I6649a24633b3e715e1ff9eb917c03862c64d1c9f
Change-Id: I6649a24633b3e715e1ff9eb917c03862c64d1c9f
diff --git a/tools/rootcanal/model/controller/dual_mode_controller.cc b/tools/rootcanal/model/controller/dual_mode_controller.cc
index a772bae..b5a2e8f 100644
--- a/tools/rootcanal/model/controller/dual_mode_controller.cc
+++ b/tools/rootcanal/model/controller/dual_mode_controller.cc
@@ -1833,7 +1833,7 @@
link_layer_controller_.SetLeMaximumCeLength(
command_view.GetMaximumCeLength());
- auto status = link_layer_controller_.SetLeConnect(true);
+ auto status = link_layer_controller_.SetLeConnect(true, false);
send_event_(bluetooth::hci::LeCreateConnectionStatusBuilder::Create(
status, kNumCommandPackets));
@@ -1911,7 +1911,7 @@
gd_hci::LeConnectionManagementCommandView::Create(
gd_hci::AclCommandView::Create(command)));
ASSERT(command_view.IsValid());
- ErrorCode status = link_layer_controller_.SetLeConnect(false);
+ ErrorCode status = link_layer_controller_.SetLeConnect(false, false);
send_event_(bluetooth::hci::LeCreateConnectionCancelCompleteBuilder::Create(
kNumCommandPackets, status));
@@ -2160,7 +2160,7 @@
link_layer_controller_.SetLeMinimumCeLength(params[0].min_ce_length_);
link_layer_controller_.SetLeMaximumCeLength(params[0].max_ce_length_);
- auto status = link_layer_controller_.SetLeConnect(true);
+ auto status = link_layer_controller_.SetLeConnect(true, true);
send_event_(bluetooth::hci::LeExtendedCreateConnectionStatusBuilder::Create(
status, kNumCommandPackets));
diff --git a/tools/rootcanal/model/controller/link_layer_controller.cc b/tools/rootcanal/model/controller/link_layer_controller.cc
index 780dff6..3b660d6 100644
--- a/tools/rootcanal/model/controller/link_layer_controller.cc
+++ b/tools/rootcanal/model/controller/link_layer_controller.cc
@@ -1354,7 +1354,7 @@
properties_.GetLeAddress(), address));
}
- if (!le_connect_) {
+ if (!le_connect_ || le_pending_connect_) {
return;
}
if (!(adv_type == model::packets::AdvertisementType::ADV_IND ||
@@ -1415,7 +1415,7 @@
LOG_INFO("Connecting to %s (type %hhx) own_address %s (type %hhx)",
incoming.GetSourceAddress().ToString().c_str(), address_type,
own_address.ToString().c_str(), le_address_type_);
- le_connect_ = false;
+ le_pending_connect_ = true;
le_scan_enable_ = bluetooth::hci::OpCode::NONE;
if (!connections_.CreatePendingLeConnection(
@@ -1557,12 +1557,11 @@
}
}
-uint16_t LinkLayerController::HandleLeConnection(AddressWithType address,
- AddressWithType own_address,
- uint8_t role,
- uint16_t connection_interval,
- uint16_t connection_latency,
- uint16_t supervision_timeout) {
+uint16_t LinkLayerController::HandleLeConnection(
+ AddressWithType address, AddressWithType own_address, uint8_t role,
+ uint16_t connection_interval, uint16_t connection_latency,
+ uint16_t supervision_timeout,
+ bool send_le_channel_selection_algorithm_event) {
// Note: the HCI_LE_Connection_Complete event is not sent if the
// HCI_LE_Enhanced_Connection_Complete event (see Section 7.7.65.10) is
// unmasked.
@@ -1619,6 +1618,19 @@
static_cast<bluetooth::hci::ClockAccuracy>(0x00)));
}
+ // Note: the HCI_LE_Connection_Complete event is immediately followed by
+ // an HCI_LE_Channel_Selection_Algorithm event if the connection is created
+ // using the LE_Extended_Create_Connection command (see Section 7.7.8.66).
+ if (send_le_channel_selection_algorithm_event &&
+ properties_.IsUnmasked(EventCode::LE_META_EVENT) &&
+ properties_.GetLeEventSupported(
+ SubeventCode::CHANNEL_SELECTION_ALGORITHM)) {
+ // The selection channel algorithm probably will have no impact
+ // on emulation.
+ send_event_(bluetooth::hci::LeChannelSelectionAlgorithmBuilder::Create(
+ handle, bluetooth::hci::ChannelSelectionAlgorithm::ALGORITHM_1));
+ }
+
if (own_address.GetAddress() == le_connecting_rpa_) {
le_connecting_rpa_ = Address::kEmpty;
}
@@ -1678,7 +1690,7 @@
static_cast<bluetooth::hci::AddressType>(connect.GetAddressType())),
my_address, static_cast<uint8_t>(bluetooth::hci::Role::PERIPHERAL),
connection_interval, connect.GetLeConnectionLatency(),
- connect.GetLeConnectionSupervisionTimeout());
+ connect.GetLeConnectionSupervisionTimeout(), false);
SendLeLinkLayerPacket(model::packets::LeConnectCompleteBuilder::Create(
incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
@@ -1711,7 +1723,10 @@
static_cast<bluetooth::hci::AddressType>(le_address_type_)),
static_cast<uint8_t>(bluetooth::hci::Role::CENTRAL),
complete.GetLeConnectionInterval(), complete.GetLeConnectionLatency(),
- complete.GetLeConnectionSupervisionTimeout());
+ complete.GetLeConnectionSupervisionTimeout(), le_extended_connect_);
+ le_connect_ = false;
+ le_extended_connect_ = false;
+ le_pending_connect_ = false;
}
void LinkLayerController::IncomingLeConnectionParameterRequest(
@@ -3705,6 +3720,8 @@
LeDisableAdvertisingSets();
le_scan_enable_ = bluetooth::hci::OpCode::NONE;
le_connect_ = false;
+ le_extended_connect_ = false;
+ le_pending_connect_ = false;
if (inquiry_timer_task_id_ != kInvalidTaskId) {
CancelScheduledTask(inquiry_timer_task_id_);
inquiry_timer_task_id_ = kInvalidTaskId;
diff --git a/tools/rootcanal/model/controller/link_layer_controller.h b/tools/rootcanal/model/controller/link_layer_controller.h
index 4643e7b..c5ab9ff 100644
--- a/tools/rootcanal/model/controller/link_layer_controller.h
+++ b/tools/rootcanal/model/controller/link_layer_controller.h
@@ -183,7 +183,8 @@
uint16_t HandleLeConnection(AddressWithType addr, AddressWithType own_addr,
uint8_t role, uint16_t connection_interval,
uint16_t connection_latency,
- uint16_t supervision_timeout);
+ uint16_t supervision_timeout,
+ bool send_le_channel_selection_algorithm_event);
bool ListBusy(uint16_t ignore_mask);
@@ -284,11 +285,13 @@
void SetLeAddressType(bluetooth::hci::OwnAddressType le_address_type) {
le_address_type_ = le_address_type;
}
- ErrorCode SetLeConnect(bool le_connect) {
+ ErrorCode SetLeConnect(bool le_connect, bool extended) {
if (le_connect_ == le_connect) {
return ErrorCode::COMMAND_DISALLOWED;
}
le_connect_ = le_connect;
+ le_extended_connect_ = extended;
+ le_pending_connect_ = false;
return ErrorCode::SUCCESS;
}
void SetLeConnectionIntervalMin(uint16_t min) {
@@ -510,6 +513,8 @@
bluetooth::hci::OwnAddressType le_address_type_{};
bool le_connect_{false};
+ bool le_extended_connect_{false};
+ bool le_pending_connect_{false};
uint16_t le_connection_interval_min_{};
uint16_t le_connection_interval_max_{};
uint16_t le_connection_latency_{};