linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH BlueZ 0/5] Additional tests for ISO and hci_sync
@ 2023-07-26 21:25 Pauli Virtanen
  2023-07-26 21:25 ` [PATCH BlueZ 1/5] btdev: check error conditions for HCI_Create_Connection_Cancel Pauli Virtanen
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: Pauli Virtanen @ 2023-07-26 21:25 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

This adds a few tests checking ISO socket handling of invalid input
parameters and cleanup in some race conditions:

    ISO QoS CIG 0xF0 - Invalid
    ISO QoS CIS 0xF0 - Invalid
    ISO Connect2 CIG 0x01 - Success/Invalid
    ISO AC 6(ii) CIS 0xEF/auto - Success
    ISO AC 6(ii) CIS 0xEF/0xEF - Invalid
    ISO Defer Close - Success
    ISO Connect Close - Success
    ISO Defer Wait Close - Success
    ISO Connect Wait Close - Success

There's also one for a hci_sync race condition that triggers GPF:

    eSCO Simultaneous Disconnect - Failure

I have a patch series fixing these, but we'll revisit the
HCI_CONN_DELETED flag there, so maybe discussion needed.

These fail on current bluetooth-next/master, so it could make most sense
to wait for the fixes first.

Pauli Virtanen (5):
  btdev: check error conditions for HCI_Create_Connection_Cancel
  sco-tester: test local and remote disconnecting simultaneously
  iso-tester: test with large CIS_ID and invalid CIG_ID/CIS_ID
  iso-tester: add tests checking Remove CIG is emitted
  btdev: fix Command Status command opcodes for Setup Sync Conn

 emulator/btdev.c   |  80 ++++++++++++++++++---
 tools/iso-tester.c | 168 +++++++++++++++++++++++++++++++++++++++++++++
 tools/sco-tester.c |  59 ++++++++++++++++
 3 files changed, 297 insertions(+), 10 deletions(-)

-- 
2.41.0


^ permalink raw reply	[flat|nested] 10+ messages in thread
* [PATCH BlueZ v2 1/5] btdev: check error conditions for HCI_Create_Connection_Cancel
@ 2023-08-01 16:38 Pauli Virtanen
  2023-08-01 18:53 ` Additional tests for ISO and hci_sync bluez.test.bot
  0 siblings, 1 reply; 10+ messages in thread
From: Pauli Virtanen @ 2023-08-01 16:38 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Pauli Virtanen

Create Connection Cancel shall return Command Complete with error status
when there is no Create Connection that can be canceled.  In these
cases, we should not send a (spurious) Connection Complete event.

Fix by keeping a list of pending Create Connection commands, and
returning command errors if there is none pending at the moment.
---

Notes:
    v2: emit Command_Complete (not Status) + fix compile

 emulator/btdev.c | 86 +++++++++++++++++++++++++++++++++++++++++-------
 monitor/bt.h     |  4 +++
 2 files changed, 79 insertions(+), 11 deletions(-)

diff --git a/emulator/btdev.c b/emulator/btdev.c
index 637f0bb98..8658b4121 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -62,6 +62,7 @@ struct hook {
 
 #define MAX_HOOK_ENTRIES 16
 #define MAX_EXT_ADV_SETS 3
+#define MAX_PENDING_CONN 16
 
 struct btdev_conn {
 	uint16_t handle;
@@ -223,6 +224,8 @@ struct btdev {
 	uint8_t  le_rl_enable;
 	uint16_t le_rl_timeout;
 
+	struct btdev *pending_conn[MAX_PENDING_CONN];
+
 	uint8_t le_local_sk256[32];
 
 	uint16_t sync_train_interval;
@@ -1211,10 +1214,36 @@ static struct btdev_conn *conn_link_bis(struct btdev *dev, struct btdev *remote,
 	return conn;
 }
 
+static void pending_conn_add(struct btdev *btdev, struct btdev *remote)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(btdev->pending_conn); ++i) {
+		if (!btdev->pending_conn[i]) {
+			btdev->pending_conn[i] = remote;
+			return;
+		}
+	}
+}
+
+static bool pending_conn_del(struct btdev *btdev, struct btdev *remote)
+{
+	unsigned int i;
+
+	for (i = 0; i < ARRAY_SIZE(btdev->pending_conn); ++i) {
+		if (btdev->pending_conn[i] == remote) {
+			btdev->pending_conn[i] = NULL;
+			return true;
+		}
+	}
+	return false;
+}
+
 static void conn_complete(struct btdev *btdev,
 					const uint8_t *bdaddr, uint8_t status)
 {
 	struct bt_hci_evt_conn_complete cc;
+	struct btdev *remote = find_btdev_by_bdaddr(bdaddr);
 
 	if (!status) {
 		struct btdev_conn *conn;
@@ -1223,6 +1252,8 @@ static void conn_complete(struct btdev *btdev,
 		if (!conn)
 			return;
 
+		pending_conn_del(conn->link->dev, btdev);
+
 		cc.status = status;
 		memcpy(cc.bdaddr, btdev->bdaddr, 6);
 		cc.encr_mode = 0x00;
@@ -1240,6 +1271,8 @@ static void conn_complete(struct btdev *btdev,
 		cc.link_type = 0x01;
 	}
 
+	pending_conn_del(btdev, remote);
+
 	cc.status = status;
 	memcpy(cc.bdaddr, bdaddr, 6);
 	cc.encr_mode = 0x00;
@@ -1260,6 +1293,8 @@ static int cmd_create_conn_complete(struct btdev *dev, const void *data,
 		memcpy(cr.dev_class, dev->dev_class, 3);
 		cr.link_type = 0x01;
 
+		pending_conn_add(dev, remote);
+
 		send_event(remote, BT_HCI_EVT_CONN_REQUEST, &cr, sizeof(cr));
 	} else {
 		conn_complete(dev, cmd->bdaddr, BT_HCI_ERR_PAGE_TIMEOUT);
@@ -1296,16 +1331,24 @@ static int cmd_add_sco_conn(struct btdev *dev, const void *data, uint8_t len)
 	cc.encr_mode = 0x00;
 
 done:
+	pending_conn_del(dev, conn->link->dev);
+
 	send_event(dev, BT_HCI_EVT_CONN_COMPLETE, &cc, sizeof(cc));
 
 	return 0;
 }
 
+static bool match_bdaddr(const void *data, const void *match_data)
+{
+	const struct btdev_conn *conn = data;
+	const uint8_t *bdaddr = match_data;
+
+	return !memcmp(conn->link->dev->bdaddr, bdaddr, 6);
+}
+
 static int cmd_create_conn_cancel(struct btdev *dev, const void *data,
 							uint8_t len)
 {
-	cmd_status(dev, BT_HCI_ERR_SUCCESS, BT_HCI_CMD_CREATE_CONN_CANCEL);
-
 	return 0;
 }
 
@@ -1313,8 +1356,37 @@ static int cmd_create_conn_cancel_complete(struct btdev *dev, const void *data,
 							uint8_t len)
 {
 	const struct bt_hci_cmd_create_conn_cancel *cmd = data;
+	struct bt_hci_rsp_create_conn_cancel rp;
+	struct btdev *remote = find_btdev_by_bdaddr(cmd->bdaddr);
+	struct btdev_conn *conn;
 
-	conn_complete(dev, cmd->bdaddr, BT_HCI_ERR_UNKNOWN_CONN_ID);
+	/* BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 4, Part E page 1848
+	 *
+	 * If the connection is already established, and the
+	 * HCI_Connection_Complete event has been sent, then the Controller
+	 * shall return an HCI_Command_Complete event with the error code
+	 * Connection Already Exists (0x0B). If the HCI_Create_Connection_Cancel
+	 * command is sent to the Controller without a preceding
+	 * HCI_Create_Connection command to the same device, the BR/EDR
+	 * Controller shall return an HCI_Command_Complete event with the error
+	 * code Unknown Connection Identifier (0x02).
+	 */
+	if (pending_conn_del(dev, remote)) {
+		rp.status = BT_HCI_ERR_SUCCESS;
+	} else {
+		conn = queue_find(dev->conns, match_bdaddr, cmd->bdaddr);
+		if (conn)
+			rp.status = BT_HCI_ERR_CONN_ALREADY_EXISTS;
+		else
+			rp.status = BT_HCI_ERR_UNKNOWN_CONN_ID;
+	}
+
+	memcpy(rp.bdaddr, cmd->bdaddr, sizeof(rp.bdaddr));
+
+	cmd_complete(dev, BT_HCI_CMD_CREATE_CONN_CANCEL, &rp, sizeof(rp));
+
+	if (!rp.status)
+		conn_complete(dev, cmd->bdaddr, BT_HCI_ERR_UNKNOWN_CONN_ID);
 
 	return 0;
 }
@@ -1372,14 +1444,6 @@ static int cmd_link_key_reply(struct btdev *dev, const void *data, uint8_t len)
 	return 0;
 }
 
-static bool match_bdaddr(const void *data, const void *match_data)
-{
-	const struct btdev_conn *conn = data;
-	const uint8_t *bdaddr = match_data;
-
-	return !memcmp(conn->link->dev->bdaddr, bdaddr, 6);
-}
-
 static void auth_complete(struct btdev_conn *conn, uint8_t status)
 {
 	struct bt_hci_evt_auth_complete ev;
diff --git a/monitor/bt.h b/monitor/bt.h
index dca2dc8b8..6fb81abfe 100644
--- a/monitor/bt.h
+++ b/monitor/bt.h
@@ -590,6 +590,10 @@ struct bt_hci_cmd_add_sco_conn {
 struct bt_hci_cmd_create_conn_cancel {
 	uint8_t  bdaddr[6];
 } __attribute__ ((packed));
+struct bt_hci_rsp_create_conn_cancel {
+	uint8_t  status;
+	uint8_t  bdaddr[6];
+} __attribute__ ((packed));
 
 #define BT_HCI_CMD_ACCEPT_CONN_REQUEST		0x0409
 struct bt_hci_cmd_accept_conn_request {
-- 
2.41.0


^ permalink raw reply related	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2023-08-01 18:53 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-07-26 21:25 [PATCH BlueZ 0/5] Additional tests for ISO and hci_sync Pauli Virtanen
2023-07-26 21:25 ` [PATCH BlueZ 1/5] btdev: check error conditions for HCI_Create_Connection_Cancel Pauli Virtanen
2023-07-26 22:21   ` Additional tests for ISO and hci_sync bluez.test.bot
2023-07-27  9:28   ` [PATCH BlueZ 1/5] btdev: check error conditions for HCI_Create_Connection_Cancel Pauli Virtanen
2023-08-01  0:19     ` Luiz Augusto von Dentz
2023-07-26 21:25 ` [PATCH BlueZ 2/5] sco-tester: test local and remote disconnecting simultaneously Pauli Virtanen
2023-07-26 21:25 ` [PATCH BlueZ 3/5] iso-tester: test with large CIS_ID and invalid CIG_ID/CIS_ID Pauli Virtanen
2023-07-26 21:25 ` [PATCH BlueZ 4/5] iso-tester: add tests checking Remove CIG is emitted Pauli Virtanen
2023-07-26 21:25 ` [PATCH BlueZ 5/5] btdev: fix Command Status command opcodes for Setup Sync Conn Pauli Virtanen
  -- strict thread matches above, loose matches on Subject: below --
2023-08-01 16:38 [PATCH BlueZ v2 1/5] btdev: check error conditions for HCI_Create_Connection_Cancel Pauli Virtanen
2023-08-01 18:53 ` Additional tests for ISO and hci_sync bluez.test.bot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).