diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 920d23d71ce..00bfe5f48a6 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -1649,6 +1649,18 @@ void ull_conn_done(struct node_rx_event_done *done) } #endif /* CONFIG_BT_CTLR_LE_PING */ +#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ) + if (conn->llcp.cte_req.req_expire != 0U) { + if (conn->llcp.cte_req.req_expire > elapsed_event) { + conn->llcp.cte_req.req_expire -= elapsed_event; + } else { + conn->llcp.cte_req.req_expire = 0U; + ull_cp_cte_req(conn, conn->llcp.cte_req.min_cte_len, + conn->llcp.cte_req.cte_type); + } + } +#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */ + #if defined(CONFIG_BT_CTLR_CONN_RSSI_EVENT) /* generate RSSI event */ if (lll->rssi_sample_count == 0U) { diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h index 115df2e9d31..dc0425f5cdb 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_conn_types.h @@ -422,6 +422,7 @@ struct llcp_struct { /* Minimum requested CTE length in 8us units */ uint8_t min_cte_len; uint16_t req_interval; + uint16_t req_expire; } cte_req; #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */ #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP) diff --git a/subsys/bluetooth/controller/ll_sw/ull_df.c b/subsys/bluetooth/controller/ll_sw/ull_df.c index 0bcf0902b77..9767cbbd55e 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_df.c +++ b/subsys/bluetooth/controller/ll_sw/ull_df.c @@ -1153,17 +1153,22 @@ uint8_t ll_df_set_conn_cte_req_enable(uint16_t handle, uint8_t enable, } if (!enable) { - /* There is no parameter validation for disable operation. */ + conn->llcp.cte_req.is_enabled = false; + conn->llcp.cte_req.req_interval = 0U; - /* TODO: Add missing implementation of disable CTE reques. - * Requires refactored LLCPs. + /* There is no verification if the command is pending. If it is already disabled + * there is no change to the state. */ + /* TODO: How handle command pending in LLL? */ + return BT_HCI_ERR_SUCCESS; } else { - if (!conn->df_rx_params.is_enabled) { + if (!conn->lll.df_rx_cfg.is_initialized) { return BT_HCI_ERR_CMD_DISALLOWED; } - /* TODO: check if CTE_REQ LLCP is active. Add when merged with refactored LLCPs */ + if (conn->llcp.cte_req.is_enabled) { + return BT_HCI_ERR_CMD_DISALLOWED; + } #if defined(CONFIG_BT_CTLR_PHY) /* Phy may be changed to CODED only if PHY update procedure is supproted. In other @@ -1200,11 +1205,14 @@ uint8_t ll_df_set_conn_cte_req_enable(uint16_t handle, uint8_t enable, BIT64(BT_LE_FEAT_BIT_ANT_SWITCH_TX_AOD))))) { return BT_HCI_ERR_UNSUPP_REMOTE_FEATURE; } + + conn->llcp.cte_req.is_enabled = true; + conn->llcp.cte_req.req_interval = cte_request_interval; + conn->llcp.cte_req.cte_type = requested_cte_type; + conn->llcp.cte_req.min_cte_len = requested_cte_length; } - /* TODO: implement disable of the CTE if PHY is changed to coded */ - - return BT_HCI_ERR_CMD_DISALLOWED; + return ull_cp_cte_req(conn, requested_cte_length, requested_cte_type); } #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */ diff --git a/subsys/bluetooth/controller/ll_sw/ull_df_types.h b/subsys/bluetooth/controller/ll_sw/ull_df_types.h index 42f669daf20..d7a38eda5a1 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_df_types.h +++ b/subsys/bluetooth/controller/ll_sw/ull_df_types.h @@ -33,7 +33,7 @@ enum df_switch_sample_support { #define SYNC_IQ_REPORT_CNT 0U #endif -#if defined(CONFIG_BT_MAX_CONN) && defined(CONFIG_BT_CTRL_DF_CONN_CTE_RX) +#if defined(CONFIG_BT_MAX_CONN) && defined(CONFIG_BT_CTLR_DF_CONN_CTE_RX) #define CONN_IQ_REPORT_CNT (CONFIG_BT_MAX_CONN * 2) #else #define CONN_IQ_REPORT_CNT 0U diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_common.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_common.c index b151a1b7b14..045c0ee24d0 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_common.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_common.c @@ -210,15 +210,9 @@ static void lp_comm_ntf_length_change(struct ll_conn *conn, struct proc_ctx *ctx #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ) static void lp_comm_ntf_cte_req(struct ll_conn *conn, struct proc_ctx *ctx, struct pdu_data *pdu) { - /* TODO (ppryga): pack IQ samples and send them to host */ - /* TODO (ppryga): procedure may be re-triggered periodically by controller itself. - * Add periodicy handling code. It should be executed after receive - * notification about end of current procedure run. - */ /* TODO (ppryga): Add handling of rejections in HCI: HCI_LE_CTE_Request_Failed. */ switch (ctx->response_opcode) { case PDU_DATA_LLCTRL_TYPE_CTE_RSP: - llcp_ntf_encode_cte_req(conn, pdu); break; case PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND: llcp_ntf_encode_reject_ext_ind(ctx, pdu); @@ -351,12 +345,22 @@ static void lp_comm_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t #endif /* CONFIG_BT_CTLR_DATA_LENGTH */ #if defined(CONFIG_BT_CTLR_DF_CONN_CTE_REQ) case PROC_CTE_REQ: - if (ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_CTE_RSP || - (ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND && - ctx->reject_ext_ind.reject_opcode == PDU_DATA_LLCTRL_TYPE_CTE_REQ)) { - lp_comm_ntf(conn, ctx); - llcp_lr_complete(conn); + if (ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_CTE_RSP) { + if (conn->llcp.cte_req.req_interval != 0U) { + conn->llcp.cte_req.req_expire = conn->llcp.cte_req.req_interval; + } else { + conn->llcp.cte_req.is_enabled = 0U; + } ctx->state = LP_COMMON_STATE_IDLE; + } else if (ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND && + ctx->reject_ext_ind.reject_opcode == PDU_DATA_LLCTRL_TYPE_CTE_REQ) { + lp_comm_ntf(conn, ctx); + conn->llcp.cte_req.is_enabled = 0U; + ctx->state = LP_COMMON_STATE_IDLE; + } + + if (ctx->state == LP_COMMON_STATE_IDLE) { + llcp_lr_complete(conn); } break; #endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */