Commit 7e788678 authored by Vinayak Kariappa Chettimada's avatar Vinayak Kariappa Chettimada Committed by Anas Nashif
Browse files

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: default avatarVinayak Kariappa Chettimada <vich@nordicsemi.no>
parent 07537107
Loading
Loading
Loading
Loading
+15 −7
Changes for subsys/bluetooth/controller/ll_sw/ctrl.c: 15 added lines, 7 removed lines.
Original line number Diff line number Diff line
@@ -303,7 +303,7 @@ 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,
static u8_t chan_map_update(struct connection *conn,
			    struct pdu_data *pdu_data_rx);

#if defined(CONFIG_BT_CTLR_PHY)
@@ -2450,15 +2450,19 @@ 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;

@@ -9320,15 +9324,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,
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],