diff mbox series

[BlueZ,2/2] iso-tester: test busy CIG error does not drop existing connections

Message ID 5f173b905f8e1cc755cd53d89481c011e3c4cf48.1691238245.git.pav@iki.fi
State New
Headers show
Series [BlueZ,1/2] btdev: fix CIG ID on Set CIG Parameters error response | expand

Commit Message

Pauli Virtanen Aug. 5, 2023, 12:29 p.m. UTC
A second connection made with same CIG while the CIG is busy, shall not
disconnect the first already existing connection.

Add test for this:

ISO Connect2 Busy CIG 0x01 - Success/Invalid

This was the original intent of "ISO Connect2 CIG 0x01 -
Success/Invalid", but the busy check should not be made synchronously in
connect() (to maintain ordering with Remove CIG etc), but must be done
in hci_sync. So the test needs to check the error async and explictly
that the first conn is not dropped.
---
 tools/iso-tester.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)
diff mbox series

Patch

diff --git a/tools/iso-tester.c b/tools/iso-tester.c
index 9b9716e06..5a8b1fe68 100644
--- a/tools/iso-tester.c
+++ b/tools/iso-tester.c
@@ -2402,6 +2402,87 @@  static void test_connect2_seq(const void *test_data)
 	setup_connect(data, 0, iso_connect2_seq_cb);
 }
 
+static gboolean test_connect2_busy_done(gpointer user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	if (data->io_id[0] > 0) {
+		/* First connection still exists */
+		g_source_remove(data->io_id[0]);
+		data->io_id[0] = 0;
+		tester_test_passed();
+	} else {
+		tester_test_failed();
+	}
+
+	return FALSE;
+}
+
+static gboolean iso_connect_cb_busy_disc(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	data->io_id[0] = 0;
+
+	tester_print("Disconnected 1");
+	tester_test_failed();
+	return FALSE;
+}
+
+static gboolean iso_connect_cb_busy_2(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	struct test_data *data = tester_get_data();
+	int err, sk_err, sk;
+	socklen_t len;
+
+	data->io_id[1] = 0;
+
+	sk = g_io_channel_unix_get_fd(io);
+
+	len = sizeof(sk_err);
+
+	if (getsockopt(sk, SOL_SOCKET, SO_ERROR, &sk_err, &len) < 0)
+		err = -errno;
+	else
+		err = -sk_err;
+
+	tester_print("Connected 2: %d", err);
+
+	if (err == -EBUSY && data->io_id[0] > 0) {
+		/* Wait in case first connection still gets disconnected */
+		data->io_id[1] = g_timeout_add(250, test_connect2_busy_done,
+									data);
+	} else {
+		tester_test_failed();
+	}
+
+	return FALSE;
+}
+
+static gboolean iso_connect_cb_busy(GIOChannel *io, GIOCondition cond,
+							gpointer user_data)
+{
+	struct test_data *data = tester_get_data();
+
+	/* First connection shall not be disconnected */
+	data->io_id[0] = g_io_add_watch(io, G_IO_ERR | G_IO_HUP,
+						iso_connect_cb_busy_disc, data);
+
+	/* Second connect shall fail since CIG is now busy */
+	setup_connect(data, 1, iso_connect_cb_busy_2);
+
+	return iso_connect(io, cond, user_data);
+}
+
+static void test_connect2_busy(const void *test_data)
+{
+	struct test_data *data = tester_get_data();
+
+	setup_connect(data, 0, iso_connect_cb_busy);
+}
+
 static gboolean iso_connect_close_cb(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
@@ -2678,6 +2759,10 @@  int main(int argc, char *argv[])
 							setup_powered,
 							test_connect2);
 
+	test_iso2("ISO Connect2 Busy CIG 0x01 - Success/Invalid",
+					&connect_1_16_2_1, setup_powered,
+					test_connect2_busy);
+
 	test_iso2("ISO Defer Connect2 CIG 0x01 - Success", &defer_1_16_2_1,
 							setup_powered,
 							test_connect2);