diff --git a/subsys/bluetooth/controller/ll_sw/ull_conn.c b/subsys/bluetooth/controller/ll_sw/ull_conn.c index 60c8b324e0a..861efa5ba32 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_conn.c +++ b/subsys/bluetooth/controller/ll_sw/ull_conn.c @@ -70,18 +70,6 @@ #include "common/log.h" #include "hal/debug.h" -/** - * User CPR Interval - */ -#if !defined(CONFIG_BT_CTLR_USER_CPR_INTERVAL_MIN) -/* Bluetooth defined CPR Interval Minimum (7.5ms) */ -#define CONN_INTERVAL_MIN(x) (6) -#else /* CONFIG_BT_CTLR_USER_CPR_INTERVAL_MIN */ -/* Proprietary user defined CPR Interval Minimum */ -extern uint16_t ull_conn_interval_min_get(struct ll_conn *conn); -#define CONN_INTERVAL_MIN(x) (MAX(ull_conn_interval_min_get(x), 1)) -#endif /* CONFIG_BT_CTLR_USER_CPR_INTERVAL_MIN */ - static int init_reset(void); #if !defined(CONFIG_BT_CTLR_LOW_LAT_ULL) static void tx_demux_sched(struct ll_conn *conn); diff --git a/subsys/bluetooth/controller/ll_sw/ull_internal.h b/subsys/bluetooth/controller/ll_sw/ull_internal.h index 7f1ed3cdd06..5acd6135cbb 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_internal.h +++ b/subsys/bluetooth/controller/ll_sw/ull_internal.h @@ -4,6 +4,18 @@ * SPDX-License-Identifier: Apache-2.0 */ +/** + * User CPR Interval + */ +#if !defined(CONFIG_BT_CTLR_USER_CPR_INTERVAL_MIN) +/* Bluetooth defined CPR Interval Minimum (7.5ms) */ +#define CONN_INTERVAL_MIN(x) (6) +#else /* CONFIG_BT_CTLR_USER_CPR_INTERVAL_MIN */ +/* Proprietary user defined CPR Interval Minimum */ +extern uint16_t ull_conn_interval_min_get(struct ll_conn *conn); +#define CONN_INTERVAL_MIN(x) (MAX(ull_conn_interval_min_get(x), 1)) +#endif /* CONFIG_BT_CTLR_USER_CPR_INTERVAL_MIN */ + /* Macro to convert time in us to connection interval units */ #define RADIO_CONN_EVENTS(x, y) ((uint16_t)(((x) + (y) - 1) / (y))) diff --git a/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c b/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c index 3ec285bafd4..0ef65fe9738 100644 --- a/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c +++ b/subsys/bluetooth/controller/ll_sw/ull_llcp_conn_upd.c @@ -42,10 +42,25 @@ #include "hal/debug.h" /* Hardcoded instant delta +6 */ -#define CONN_UPDATE_INSTANT_DELTA 6U +#define CONN_UPDATE_INSTANT_DELTA 6U -/* TODO: Known, missing items (missing implementation): - * LL/CON/MAS/BV-34-C [Accepting Connection Parameter Request ? event masked] +/* CPR parameter ranges */ +#define CONN_UPDATE_TIMEOUT_100MS 10U +#define CONN_UPDATE_TIMEOUT_32SEC 3200U +#define CONN_UPDATE_LATENCY_MAX 499U +#define CONN_UPDATE_CONN_INTV_4SEC 3200U + +/* + * TODO - Known, missing items (missing implementation): + * + * If DLE procedure supported: + * and current PHY is Coded PHY: + * ... (5.3.6.B.5.1.1) the new connection interval shall be at least connIntervalCodedMin us. + * ... (5.3.6.B.5.1.7.4) packet tx time restrictions should be in effect + * + * Inter-connection mutual exclusion on CPR + * + * LL/CON/MAS/BV-34-C [Accepting Connection Parameter Request w. event masked] */ /* LLCP Local Procedure Connection Update FSM states */ @@ -55,6 +70,7 @@ enum { LP_CU_STATE_WAIT_RX_CONN_PARAM_RSP, LP_CU_STATE_WAIT_TX_CONN_UPDATE_IND, LP_CU_STATE_WAIT_RX_CONN_UPDATE_IND, + LP_CU_STATE_WAIT_TX_REJECT_EXT_IND, LP_CU_STATE_WAIT_INSTANT, LP_CU_STATE_WAIT_NTF, }; @@ -139,6 +155,29 @@ static void cu_update_conn_parameters(struct ll_conn *conn, struct proc_ctx *ctx ctx->data.cu.instant); } +#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) +static bool cu_check_conn_parameters(struct ll_conn *conn, struct proc_ctx *ctx) +{ + const uint16_t interval_min = ctx->data.cu.interval_min; + const uint16_t interval_max = ctx->data.cu.interval_max; /* unit conn events (ie 1.25ms) */ + const uint16_t timeout = ctx->data.cu.timeout; /* unit 10ms */ + const uint16_t latency = ctx->data.cu.latency; + const uint16_t preferred_periodicity = ctx->data.cu.preferred_periodicity; + + /* Invalid parameters */ + const bool invalid = ((interval_min < CONN_INTERVAL_MIN(conn)) || + (interval_max > CONN_UPDATE_CONN_INTV_4SEC) || + (interval_min > interval_max) || + (latency > CONN_UPDATE_LATENCY_MAX) || + (timeout < CONN_UPDATE_TIMEOUT_100MS) || (timeout > CONN_UPDATE_TIMEOUT_32SEC) || + ((timeout * 4U) <= /* *4U re. conn events is equivalent to *2U re. ms */ + ((latency + 1) * interval_max)) || + (preferred_periodicity > interval_max)); + + return !invalid; +} +#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */ + static bool cu_should_notify_host(struct proc_ctx *ctx) { return (((ctx->proc == PROC_CONN_PARAM_REQ) && (ctx->data.cu.error != 0U)) || @@ -162,6 +201,10 @@ static void lp_cu_tx(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t opcode) case PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ: llcp_pdu_encode_conn_param_req(ctx, pdu); break; + case PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND: + llcp_pdu_encode_reject_ext_ind(pdu, PDU_DATA_LLCTRL_TYPE_CONN_PARAM_RSP, + ctx->data.cu.error); + break; #endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */ #if defined(CONFIG_BT_CENTRAL) case PDU_DATA_LLCTRL_TYPE_CONN_UPDATE_IND: @@ -214,6 +257,19 @@ static void lp_cu_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t e } #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) +static void lp_cu_send_reject_ext_ind(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, + void *param) +{ + if (ctx->pause || !llcp_tx_alloc_peek(conn, ctx)) { + ctx->state = LP_CU_STATE_WAIT_TX_REJECT_EXT_IND; + } else { + llcp_rr_set_incompat(conn, INCOMPAT_NO_COLLISION); + lp_cu_tx(conn, ctx, PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND); + llcp_lr_complete(conn); + ctx->state = LP_CU_STATE_IDLE; + } +} + static void lp_cu_send_conn_param_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param) { @@ -304,6 +360,20 @@ static void lp_cu_st_idle(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t ev } #if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) +static void lp_cu_st_wait_tx_reject_ext_ind(struct ll_conn *conn, struct proc_ctx *ctx, + uint8_t evt, void *param) +{ + switch (evt) { + case LP_CU_EVT_RUN: + lp_cu_send_reject_ext_ind(conn, ctx, evt, param); + break; + default: + /* Ignore other evts */ + break; + } +} + + static void lp_cu_st_wait_tx_conn_param_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param) { @@ -327,7 +397,14 @@ static void lp_cu_st_wait_rx_conn_param_rsp(struct ll_conn *conn, struct proc_ct switch (evt) { case LP_CU_EVT_CONN_PARAM_RSP: + llcp_pdu_decode_conn_param_rsp(ctx, param); llcp_rr_set_incompat(conn, INCOMPAT_RESERVED); + /* Perform Param check and possibly reject (LL_REJECT_EXT_IND) */ + if (!cu_check_conn_parameters(conn, ctx)) { + ctx->data.cu.error = BT_HCI_ERR_INVALID_LL_PARAM; + lp_cu_send_reject_ext_ind(conn, ctx, evt, param); + break; + } lp_cu_send_conn_update_ind(conn, ctx, evt, param); break; case LP_CU_EVT_UNKNOWN: @@ -407,10 +484,10 @@ static void lp_cu_check_instant(struct ll_conn *conn, struct proc_ctx *ctx, uint /* Procedure is complete when the instant has passed, and the * new connection event parameters have been applied. */ + llcp_rr_set_incompat(conn, INCOMPAT_NO_COLLISION); cu_update_conn_parameters(conn, ctx); notify = cu_should_notify_host(ctx); if (notify) { - llcp_rr_set_incompat(conn, INCOMPAT_NO_COLLISION); ctx->data.cu.error = BT_HCI_ERR_SUCCESS; lp_cu_complete(conn, ctx, evt, param); } else { @@ -471,6 +548,11 @@ static void lp_cu_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8_ lp_cu_st_wait_rx_conn_update_ind(conn, ctx, evt, param); break; #endif /* CONFIG_BT_PERIPHERAL */ +#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ) + case LP_CU_STATE_WAIT_TX_REJECT_EXT_IND: + lp_cu_st_wait_tx_reject_ext_ind(conn, ctx, evt, param); + break; +#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */ case LP_CU_STATE_WAIT_INSTANT: lp_cu_st_wait_instant(conn, ctx, evt, param); break; @@ -719,7 +801,14 @@ static void rp_cu_st_wait_rx_conn_param_req(struct ll_conn *conn, struct proc_ct case RP_CU_EVT_CONN_PARAM_REQ: llcp_pdu_decode_conn_param_req(ctx, param); - bool params_changed = + /* Perform Param check and reject if invalid (LL_REJECT_EXT_IND) */ + if (!cu_check_conn_parameters(conn, ctx)) { + ctx->data.cu.error = BT_HCI_ERR_INVALID_LL_PARAM; + rp_cu_send_reject_ext_ind(conn, ctx, evt, param); + break; + } + + const bool params_changed = cu_have_params_changed(conn, ctx->data.cu.interval_max, ctx->data.cu.latency, ctx->data.cu.timeout); diff --git a/tests/bluetooth/controller/ctrl_conn_update/src/main.c b/tests/bluetooth/controller/ctrl_conn_update/src/main.c index 5945cf9efd3..6990e6bf255 100644 --- a/tests/bluetooth/controller/ctrl_conn_update/src/main.c +++ b/tests/bluetooth/controller/ctrl_conn_update/src/main.c @@ -80,6 +80,32 @@ struct pdu_data_llctrl_conn_param_rsp conn_param_rsp = { .interval_min = INTVL_M .offset4 = 0xffffU, .offset5 = 0xffffU }; +/* Invalid conn_param_req PDU */ +struct pdu_data_llctrl_conn_param_req conn_param_req_invalid = { .interval_min = INTVL_MIN - 1, + .interval_max = INTVL_MAX + 1, + .latency = LATENCY, + .timeout = TIMEOUT - 1, + .preferred_periodicity = 0U, + .reference_conn_event_count = 0u, + .offset0 = 0x0000U, + .offset1 = 0xffffU, + .offset2 = 0xffffU, + .offset3 = 0xffffU, + .offset4 = 0xffffU, + .offset5 = 0xffffU }; +/* Invalid conn_param_rsp PDU */ +struct pdu_data_llctrl_conn_param_rsp conn_param_rsp_invalid = { .interval_min = INTVL_MIN - 1, + .interval_max = INTVL_MAX + 1, + .latency = LATENCY, + .timeout = TIMEOUT - 1, + .preferred_periodicity = 0U, + .reference_conn_event_count = 0u, + .offset0 = 0x0000U, + .offset1 = 0xffffU, + .offset2 = 0xffffU, + .offset3 = 0xffffU, + .offset4 = 0xffffU, + .offset5 = 0xffffU }; /* Different PDU contents for (B) */ /* Default conn_param_req PDU (B) */ @@ -169,7 +195,7 @@ static bool is_instant_reached(struct ll_conn *conn, uint16_t instant) * Central requests change in LE connection parameters, peripheral’s Host accepts. * * +-----+ +-------+ +-----+ - * | UT | | LL_M | | LT | + * | UT | | LL_C | | LT | * +-----+ +-------+ +-----+ * | | | * | LE Connection Update | | @@ -278,12 +304,85 @@ void test_conn_update_central_loc_accept(void) "Free CTX buffers %d", ctx_buffers_free()); } +/* + * Central-initiated Connection Parameters Request procedure. + * Central requests change in LE connection parameters, peripheral + * responds with invalid params + * + * +-----+ +-------+ +-----+ + * | UT | | LL_C | | LT | + * +-----+ +-------+ +-----+ + * | | | + * | LE Connection Update | | + * |-------------------------->| | + * | | LL_CONNECTION_PARAM_REQ | + * | |-------------------------->| + * | | | + * | | LL_CONNECTION_PARAM_RSP | + * | |<--------------------------| + * | | | + * | | LL_REJECT_EXT_IND | + * | |-------------------------->| + * | | | + * | | | + * | | | + */ +void test_conn_update_central_loc_invalid_param_rsp(void) +{ + uint8_t err; + struct node_tx *tx; + struct pdu_data_llctrl_reject_ext_ind reject_ext_ind = { + .reject_opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_RSP, + .error_code = BT_HCI_ERR_INVALID_LL_PARAM + }; + + + /* Role */ + test_set_role(&conn, BT_HCI_ROLE_CENTRAL); + + /* Connect */ + ull_cp_state_set(&conn, ULL_CP_CONNECTED); + + /* Initiate a Connection Parameter Request Procedure */ + err = ull_cp_conn_update(&conn, INTVL_MIN, INTVL_MAX, LATENCY, TIMEOUT); + zassert_equal(err, BT_HCI_ERR_SUCCESS, NULL); + + /* Prepare */ + event_prepare(&conn); + + /* Tx Queue should have one LL Control PDU */ + lt_rx(LL_CONNECTION_PARAM_REQ, &conn, &tx, &conn_param_req); + lt_rx_q_is_empty(&conn); + + /* Rx */ + lt_tx(LL_CONNECTION_PARAM_RSP, &conn, &conn_param_rsp_invalid); + + /* Done */ + event_done(&conn); + + /* Release Tx */ + ull_cp_release_tx(&conn, tx); + + /* Prepare */ + event_prepare(&conn); + + /* Tx Queue should have one LL Control PDU */ + lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &reject_ext_ind); + lt_rx_q_is_empty(&conn); + + /* Done */ + event_done(&conn); + + zassert_equal(ctx_buffers_free(), test_ctx_buffers_cnt(), + "Free CTX buffers %d", ctx_buffers_free()); +} + /* * Central-initiated Connection Parameters Request procedure. * Central requests change in LE connection parameters, peripheral’s Host rejects. * * +-----+ +-------+ +-----+ - * | UT | | LL_M | | LT | + * | UT | | LL_C | | LT | * +-----+ +-------+ +-----+ * | | | * | LE Connection Update | | @@ -353,7 +452,7 @@ void test_conn_update_central_loc_reject(void) * Central requests change in LE connection parameters, peripheral’s Host is legacy. * * +-----+ +-------+ +-----+ - * | UT | | LL_M | | LT | + * | UT | | LL_C | | LT | * +-----+ +-------+ +-----+ * | | | * | LE Connection Update | | @@ -477,7 +576,7 @@ void test_conn_update_central_loc_remote_legacy(void) * support Connection Parameters Request procedure, features not exchanged. * * +-----+ +-------+ +-----+ - * | UT | | LL_M | | LT | + * | UT | | LL_C | | LT | * +-----+ +-------+ +-----+ * | | | * | LE Connection Update | | @@ -600,7 +699,7 @@ void test_conn_update_central_loc_unsupp_wo_feat_exch(void) * support Connection Parameters Request procedure, features exchanged. * * +-----+ +-------+ +-----+ - * | UT | | LL_M | | LT | + * | UT | | LL_C | | LT | * +-----+ +-------+ +-----+ * | | | * | LE Connection Update | | @@ -705,7 +804,7 @@ void test_conn_update_central_loc_unsupp_w_feat_exch(void) * Procedure collides and is rejected. * * +-----+ +-------+ +-----+ - * | UT | | LL_M | | LT | + * | UT | | LL_C | | LT | * +-----+ +-------+ +-----+ * | | | * | LE Connection Update | | @@ -863,7 +962,7 @@ void test_conn_update_central_loc_collision(void) * Peripheral requests change in LE connection parameters, central’s Host accepts. * * +-----+ +-------+ +-----+ - * | UT | | LL_M | | LT | + * | UT | | LL_C | | LT | * +-----+ +-------+ +-----+ * | | | * | | LL_CONNECTION_PARAM_REQ | @@ -978,12 +1077,69 @@ void test_conn_update_central_rem_accept(void) "Free CTX buffers %d", ctx_buffers_free()); } +/* + * Peripheral-initiated Connection Parameters Request procedure. + * Peripheral requests change in LE connection with invalid parameters, + * + * +-----+ +-------+ +-----+ + * | UT | | LL_C | | LT | + * +-----+ +-------+ +-----+ + * | | | + * | | LL_CONNECTION_PARAM_REQ | + * | |<--------------------------| + * | | | + * | | | + * | | LL_REJECT_EXT_IND | + * | |-------------------------->| + * | | | + * | | | + */ +void test_conn_update_central_rem_invalid_req(void) +{ + struct node_tx *tx; + struct pdu_data_llctrl_reject_ext_ind reject_ext_ind = { + .reject_opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ, + .error_code = BT_HCI_ERR_INVALID_LL_PARAM + }; + + /* Role */ + test_set_role(&conn, BT_HCI_ROLE_CENTRAL); + + /* Connect */ + ull_cp_state_set(&conn, ULL_CP_CONNECTED); + + /* Prepare */ + event_prepare(&conn); + + /* Rx */ + lt_tx(LL_CONNECTION_PARAM_REQ, &conn, &conn_param_req_invalid); + + /* Done */ + event_done(&conn); + + /* Prepare */ + event_prepare(&conn); + + /* Tx Queue should have one LL Control PDU */ + lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &reject_ext_ind); + lt_rx_q_is_empty(&conn); + + /* Done */ + event_done(&conn); + + /* Release Tx */ + ull_cp_release_tx(&conn, tx); + zassert_equal(ctx_buffers_free(), test_ctx_buffers_cnt(), + "Free CTX buffers %d", ctx_buffers_free()); + +} + /* * Peripheral-initiated Connection Parameters Request procedure. * Peripheral requests change in LE connection parameters, central’s Host rejects. * * +-----+ +-------+ +-----+ - * | UT | | LL_M | | LT | + * | UT | | LL_C | | LT | * +-----+ +-------+ +-----+ * | | | * | | LL_CONNECTION_PARAM_REQ | @@ -1060,7 +1216,7 @@ void test_conn_update_central_rem_reject(void) * support Connection Parameters Request procedure. * * +-----+ +-------+ +-----+ - * | UT | | LL_M | | LT | + * | UT | | LL_C | | LT | * +-----+ +-------+ +-----+ * | | | * | | LL_CONNECTION_PARAM_REQ | @@ -1094,7 +1250,7 @@ void test_conn_update_central_rem_unsupp_feat(void) * Central-initiated Connection Parameters Request procedure is resumed. * * +-----+ +-------+ +-----+ - * | UT | | LL_M | | LT | + * | UT | | LL_C | | LT | * +-----+ +-------+ +-----+ * | | | * | | LL_CONNECTION_PARAM_REQ | @@ -1323,7 +1479,7 @@ void test_conn_update_central_rem_collision(void) * Peripheral requests change in LE connection parameters, central’s Host accepts. * * +-----+ +-------+ +-----+ - * | UT | | LL_S | | LT | + * | UT | | LL_P | | LT | * +-----+ +-------+ +-----+ * | | | * | LE Connection Update | | @@ -1425,7 +1581,7 @@ void test_conn_update_periph_loc_accept(void) * Peripheral requests change in LE connection parameters, central’s Host rejects. * * +-----+ +-------+ +-----+ - * | UT | | LL_S | | LT | + * | UT | | LL_P | | LT | * +-----+ +-------+ +-----+ * | | | * | LE Connection Update | | @@ -1505,7 +1661,7 @@ void test_conn_update_periph_loc_reject(void) * support Connection Parameters Request procedure, features not exchanged. * * +-----+ +-------+ +-----+ - * | UT | | LL_S | | LT | + * | UT | | LL_P | | LT | * +-----+ +-------+ +-----+ * | | | * | LE Connection Update | | @@ -1584,7 +1740,7 @@ void test_conn_update_periph_loc_unsupp_feat_wo_feat_exch(void) * support Connection Parameters Request procedure, features exchanged. * * +-----+ +-------+ +-----+ - * | UT | | LL_S | | LT | + * | UT | | LL_P | | LT | * +-----+ +-------+ +-----+ * | | | * | LE Connection Update | | @@ -1638,7 +1794,7 @@ void test_conn_update_periph_loc_unsupp_feat_w_feat_exch(void) * Central requests change in LE connection parameters, peripheral’s Host accepts. * * +-----+ +-------+ +-----+ - * | UT | | LL_S | | LT | + * | UT | | LL_P | | LT | * +-----+ +-------+ +-----+ * | | | * | LE Connection Update | | @@ -1809,7 +1965,7 @@ void test_conn_update_periph_loc_collision(void) * Central requests change in LE connection parameters, peripheral’s Host accepts. * * +-----+ +-------+ +-----+ - * | UT | | LL_S | | LT | + * | UT | | LL_P | | LT | * +-----+ +-------+ +-----+ * | | | * | | LL_CONNECTION_PARAM_REQ | @@ -1934,12 +2090,69 @@ void test_conn_update_periph_rem_accept(void) "Free CTX buffers %d", ctx_buffers_free()); } +/* + * Central-initiated Connection Parameters Request procedure. + * Central requests change in LE connection with invalid parameters, + * + * +-----+ +-------+ +-----+ + * | UT | | LL_P | | LT | + * +-----+ +-------+ +-----+ + * | | | + * | | LL_CONNECTION_PARAM_REQ | + * | |<--------------------------| + * | | | + * | | | + * | | LL_REJECT_EXT_IND | + * | |-------------------------->| + * | | | + * | | | + */ +void test_conn_update_periph_rem_invalid_req(void) +{ + struct node_tx *tx; + struct pdu_data_llctrl_reject_ext_ind reject_ext_ind = { + .reject_opcode = PDU_DATA_LLCTRL_TYPE_CONN_PARAM_REQ, + .error_code = BT_HCI_ERR_INVALID_LL_PARAM + }; + + /* Role */ + test_set_role(&conn, BT_HCI_ROLE_PERIPHERAL); + + /* Connect */ + ull_cp_state_set(&conn, ULL_CP_CONNECTED); + + /* Prepare */ + event_prepare(&conn); + + /* Rx */ + lt_tx(LL_CONNECTION_PARAM_REQ, &conn, &conn_param_req_invalid); + + /* Done */ + event_done(&conn); + + /* Prepare */ + event_prepare(&conn); + + /* Tx Queue should have one LL Control PDU */ + lt_rx(LL_REJECT_EXT_IND, &conn, &tx, &reject_ext_ind); + lt_rx_q_is_empty(&conn); + + /* Done */ + event_done(&conn); + + /* Release Tx */ + ull_cp_release_tx(&conn, tx); + zassert_equal(ctx_buffers_free(), test_ctx_buffers_cnt(), + "Free CTX buffers %d", ctx_buffers_free()); + +} + /* * Central-initiated Connection Parameters Request procedure. * Central requests change in LE connection parameters, peripheral’s Host rejects. * * +-----+ +-------+ +-----+ - * | UT | | LL_S | | LT | + * | UT | | LL_P | | LT | * +-----+ +-------+ +-----+ * | | | * | | LL_CONNECTION_PARAM_REQ | @@ -2020,7 +2233,7 @@ void test_conn_update_periph_rem_reject(void) * support Connection Parameters Request procedure. * * +-----+ +-------+ +-----+ - * | UT | | LL_S | | LT | + * | UT | | LL_P | | LT | * +-----+ +-------+ +-----+ * | | | * | | LL_CONNECTION_PARAM_REQ | @@ -2054,7 +2267,7 @@ void test_conn_update_periph_rem_unsupp_feat(void) * Peripheral-initiated Connection Parameters Request procedure is resumed. * * +-----+ +-------+ +-----+ - * | UT | | LL_S | | LT | + * | UT | | LL_P | | LT | * +-----+ +-------+ +-----+ * | | | * | | LL_CONNECTION_PARAM_REQ | @@ -2272,7 +2485,7 @@ void test_conn_update_periph_rem_collision(void) * Central requests update of LE connection. * * +-----+ +-------+ +-----+ - * | UT | | LL_M | | LT | + * | UT | | LL_C | | LT | * +-----+ +-------+ +-----+ * | | | * | LE Connection Update | | @@ -2383,7 +2596,7 @@ void test_conn_update_central_loc_accept_no_param_req(void) * Central receives Connection Update parameters. * * +-----+ +-------+ +-----+ - * | UT | | LL_M | | LT | + * | UT | | LL_C | | LT | * +-----+ +-------+ +-----+ * | | | * | | LL_CONNECTION_UPDATE_IND | @@ -2440,7 +2653,7 @@ void test_conn_update_central_rem_accept_no_param_req(void) * Peripheral receives Connection Update parameters. * * +-----+ +-------+ +-----+ - * | UT | | LL_S | | LT | + * | UT | | LL_P | | LT | * +-----+ +-------+ +-----+ * | | | * | | LL_CONNECTION_UPDATE_IND | @@ -2530,7 +2743,7 @@ void test_conn_update_periph_rem_accept_no_param_req(void) * Peripheral-initiated Connection Update procedure (not allowed). * * +-----+ +-------+ +-----+ - * | UT | | LL_S | | LT | + * | UT | | LL_P | | LT | * +-----+ +-------+ +-----+ * | | | * | LE Connection Update | | @@ -2577,6 +2790,8 @@ void test_main(void) central_loc, ztest_unit_test_setup_teardown(test_conn_update_central_loc_accept, setup, unit_test_noop), + ztest_unit_test_setup_teardown(test_conn_update_central_loc_invalid_param_rsp, + setup, unit_test_noop), ztest_unit_test_setup_teardown(test_conn_update_central_loc_reject, setup, unit_test_noop), ztest_unit_test_setup_teardown(test_conn_update_central_loc_remote_legacy, @@ -2591,6 +2806,8 @@ void test_main(void) ztest_test_suite(central_rem, ztest_unit_test_setup_teardown(test_conn_update_central_rem_accept, setup, unit_test_noop), + ztest_unit_test_setup_teardown(test_conn_update_central_rem_invalid_req, + setup, unit_test_noop), ztest_unit_test_setup_teardown(test_conn_update_central_rem_reject, setup, unit_test_noop), ztest_unit_test_setup_teardown(test_conn_update_central_rem_unsupp_feat, @@ -2614,6 +2831,8 @@ void test_main(void) ztest_test_suite(periph_rem, ztest_unit_test_setup_teardown(test_conn_update_periph_rem_accept, setup, unit_test_noop), + ztest_unit_test_setup_teardown(test_conn_update_periph_rem_invalid_req, + setup, unit_test_noop), ztest_unit_test_setup_teardown(test_conn_update_periph_rem_reject, setup, unit_test_noop), ztest_unit_test_setup_teardown(test_conn_update_periph_rem_unsupp_feat,