Bluetooth: controller: split: Port Enc setup to be queueable

Port the fix for the controller implementation to make start
encryption queueable if there is any control procedure in
progress.

Refer to #15335.
Relates to #15335, #15186, #15958 and #14636.

Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
Vinayak Kariappa Chettimada 2019-05-29 21:54:38 +02:00 committed by Carles Cufí
commit 79cb615770
5 changed files with 178 additions and 124 deletions

View file

@ -564,11 +564,6 @@ u8_t ll_adv_enable(u8_t enable)
conn_lll->nesn = 0;
conn_lll->empty = 0;
#if defined(CONFIG_BT_CTLR_LE_ENC)
conn_lll->enc_rx = 0;
conn_lll->enc_tx = 0;
#endif /* CONFIG_BT_CTLR_LE_ENC */
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
conn_lll->max_tx_octets = PDU_DC_PAYLOAD_SIZE_MIN;
conn_lll->max_rx_octets = PDU_DC_PAYLOAD_SIZE_MIN;
@ -627,7 +622,10 @@ u8_t ll_adv_enable(u8_t enable)
conn->llcp_terminate.node_rx.hdr.link = link;
#if defined(CONFIG_BT_CTLR_LE_ENC)
conn->pause_tx = conn->pause_rx = conn->refresh = 0;
conn_lll->enc_rx = conn_lll->enc_tx = 0U;
conn->llcp_enc.req = conn->llcp_enc.ack = 0U;
conn->llcp_enc.pause_tx = conn->llcp_enc.pause_rx = 0U;
conn->llcp_enc.refresh = 0U;
#endif /* CONFIG_BT_CTLR_LE_ENC */
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)

View file

@ -57,6 +57,7 @@ static inline void event_ch_map_prep(struct ll_conn *conn,
static void terminate_ind_rx_enqueue(struct ll_conn *conn, u8_t reason);
#if defined(CONFIG_BT_CTLR_LE_ENC)
static bool is_enc_req_pause_tx(struct ll_conn *conn);
static inline void event_enc_prep(struct ll_conn *conn);
static int enc_rsp_send(struct ll_conn *conn);
static int start_enc_rsp_send(struct ll_conn *conn,
@ -674,7 +675,7 @@ int ull_conn_rx(memq_link_t *link, struct node_rx_pdu **rx)
case PDU_DATA_LLID_DATA_CONTINUE:
case PDU_DATA_LLID_DATA_START:
#if defined(CONFIG_BT_CTLR_LE_ENC)
if (conn->pause_rx) {
if (conn->llcp_enc.pause_rx) {
conn->llcp_terminate.reason_peer =
BT_HCI_ERR_TERM_DUE_TO_MIC_FAIL;
@ -687,7 +688,7 @@ int ull_conn_rx(memq_link_t *link, struct node_rx_pdu **rx)
case PDU_DATA_LLID_RESV:
default:
#if defined(CONFIG_BT_CTLR_LE_ENC)
if (conn->pause_rx) {
if (conn->llcp_enc.pause_rx) {
conn->llcp_terminate.reason_peer =
BT_HCI_ERR_TERM_DUE_TO_MIC_FAIL;
}
@ -715,7 +716,7 @@ int ull_conn_llcp(struct ll_conn *conn, u32_t ticks_at_expire, u16_t lazy)
*/
if ((conn->llcp_ack == conn->llcp_req) &&
#if defined(CONFIG_BT_CTLR_LE_ENC)
!conn->pause_rx) {
!conn->llcp_enc.pause_rx) {
#else /* !CONFIG_BT_CTLR_LE_ENC */
1) {
#endif /* !CONFIG_BT_CTLR_LE_ENC */
@ -736,6 +737,13 @@ int ull_conn_llcp(struct ll_conn *conn, u32_t ticks_at_expire, u16_t lazy)
ticks_at_expire);
#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
/* check if procedure is requested */
} else if (conn->llcp_length.ack != conn->llcp_length.req) {
/* handle DLU state machine */
event_len_prep(conn);
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
#if defined(CONFIG_BT_CTLR_PHY)
/* check if PHY Req procedure is requested */
} else if (conn->llcp_phy.ack != conn->llcp_phy.req) {
@ -819,14 +827,6 @@ int ull_conn_llcp(struct ll_conn *conn, u32_t ticks_at_expire, u16_t lazy)
}
}
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
/* check if procedure is requested */
if (conn->llcp_length.ack != conn->llcp_length.req) {
/* handle DLU state machine */
event_len_prep(conn);
}
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
/* Terminate Procedure Request */
if (conn->llcp_terminate.ack != conn->llcp_terminate.req) {
struct node_tx *tx;
@ -891,7 +891,7 @@ void ull_conn_done(struct node_rx_event_done *done)
switch (done->extra.mic_state) {
case LLL_CONN_MIC_NONE:
#if defined(CONFIG_BT_CTLR_LE_PING)
if (lll->enc_rx || conn->pause_rx) {
if (lll->enc_rx || conn->llcp_enc.pause_rx) {
u16_t appto_reload_new;
/* check for change in apto */
@ -1190,42 +1190,43 @@ void ull_conn_tx_demux(u8_t count)
void ull_conn_tx_lll_enqueue(struct ll_conn *conn, u8_t count)
{
struct node_tx *tx;
bool pause_tx = false;
tx = conn->tx_head;
while (tx &&
while (conn->tx_head &&
((
#if defined(CONFIG_BT_CTLR_LE_ENC)
!conn->pause_tx &&
#endif /* CONFIG_BT_CTLR_LE_ENC */
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
!conn->llcp_length.pause_tx &&
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
#if defined(CONFIG_BT_CTLR_PHY)
!conn->llcp_phy.pause_tx &&
#endif /* CONFIG_BT_CTLR_PHY */
1) || (tx == conn->tx_ctrl)) && count--) {
#if defined(CONFIG_BT_CTLR_LE_ENC)
!conn->llcp_enc.pause_tx &&
!(pause_tx = is_enc_req_pause_tx(conn)) &&
#endif /* CONFIG_BT_CTLR_LE_ENC */
1) ||
(!pause_tx && (conn->tx_head == conn->tx_ctrl))) && count--) {
struct node_tx *tx_lll;
memq_link_t *link;
tx_lll = tx;
tx_lll = conn->tx_head;
if (tx == conn->tx_ctrl) {
tx = conn->tx_head = conn->tx_head->next;
if (conn->tx_head == conn->tx_ctrl) {
conn->tx_head = conn->tx_head->next;
if (conn->tx_ctrl == conn->tx_ctrl_last) {
conn->tx_ctrl = NULL;
conn->tx_ctrl_last = NULL;
} else {
conn->tx_ctrl = tx;
conn->tx_ctrl = conn->tx_head;
}
/* point to self to indicate a control PDU mem alloc */
tx_lll->next = tx_lll;
} else {
if (tx == conn->tx_data) {
if (conn->tx_head == conn->tx_data) {
conn->tx_data = conn->tx_data->next;
}
tx = conn->tx_head = conn->tx_head->next;
conn->tx_head = conn->tx_head->next;
}
link = mem_acquire(&mem_link_tx.free);
@ -1510,7 +1511,7 @@ static void ctrl_tx_enqueue(struct ll_conn *conn, struct node_tx *tx)
/* data/ctrl packet is in the head */
conn->tx_head &&
#if defined(CONFIG_BT_CTLR_LE_ENC)
!conn->pause_tx &&
!conn->llcp_enc.pause_tx &&
#endif /* CONFIG_BT_CTLR_LE_ENC */
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
!conn->llcp_length.pause_tx &&
@ -1567,7 +1568,7 @@ static void ctrl_tx_enqueue(struct ll_conn *conn, struct node_tx *tx)
static void ctrl_tx_sec_enqueue(struct ll_conn *conn, struct node_tx *tx)
{
#if defined(CONFIG_BT_CTLR_LE_ENC)
if (conn->pause_tx) {
if (conn->llcp_enc.pause_tx) {
if (!conn->tx_ctrl) {
tx->next = conn->tx_head;
conn->tx_head = tx;
@ -1583,6 +1584,65 @@ static void ctrl_tx_sec_enqueue(struct ll_conn *conn, struct node_tx *tx)
}
}
#if defined(CONFIG_BT_CTLR_LE_ENC)
static bool is_enc_req_pause_tx(struct ll_conn *conn)
{
struct pdu_data *pdu_data_tx;
pdu_data_tx = (void *)conn->tx_head->pdu;
if ((pdu_data_tx->ll_id == PDU_DATA_LLID_CTRL) &&
(pdu_data_tx->llctrl.opcode == PDU_DATA_LLCTRL_TYPE_ENC_REQ)) {
if ((conn->llcp_req != conn->llcp_ack) ||
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
(conn->llcp_conn_param.ack != conn->llcp_conn_param.req) ||
#endif /* CONFIG_BT_CTLR_CONN_PARAM_REQ */
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
(conn->llcp_length.ack != conn->llcp_length.req) ||
#endif /* CONFIG_BT_CTLR_DATA_LENGTH */
#if defined(CONFIG_BT_CTLR_PHY)
(conn->llcp_phy.ack != conn->llcp_phy.req) ||
#endif /* CONFIG_BT_CTLR_PHY */
0) {
struct node_tx *tx;
/* if we have control packets enqueued after this PDU
* bring it ahead, and move the enc_req to last of
* ctrl queue.
*/
tx = conn->tx_head;
if ((tx->next != NULL) &&
(tx->next == conn->tx_ctrl)) {
conn->tx_head = tx->next;
tx->next = conn->tx_ctrl_last->next;
conn->tx_ctrl_last->next = tx;
conn->tx_data = tx;
if (!conn->tx_data_last) {
conn->tx_data_last = tx;
}
/* Head now contains a control packet permitted
* to be transmitted to peer.
*/
return false;
}
/* Head contains ENC_REQ packet deferred due to another
* control procedure in progress.
*/
return true;
}
conn->llcp.encryption.initiate = 1U;
conn->llcp_type = LLCP_ENCRYPTION;
conn->llcp_ack -= 2U;
}
/* Head contains a permitted data or control packet. */
return false;
}
#endif /* CONFIG_BT_CTLR_LE_ENC */
static inline void event_conn_upd_init(struct ll_conn *conn,
u16_t event_counter,
u32_t ticks_at_expire,
@ -2046,9 +2106,9 @@ static inline void event_enc_prep(struct ll_conn *conn)
/* master sends encrypted enc start rsp in control priority */
if (!lll->role) {
/* calc the Session Key */
ecb_encrypt(&conn->llcp.encryption.ltk[0],
&conn->llcp.encryption.skd[0],
NULL, &lll->ccm_rx.key[0]);
ecb_encrypt(&conn->llcp_enc.ltk[0],
&conn->llcp.encryption.skd[0], NULL,
&lll->ccm_rx.key[0]);
/* copy the Session Key */
memcpy(&lll->ccm_tx.key[0], &lll->ccm_rx.key[0],
@ -2080,7 +2140,7 @@ static inline void event_enc_prep(struct ll_conn *conn)
#if defined(CONFIG_BT_CTLR_FAST_ENC)
else {
#else /* !CONFIG_BT_CTLR_FAST_ENC */
else if (!conn->pause_tx || conn->refresh) {
else if (!conn->llcp_enc.pause_tx || conn->llcp_enc.refresh) {
#endif /* !CONFIG_BT_CTLR_FAST_ENC */
/* place the reject ind packet as next in tx queue */
@ -2106,7 +2166,7 @@ static inline void event_enc_prep(struct ll_conn *conn)
#endif /* !CONFIG_BT_CTLR_FAST_ENC */
/* calc the Session Key */
ecb_encrypt(&conn->llcp.encryption.ltk[0],
ecb_encrypt(&conn->llcp_enc.ltk[0],
&conn->llcp.encryption.skd[0], NULL,
&lll->ccm_rx.key[0]);
@ -2120,20 +2180,20 @@ static inline void event_enc_prep(struct ll_conn *conn)
sizeof(lll->ccm_tx.iv));
/* initialise counter */
lll->ccm_rx.counter = 0;
lll->ccm_tx.counter = 0;
lll->ccm_rx.counter = 0U;
lll->ccm_tx.counter = 0U;
/* set direction: slave to master = 0,
* master to slave = 1
*/
lll->ccm_rx.direction = 1;
lll->ccm_tx.direction = 0;
lll->ccm_rx.direction = 1U;
lll->ccm_tx.direction = 0U;
/* enable receive encryption (transmit turned
* on when start enc resp from master is
* received)
*/
lll->enc_rx = 1;
lll->enc_rx = 1U;
/* prepare the start enc req */
pdu_ctrl_tx->ll_id = PDU_DATA_LLID_CTRL;
@ -2149,8 +2209,8 @@ static inline void event_enc_prep(struct ll_conn *conn)
start_enc_rsp_send(conn, pdu_ctrl_tx);
/* resume data packet rx and tx */
conn->pause_rx = 0;
conn->pause_tx = 0;
conn->llcp_enc.pause_rx = 0U;
conn->llcp_enc.pause_tx = 0U;
#endif /* !CONFIG_BT_CTLR_FAST_ENC */
}
@ -2518,7 +2578,7 @@ static inline void event_conn_param_app_req(struct ll_conn *conn)
#if defined(CONFIG_BT_CTLR_LE_ENC)
/* defer until encryption setup is complete */
if (conn->pause_tx) {
if (conn->llcp_enc.pause_tx) {
return;
}
#endif /* CONFIG_BT_CTLR_LE_ENC */
@ -2762,7 +2822,7 @@ static inline void event_phy_req_prep(struct ll_conn *conn)
conn->phy_pref_flags = conn->llcp_phy.flags;
/* pause data packet tx */
conn->llcp_phy.pause_tx = 1;
conn->llcp_phy.pause_tx = 1U;
/* place the phy req packet as next in tx queue */
pdu_ctrl_tx = (void *)tx->pdu;
@ -3116,13 +3176,10 @@ static void enc_req_reused_send(struct ll_conn *conn, struct node_tx **tx)
pdu_ctrl_tx->len = offsetof(struct pdu_data_llctrl, enc_req) +
sizeof(struct pdu_data_llctrl_enc_req);
pdu_ctrl_tx->llctrl.opcode = PDU_DATA_LLCTRL_TYPE_ENC_REQ;
memcpy(&pdu_ctrl_tx->llctrl.enc_req.rand[0],
&conn->llcp.encryption.rand[0],
memcpy(&pdu_ctrl_tx->llctrl.enc_req.rand[0], &conn->llcp_enc.rand[0],
sizeof(pdu_ctrl_tx->llctrl.enc_req.rand));
pdu_ctrl_tx->llctrl.enc_req.ediv[0] =
conn->llcp.encryption.ediv[0];
pdu_ctrl_tx->llctrl.enc_req.ediv[1] =
conn->llcp.encryption.ediv[1];
pdu_ctrl_tx->llctrl.enc_req.ediv[0] = conn->llcp_enc.ediv[0];
pdu_ctrl_tx->llctrl.enc_req.ediv[1] = conn->llcp_enc.ediv[1];
/*
* Take advantage of the fact that ivm and skdm fields, which both have
@ -3218,13 +3275,13 @@ static int start_enc_rsp_send(struct ll_conn *conn,
static inline bool ctrl_is_unexpected(struct ll_conn *conn, u8_t opcode)
{
return (!conn->lll.role &&
((!conn->refresh &&
((!conn->llcp_enc.refresh &&
(opcode != PDU_DATA_LLCTRL_TYPE_TERMINATE_IND) &&
(opcode != PDU_DATA_LLCTRL_TYPE_START_ENC_REQ) &&
(opcode != PDU_DATA_LLCTRL_TYPE_START_ENC_RSP) &&
(opcode != PDU_DATA_LLCTRL_TYPE_REJECT_IND) &&
(opcode != PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND)) ||
(conn->refresh &&
(conn->llcp_enc.refresh &&
(opcode != PDU_DATA_LLCTRL_TYPE_TERMINATE_IND) &&
(opcode != PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_RSP) &&
(opcode != PDU_DATA_LLCTRL_TYPE_ENC_RSP) &&
@ -3233,13 +3290,13 @@ static inline bool ctrl_is_unexpected(struct ll_conn *conn, u8_t opcode)
(opcode != PDU_DATA_LLCTRL_TYPE_REJECT_IND) &&
(opcode != PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND)))) ||
(conn->lll.role &&
((!conn->refresh &&
((!conn->llcp_enc.refresh &&
(opcode != PDU_DATA_LLCTRL_TYPE_UNKNOWN_RSP) &&
(opcode != PDU_DATA_LLCTRL_TYPE_TERMINATE_IND) &&
(opcode != PDU_DATA_LLCTRL_TYPE_START_ENC_RSP) &&
(opcode != PDU_DATA_LLCTRL_TYPE_REJECT_IND) &&
(opcode != PDU_DATA_LLCTRL_TYPE_REJECT_EXT_IND)) ||
(conn->refresh &&
(conn->llcp_enc.refresh &&
(opcode != PDU_DATA_LLCTRL_TYPE_TERMINATE_IND) &&
(opcode != PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_RSP) &&
(opcode != PDU_DATA_LLCTRL_TYPE_ENC_REQ) &&
@ -3362,7 +3419,7 @@ static int pause_enc_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx,
}
/* key refresh */
conn->refresh = 1U;
conn->llcp_enc.refresh = 1U;
} else if (!conn->lll.role) {
/* acquire tx mem */
tx = mem_acquire(&mem_conn_tx_ctrl.free);
@ -3380,7 +3437,7 @@ static int pause_enc_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx,
}
/* pause data packet rx */
conn->pause_rx = 1U;
conn->llcp_enc.pause_rx = 1U;
/* disable receive encryption */
conn->lll.enc_rx = 0;
@ -3683,8 +3740,8 @@ static void reject_ext_ind_recv(struct ll_conn *conn, struct node_rx_pdu *rx,
switch (rej_ext_ind->reject_opcode) {
case PDU_DATA_LLCTRL_TYPE_ENC_REQ:
/* resume data packet rx and tx */
conn->pause_rx = 0U;
conn->pause_tx = 0U;
conn->llcp_enc.pause_rx = 0U;
conn->llcp_enc.pause_tx = 0U;
/* Procedure complete */
conn->procedure_expire = 0U;
@ -4010,7 +4067,7 @@ static int phy_rsp_send(struct ll_conn *conn, struct node_rx_pdu *rx,
conn->llcp_phy.rx &= p->tx_phys;
/* pause data packet tx */
conn->llcp_phy.pause_tx = 1;
conn->llcp_phy.pause_tx = 1U;
pdu_ctrl_tx = (void *)tx->pdu;
pdu_ctrl_tx->ll_id = PDU_DATA_LLID_CTRL;
@ -4146,18 +4203,21 @@ static inline void ctrl_tx_ack(struct ll_conn *conn, struct node_tx **tx,
&pdu_tx->llctrl.enc_req.ivm[0], 4);
/* pause data packet tx */
conn->pause_tx = 1U;
conn->llcp_enc.pause_tx = 1U;
/* Start Procedure Timeout (this will not replace terminate
* procedure which always gets place before any packets
* going out, hence safe by design).
*/
conn->procedure_expire = conn->procedure_reload;
/* Reset enc req queued state */
conn->llcp_enc.ack = conn->llcp_enc.req;
break;
case PDU_DATA_LLCTRL_TYPE_ENC_RSP:
/* pause data packet tx */
conn->pause_tx = 1U;
conn->llcp_enc.pause_tx = 1U;
break;
case PDU_DATA_LLCTRL_TYPE_START_ENC_REQ:
@ -4169,10 +4229,10 @@ static inline void ctrl_tx_ack(struct ll_conn *conn, struct node_tx **tx,
case PDU_DATA_LLCTRL_TYPE_PAUSE_ENC_REQ:
/* pause data packet tx */
conn->pause_tx = 1U;
conn->llcp_enc.pause_tx = 1U;
/* key refresh */
conn->refresh = 1U;
conn->llcp_enc.refresh = 1U;
/* Start Procedure Timeout (this will not replace terminate
* procedure which always gets place before any packets
@ -4187,7 +4247,7 @@ static inline void ctrl_tx_ack(struct ll_conn *conn, struct node_tx **tx,
enc_req_reused_send(conn, tx);
} else {
/* pause data packet tx */
conn->pause_tx = 1U;
conn->llcp_enc.pause_tx = 1U;
}
break;
@ -4200,8 +4260,8 @@ static inline void ctrl_tx_ack(struct ll_conn *conn, struct node_tx **tx,
case PDU_DATA_LLCTRL_TYPE_REJECT_IND:
/* resume data packet rx and tx */
conn->pause_rx = 0U;
conn->pause_tx = 0U;
conn->llcp_enc.pause_rx = 0U;
conn->llcp_enc.pause_tx = 0U;
/* Procedure complete */
conn->procedure_expire = 0U;
@ -4242,13 +4302,13 @@ static inline void ctrl_tx_ack(struct ll_conn *conn, struct node_tx **tx,
}
/* resume data packet tx */
conn->llcp_phy.pause_tx = 0;
conn->llcp_phy.pause_tx = 0U;
break;
case PDU_DATA_LLCTRL_TYPE_PHY_UPD_IND:
conn->lll.phy_tx_time = conn->llcp.phy_upd_ind.tx;
/* resume data packet tx */
conn->llcp_phy.pause_tx = 0;
conn->llcp_phy.pause_tx = 0U;
break;
#endif /* CONFIG_BT_CTLR_PHY */
@ -4328,7 +4388,7 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
#if defined(CONFIG_BT_CTLR_LE_ENC)
/* FIXME: do check in individual case to reduce CPU time */
if (conn->pause_rx && ctrl_is_unexpected(conn, opcode)) {
if (conn->llcp_enc.pause_rx && ctrl_is_unexpected(conn, opcode)) {
conn->llcp_terminate.reason_peer =
BT_HCI_ERR_TERM_DUE_TO_MIC_FAIL;
@ -4412,7 +4472,7 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
&pdu_rx->llctrl.enc_req.ivm[0], 4);
/* pause rx data packets */
conn->pause_rx = 1U;
conn->llcp_enc.pause_rx = 1U;
/* Start Procedure Timeout (TODO: this shall not replace
* terminate procedure).
@ -4434,7 +4494,7 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
&pdu_rx->llctrl.enc_rsp.ivs[0], 4);
/* pause rx data packets */
conn->pause_rx = 1U;
conn->llcp_enc.pause_rx = 1U;
/* Mark for buffer for release */
(*rx)->hdr.type = NODE_RX_TYPE_DC_PDU_RELEASE;
@ -4442,10 +4502,9 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
break;
case PDU_DATA_LLCTRL_TYPE_START_ENC_REQ:
LL_ASSERT((conn->llcp_req == conn->llcp_ack) ||
(conn->llcp_type == LLCP_ENCRYPTION));
if (conn->lll.role ||
((conn->llcp_req != conn->llcp_ack) &&
(conn->llcp_type != LLCP_ENCRYPTION)) ||
!pdu_len_cmp(PDU_DATA_LLCTRL_TYPE_START_ENC_REQ,
pdu_rx->len)) {
goto ull_conn_rx_unknown_rsp_send;
@ -4471,8 +4530,10 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
if (conn->lll.role) {
#if !defined(CONFIG_BT_CTLR_FAST_ENC)
LL_ASSERT((conn->llcp_req == conn->llcp_ack) ||
(conn->llcp_type == LLCP_ENCRYPTION));
if ((conn->llcp_req != conn->llcp_ack) &&
(conn->llcp_type != LLCP_ENCRYPTION)) {
goto ull_conn_rx_unknown_rsp_send;
}
/* start enc rsp to be scheduled in slave prepare */
conn->llcp.encryption.initiate = 0U;
@ -4487,19 +4548,19 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
}
/* resume data packet rx and tx */
conn->pause_rx = 0U;
conn->pause_tx = 0U;
conn->llcp_enc.pause_rx = 0U;
conn->llcp_enc.pause_tx = 0U;
#endif /* CONFIG_BT_CTLR_FAST_ENC */
} else {
/* resume data packet rx and tx */
conn->pause_rx = 0U;
conn->pause_tx = 0U;
conn->llcp_enc.pause_rx = 0U;
conn->llcp_enc.pause_tx = 0U;
}
/* enqueue the start enc resp (encryption change/refresh) */
if (conn->refresh) {
conn->refresh = 0U;
if (conn->llcp_enc.refresh) {
conn->llcp_enc.refresh = 0U;
/* key refresh event */
(*rx)->hdr.type = NODE_RX_TYPE_ENC_REFRESH;
@ -4579,8 +4640,8 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
}
/* resume data packet rx and tx */
conn->pause_rx = 0U;
conn->pause_tx = 0U;
conn->llcp_enc.pause_rx = 0U;
conn->llcp_enc.pause_tx = 0U;
/* Procedure complete */
conn->procedure_expire = 0U;
@ -4719,7 +4780,7 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
/* postpone CP request event if under
* encryption setup
*/
if (conn->pause_tx) {
if (conn->llcp_enc.pause_tx) {
conn->llcp_conn_param.state =
LLCP_CPR_STATE_APP_REQ;
@ -5036,7 +5097,7 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
/* Procedure complete */
conn->llcp_phy.ack = conn->llcp_phy.req;
conn->llcp_phy.pause_tx = 0;
conn->llcp_phy.pause_tx = 0U;
/* Reset packet timing restrictions */
lll->phy_tx_time = lll->phy_tx;
@ -5171,7 +5232,7 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
conn->llcp_phy.rx &= p->tx_phys;
/* pause data packet tx */
conn->llcp_phy.pause_tx = 1;
conn->llcp_phy.pause_tx = 1U;
/* Mark for buffer for release */
(*rx)->hdr.type = NODE_RX_TYPE_DC_PDU_RELEASE;
@ -5199,7 +5260,7 @@ static inline int ctrl_rx(memq_link_t *link, struct node_rx_pdu **rx,
conn->llcp_phy.rx &= p->tx_phys;
/* pause data packet tx */
conn->llcp_phy.pause_tx = 1;
conn->llcp_phy.pause_tx = 1U;
/* Procedure timeout is stopped */
conn->procedure_expire = 0U;

View file

@ -87,9 +87,6 @@ struct ll_conn {
struct {
u8_t initiate;
u8_t error_code;
u8_t rand[8];
u8_t ediv[2];
u8_t ltk[16];
u8_t skd[16];
} encryption;
#endif /* CONFIG_BT_CTLR_LE_ENC */
@ -118,6 +115,19 @@ struct ll_conn {
} node_rx;
} llcp_terminate;
#if defined(CONFIG_BT_CTLR_LE_ENC)
struct {
u8_t req;
u8_t ack;
u8_t pause_rx:1;
u8_t pause_tx:1;
u8_t refresh:1;
u8_t ediv[2];
u8_t rand[8];
u8_t ltk[16];
} llcp_enc;
#endif /* CONFIG_BT_CTLR_LE_ENC */
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
struct {
u8_t req;
@ -191,12 +201,6 @@ struct ll_conn {
u8_t phy_pref_rx:3;
#endif /* CONFIG_BT_CTLR_PHY */
#if defined(CONFIG_BT_CTLR_LE_ENC)
u8_t pause_rx:1;
u8_t pause_tx:1;
u8_t refresh:1;
#endif /* CONFIG_BT_CTLR_LE_ENC */
struct node_tx *tx_head;
struct node_tx *tx_ctrl;
struct node_tx *tx_ctrl_last;

View file

@ -118,11 +118,6 @@ u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
conn_lll->nesn = 0;
conn_lll->empty = 0;
#if defined(CONFIG_BT_CTLR_LE_ENC)
conn_lll->enc_rx = 0;
conn_lll->enc_tx = 0;
#endif /* CONFIG_BT_CTLR_LE_ENC */
#if defined(CONFIG_BT_CTLR_DATA_LENGTH)
conn_lll->max_tx_octets = PDU_DC_PAYLOAD_SIZE_MIN;
conn_lll->max_rx_octets = PDU_DC_PAYLOAD_SIZE_MIN;
@ -197,7 +192,10 @@ u8_t ll_create_connection(u16_t scan_interval, u16_t scan_window,
conn->llcp_terminate.node_rx.hdr.link = link;
#if defined(CONFIG_BT_CTLR_LE_ENC)
conn->pause_tx = conn->pause_rx = conn->refresh = 0U;
conn_lll->enc_rx = conn_lll->enc_tx = 0U;
conn->llcp_enc.req = conn->llcp_enc.ack = 0U;
conn->llcp_enc.pause_tx = conn->llcp_enc.pause_rx = 0U;
conn->llcp_enc.refresh = 0U;
#endif /* CONFIG_BT_CTLR_LE_ENC */
#if defined(CONFIG_BT_CTLR_CONN_PARAM_REQ)
@ -337,16 +335,14 @@ u8_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, u8_t *ltk)
{
struct ll_conn *conn;
struct node_tx *tx;
u8_t ret;
conn = ll_connected_get(handle);
if (!conn) {
return BT_HCI_ERR_UNKNOWN_CONN_ID;
}
ret = ull_conn_llcp_req(conn);
if (ret) {
return ret;
if (conn->llcp_enc.req != conn->llcp_enc.ack) {
return BT_HCI_ERR_CMD_DISALLOWED;
}
tx = ll_tx_mem_acquire();
@ -355,8 +351,7 @@ u8_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, u8_t *ltk)
pdu_data_tx = (void *)tx->pdu;
memcpy(&conn->llcp.encryption.ltk[0], ltk,
sizeof(conn->llcp.encryption.ltk));
memcpy(&conn->llcp_enc.ltk[0], ltk, sizeof(conn->llcp_enc.ltk));
if ((conn->lll.enc_rx == 0) && (conn->lll.enc_tx == 0)) {
struct pdu_data_llctrl_enc_req *enc_req;
@ -375,11 +370,11 @@ u8_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, u8_t *ltk)
bt_rand(enc_req->skdm, sizeof(enc_req->skdm));
bt_rand(enc_req->ivm, sizeof(enc_req->ivm));
} else if ((conn->lll.enc_rx != 0) && (conn->lll.enc_tx != 0)) {
memcpy(&conn->llcp.encryption.rand[0], rand,
sizeof(conn->llcp.encryption.rand));
memcpy(&conn->llcp_enc.rand[0], rand,
sizeof(conn->llcp_enc.rand));
conn->llcp.encryption.ediv[0] = ediv[0];
conn->llcp.encryption.ediv[1] = ediv[1];
conn->llcp_enc.ediv[0] = ediv[0];
conn->llcp_enc.ediv[1] = ediv[1];
pdu_data_tx->ll_id = PDU_DATA_LLID_CTRL;
pdu_data_tx->len = offsetof(struct pdu_data_llctrl,
@ -398,10 +393,7 @@ u8_t ll_enc_req_send(u16_t handle, u8_t *rand, u8_t *ediv, u8_t *ltk)
return BT_HCI_ERR_CMD_DISALLOWED;
}
conn->llcp.encryption.initiate = 1U;
conn->llcp_type = LLCP_ENCRYPTION;
conn->llcp_req++;
conn->llcp_enc.req++;
return 0;
}

View file

@ -393,7 +393,7 @@ u8_t ll_start_enc_req_send(u16_t handle, u8_t error_code,
}
if (error_code) {
if (conn->refresh == 0U) {
if (conn->llcp_enc.refresh == 0U) {
ret = ull_conn_llcp_req(conn);
if (ret) {
return ret;
@ -415,14 +415,13 @@ u8_t ll_start_enc_req_send(u16_t handle, u8_t error_code,
conn->llcp_terminate.req++;
}
} else {
memcpy(&conn->llcp.encryption.ltk[0], ltk,
sizeof(conn->llcp.encryption.ltk));
ret = ull_conn_llcp_req(conn);
if (ret) {
return ret;
}
memcpy(&conn->llcp_enc.ltk[0], ltk, sizeof(conn->llcp_enc.ltk));
conn->llcp.encryption.error_code = 0U;
conn->llcp.encryption.initiate = 0U;