summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Henri Chataing <henrichataing@google.com> 2023-05-04 10:37:17 -0700
committer Henri Chataing <henrichataing@google.com> 2023-05-06 01:04:14 +0000
commite0cf5f94f2087f87c02b7f95e49bb8818cb48bea (patch)
tree395a2a7964833a83a1a7c962cb69d40970fa5e88
parente1e32a6f97660a33944adf2974cada9d517ed4d8 (diff)
RootCanal: Implement the LL phy update procedure
Implement the full semantic of the LE Set Phy and LE Set Default Phy commands by performing the LL phy update procedure. Bug: 275970864 Test: m root-canal Change-Id: I144ec8c153e0f2a3d96bcc408a46f0d383077625
-rw-r--r--tools/rootcanal/model/controller/acl_connection.cc16
-rw-r--r--tools/rootcanal/model/controller/acl_connection.h44
-rw-r--r--tools/rootcanal/model/controller/acl_connection_handler.cc5
-rw-r--r--tools/rootcanal/model/controller/acl_connection_handler.h4
-rw-r--r--tools/rootcanal/model/controller/dual_mode_controller.cc9
-rw-r--r--tools/rootcanal/model/controller/link_layer_controller.cc193
-rw-r--r--tools/rootcanal/model/controller/link_layer_controller.h10
-rw-r--r--tools/rootcanal/packets/hci/hci_packets.pdl12
-rw-r--r--tools/rootcanal/packets/link_layer_packets.pdl20
9 files changed, 247 insertions, 66 deletions
diff --git a/tools/rootcanal/model/controller/acl_connection.cc b/tools/rootcanal/model/controller/acl_connection.cc
index 85915b7d09..2c47ad191d 100644
--- a/tools/rootcanal/model/controller/acl_connection.cc
+++ b/tools/rootcanal/model/controller/acl_connection.cc
@@ -33,22 +33,6 @@ void AclConnection::Encrypt() { encrypted_ = true; };
bool AclConnection::IsEncrypted() const { return encrypted_; };
-AddressWithType AclConnection::GetAddress() const { return address_; }
-
-void AclConnection::SetAddress(AddressWithType address) { address_ = address; }
-
-AddressWithType AclConnection::GetOwnAddress() const { return own_address_; }
-
-AddressWithType AclConnection::GetResolvedAddress() const {
- return resolved_address_;
-}
-
-void AclConnection::SetOwnAddress(AddressWithType address) {
- own_address_ = address;
-}
-
-Phy::Type AclConnection::GetPhyType() const { return type_; }
-
uint16_t AclConnection::GetLinkPolicySettings() const {
return link_policy_settings_;
};
diff --git a/tools/rootcanal/model/controller/acl_connection.h b/tools/rootcanal/model/controller/acl_connection.h
index eed6a0540d..74bc9a700a 100644
--- a/tools/rootcanal/model/controller/acl_connection.h
+++ b/tools/rootcanal/model/controller/acl_connection.h
@@ -35,44 +35,39 @@ class AclConnection {
virtual ~AclConnection() = default;
- void Encrypt();
-
- bool IsEncrypted() const;
-
- AddressWithType GetAddress() const;
-
- void SetAddress(AddressWithType address);
-
- AddressWithType GetOwnAddress() const;
+ Phy::Type GetPhyType() const { return type_; }
- void SetOwnAddress(AddressWithType address);
+ AddressWithType GetAddress() const { return address_; }
+ AddressWithType GetOwnAddress() const { return own_address_; }
+ AddressWithType GetResolvedAddress() const { return resolved_address_; }
- AddressWithType GetResolvedAddress() const;
-
- Phy::Type GetPhyType() const;
+ void Encrypt();
+ bool IsEncrypted() const;
uint16_t GetLinkPolicySettings() const;
-
void SetLinkPolicySettings(uint16_t settings);
bluetooth::hci::Role GetRole() const;
-
void SetRole(bluetooth::hci::Role role);
int8_t GetRssi() const;
-
void SetRssi(int8_t rssi);
- void ResetLinkTimer();
-
std::chrono::steady_clock::duration TimeUntilNearExpiring() const;
-
- bool IsNearExpiring() const;
-
std::chrono::steady_clock::duration TimeUntilExpired() const;
-
+ void ResetLinkTimer();
+ bool IsNearExpiring() const;
bool HasExpired() const;
+ // LE-ACL state.
+ void InitiatePhyUpdate() { initiated_phy_update_ = true; }
+ void PhyUpdateComplete() { initiated_phy_update_ = false; }
+ bool InitiatedPhyUpdate() const { return initiated_phy_update_; }
+ bluetooth::hci::PhyType GetTxPhy() const { return tx_phy_; }
+ bluetooth::hci::PhyType GetRxPhy() const { return rx_phy_; }
+ void SetTxPhy(bluetooth::hci::PhyType phy) { tx_phy_ = phy; }
+ void SetRxPhy(bluetooth::hci::PhyType phy) { rx_phy_ = phy; }
+
private:
AddressWithType address_;
AddressWithType own_address_;
@@ -89,6 +84,11 @@ class AclConnection {
bluetooth::hci::Role role_{bluetooth::hci::Role::CENTRAL};
std::chrono::steady_clock::time_point last_packet_timestamp_;
std::chrono::steady_clock::duration timeout_;
+
+ // LE-ACL state.
+ bluetooth::hci::PhyType tx_phy_{bluetooth::hci::PhyType::LE_1M};
+ bluetooth::hci::PhyType rx_phy_{bluetooth::hci::PhyType::LE_1M};
+ bool initiated_phy_update_{false};
};
} // namespace rootcanal
diff --git a/tools/rootcanal/model/controller/acl_connection_handler.cc b/tools/rootcanal/model/controller/acl_connection_handler.cc
index 2e3bd5a2a0..d310450b10 100644
--- a/tools/rootcanal/model/controller/acl_connection_handler.cc
+++ b/tools/rootcanal/model/controller/acl_connection_handler.cc
@@ -197,6 +197,11 @@ uint16_t AclConnectionHandler::GetHandleOnlyAddress(
return kReservedHandle;
}
+AclConnection& AclConnectionHandler::GetAclConnection(uint16_t handle) {
+ ASSERT_LOG(HasHandle(handle), "Unknown handle %d", handle);
+ return acl_connections_.at(handle);
+}
+
AddressWithType AclConnectionHandler::GetAddress(uint16_t handle) const {
ASSERT_LOG(HasHandle(handle), "Unknown handle %hd", handle);
return acl_connections_.at(handle).GetAddress();
diff --git a/tools/rootcanal/model/controller/acl_connection_handler.h b/tools/rootcanal/model/controller/acl_connection_handler.h
index 1534fe17bb..c9bf92aaec 100644
--- a/tools/rootcanal/model/controller/acl_connection_handler.h
+++ b/tools/rootcanal/model/controller/acl_connection_handler.h
@@ -91,6 +91,10 @@ class AclConnectionHandler {
bluetooth::hci::AddressWithType GetOwnAddress(uint16_t handle) const;
bluetooth::hci::AddressWithType GetResolvedAddress(uint16_t handle) const;
+ // Return the AclConnection for the selected connection handle, asserts
+ // if the handle is not currently used.
+ AclConnection& GetAclConnection(uint16_t handle);
+
void Encrypt(uint16_t handle);
bool IsEncrypted(uint16_t handle) const;
diff --git a/tools/rootcanal/model/controller/dual_mode_controller.cc b/tools/rootcanal/model/controller/dual_mode_controller.cc
index 97da8504b0..b6efbd4510 100644
--- a/tools/rootcanal/model/controller/dual_mode_controller.cc
+++ b/tools/rootcanal/model/controller/dual_mode_controller.cc
@@ -1824,8 +1824,8 @@ void DualModeController::LeSetDefaultPhy(CommandView command) {
ASSERT(command_view.IsValid());
ErrorCode status = link_layer_controller_.LeSetDefaultPhy(
command_view.GetAllPhysNoTransmitPreference(),
- command_view.GetAllPhysNoReceivePreference(),
- command_view.GetTxPhysBitmask(), command_view.GetRxPhysBitmask());
+ command_view.GetAllPhysNoReceivePreference(), command_view.GetTxPhys(),
+ command_view.GetRxPhys());
send_event_(bluetooth::hci::LeSetDefaultPhyCompleteBuilder::Create(
kNumCommandPackets, status));
}
@@ -1836,9 +1836,8 @@ void DualModeController::LeSetPhy(CommandView command) {
ErrorCode status = link_layer_controller_.LeSetPhy(
command_view.GetConnectionHandle(),
command_view.GetAllPhysNoTransmitPreference(),
- command_view.GetAllPhysNoReceivePreference(),
- command_view.GetTxPhysBitmask(), command_view.GetRxPhysBitmask(),
- command_view.GetPhyOptions());
+ command_view.GetAllPhysNoReceivePreference(), command_view.GetTxPhys(),
+ command_view.GetRxPhys(), command_view.GetPhyOptions());
send_event_(bluetooth::hci::LeSetPhyStatusBuilder::Create(
status, kNumCommandPackets));
}
diff --git a/tools/rootcanal/model/controller/link_layer_controller.cc b/tools/rootcanal/model/controller/link_layer_controller.cc
index d428eb5a31..00eb1b0c42 100644
--- a/tools/rootcanal/model/controller/link_layer_controller.cc
+++ b/tools/rootcanal/model/controller/link_layer_controller.cc
@@ -319,9 +319,10 @@ ErrorCode LinkLayerController::LeReadPhy(uint16_t connection_handle,
return ErrorCode::UNKNOWN_CONNECTION;
}
- // TODO(b/275970864) save the phy in the connection state.
- *tx_phy = bluetooth::hci::PhyType::LE_1M;
- *rx_phy = bluetooth::hci::PhyType::LE_1M;
+ AclConnection const& connection =
+ connections_.GetAclConnection(connection_handle);
+ *tx_phy = connection.GetTxPhy();
+ *rx_phy = connection.GetRxPhy();
return ErrorCode::SUCCESS;
}
@@ -335,7 +336,7 @@ ErrorCode LinkLayerController::LeSetDefaultPhy(
// the TX_PHYs parameter shall be ignored; otherwise at least one bit shall
// be set to 1.
if (all_phys_no_transmit_preference) {
- tx_phys = 0x1; // LE_1M_PHY by default.
+ tx_phys = supported_phys;
}
if (tx_phys == 0) {
LOG_INFO("TX_Phys does not configure any bit");
@@ -346,7 +347,7 @@ ErrorCode LinkLayerController::LeSetDefaultPhy(
// the RX_PHYs parameter shall be ignored; otherwise at least one bit shall
// be set to 1.
if (all_phys_no_receive_preference) {
- rx_phys = 0x1; // LE_1M_PHY by default.
+ rx_phys = supported_phys;
}
if (rx_phys == 0) {
LOG_INFO("RX_Phys does not configure any bit");
@@ -366,7 +367,8 @@ ErrorCode LinkLayerController::LeSetDefaultPhy(
return ErrorCode::UNSUPPORTED_FEATURE_OR_PARAMETER_VALUE;
}
- // TODO(b/275970864) save the phy default preference.
+ default_tx_phys_ = tx_phys;
+ default_rx_phys_ = rx_phys;
return ErrorCode::SUCCESS;
}
@@ -374,7 +376,7 @@ ErrorCode LinkLayerController::LeSetDefaultPhy(
ErrorCode LinkLayerController::LeSetPhy(
uint16_t connection_handle, bool all_phys_no_transmit_preference,
bool all_phys_no_receive_preference, uint8_t tx_phys, uint8_t rx_phys,
- bluetooth::hci::PhyOptions phy_options) {
+ bluetooth::hci::PhyOptions /*phy_options*/) {
uint8_t supported_phys = properties_.LeSupportedPhys();
// Note: no documented status code for this case.
@@ -388,7 +390,7 @@ ErrorCode LinkLayerController::LeSetPhy(
// the TX_PHYs parameter shall be ignored; otherwise at least one bit shall
// be set to 1.
if (all_phys_no_transmit_preference) {
- tx_phys = 0x1; // LE_1M_PHY by default.
+ tx_phys = supported_phys;
}
if (tx_phys == 0) {
LOG_INFO("TX_Phys does not configure any bit");
@@ -399,7 +401,7 @@ ErrorCode LinkLayerController::LeSetPhy(
// the RX_PHYs parameter shall be ignored; otherwise at least one bit shall
// be set to 1.
if (all_phys_no_receive_preference) {
- rx_phys = 0x1; // LE_1M_PHY by default.
+ rx_phys = supported_phys;
}
if (rx_phys == 0) {
LOG_INFO("RX_Phys does not configure any bit");
@@ -422,18 +424,164 @@ ErrorCode LinkLayerController::LeSetPhy(
// The HCI_LE_PHY_Update_Complete event shall be generated either when one
// or both PHY changes or when the Controller determines that neither PHY
// will change immediately.
- // TODO(b/275970864) send LL_PHY_REQ to the peer.
- ScheduleTask(0ms, [this, connection_handle] {
- send_event_(bluetooth::hci::LePhyUpdateCompleteBuilder::Create(
- ErrorCode::SUCCESS, connection_handle,
- static_cast<uint8_t>(bluetooth::hci::PhyType::LE_1M),
- static_cast<uint8_t>(bluetooth::hci::PhyType::LE_1M)));
- });
+ SendLeLinkLayerPacket(model::packets::LlPhyReqBuilder::Create(
+ connections_.GetOwnAddress(connection_handle).GetAddress(),
+ connections_.GetAddress(connection_handle).GetAddress(), tx_phys,
+ rx_phys));
- // TODO(b/275970864) save the phy preference.
+ connections_.GetAclConnection(connection_handle).InitiatePhyUpdate();
+ requested_tx_phys_ = tx_phys;
+ requested_rx_phys_ = rx_phys;
return ErrorCode::SUCCESS;
}
+// Helper to pick one phy in enabled phys.
+static bluetooth::hci::PhyType select_phy(uint8_t phys,
+ bluetooth::hci::PhyType current) {
+ return (phys & 0x4) ? bluetooth::hci::PhyType::LE_CODED
+ : (phys & 0x2) ? bluetooth::hci::PhyType::LE_2M
+ : (phys & 0x1) ? bluetooth::hci::PhyType::LE_1M
+ : current;
+}
+
+// Helper to generate the LL_PHY_UPDATE_IND mask for the selected phy.
+// The mask is non zero only if the phy has changed.
+static uint8_t indicate_phy(bluetooth::hci::PhyType selected,
+ bluetooth::hci::PhyType current) {
+ return selected == current ? 0x0
+ : selected == bluetooth::hci::PhyType::LE_CODED ? 0x4
+ : selected == bluetooth::hci::PhyType::LE_2M ? 0x2
+ : 0x1;
+}
+
+void LinkLayerController::IncomingLlPhyReq(
+ model::packets::LinkLayerPacketView incoming) {
+ auto phy_req = model::packets::LlPhyReqView::Create(incoming);
+ ASSERT(phy_req.IsValid());
+ uint16_t connection_handle =
+ connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
+ AclConnection& connection = connections_.GetAclConnection(connection_handle);
+
+ if (connection.GetRole() == bluetooth::hci::Role::PERIPHERAL) {
+ // Peripheral receives the request: respond with local phy preferences
+ // in LL_PHY_RSP pdu.
+ SendLeLinkLayerPacket(model::packets::LlPhyRspBuilder::Create(
+ incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
+ default_tx_phys_, default_rx_phys_));
+ } else {
+ // Central receives the request: respond with LL_PHY_UPDATE_IND and
+ // the selected phys.
+
+ // Intersect phy preferences with local preferences.
+ uint8_t tx_phys = phy_req.GetRxPhys() & default_tx_phys_;
+ uint8_t rx_phys = phy_req.GetTxPhys() & default_rx_phys_;
+
+ // Select valid TX and RX phys from preferences.
+ bluetooth::hci::PhyType phy_c_to_p =
+ select_phy(tx_phys, connection.GetTxPhy());
+ bluetooth::hci::PhyType phy_p_to_c =
+ select_phy(rx_phys, connection.GetRxPhy());
+
+ // Send LL_PHY_UPDATE_IND to notify selected phys.
+ //
+ // PHY_C_TO_P shall be set to indicate the PHY that shall be used for
+ // packets sent from the Central to the Peripheral. These fields each
+ // consist of 8 bits. If a PHY is changing, the bit corresponding to the new
+ // PHY shall be set to 1 and the remaining bits to 0; if a PHY is remaining
+ // unchanged, then the corresponding field shall be set to the value 0.
+ SendLeLinkLayerPacket(model::packets::LlPhyUpdateIndBuilder::Create(
+ incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
+ indicate_phy(phy_c_to_p, connection.GetTxPhy()),
+ indicate_phy(phy_p_to_c, connection.GetRxPhy()), 0));
+
+ // Notify the host when the phy selection has changed
+ // (responder in this case).
+ if ((phy_c_to_p != connection.GetTxPhy() ||
+ phy_p_to_c != connection.GetRxPhy()) &&
+ IsLeEventUnmasked(SubeventCode::PHY_UPDATE_COMPLETE)) {
+ send_event_(bluetooth::hci::LePhyUpdateCompleteBuilder::Create(
+ ErrorCode::SUCCESS, connection_handle, phy_c_to_p, phy_p_to_c));
+ }
+
+ // Update local state.
+ connection.SetTxPhy(phy_c_to_p);
+ connection.SetRxPhy(phy_p_to_c);
+ }
+}
+
+void LinkLayerController::IncomingLlPhyRsp(
+ model::packets::LinkLayerPacketView incoming) {
+ auto phy_rsp = model::packets::LlPhyRspView::Create(incoming);
+ ASSERT(phy_rsp.IsValid());
+ uint16_t connection_handle =
+ connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
+ AclConnection& connection = connections_.GetAclConnection(connection_handle);
+ ASSERT(connection.GetRole() == bluetooth::hci::Role::CENTRAL);
+
+ // Intersect phy preferences with local preferences.
+ uint8_t tx_phys = phy_rsp.GetRxPhys() & requested_tx_phys_;
+ uint8_t rx_phys = phy_rsp.GetTxPhys() & requested_rx_phys_;
+
+ // Select valid TX and RX phys from preferences.
+ bluetooth::hci::PhyType phy_c_to_p =
+ select_phy(tx_phys, connection.GetTxPhy());
+ bluetooth::hci::PhyType phy_p_to_c =
+ select_phy(rx_phys, connection.GetRxPhy());
+
+ // Send LL_PHY_UPDATE_IND to notify selected phys.
+ //
+ // PHY_C_TO_P shall be set to indicate the PHY that shall be used for
+ // packets sent from the Central to the Peripheral. These fields each
+ // consist of 8 bits. If a PHY is changing, the bit corresponding to the new
+ // PHY shall be set to 1 and the remaining bits to 0; if a PHY is remaining
+ // unchanged, then the corresponding field shall be set to the value 0.
+ SendLeLinkLayerPacket(model::packets::LlPhyUpdateIndBuilder::Create(
+ incoming.GetDestinationAddress(), incoming.GetSourceAddress(),
+ indicate_phy(phy_c_to_p, connection.GetTxPhy()),
+ indicate_phy(phy_p_to_c, connection.GetRxPhy()), 0));
+
+ // Always notify the host, even if the phy selection has not changed
+ // (initiator in this case).
+ if (IsLeEventUnmasked(SubeventCode::PHY_UPDATE_COMPLETE)) {
+ send_event_(bluetooth::hci::LePhyUpdateCompleteBuilder::Create(
+ ErrorCode::SUCCESS, connection_handle, phy_c_to_p, phy_p_to_c));
+ }
+
+ // Update local state.
+ connection.PhyUpdateComplete();
+ connection.SetTxPhy(phy_c_to_p);
+ connection.SetRxPhy(phy_p_to_c);
+}
+
+void LinkLayerController::IncomingLlPhyUpdateInd(
+ model::packets::LinkLayerPacketView incoming) {
+ auto phy_update_ind = model::packets::LlPhyUpdateIndView::Create(incoming);
+ ASSERT(phy_update_ind.IsValid());
+ uint16_t connection_handle =
+ connections_.GetHandleOnlyAddress(incoming.GetSourceAddress());
+ AclConnection& connection = connections_.GetAclConnection(connection_handle);
+ ASSERT(connection.GetRole() == bluetooth::hci::Role::PERIPHERAL);
+
+ bluetooth::hci::PhyType tx_phy =
+ select_phy(phy_update_ind.GetPhyPToC(), connection.GetTxPhy());
+ bluetooth::hci::PhyType rx_phy =
+ select_phy(phy_update_ind.GetPhyCToP(), connection.GetRxPhy());
+
+ // Update local state, and notify the host.
+ // The notification is sent only when the local host is initiator
+ // of the Phy update procedure or the phy selection has changed.
+ if (IsLeEventUnmasked(SubeventCode::PHY_UPDATE_COMPLETE) &&
+ (tx_phy != connection.GetTxPhy() || rx_phy != connection.GetRxPhy() ||
+ connection.InitiatedPhyUpdate())) {
+ send_event_(bluetooth::hci::LePhyUpdateCompleteBuilder::Create(
+ ErrorCode::SUCCESS, connection_handle, tx_phy, rx_phy));
+ }
+
+ connection.PhyUpdateComplete();
+ connection.SetTxPhy(tx_phy);
+ connection.SetRxPhy(rx_phy);
+}
+
// HCI LE Set Host Feature command (Vol 4, Part E ยง 7.8.115).
ErrorCode LinkLayerController::LeSetHostFeature(uint8_t bit_number,
uint8_t bit_value) {
@@ -2209,6 +2357,15 @@ void LinkLayerController::IncomingPacket(
case model::packets::PacketType::ROLE_SWITCH_RESPONSE:
IncomingRoleSwitchResponse(incoming);
break;
+ case model::packets::PacketType::LL_PHY_REQ:
+ IncomingLlPhyReq(incoming);
+ break;
+ case model::packets::PacketType::LL_PHY_RSP:
+ IncomingLlPhyRsp(incoming);
+ break;
+ case model::packets::PacketType::LL_PHY_UPDATE_IND:
+ IncomingLlPhyUpdateInd(incoming);
+ break;
default:
LOG_WARN("Dropping unhandled packet of type %s",
model::packets::PacketTypeText(incoming.GetType()).c_str());
@@ -5975,6 +6132,8 @@ void LinkLayerController::Reset() {
inquiry_mode_ = InquiryType::STANDARD;
inquiry_lap_ = 0;
inquiry_max_responses_ = 0;
+ default_tx_phys_ = properties_.LeSupportedPhys();
+ default_rx_phys_ = properties_.LeSupportedPhys();
bluetooth::hci::Lap general_iac;
general_iac.lap_ = 0x33; // 0x9E8B33
diff --git a/tools/rootcanal/model/controller/link_layer_controller.h b/tools/rootcanal/model/controller/link_layer_controller.h
index cf89e6ae14..f7300747ee 100644
--- a/tools/rootcanal/model/controller/link_layer_controller.h
+++ b/tools/rootcanal/model/controller/link_layer_controller.h
@@ -709,6 +709,10 @@ class LinkLayerController {
void IncomingRoleSwitchRequest(model::packets::LinkLayerPacketView incoming);
void IncomingRoleSwitchResponse(model::packets::LinkLayerPacketView incoming);
+ void IncomingLlPhyReq(model::packets::LinkLayerPacketView incoming);
+ void IncomingLlPhyRsp(model::packets::LinkLayerPacketView incoming);
+ void IncomingLlPhyUpdateInd(model::packets::LinkLayerPacketView incoming);
+
public:
bool IsEventUnmasked(bluetooth::hci::EventCode event) const;
bool IsLeEventUnmasked(bluetooth::hci::SubeventCode subevent) const;
@@ -991,6 +995,12 @@ class LinkLayerController {
// Extended advertising sets.
std::unordered_map<uint8_t, ExtendedAdvertiser> extended_advertisers_{};
+ // Local phy preferences, defaults to LE 1M Phy.
+ uint8_t default_tx_phys_{0x1};
+ uint8_t default_rx_phys_{0x1};
+ uint8_t requested_tx_phys_{0x1};
+ uint8_t requested_rx_phys_{0x1};
+
struct PeriodicAdvertiserListEntry {
bluetooth::hci::AdvertiserAddressType advertiser_address_type;
Address advertiser_address;
diff --git a/tools/rootcanal/packets/hci/hci_packets.pdl b/tools/rootcanal/packets/hci/hci_packets.pdl
index f4c9766c0e..2eb4e5ea5a 100644
--- a/tools/rootcanal/packets/hci/hci_packets.pdl
+++ b/tools/rootcanal/packets/hci/hci_packets.pdl
@@ -3718,9 +3718,9 @@ packet LeSetDefaultPhy : Command (op_code = LE_SET_DEFAULT_PHY) {
all_phys_no_transmit_preference : 1,
all_phys_no_receive_preference : 1,
_reserved_ : 6,
- tx_phys_bitmask : 3,
+ tx_phys : 3,
_reserved_ : 5,
- rx_phys_bitmask : 3,
+ rx_phys : 3,
_reserved_ : 5,
}
@@ -3740,9 +3740,9 @@ packet LeSetPhy : Command (op_code = LE_SET_PHY) {
all_phys_no_transmit_preference : 1,
all_phys_no_receive_preference : 1,
_reserved_ : 6,
- tx_phys_bitmask : 3,
+ tx_phys : 3,
_reserved_ : 5,
- rx_phys_bitmask : 3,
+ rx_phys : 3,
_reserved_ : 5,
phy_options : PhyOptions,
}
@@ -5871,8 +5871,8 @@ packet LePhyUpdateComplete : LeMetaEvent (subevent_code = PHY_UPDATE_COMPLETE) {
status : ErrorCode,
connection_handle : 12,
_reserved_ : 4,
- tx_phy : 8,
- rx_phy : 8,
+ tx_phy : PhyType,
+ rx_phy : PhyType,
}
enum DataStatus : 2 {
diff --git a/tools/rootcanal/packets/link_layer_packets.pdl b/tools/rootcanal/packets/link_layer_packets.pdl
index f168de24c0..3a92e39f08 100644
--- a/tools/rootcanal/packets/link_layer_packets.pdl
+++ b/tools/rootcanal/packets/link_layer_packets.pdl
@@ -52,6 +52,10 @@ enum PacketType : 8 {
PING_RESPONSE = 0x36,
ROLE_SWITCH_REQUEST = 0x38,
ROLE_SWITCH_RESPONSE = 0x39,
+
+ LL_PHY_REQ = 0x50,
+ LL_PHY_RSP = 0x51,
+ LL_PHY_UPDATE_IND = 0x52,
}
packet LinkLayerPacket {
@@ -404,3 +408,19 @@ packet RoleSwitchResponse : LinkLayerPacket (type = ROLE_SWITCH_RESPONSE) {
status: 8,
initiator_new_role: 8,
}
+
+packet LlPhyReq : LinkLayerPacket (type = LL_PHY_REQ) {
+ tx_phys: 8,
+ rx_phys: 8,
+}
+
+packet LlPhyRsp : LinkLayerPacket (type = LL_PHY_RSP) {
+ tx_phys: 8,
+ rx_phys: 8,
+}
+
+packet LlPhyUpdateInd : LinkLayerPacket (type = LL_PHY_UPDATE_IND) {
+ phy_c_to_p: 8,
+ phy_p_to_c: 8,
+ instant: 16,
+}