Bluetooth: controller: refactor to remove duplicated functionality

Duplicated functionality used for tx handling is moved to local proxy
functions to avoid code overhead

Signed-off-by: Erik Brockhoff <erbr@oticon.com>
This commit is contained in:
Erik Brockhoff 2022-11-16 13:54:49 +01:00 committed by Carles Cufí
parent edef6f3b46
commit 7c9d792211
2 changed files with 67 additions and 103 deletions

View file

@ -293,6 +293,7 @@ static struct proc_ctx *create_procedure(enum llcp_proc proc, struct llcp_mem_po
ctx->collision = 0U;
ctx->done = 0U;
ctx->rx_greedy = 0U;
ctx->tx_ack = NULL;
/* Clear procedure data */
memset((void *)&ctx->data, 0, sizeof(ctx->data));

View file

@ -424,6 +424,23 @@ static void lp_comm_terminate_invalid_pdu(struct ll_conn *conn, struct proc_ctx
ctx->state = LP_COMMON_STATE_IDLE;
}
static void lp_comm_ntf_complete_proxy(struct ll_conn *conn, struct proc_ctx *ctx,
const bool valid_pdu)
{
if (valid_pdu) {
if (!llcp_ntf_alloc_is_available()) {
ctx->state = LP_COMMON_STATE_WAIT_NTF;
} else {
lp_comm_ntf(conn, ctx);
llcp_lr_complete(conn);
ctx->state = LP_COMMON_STATE_IDLE;
}
} else {
/* Illegal response opcode */
lp_comm_terminate_invalid_pdu(conn, ctx);
}
}
static void lp_comm_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param)
{
switch (ctx->proc) {
@ -440,19 +457,9 @@ static void lp_comm_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t
break;
#endif /* CONFIG_BT_CTLR_LE_PING */
case PROC_FEATURE_EXCHANGE:
if (ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_UNKNOWN_RSP ||
ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_FEATURE_RSP) {
if (!llcp_ntf_alloc_is_available()) {
ctx->state = LP_COMMON_STATE_WAIT_NTF;
} else {
lp_comm_ntf(conn, ctx);
llcp_lr_complete(conn);
ctx->state = LP_COMMON_STATE_IDLE;
}
} else {
/* Illegal response opcode */
lp_comm_terminate_invalid_pdu(conn, ctx);
}
lp_comm_ntf_complete_proxy(conn, ctx,
(ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_UNKNOWN_RSP ||
ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_FEATURE_RSP));
break;
#if defined(CONFIG_BT_CTLR_MIN_USED_CHAN) && defined(CONFIG_BT_PERIPHERAL)
case PROC_MIN_USED_CHANS:
@ -461,18 +468,8 @@ static void lp_comm_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t
break;
#endif /* CONFIG_BT_CTLR_MIN_USED_CHAN && CONFIG_BT_PERIPHERAL */
case PROC_VERSION_EXCHANGE:
if (ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_VERSION_IND) {
if (!llcp_ntf_alloc_is_available()) {
ctx->state = LP_COMMON_STATE_WAIT_NTF;
} else {
lp_comm_ntf(conn, ctx);
llcp_lr_complete(conn);
ctx->state = LP_COMMON_STATE_IDLE;
}
} else {
/* Illegal response opcode */
lp_comm_terminate_invalid_pdu(conn, ctx);
}
lp_comm_ntf_complete_proxy(conn, ctx,
(ctx->response_opcode == PDU_DATA_LLCTRL_TYPE_VERSION_IND));
break;
case PROC_TERMINATE:
/* No notification */
@ -577,36 +574,36 @@ static bool lp_cis_terminated(struct ll_conn *conn)
}
#endif /* CONFIG_BT_CTLR_CENTRAL_ISO || CONFIG_BT_CTLR_PERIPHERAL_ISO */
static bool lp_comm_tx_proxy(struct ll_conn *conn, struct proc_ctx *ctx, const bool extra_cond)
{
if (extra_cond || llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
ctx->state = LP_COMMON_STATE_WAIT_TX;
} else {
lp_comm_tx(conn, ctx);
/* Select correct state, depending on TX ack handling 'request' */
ctx->state = ctx->tx_ack ? LP_COMMON_STATE_WAIT_TX_ACK : LP_COMMON_STATE_WAIT_RX;
return true;
}
return false;
}
static void lp_comm_send_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param)
{
switch (ctx->proc) {
#if defined(CONFIG_BT_CTLR_LE_PING)
case PROC_LE_PING:
if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
ctx->state = LP_COMMON_STATE_WAIT_TX;
} else {
lp_comm_tx(conn, ctx);
ctx->state = LP_COMMON_STATE_WAIT_RX;
}
lp_comm_tx_proxy(conn, ctx, false);
break;
#endif /* CONFIG_BT_CTLR_LE_PING */
case PROC_FEATURE_EXCHANGE:
if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
ctx->state = LP_COMMON_STATE_WAIT_TX;
} else {
lp_comm_tx(conn, ctx);
if (lp_comm_tx_proxy(conn, ctx, false)) {
conn->llcp.fex.sent = 1;
ctx->state = LP_COMMON_STATE_WAIT_RX;
}
break;
#if defined(CONFIG_BT_CTLR_MIN_USED_CHAN) && defined(CONFIG_BT_PERIPHERAL)
case PROC_MIN_USED_CHANS:
if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
ctx->state = LP_COMMON_STATE_WAIT_TX;
} else {
lp_comm_tx(conn, ctx);
ctx->state = LP_COMMON_STATE_WAIT_TX_ACK;
}
lp_comm_tx_proxy(conn, ctx, false);
break;
#endif /* CONFIG_BT_CTLR_MIN_USED_CHAN && CONFIG_BT_PERIPHERAL */
case PROC_VERSION_EXCHANGE:
@ -614,12 +611,8 @@ static void lp_comm_send_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t
* one LL_VERSION_IND PDU during a connection.
*/
if (!conn->llcp.vex.sent) {
if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
ctx->state = LP_COMMON_STATE_WAIT_TX;
} else {
lp_comm_tx(conn, ctx);
if (lp_comm_tx_proxy(conn, ctx, false)) {
conn->llcp.vex.sent = 1;
ctx->state = LP_COMMON_STATE_WAIT_RX;
}
} else {
ctx->response_opcode = PDU_DATA_LLCTRL_TYPE_VERSION_IND;
@ -637,13 +630,7 @@ static void lp_comm_send_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t
break;
#if defined(CONFIG_BT_CTLR_CENTRAL_ISO) || defined(CONFIG_BT_CTLR_PERIPHERAL_ISO)
case PROC_CIS_TERMINATE:
if (!lp_cis_terminated(conn) || llcp_lr_ispaused(conn) ||
!llcp_tx_alloc_peek(conn, ctx)) {
ctx->state = LP_COMMON_STATE_WAIT_TX;
} else {
lp_comm_tx(conn, ctx);
ctx->state = LP_COMMON_STATE_WAIT_TX_ACK;
}
lp_comm_tx_proxy(conn, ctx, !lp_cis_terminated(conn));
break;
#endif /* CONFIG_BT_CTLR_CENTRAL_ISO || CONFIG_BT_CTLR_PERIPHERAL_ISO */
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
@ -678,13 +665,8 @@ static void lp_comm_send_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t
#else
1) {
#endif /* CONFIG_BT_CTLR_PHY */
if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx) ||
(llcp_rr_get_paused_cmd(conn) == PROC_CTE_REQ)) {
ctx->state = LP_COMMON_STATE_WAIT_TX;
} else {
lp_comm_tx(conn, ctx);
ctx->state = LP_COMMON_STATE_WAIT_RX;
}
lp_comm_tx_proxy(conn, ctx,
(llcp_rr_get_paused_cmd(conn) == PROC_CTE_REQ));
} else {
/* The PHY was changed to CODED when the request was waiting in a local
* request queue.
@ -702,12 +684,7 @@ static void lp_comm_send_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t
#endif /* CONFIG_BT_CTLR_DF_CONN_CTE_REQ */
#if defined(CONFIG_BT_CTLR_SCA_UPDATE)
case PROC_SCA_UPDATE:
if (llcp_lr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
ctx->state = LP_COMMON_STATE_WAIT_TX;
} else {
lp_comm_tx(conn, ctx);
ctx->state = LP_COMMON_STATE_WAIT_RX;
}
lp_comm_tx_proxy(conn, ctx, false);
break;
#endif /* CONFIG_BT_CTLR_SCA_UPDATE */
default:
@ -1190,30 +1167,36 @@ static void rp_comm_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
}
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
static bool rp_comm_tx_proxy(struct ll_conn *conn, struct proc_ctx *ctx, const bool complete)
{
if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
ctx->state = RP_COMMON_STATE_WAIT_TX;
return false;
}
rp_comm_tx(conn, ctx);
ctx->state = RP_COMMON_STATE_WAIT_TX_ACK;
if (complete) {
llcp_rr_complete(conn);
ctx->state = RP_COMMON_STATE_IDLE;
}
return true;
}
static void rp_comm_send_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param)
{
switch (ctx->proc) {
#if defined(CONFIG_BT_CTLR_LE_PING)
case PROC_LE_PING:
/* Always respond on remote ping */
if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
ctx->state = RP_COMMON_STATE_WAIT_TX;
} else {
rp_comm_tx(conn, ctx);
llcp_rr_complete(conn);
ctx->state = RP_COMMON_STATE_IDLE;
}
rp_comm_tx_proxy(conn, ctx, true);
break;
#endif /* CONFIG_BT_CTLR_LE_PING */
case PROC_FEATURE_EXCHANGE:
/* Always respond on remote feature exchange */
if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
ctx->state = RP_COMMON_STATE_WAIT_TX;
} else {
rp_comm_tx(conn, ctx);
if (rp_comm_tx_proxy(conn, ctx, true)) {
conn->llcp.fex.sent = 1;
llcp_rr_complete(conn);
ctx->state = RP_COMMON_STATE_IDLE;
}
break;
case PROC_VERSION_EXCHANGE:
@ -1224,13 +1207,8 @@ static void rp_comm_send_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t
* LL_VERSION_IND PDU to the peer device.
*/
if (!conn->llcp.vex.sent) {
if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
ctx->state = RP_COMMON_STATE_WAIT_TX;
} else {
rp_comm_tx(conn, ctx);
if (rp_comm_tx_proxy(conn, ctx, true)) {
conn->llcp.vex.sent = 1;
llcp_rr_complete(conn);
ctx->state = RP_COMMON_STATE_IDLE;
}
} else {
/* Invalid behaviour
@ -1297,15 +1275,7 @@ static void rp_comm_send_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t
#endif /* CONFIG_BT_CTLR_CENTRAL_ISO || CONFIG_BT_CTLR_PERIPHERAL_ISO */
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
case PROC_DATA_LENGTH_UPDATE:
if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
ctx->state = RP_COMMON_STATE_WAIT_TX;
} else {
/* On RSP tx close the window for possible local req piggy-back */
rp_comm_tx(conn, ctx);
/* Wait for the peer to have ack'ed the RSP before updating DLE */
ctx->state = RP_COMMON_STATE_WAIT_TX_ACK;
}
rp_comm_tx_proxy(conn, ctx, false);
break;
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP)
@ -1323,14 +1293,7 @@ static void rp_comm_send_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t
#if defined(CONFIG_BT_CTLR_SCA_UPDATE)
case PROC_SCA_UPDATE:
/* Always respond to remote SCA */
if (llcp_rr_ispaused(conn) || !llcp_tx_alloc_peek(conn, ctx)) {
ctx->state = RP_COMMON_STATE_WAIT_TX;
} else {
rp_comm_tx(conn, ctx);
/* Wait for the peer to have ack'ed the RSP before completing */
ctx->state = RP_COMMON_STATE_WAIT_TX_ACK;
}
rp_comm_tx_proxy(conn, ctx, false);
break;
#endif /* CONFIG_BT_CTLR_SCA_UPDATE */
default: