Bluetooth: controller: Do not use LL procedures not supported by remote

Update LLCP handling during PHY update and Data Length update to not
start the LL control procedure if the remote has already indicated that
the procedure is not supported.

This fulfills the following requirement from the BT Core Specification
(Core_v5.2, Vol 6, Part B, Section 4.6):

Except where explicitly stated elsewhere in this specification, if the
peer Link Layer has indicated either during a feature exchange procedure
or by responding with an LL_UNKNOWN_RSP PDU that it does not support a
procedure, then the Link Layer shall not use that procedure.

Re-use the connection parameter request handling for PHY and
data length update procedures.

Signed-off-by: Joakim Andersson <joakim.andersson@nordicsemi.no>
This commit is contained in:
Joakim Andersson 2020-02-26 16:14:29 +01:00 committed by Carles Cufí
commit 8514794ed3
6 changed files with 48 additions and 0 deletions

View file

@ -425,6 +425,12 @@ u32_t ll_length_req_send(u16_t handle, u16_t tx_octets, u16_t tx_time)
return BT_HCI_ERR_UNKNOWN_CONN_ID;
}
if (conn->llcp_length.disabled ||
(conn->common.fex_valid &&
!(conn->llcp_feature.features & BIT(BT_LE_FEAT_BIT_DLE)))) {
return BT_HCI_ERR_UNSUPP_REMOTE_FEATURE;
}
if (conn->llcp_length.req != conn->llcp_length.ack) {
switch (conn->llcp_length.state) {
case LLCP_LENGTH_STATE_RSP_ACK_WAIT:
@ -526,6 +532,13 @@ u8_t ll_phy_req_send(u16_t handle, u8_t tx, u8_t flags, u8_t rx)
return BT_HCI_ERR_UNKNOWN_CONN_ID;
}
if (conn->llcp_phy.disabled ||
(conn->common.fex_valid &&
!(conn->llcp_feature.features & BIT(BT_LE_FEAT_BIT_PHY_2M)) &&
!(conn->llcp_feature.features & BIT(BT_LE_FEAT_BIT_PHY_CODED)))) {
return BT_HCI_ERR_UNSUPP_REMOTE_FEATURE;
}
if ((conn->llcp_req != conn->llcp_ack) ||
(conn->llcp_phy.req != conn->llcp_phy.ack)) {
return BT_HCI_ERR_CMD_DISALLOWED;
@ -5878,6 +5891,9 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
} else if (conn->llcp_length.req != conn->llcp_length.ack) {
/* Mark length update as unsupported */
conn->llcp_length.disabled = 1U;
/* Procedure complete */
conn->llcp_length.ack = conn->llcp_length.req;
@ -5891,6 +5907,9 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
conn->llcp_phy.ack) {
struct lll_conn *lll = &conn->lll;
/* Mark phy update as unsupported */
conn->llcp_phy.disabled = 1U;
/* Procedure complete */
conn->llcp_phy.ack = conn->llcp_phy.req;
conn->llcp_phy.pause_tx = 0U;