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:
Vinayak Kariappa Chettimada 2018-12-12 07:28:22 +01:00 committed by Carles Cufí
commit afbbb97ab1

View file

@ -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],