Bluetooth: Controller: legacy: Fix conn param request to be cacheable
Fix connection parameter request procedure to be cacheable if a remote control procedure is in progress. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
5e848761c5
commit
680e29dd0e
5 changed files with 72 additions and 15 deletions
|
@ -1149,10 +1149,11 @@ uint8_t ll_adv_enable(uint8_t enable)
|
|||
#endif /* CONFIG_BT_CTLR_LE_ENC */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
|
||||
conn->llcp_conn_param.req = 0;
|
||||
conn->llcp_conn_param.ack = 0;
|
||||
conn->llcp_conn_param.disabled = 0;
|
||||
conn->periph.ticks_to_offset = 0;
|
||||
conn->llcp_conn_param.req = 0U;
|
||||
conn->llcp_conn_param.ack = 0U;
|
||||
conn->llcp_conn_param.disabled = 0U;
|
||||
conn->llcp_conn_param.cache.timeout = 0U;
|
||||
conn->periph.ticks_to_offset = 0U;
|
||||
#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
|
||||
|
|
|
@ -343,6 +343,7 @@ uint8_t ll_create_connection(uint16_t scan_interval, uint16_t scan_window,
|
|||
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
|
||||
conn->llcp_conn_param.req = 0U;
|
||||
conn->llcp_conn_param.ack = 0U;
|
||||
conn->llcp_conn_param.cache.timeout = 0U;
|
||||
conn->llcp_conn_param.disabled = 0U;
|
||||
#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
|
||||
|
||||
|
|
|
@ -139,6 +139,7 @@ static inline bool ctrl_is_unexpected(struct ll_conn *conn, uint8_t opcode);
|
|||
static inline void event_conn_param_prep(struct ll_conn *conn,
|
||||
uint16_t event_counter,
|
||||
uint32_t ticks_at_expire);
|
||||
static void cpr_cache_initiate_or_complete(struct ll_conn *conn);
|
||||
#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_LE_PING)
|
||||
|
@ -451,9 +452,23 @@ uint8_t ll_conn_update(uint16_t handle, uint8_t cmd, uint8_t status, uint16_t in
|
|||
} else {
|
||||
if (conn->llcp_conn_param.req !=
|
||||
conn->llcp_conn_param.ack) {
|
||||
if (!conn->llcp_conn_param.remote ||
|
||||
conn->llcp_conn_param.cache.timeout) {
|
||||
return BT_HCI_ERR_CMD_DISALLOWED;
|
||||
}
|
||||
|
||||
conn->llcp_conn_param.cache.interval_min =
|
||||
interval_min;
|
||||
conn->llcp_conn_param.cache.interval_max =
|
||||
interval_max;
|
||||
conn->llcp_conn_param.cache.latency =
|
||||
latency;
|
||||
conn->llcp_conn_param.cache.timeout =
|
||||
timeout;
|
||||
|
||||
return BT_HCI_ERR_SUCCESS;
|
||||
}
|
||||
|
||||
conn->llcp_conn_param.status = 0U;
|
||||
conn->llcp_conn_param.interval_min = interval_min;
|
||||
conn->llcp_conn_param.interval_max = interval_max;
|
||||
|
@ -461,6 +476,7 @@ uint8_t ll_conn_update(uint16_t handle, uint8_t cmd, uint8_t status, uint16_t in
|
|||
conn->llcp_conn_param.timeout = timeout;
|
||||
conn->llcp_conn_param.state = cmd;
|
||||
conn->llcp_conn_param.cmd = 1U;
|
||||
conn->llcp_conn_param.remote = 0U;
|
||||
conn->llcp_conn_param.req++;
|
||||
|
||||
if (IS_ENABLED(CONFIG_BT_PERIPHERAL) &&
|
||||
|
@ -3272,7 +3288,9 @@ static inline int event_conn_upd_prep(struct ll_conn *conn, uint16_t lazy,
|
|||
/* procedure request acked */
|
||||
conn->llcp_ack = conn->llcp_req;
|
||||
conn->llcp_cu.ack = conn->llcp_cu.req;
|
||||
conn->llcp_conn_param.ack = conn->llcp_conn_param.req;
|
||||
|
||||
/* Check and initiate new CPR from cache, if any */
|
||||
cpr_cache_initiate_or_complete(conn);
|
||||
|
||||
/* Reset CPR mutex */
|
||||
cpr_active_reset();
|
||||
|
@ -3396,7 +3414,8 @@ static inline int event_conn_upd_prep(struct ll_conn *conn, uint16_t lazy,
|
|||
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
|
||||
if ((conn->llcp_conn_param.req != conn->llcp_conn_param.ack) &&
|
||||
(conn->llcp_conn_param.state == LLCP_CPR_STATE_UPD)) {
|
||||
conn->llcp_conn_param.ack = conn->llcp_conn_param.req;
|
||||
/* Check and initiate new CPR from cache, if any */
|
||||
cpr_cache_initiate_or_complete(conn);
|
||||
|
||||
/* Stop procedure timeout */
|
||||
conn->procedure_expire = 0U;
|
||||
|
@ -4182,8 +4201,8 @@ static inline void event_conn_param_rsp(struct ll_conn *conn)
|
|||
|
||||
ctrl_tx_enqueue(conn, tx);
|
||||
|
||||
/* procedure request acked */
|
||||
conn->llcp_conn_param.ack = conn->llcp_conn_param.req;
|
||||
/* Check and initiate new CPR from cache, if any */
|
||||
cpr_cache_initiate_or_complete(conn);
|
||||
|
||||
/* Reset CPR mutex */
|
||||
cpr_active_reset();
|
||||
|
@ -5117,7 +5136,8 @@ static uint8_t conn_upd_recv(struct ll_conn *conn, memq_link_t *link,
|
|||
if ((conn->llcp_conn_param.req != conn->llcp_conn_param.ack) &&
|
||||
((conn->llcp_conn_param.state == LLCP_CPR_STATE_RSP_WAIT) ||
|
||||
(conn->llcp_conn_param.state == LLCP_CPR_STATE_UPD_WAIT))) {
|
||||
conn->llcp_conn_param.ack = conn->llcp_conn_param.req;
|
||||
/* Check and initiate new CPR from cache, if any */
|
||||
cpr_cache_initiate_or_complete(conn);
|
||||
}
|
||||
#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
|
||||
|
||||
|
@ -5661,8 +5681,8 @@ static inline int reject_ind_conn_upd_recv(struct ll_conn *conn,
|
|||
/* Reset CPR mutex */
|
||||
cpr_active_reset();
|
||||
|
||||
/* Procedure complete */
|
||||
conn->llcp_conn_param.ack = conn->llcp_conn_param.req;
|
||||
/* Check and initiate new CPR from cache, if any */
|
||||
cpr_cache_initiate_or_complete(conn);
|
||||
|
||||
/* Stop procedure timeout */
|
||||
conn->procedure_expire = 0U;
|
||||
|
@ -5691,6 +5711,30 @@ static inline int reject_ind_conn_upd_recv(struct ll_conn *conn,
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cpr_cache_initiate_or_complete(struct ll_conn *conn)
|
||||
{
|
||||
if (conn->llcp_conn_param.cache.timeout) {
|
||||
conn->llcp_conn_param.status = 0U;
|
||||
conn->llcp_conn_param.interval_min =
|
||||
conn->llcp_conn_param.cache.interval_min;
|
||||
conn->llcp_conn_param.interval_max =
|
||||
conn->llcp_conn_param.cache.interval_max;
|
||||
conn->llcp_conn_param.latency =
|
||||
conn->llcp_conn_param.cache.latency;
|
||||
conn->llcp_conn_param.timeout =
|
||||
conn->llcp_conn_param.cache.timeout;
|
||||
conn->llcp_conn_param.state = LLCP_CPR_STATE_REQ;
|
||||
conn->llcp_conn_param.cmd = 1U;
|
||||
conn->llcp_conn_param.remote = 0U;
|
||||
|
||||
/* Invalidate cache */
|
||||
conn->llcp_conn_param.cache.timeout = 0U;
|
||||
} else {
|
||||
conn->llcp_conn_param.ack = conn->llcp_conn_param.req;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
|
||||
|
@ -7343,6 +7387,8 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
|
|||
NODE_RX_TYPE_RELEASE;
|
||||
}
|
||||
|
||||
conn->llcp_conn_param.remote = 1U;
|
||||
|
||||
conn->llcp_conn_param.ack--;
|
||||
|
||||
/* Set CPR mutex */
|
||||
|
@ -7424,6 +7470,8 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
|
|||
(*rx)->hdr.type = NODE_RX_TYPE_RELEASE;
|
||||
}
|
||||
|
||||
conn->llcp_conn_param.remote = 1U;
|
||||
|
||||
conn->llcp_conn_param.ack--;
|
||||
|
||||
/* Set CPR mutex */
|
||||
|
@ -7593,8 +7641,8 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
|
|||
/* Reset CPR mutex */
|
||||
cpr_active_reset();
|
||||
|
||||
/* Procedure complete */
|
||||
conn->llcp_conn_param.ack = conn->llcp_conn_param.req;
|
||||
/* Check and initiate new CPR from cache, if any */
|
||||
cpr_cache_initiate_or_complete(conn);
|
||||
|
||||
/* skip event generation if not cmd initiated */
|
||||
if (!conn->llcp_conn_param.cmd) {
|
||||
|
|
|
@ -243,12 +243,19 @@ struct ll_conn {
|
|||
LLCP_CPR_STATE_OFFS_RDY,
|
||||
} state:4 __packed;
|
||||
uint8_t cmd:1;
|
||||
uint8_t remote:1;
|
||||
uint8_t disabled:1;
|
||||
uint8_t status;
|
||||
uint16_t interval_min;
|
||||
uint16_t interval_max;
|
||||
uint16_t latency;
|
||||
uint16_t timeout;
|
||||
struct {
|
||||
uint16_t interval_min;
|
||||
uint16_t interval_max;
|
||||
uint16_t latency;
|
||||
uint16_t timeout;
|
||||
} cache;
|
||||
uint8_t preferred_periodicity;
|
||||
uint16_t reference_conn_event_count;
|
||||
uint16_t offset0;
|
||||
|
|
|
@ -35,7 +35,7 @@ LL/CON/CEN/BV-21-C
|
|||
LL/CON/CEN/BV-23-C
|
||||
LL/CON/CEN/BV-24-C
|
||||
LL/CON/CEN/BV-25-C
|
||||
LL/CON/CEN/BV-26-C
|
||||
#LL/CON/CEN/BV-26-C # This test case is not valid, and will fail with CPR cache
|
||||
LL/CON/CEN/BV-27-C
|
||||
LL/CON/CEN/BV-29-C
|
||||
LL/CON/CEN/BV-30-C
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue