Bluetooth: controller: use RX node piggy-back for NTF when possible
When possible re-use the already allocated RX node for notifications. Store (retain) RX node and Link element on RX if NTF could occur. Pass link element to LLCP (ull_cp_rx()) together with RX node. New RX node type RETAIN introduced to signal retention When no RX node is available allocate one and hold off TX on procedures until such time that a node is available for NTF. In case waiting for NTF buffer avail is needed, allocate and store TX node to use for TX once NTF becomes available. CIS Established (incl. timeout handling) is now handled entirely as a specific event driven by ull_conn_iso - ie removal of procedure check of cis->established and cis->expire, as this is doubling mechanism in the conn_iso context. Unit test and helpers updated to handle new node type. Function ull_cp_release_ntf() was used only in unit test, so moved to helper context. Updating release_ntf to handle the fact that with piggy-backing in test context the node used for NTF can be from two different memory pools Signed-off-by: Erik Brockhoff <erbr@oticon.com>
This commit is contained in:
parent
7c3a708ab8
commit
998512f59b
26 changed files with 841 additions and 813 deletions
|
@ -59,7 +59,6 @@ enum {
|
|||
LP_ENC_STATE_WAIT_RX_START_ENC_REQ,
|
||||
LP_ENC_STATE_WAIT_TX_START_ENC_RSP,
|
||||
LP_ENC_STATE_WAIT_RX_START_ENC_RSP,
|
||||
LP_ENC_STATE_WAIT_NTF,
|
||||
/* Pause Procedure */
|
||||
LP_ENC_STATE_ENCRYPTED,
|
||||
LP_ENC_STATE_WAIT_TX_PAUSE_ENC_REQ,
|
||||
|
@ -99,12 +98,10 @@ enum {
|
|||
RP_ENC_STATE_UNENCRYPTED,
|
||||
RP_ENC_STATE_WAIT_RX_ENC_REQ,
|
||||
RP_ENC_STATE_WAIT_TX_ENC_RSP,
|
||||
RP_ENC_STATE_WAIT_NTF_LTK_REQ,
|
||||
RP_ENC_STATE_WAIT_LTK_REPLY,
|
||||
RP_ENC_STATE_WAIT_TX_START_ENC_REQ,
|
||||
RP_ENC_STATE_WAIT_TX_REJECT_IND,
|
||||
RP_ENC_STATE_WAIT_RX_START_ENC_RSP,
|
||||
RP_ENC_STATE_WAIT_NTF,
|
||||
RP_ENC_STATE_WAIT_TX_START_ENC_RSP,
|
||||
/* Pause Procedure */
|
||||
RP_ENC_STATE_ENCRYPTED,
|
||||
|
@ -225,8 +222,8 @@ static void lp_enc_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
|
|||
struct node_rx_pdu *ntf;
|
||||
struct pdu_data *pdu;
|
||||
|
||||
/* Allocate ntf node */
|
||||
ntf = llcp_ntf_alloc();
|
||||
/* Piggy-back on RX node */
|
||||
ntf = ctx->node_ref.rx;
|
||||
LL_ASSERT(ntf);
|
||||
|
||||
ntf->hdr.type = NODE_RX_TYPE_DC_PDU;
|
||||
|
@ -248,20 +245,13 @@ static void lp_enc_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
|
|||
} else {
|
||||
llcp_pdu_encode_reject_ind(pdu, ctx->data.enc.error);
|
||||
}
|
||||
|
||||
/* Enqueue notification towards LL */
|
||||
ll_rx_put_sched(ntf->hdr.link, ntf);
|
||||
}
|
||||
|
||||
static void lp_enc_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param)
|
||||
{
|
||||
if (!llcp_ntf_alloc_is_available()) {
|
||||
ctx->state = LP_ENC_STATE_WAIT_NTF;
|
||||
} else {
|
||||
lp_enc_ntf(conn, ctx);
|
||||
llcp_lr_complete(conn);
|
||||
ctx->state = LP_ENC_STATE_UNENCRYPTED;
|
||||
}
|
||||
lp_enc_ntf(conn, ctx);
|
||||
llcp_lr_complete(conn);
|
||||
ctx->state = LP_ENC_STATE_UNENCRYPTED;
|
||||
}
|
||||
|
||||
static void lp_enc_store_m(struct ll_conn *conn, struct proc_ctx *ctx, struct pdu_data *pdu)
|
||||
|
@ -519,18 +509,6 @@ static void lp_enc_st_wait_rx_start_enc_rsp(struct ll_conn *conn, struct proc_ct
|
|||
}
|
||||
}
|
||||
|
||||
static void lp_enc_st_wait_ntf(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param)
|
||||
{
|
||||
switch (evt) {
|
||||
case LP_ENC_EVT_RUN:
|
||||
lp_enc_complete(conn, ctx, evt, param);
|
||||
break;
|
||||
default:
|
||||
/* Ignore other evts */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void lp_enc_state_encrypted(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||
void *param)
|
||||
{
|
||||
|
@ -612,9 +590,6 @@ static void lp_enc_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8
|
|||
case LP_ENC_STATE_WAIT_RX_START_ENC_RSP:
|
||||
lp_enc_st_wait_rx_start_enc_rsp(conn, ctx, evt, param);
|
||||
break;
|
||||
case LP_ENC_STATE_WAIT_NTF:
|
||||
lp_enc_st_wait_ntf(conn, ctx, evt, param);
|
||||
break;
|
||||
/* Pause Procedure */
|
||||
case LP_ENC_STATE_ENCRYPTED:
|
||||
lp_enc_state_encrypted(conn, ctx, evt, param);
|
||||
|
@ -755,19 +730,26 @@ static void rp_enc_ntf_ltk(struct ll_conn *conn, struct proc_ctx *ctx)
|
|||
{
|
||||
struct node_rx_pdu *ntf;
|
||||
struct pdu_data *pdu;
|
||||
uint8_t piggy_back;
|
||||
|
||||
/* Allocate ntf node */
|
||||
ntf = llcp_ntf_alloc();
|
||||
/* Piggy-back on RX node */
|
||||
ntf = ctx->node_ref.rx;
|
||||
ctx->node_ref.rx = NULL;
|
||||
LL_ASSERT(ntf);
|
||||
|
||||
piggy_back = (ntf->hdr.type != NODE_RX_TYPE_RETAIN);
|
||||
|
||||
ntf->hdr.type = NODE_RX_TYPE_DC_PDU;
|
||||
ntf->hdr.handle = conn->lll.handle;
|
||||
pdu = (struct pdu_data *)ntf->pdu;
|
||||
|
||||
llcp_ntf_encode_enc_req(ctx, pdu);
|
||||
|
||||
/* Enqueue notification towards LL */
|
||||
ll_rx_put_sched(ntf->hdr.link, ntf);
|
||||
if (!piggy_back) {
|
||||
/* Enqueue notification towards LL unless it's piggybacked */
|
||||
ll_rx_put_sched(ntf->hdr.link, ntf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
static void rp_enc_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
|
||||
|
@ -775,8 +757,9 @@ static void rp_enc_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
|
|||
struct node_rx_pdu *ntf;
|
||||
struct pdu_data *pdu;
|
||||
|
||||
/* Allocate ntf node */
|
||||
ntf = llcp_ntf_alloc();
|
||||
/* Piggy-back on RX node */
|
||||
ntf = ctx->node_ref.rx;
|
||||
ctx->node_ref.rx = NULL;
|
||||
LL_ASSERT(ntf);
|
||||
|
||||
ntf->hdr.type = NODE_RX_TYPE_DC_PDU;
|
||||
|
@ -794,9 +777,6 @@ static void rp_enc_ntf(struct ll_conn *conn, struct proc_ctx *ctx)
|
|||
/* Should never happen */
|
||||
LL_ASSERT(0);
|
||||
}
|
||||
|
||||
/* Enqueue notification towards LL */
|
||||
ll_rx_put_sched(ntf->hdr.link, ntf);
|
||||
}
|
||||
|
||||
static void rp_enc_send_start_enc_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||
|
@ -804,23 +784,8 @@ static void rp_enc_send_start_enc_rsp(struct ll_conn *conn, struct proc_ctx *ctx
|
|||
|
||||
static void rp_enc_complete(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt, void *param)
|
||||
{
|
||||
if (!llcp_ntf_alloc_is_available()) {
|
||||
ctx->state = RP_ENC_STATE_WAIT_NTF;
|
||||
} else {
|
||||
rp_enc_ntf(conn, ctx);
|
||||
rp_enc_send_start_enc_rsp(conn, ctx, evt, param);
|
||||
}
|
||||
}
|
||||
|
||||
static void rp_enc_send_ltk_ntf(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||
void *param)
|
||||
{
|
||||
if (!llcp_ntf_alloc_is_available()) {
|
||||
ctx->state = RP_ENC_STATE_WAIT_NTF_LTK_REQ;
|
||||
} else {
|
||||
rp_enc_ntf_ltk(conn, ctx);
|
||||
ctx->state = RP_ENC_STATE_WAIT_LTK_REPLY;
|
||||
}
|
||||
rp_enc_ntf(conn, ctx);
|
||||
rp_enc_send_start_enc_rsp(conn, ctx, evt, param);
|
||||
}
|
||||
|
||||
static void rp_enc_store_s(struct ll_conn *conn, struct proc_ctx *ctx, struct pdu_data *pdu)
|
||||
|
@ -840,11 +805,15 @@ static void rp_enc_send_enc_rsp(struct ll_conn *conn, struct proc_ctx *ctx, uint
|
|||
struct node_tx *tx;
|
||||
|
||||
if (!llcp_tx_alloc_peek(conn, ctx)) {
|
||||
/* Mark RX node to not release, needed for LTK NTF */
|
||||
llcp_rx_node_retain(ctx);
|
||||
ctx->state = RP_ENC_STATE_WAIT_TX_ENC_RSP;
|
||||
} else {
|
||||
tx = llcp_rp_enc_tx(conn, ctx, PDU_DATA_LLCTRL_TYPE_ENC_RSP);
|
||||
rp_enc_store_s(conn, ctx, (struct pdu_data *)tx->pdu);
|
||||
rp_enc_send_ltk_ntf(conn, ctx, evt, param);
|
||||
|
||||
rp_enc_ntf_ltk(conn, ctx);
|
||||
ctx->state = RP_ENC_STATE_WAIT_LTK_REPLY;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -969,6 +938,7 @@ static void rp_enc_state_wait_rx_enc_req(struct ll_conn *conn, struct proc_ctx *
|
|||
llcp_lr_pause(conn);
|
||||
|
||||
rp_enc_store_m(conn, ctx, param);
|
||||
|
||||
rp_enc_send_enc_rsp(conn, ctx, evt, param);
|
||||
break;
|
||||
default:
|
||||
|
@ -990,19 +960,6 @@ static void rp_enc_state_wait_tx_enc_rsp(struct ll_conn *conn, struct proc_ctx *
|
|||
}
|
||||
}
|
||||
|
||||
static void rp_enc_state_wait_ntf_ltk_req(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||
void *param)
|
||||
{
|
||||
switch (evt) {
|
||||
case RP_ENC_EVT_RUN:
|
||||
rp_enc_send_ltk_ntf(conn, ctx, evt, param);
|
||||
break;
|
||||
default:
|
||||
/* Ignore other evts */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rp_enc_state_wait_ltk_reply(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||
void *param)
|
||||
{
|
||||
|
@ -1058,19 +1015,6 @@ static void rp_enc_state_wait_rx_start_enc_rsp(struct ll_conn *conn, struct proc
|
|||
}
|
||||
}
|
||||
|
||||
static void rp_enc_state_wait_ntf(struct ll_conn *conn, struct proc_ctx *ctx, uint8_t evt,
|
||||
void *param)
|
||||
{
|
||||
switch (evt) {
|
||||
case RP_ENC_EVT_RUN:
|
||||
rp_enc_complete(conn, ctx, evt, param);
|
||||
break;
|
||||
default:
|
||||
/* Ignore other evts */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void rp_enc_state_wait_tx_start_enc_rsp(struct ll_conn *conn, struct proc_ctx *ctx,
|
||||
uint8_t evt, void *param)
|
||||
{
|
||||
|
@ -1162,9 +1106,6 @@ static void rp_enc_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8
|
|||
case RP_ENC_STATE_WAIT_TX_ENC_RSP:
|
||||
rp_enc_state_wait_tx_enc_rsp(conn, ctx, evt, param);
|
||||
break;
|
||||
case RP_ENC_STATE_WAIT_NTF_LTK_REQ:
|
||||
rp_enc_state_wait_ntf_ltk_req(conn, ctx, evt, param);
|
||||
break;
|
||||
case RP_ENC_STATE_WAIT_LTK_REPLY:
|
||||
rp_enc_state_wait_ltk_reply(conn, ctx, evt, param);
|
||||
break;
|
||||
|
@ -1177,9 +1118,6 @@ static void rp_enc_execute_fsm(struct ll_conn *conn, struct proc_ctx *ctx, uint8
|
|||
case RP_ENC_STATE_WAIT_RX_START_ENC_RSP:
|
||||
rp_enc_state_wait_rx_start_enc_rsp(conn, ctx, evt, param);
|
||||
break;
|
||||
case RP_ENC_STATE_WAIT_NTF:
|
||||
rp_enc_state_wait_ntf(conn, ctx, evt, param);
|
||||
break;
|
||||
case RP_ENC_STATE_WAIT_TX_START_ENC_RSP:
|
||||
rp_enc_state_wait_tx_start_enc_rsp(conn, ctx, evt, param);
|
||||
break;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue