diff --git a/subsys/bluetooth/controller/ll_sw/ctrl.c b/subsys/bluetooth/controller/ll_sw/ctrl.c index eb4c0fea54e174..24f9aa206c22b3 100644 --- a/subsys/bluetooth/controller/ll_sw/ctrl.c +++ b/subsys/bluetooth/controller/ll_sw/ctrl.c @@ -2484,9 +2484,7 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx, * with response. */ ((_radio.conn_curr->llcp_length.req == - _radio.conn_curr->llcp_length.ack) && - (pdu_data_rx->llctrl.opcode == - PDU_DATA_LLCTRL_TYPE_LENGTH_REQ)) || + _radio.conn_curr->llcp_length.ack) && node_tx) || /* or Local has active... */ ((_radio.conn_curr->llcp_length.req != _radio.conn_curr->llcp_length.ack) && @@ -2496,19 +2494,13 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx, ((((_radio.conn_curr->llcp_length.state == LLCP_LENGTH_STATE_REQ) || (_radio.conn_curr->llcp_length.state == - LLCP_LENGTH_STATE_REQ_ACK_WAIT)) && - (pdu_data_rx->llctrl.opcode == - PDU_DATA_LLCTRL_TYPE_LENGTH_REQ)) || + LLCP_LENGTH_STATE_REQ_ACK_WAIT)) && node_tx) || /* with Local waiting for response, and Peer response then * complete the Local procedure or Peer request then complete the * Peer procedure with response. */ - ((_radio.conn_curr->llcp_length.state == - LLCP_LENGTH_STATE_RSP_WAIT) && - ((pdu_data_rx->llctrl.opcode == - PDU_DATA_LLCTRL_TYPE_LENGTH_RSP) || - (pdu_data_rx->llctrl.opcode == - PDU_DATA_LLCTRL_TYPE_LENGTH_REQ)))))) { + (_radio.conn_curr->llcp_length.state == + LLCP_LENGTH_STATE_RSP_WAIT)))) { struct pdu_data_llctrl_length_req *lr; lr = &pdu_data_rx->llctrl.length_req; @@ -2694,9 +2686,21 @@ static inline u8_t isr_rx_conn_pkt_ctrl_dle(struct pdu_data *pdu_data_rx, *rx_enqueue = 1U; } } else { - /* Drop response with no Local initiated request. */ - LL_ASSERT(pdu_data_rx->llctrl.opcode == - PDU_DATA_LLCTRL_TYPE_LENGTH_RSP); + /* Drop response with no Local initiated request and duplicate + * requests. + */ + if (pdu_data_rx->llctrl.opcode != + PDU_DATA_LLCTRL_TYPE_LENGTH_RSP) { + mem_release(node_tx, &_radio.pkt_tx_ctrl_free); + + /* Defer new request if previous in resize state */ + if (_radio.conn_curr->llcp_length.state == + LLCP_LENGTH_STATE_RESIZE) { + return 1U; + } + } + + return 0; } send_length_resp: