Commit 010c5c2f authored by Wolfgang Puffitsch's avatar Wolfgang Puffitsch Committed by Anas Nashif
Browse files

Bluetooth: controller: Ignore connections from same peer



Ignore connection indications from peers that are already
connected. This is to bring the behavior of the controller in
accordance with [5.2, Vol 6, Part B, 4.5 Connection state]:
"If an advertiser receives a connection request from an initiator it
is already connected to, it shall ignore that request."

Signed-off-by: default avatarWolfgang Puffitsch <wopu@demant.com>
parent 1161c1dc
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -372,6 +372,10 @@ config BT_CTLR_CONN_RSSI
	help
	  Enable connection RSSI measurement.

config BT_CTLR_CHECK_SAME_PEER_CONN
	bool
	default BT_MAX_CONN > 1 && !BT_CTLR_ALLOW_SAME_PEER_CONN

endif # BT_CONN

config BT_CTLR_FILTER
+12 −0
Original line number Diff line number Diff line
@@ -475,6 +475,18 @@ config BT_CTLR_CONN_RSSI_EVENT
	help
	  Generate events for connection RSSI measurement.

config BT_CTLR_ALLOW_SAME_PEER_CONN
	bool "Allow connection requests from same peer"
	depends on BT_MAX_CONN > 1
	help
	  Allow connection requests from the same peer. While the
	  Bluetooth specification does not allow multiple connections
	  with the same peer, allowing such connections is useful
	  while debugging multiple connections.

	  WARNING: This option enables behavior that violates the Bluetooth
	  specification.

endif # BT_CONN

config BT_CTLR_ADV_INDICATION
+28 −7
Original line number Diff line number Diff line
@@ -893,6 +893,13 @@ uint8_t ll_adv_enable(uint8_t enable)
		conn->supervision_expire = 0;
		conn->procedure_expire = 0;

#if defined(CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN)
		conn->own_addr_type = BT_ADDR_LE_NONE->type;
		memcpy(conn->own_addr, BT_ADDR_LE_NONE->a.val, sizeof(conn->own_addr));
		conn->peer_addr_type = BT_ADDR_LE_NONE->type;
		memcpy(conn->peer_addr, BT_ADDR_LE_NONE->a.val, sizeof(conn->peer_addr));
#endif /* CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN */

		conn->common.fex_valid = 0;
		conn->slave.latency_cancel = 0;

@@ -2089,20 +2096,34 @@ static inline uint8_t *adv_pdu_adva_get(struct pdu_adv *pdu)
static const uint8_t *adva_update(struct ll_adv_set *adv, struct pdu_adv *pdu)
{
#if defined(CONFIG_BT_CTLR_PRIVACY)
	const uint8_t *tx_addr = ull_filter_adva_get(adv);
	const uint8_t *rpa = ull_filter_adva_get(adv);
#else
	const uint8_t *tx_addr = NULL;
	const uint8_t *rpa = NULL;
#endif
	const uint8_t *own_addr;
	const uint8_t *tx_addr;
	uint8_t *adv_addr;

	if (tx_addr) {
		pdu->tx_addr = 1;
	if (!rpa || IS_ENABLED(CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN)) {
		if (0) {
#if defined(CONFIG_BT_CTLR_ADV_EXT)
		} else if (ll_adv_cmds_is_ext() && pdu->tx_addr) {
		tx_addr = ll_adv_aux_random_addr_get(adv, NULL);
			own_addr = ll_adv_aux_random_addr_get(adv, NULL);
#endif
		} else {
		tx_addr = ll_addr_get(pdu->tx_addr, NULL);
			own_addr = ll_addr_get(pdu->tx_addr, NULL);
		}
	}

#if defined(CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN)
	memcpy(adv->own_addr, own_addr, BDADDR_SIZE);
#endif /* CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN */

	if (rpa) {
		pdu->tx_addr = 1;
		tx_addr = rpa;
	} else {
		tx_addr = own_addr;
	}

	adv_addr = adv_pdu_adva_get(pdu);
+4 −0
Original line number Diff line number Diff line
@@ -41,6 +41,10 @@ struct ll_adv_set {
	uint8_t  peer_addr[BDADDR_SIZE];
#endif /* CONFIG_BT_CTLR_PRIVACY */

#if defined(CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN)
	uint8_t  own_addr[BDADDR_SIZE];
#endif /* CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN */

#if defined(CONFIG_BT_CTLR_DF_ADV_CTE_TX)
	struct lll_df_adv_cfg *df_cfg;
#endif /* CONFIG_BT_CTLR_DF_ADV_CTE_TX */
+22 −0
Original line number Diff line number Diff line
@@ -770,6 +770,28 @@ uint8_t ull_conn_default_phy_rx_get(void)
}
#endif /* CONFIG_BT_CTLR_PHY */

#if defined(CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN)
bool ull_conn_peer_connected(uint8_t own_addr_type, uint8_t *own_addr,
			     uint8_t peer_addr_type, uint8_t *peer_addr)
{
	uint16_t handle;

	for (handle = 0U; handle < CONFIG_BT_MAX_CONN; handle++) {
		struct ll_conn *conn = ll_connected_get(handle);

		if (conn &&
		    conn->peer_addr_type == peer_addr_type &&
		    !memcmp(conn->peer_addr, peer_addr, BDADDR_SIZE) &&
		    conn->own_addr_type == own_addr_type &&
		    !memcmp(conn->own_addr, own_addr, BDADDR_SIZE)) {
			return true;
		}
	}

	return false;
}
#endif /* CONFIG_BT_CTLR_CHECK_SAME_PEER_CONN */

void ull_conn_setup(memq_link_t *link, struct node_rx_hdr *rx)
{
	struct node_rx_ftr *ftr;
Loading