Bluetooth: controller: Fix chan map update's diff trans collision
Fix channel map update procedure implementation's handling of different transaction collision by not asserting but disconnecting the connection due to invalid behavior by peer implementation. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no>
This commit is contained in:
parent
eb9f13e3e2
commit
afbbb97ab1
1 changed files with 18 additions and 10 deletions
|
@ -302,8 +302,8 @@ static u8_t conn_update(struct connection *conn, struct pdu_data *pdu_data_rx);
|
|||
static u32_t conn_update_req(struct connection *conn);
|
||||
#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED && CONFIG_BT_CTLR_SCHED_ADVANCED */
|
||||
|
||||
static u32_t chan_map_update(struct connection *conn,
|
||||
struct pdu_data *pdu_data_rx);
|
||||
static u8_t chan_map_update(struct connection *conn,
|
||||
struct pdu_data *pdu_data_rx);
|
||||
|
||||
#if defined(CONFIG_BT_CTLR_PHY)
|
||||
static inline u8_t phy_upd_ind_recv(struct radio_pdu_node_rx *node_rx,
|
||||
|
@ -2452,17 +2452,21 @@ isr_rx_conn_pkt_ctrl(struct radio_pdu_node_rx *node_rx, u8_t *rx_enqueue)
|
|||
break;
|
||||
|
||||
case PDU_DATA_LLCTRL_TYPE_CHAN_MAP_IND:
|
||||
{
|
||||
u8_t err;
|
||||
|
||||
if (!_radio.conn_curr->role ||
|
||||
!pdu_len_cmp(PDU_DATA_LLCTRL_TYPE_CHAN_MAP_IND,
|
||||
pdu_data_rx->len)) {
|
||||
goto isr_rx_conn_unknown_rsp_send;
|
||||
}
|
||||
|
||||
if (chan_map_update(_radio.conn_curr, pdu_data_rx)) {
|
||||
_radio.conn_curr->llcp_terminate.reason_peer =
|
||||
BT_HCI_ERR_INSTANT_PASSED;
|
||||
err = chan_map_update(_radio.conn_curr, pdu_data_rx);
|
||||
if (err) {
|
||||
_radio.conn_curr->llcp_terminate.reason_peer = err;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case PDU_DATA_LLCTRL_TYPE_TERMINATE_IND:
|
||||
if (!pdu_len_cmp(PDU_DATA_LLCTRL_TYPE_TERMINATE_IND,
|
||||
|
@ -9334,15 +9338,19 @@ static u32_t conn_update_req(struct connection *conn)
|
|||
}
|
||||
#endif /* CONFIG_BT_CTLR_XTAL_ADVANCED && CONFIG_BT_CTLR_SCHED_ADVANCED */
|
||||
|
||||
static u32_t chan_map_update(struct connection *conn,
|
||||
struct pdu_data *pdu_data_rx)
|
||||
static u8_t chan_map_update(struct connection *conn,
|
||||
struct pdu_data *pdu_data_rx)
|
||||
{
|
||||
if (((pdu_data_rx->llctrl.chan_map_ind.instant -
|
||||
conn->event_counter) & 0xffff) > 0x7fff) {
|
||||
return 1;
|
||||
return BT_HCI_ERR_INSTANT_PASSED;
|
||||
}
|
||||
|
||||
/* different transaction collision */
|
||||
if (conn->llcp_req != conn->llcp_ack) {
|
||||
return BT_HCI_ERR_DIFF_TRANS_COLLISION;
|
||||
}
|
||||
|
||||
LL_ASSERT(conn->llcp_req == conn->llcp_ack);
|
||||
|
||||
memcpy(&conn->llcp.chan_map.chm[0],
|
||||
&pdu_data_rx->llctrl.chan_map_ind.chm[0],
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue