diff mbox series

[BlueZ,8/8] tools/iso-tester: Use dedicated ISO QoS options for unicast and broadcast

Message ID 20230320143713.25449-9-iulia.tanasescu@nxp.com (mailing list archive)
State Superseded
Headers show
Series Split bt_iso_qos into dedicated structures | expand

Commit Message

Iulia Tanasescu March 20, 2023, 2:37 p.m. UTC
Convert the generic bt_iso_qos structure into dedicated ISO QoS structures
for unicast or broadcast.

---
 tools/iso-tester.c | 270 +++++++++++++++++++++++++++++++++------------
 1 file changed, 200 insertions(+), 70 deletions(-)
diff mbox series

Patch

diff --git a/tools/iso-tester.c b/tools/iso-tester.c
index e4582573a..a763c6a09 100644
--- a/tools/iso-tester.c
+++ b/tools/iso-tester.c
@@ -4,6 +4,7 @@ 
  *  BlueZ - Bluetooth protocol stack for Linux
  *
  *  Copyright (C) 2022  Intel Corporation.
+ *  Copyright 2023 NXP
  *
  */
 
@@ -119,10 +120,52 @@ 
 #define QOS_48_5_2 QOS_OUT(7500, 75, 117, 0x02, 13)
 #define QOS_48_6_2 QOS_OUT(10000, 100, 155, 0x02, 13)
 
-#define QOS_OUT_16_2_1 QOS_OUT(10000, 10, 40, 0x02, 2)
-#define QOS_OUT_1_16_2_1 QOS_OUT_1(10000, 10, 40, 0x02, 2)
-#define QOS_OUT_1_1_16_2_1 QOS_OUT_1_1(10000, 10, 40, 0x02, 2)
-#define QOS_IN_16_2_1 QOS_IN(10000, 10, 40, 0x02, 2)
+#define QOS_SINK_FULL(_big, _in) \
+{ \
+	.options = 0x00, \
+	.skip = 0x0000, \
+	.sync_timeout = 0x4000, \
+	.sync_cte_type = 0x00, \
+	.big = _big, \
+	.encryption = 0x00, \
+	.bcode = {0}, \
+	.mse = 0x00, \
+	.timeout = 0x4000, \
+	.in = _in, \
+}
+
+#define QOS_SOURCE_FULL(_big, _bis, _out) \
+{ \
+	.sync_interval = 0x07, \
+	.big = _big, \
+	.bis = _bis, \
+	.packing = 0x00, \
+	.framing = 0x00, \
+	.encryption = 0x00, \
+	.bcode = {0}, \
+	.out = _out, \
+}
+
+#define BCAST_QOS_OUT(_interval, _latency, _sdu, _phy, _rtn) \
+	QOS_SOURCE_FULL(BT_ISO_QOS_BIG_UNSET, BT_ISO_QOS_BIS_UNSET, \
+		QOS_IO(_interval, _latency, _sdu, _phy, _rtn))
+
+#define BCAST_QOS_OUT_1(_interval, _latency, _sdu, _phy, _rtn) \
+	QOS_SOURCE_FULL(0x01, BT_ISO_QOS_BIS_UNSET, \
+		QOS_IO(_interval, _latency, _sdu, _phy, _rtn))
+
+#define BCAST_QOS_OUT_1_1(_interval, _latency, _sdu, _phy, _rtn) \
+	QOS_SOURCE_FULL(0x01, 0x01, \
+		QOS_IO(_interval, _latency, _sdu, _phy, _rtn))
+
+#define BCAST_QOS_IN(_interval, _latency, _sdu, _phy, _rtn) \
+	QOS_SINK_FULL(BT_ISO_QOS_BIG_UNSET, \
+		QOS_IO(_interval, _latency, _sdu, _phy, _rtn))
+
+#define QOS_OUT_16_2_1 BCAST_QOS_OUT(10000, 10, 40, 0x02, 2)
+#define QOS_OUT_1_16_2_1 BCAST_QOS_OUT_1(10000, 10, 40, 0x02, 2)
+#define QOS_OUT_1_1_16_2_1 BCAST_QOS_OUT_1_1(10000, 10, 40, 0x02, 2)
+#define QOS_IN_16_2_1 BCAST_QOS_IN(10000, 10, 40, 0x02, 2)
 
 struct test_data {
 	const void *test_data;
@@ -141,7 +184,9 @@  struct test_data {
 };
 
 struct iso_client_data {
-	struct bt_iso_qos qos;
+	struct bt_iso_unicast_qos unicast_qos;
+	struct bt_iso_bcast_sink_qos sink_qos;
+	struct bt_iso_bcast_source_qos source_qos;
 	int expect_err;
 	const struct iovec *send;
 	const struct iovec *recv;
@@ -369,182 +414,182 @@  static void test_data_free(void *test_data)
 	test_iso_full(name, data, setup, func, 1, reason)
 
 static const struct iso_client_data connect_8_1_1 = {
-	.qos = QOS_8_1_1,
+	.unicast_qos = QOS_8_1_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_8_2_1 = {
-	.qos = QOS_8_2_1,
+	.unicast_qos = QOS_8_2_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_16_1_1 = {
-	.qos = QOS_16_1_1,
+	.unicast_qos = QOS_16_1_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_16_2_1 = {
-	.qos = QOS_16_2_1,
+	.unicast_qos = QOS_16_2_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_1_16_2_1 = {
-	.qos = QOS_1_16_2_1,
+	.unicast_qos = QOS_1_16_2_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_1_1_16_2_1 = {
-	.qos = QOS_1_1_16_2_1,
+	.unicast_qos = QOS_1_1_16_2_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_24_1_1 = {
-	.qos = QOS_24_1_1,
+	.unicast_qos = QOS_24_1_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_24_2_1 = {
-	.qos = QOS_24_2_1,
+	.unicast_qos = QOS_24_2_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_32_1_1 = {
-	.qos = QOS_32_1_1,
+	.unicast_qos = QOS_32_1_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_32_2_1 = {
-	.qos = QOS_32_2_1,
+	.unicast_qos = QOS_32_2_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_44_1_1 = {
-	.qos = QOS_44_1_1,
+	.unicast_qos = QOS_44_1_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_44_2_1 = {
-	.qos = QOS_44_2_1,
+	.unicast_qos = QOS_44_2_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_48_1_1 = {
-	.qos = QOS_48_1_1,
+	.unicast_qos = QOS_48_1_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_48_2_1 = {
-	.qos = QOS_48_2_1,
+	.unicast_qos = QOS_48_2_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_48_3_1 = {
-	.qos = QOS_48_3_1,
+	.unicast_qos = QOS_48_3_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_48_4_1 = {
-	.qos = QOS_48_4_1,
+	.unicast_qos = QOS_48_4_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_48_5_1 = {
-	.qos = QOS_48_5_1,
+	.unicast_qos = QOS_48_5_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_48_6_1 = {
-	.qos = QOS_48_6_1,
+	.unicast_qos = QOS_48_6_1,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_8_1_2 = {
-	.qos = QOS_8_1_2,
+	.unicast_qos = QOS_8_1_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_8_2_2 = {
-	.qos = QOS_8_2_2,
+	.unicast_qos = QOS_8_2_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_16_1_2 = {
-	.qos = QOS_16_1_2,
+	.unicast_qos = QOS_16_1_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_16_2_2 = {
-	.qos = QOS_16_2_2,
+	.unicast_qos = QOS_16_2_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_24_1_2 = {
-	.qos = QOS_24_1_2,
+	.unicast_qos = QOS_24_1_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_24_2_2 = {
-	.qos = QOS_24_2_2,
+	.unicast_qos = QOS_24_2_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_32_1_2 = {
-	.qos = QOS_32_1_2,
+	.unicast_qos = QOS_32_1_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_32_2_2 = {
-	.qos = QOS_32_2_2,
+	.unicast_qos = QOS_32_2_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_44_1_2 = {
-	.qos = QOS_44_1_2,
+	.unicast_qos = QOS_44_1_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_44_2_2 = {
-	.qos = QOS_44_2_2,
+	.unicast_qos = QOS_44_2_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_48_1_2 = {
-	.qos = QOS_48_1_2,
+	.unicast_qos = QOS_48_1_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_48_2_2 = {
-	.qos = QOS_48_2_2,
+	.unicast_qos = QOS_48_2_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_48_3_2 = {
-	.qos = QOS_48_3_2,
+	.unicast_qos = QOS_48_3_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_48_4_2 = {
-	.qos = QOS_48_4_2,
+	.unicast_qos = QOS_48_4_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_48_5_2 = {
-	.qos = QOS_48_5_2,
+	.unicast_qos = QOS_48_5_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_48_6_2 = {
-	.qos = QOS_48_6_2,
+	.unicast_qos = QOS_48_6_2,
 	.expect_err = 0
 };
 
 static const struct iso_client_data connect_invalid = {
-	.qos = QOS(0, 0, 0, 0, 0),
+	.unicast_qos = QOS(0, 0, 0, 0, 0),
 	.expect_err = -EINVAL
 };
 
 static const struct iso_client_data connect_reject = {
-	.qos = QOS_16_1_2,
+	.unicast_qos = QOS_16_1_2,
 	.expect_err = -ENOSYS
 };
 
@@ -561,20 +606,20 @@  static const struct iovec send_48_2_1 = {
 };
 
 static const struct iso_client_data connect_16_2_1_send = {
-	.qos = QOS_16_2_1,
+	.unicast_qos = QOS_16_2_1,
 	.expect_err = 0,
 	.send = &send_16_2_1,
 };
 
 static const struct iso_client_data listen_16_2_1_recv = {
-	.qos = QOS_16_2_1,
+	.unicast_qos = QOS_16_2_1,
 	.expect_err = 0,
 	.recv = &send_16_2_1,
 	.server = true,
 };
 
 static const struct iso_client_data listen_16_2_1_recv_ts = {
-	.qos = QOS_16_2_1,
+	.unicast_qos = QOS_16_2_1,
 	.expect_err = 0,
 	.recv = &send_16_2_1,
 	.server = true,
@@ -582,27 +627,27 @@  static const struct iso_client_data listen_16_2_1_recv_ts = {
 };
 
 static const struct iso_client_data defer_16_2_1 = {
-	.qos = QOS_16_2_1,
+	.unicast_qos = QOS_16_2_1,
 	.expect_err = 0,
 	.defer = true,
 };
 
 static const struct iso_client_data connect_16_2_1_defer_send = {
-	.qos = QOS_16_2_1,
+	.unicast_qos = QOS_16_2_1,
 	.expect_err = 0,
 	.send = &send_16_2_1,
 	.defer = true,
 };
 
 static const struct iso_client_data connect_48_2_1_defer_send = {
-	.qos = QOS_48_2_1,
+	.unicast_qos = QOS_48_2_1,
 	.expect_err = 0,
 	.send = &send_16_2_1,
 	.defer = true,
 };
 
 static const struct iso_client_data listen_16_2_1_defer_recv = {
-	.qos = QOS_16_2_1,
+	.unicast_qos = QOS_16_2_1,
 	.expect_err = 0,
 	.recv = &send_16_2_1,
 	.server = true,
@@ -610,7 +655,7 @@  static const struct iso_client_data listen_16_2_1_defer_recv = {
 };
 
 static const struct iso_client_data listen_48_2_1_defer_recv = {
-	.qos = QOS_48_2_1,
+	.unicast_qos = QOS_48_2_1,
 	.expect_err = 0,
 	.recv = &send_48_2_1,
 	.server = true,
@@ -618,7 +663,7 @@  static const struct iso_client_data listen_48_2_1_defer_recv = {
 };
 
 static const struct iso_client_data listen_16_2_1_defer_reject = {
-	.qos = QOS_16_2_1,
+	.unicast_qos = QOS_16_2_1,
 	.expect_err = -1,
 	.recv = &send_16_2_1,
 	.server = true,
@@ -626,50 +671,51 @@  static const struct iso_client_data listen_16_2_1_defer_reject = {
 };
 
 static const struct iso_client_data connect_16_2_1_send_recv = {
-	.qos = QOS_16_2_1,
+	.unicast_qos = QOS_16_2_1,
 	.expect_err = 0,
 	.send = &send_16_2_1,
 	.recv = &send_16_2_1,
 };
 
 static const struct iso_client_data disconnect_16_2_1 = {
-	.qos = QOS_16_2_1,
+	.unicast_qos = QOS_16_2_1,
 	.expect_err = 0,
 	.disconnect = true,
 };
 
 static const struct iso_client_data reconnect_16_2_1 = {
-	.qos = QOS_16_2_1,
+	.unicast_qos = QOS_16_2_1,
 	.expect_err = 0,
 	.disconnect = true,
 };
 
 static const struct iso_client_data bcast_16_2_1_send = {
-	.qos = QOS_OUT_16_2_1,
+	.source_qos = QOS_OUT_16_2_1,
 	.expect_err = 0,
 	.send = &send_16_2_1,
 	.bcast = true,
 };
 
 static const struct iso_client_data bcast_1_16_2_1_send = {
-	.qos = QOS_OUT_1_16_2_1,
+	.source_qos = QOS_OUT_1_16_2_1,
 	.expect_err = 0,
 	.send = &send_16_2_1,
 	.bcast = true,
 };
 
 static const struct iso_client_data bcast_1_1_16_2_1_send = {
-	.qos = QOS_OUT_1_1_16_2_1,
+	.source_qos = QOS_OUT_1_1_16_2_1,
 	.expect_err = 0,
 	.send = &send_16_2_1,
 	.bcast = true,
 };
 
 static const struct iso_client_data bcast_16_2_1_recv = {
-	.qos = QOS_IN_16_2_1,
+	.sink_qos = QOS_IN_16_2_1,
 	.expect_err = 0,
 	.recv = &send_16_2_1,
 	.bcast = true,
+	.server = true,
 };
 
 static void client_connectable_complete(uint16_t opcode, uint8_t status,
@@ -854,7 +900,7 @@  static void test_getsockopt(const void *test_data)
 {
 	int sk, err;
 	socklen_t len;
-	struct bt_iso_qos qos;
+	struct bt_iso_unicast_qos qos;
 
 	sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_ISO);
 	if (sk < 0) {
@@ -867,7 +913,7 @@  static void test_getsockopt(const void *test_data)
 	len = sizeof(qos);
 	memset(&qos, 0, len);
 
-	err = getsockopt(sk, SOL_BLUETOOTH, BT_ISO_QOS, &qos, &len);
+	err = getsockopt(sk, SOL_BLUETOOTH, BT_ISO_UNICAST_QOS, &qos, &len);
 	if (err < 0) {
 		tester_warn("Can't get socket option : %s (%d)",
 							strerror(errno), errno);
@@ -885,7 +931,7 @@  static void test_setsockopt(const void *test_data)
 {
 	int sk, err;
 	socklen_t len;
-	struct bt_iso_qos qos = QOS_16_1_2;
+	struct bt_iso_unicast_qos qos = QOS_16_1_2;
 
 	sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_ISO);
 	if (sk < 0) {
@@ -895,7 +941,8 @@  static void test_setsockopt(const void *test_data)
 		goto end;
 	}
 
-	err = setsockopt(sk, SOL_BLUETOOTH, BT_ISO_QOS, &qos, sizeof(qos));
+	err = setsockopt(sk, SOL_BLUETOOTH, BT_ISO_UNICAST_QOS,
+						&qos, sizeof(qos));
 	if (err < 0) {
 		tester_warn("Can't set socket option : %s (%d)",
 							strerror(errno), errno);
@@ -906,7 +953,7 @@  static void test_setsockopt(const void *test_data)
 	len = sizeof(qos);
 	memset(&qos, 0, len);
 
-	err = getsockopt(sk, SOL_BLUETOOTH, BT_ISO_QOS, &qos, &len);
+	err = getsockopt(sk, SOL_BLUETOOTH, BT_ISO_UNICAST_QOS, &qos, &len);
 	if (err < 0) {
 		tester_warn("Can't get socket option : %s (%d)",
 							strerror(errno), errno);
@@ -1004,8 +1051,14 @@  static int connect_iso_sock(struct test_data *data, uint8_t num, int sk)
 		}
 	}
 
-	err = setsockopt(sk, SOL_BLUETOOTH, BT_ISO_QOS, &isodata->qos,
-						sizeof(isodata->qos));
+	if (!isodata->bcast)
+		err = setsockopt(sk, SOL_BLUETOOTH, BT_ISO_UNICAST_QOS,
+			&isodata->unicast_qos, sizeof(isodata->unicast_qos));
+	else {
+		err = setsockopt(sk, SOL_BLUETOOTH, BT_ISO_BCAST_SOURCE_QOS,
+			&isodata->source_qos, sizeof(isodata->source_qos));
+	}
+
 	if (err < 0) {
 		tester_warn("Can't set socket BT_ISO_QOS option : %s (%d)",
 							strerror(errno), errno);
@@ -1080,8 +1133,8 @@  static bool check_io_qos(const struct bt_iso_io_qos *io1,
 	return true;
 }
 
-static bool check_qos(const struct bt_iso_qos *qos1,
-				const struct bt_iso_qos *qos2)
+static bool check_unicast_qos(const struct bt_iso_unicast_qos *qos1,
+				const struct bt_iso_unicast_qos *qos2)
 {
 	if (qos1->cig != BT_ISO_QOS_CIG_UNSET &&
 			qos2->cig != BT_ISO_QOS_CIG_UNSET &&
@@ -1124,6 +1177,62 @@  static bool check_qos(const struct bt_iso_qos *qos1,
 	return true;
 }
 
+static bool check_bcast_source_qos(const struct bt_iso_bcast_source_qos *qos1,
+				const struct bt_iso_bcast_source_qos *qos2)
+{
+	if (qos1->sync_interval != qos2->sync_interval) {
+		tester_warn("Unexpected QoS sync interval: 0x%02x != 0x%02x",
+				qos1->sync_interval, qos2->sync_interval);
+		return false;
+	}
+
+	if (qos1->big != BT_ISO_QOS_BIG_UNSET &&
+			qos2->big != BT_ISO_QOS_BIG_UNSET &&
+			qos1->big != qos2->big) {
+		tester_warn("Unexpected BIG ID: 0x%02x != 0x%02x",
+				qos1->big, qos2->big);
+		return false;
+	}
+
+	if (qos1->bis != BT_ISO_QOS_BIS_UNSET &&
+			qos2->bis != BT_ISO_QOS_BIS_UNSET &&
+			qos1->bis != qos2->bis) {
+		tester_warn("Unexpected BIS ID: 0x%02x != 0x%02x",
+				qos1->bis, qos2->bis);
+		return false;
+	}
+
+	if (qos1->packing != qos2->packing) {
+		tester_warn("Unexpected QoS packing: 0x%02x != 0x%02x",
+				qos1->packing, qos2->packing);
+		return false;
+	}
+
+	if (qos1->framing != qos2->framing) {
+		tester_warn("Unexpected QoS framing: 0x%02x != 0x%02x",
+				qos1->framing, qos2->framing);
+		return false;
+	}
+
+	if (qos1->encryption != qos2->encryption) {
+		tester_warn("Unexpected QoS encryption: 0x%02x != 0x%02x",
+				qos1->encryption, qos2->encryption);
+		return false;
+	}
+
+	if (memcmp(qos1->bcode, qos2->bcode, sizeof(qos1->bcode))) {
+		tester_warn("Unexpected QoS Broadcast Code");
+		return false;
+	}
+
+	if (!check_io_qos(&qos1->out, &qos2->out)) {
+		tester_warn("Unexpected Output QoS");
+		return false;
+	}
+
+	return true;
+}
+
 static gboolean iso_recv_data(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
@@ -1249,14 +1358,28 @@  static gboolean iso_connect(GIOChannel *io, GIOCondition cond,
 	const struct iso_client_data *isodata = data->test_data;
 	int err, sk_err, sk;
 	socklen_t len;
-	struct bt_iso_qos qos;
+	int optname;
+	bool ret = true;
+
+	union {
+		struct bt_iso_unicast_qos unicast_qos;
+		struct bt_iso_bcast_sink_qos sink_qos;
+		struct bt_iso_bcast_source_qos source_qos;
+	} qos;
 
 	sk = g_io_channel_unix_get_fd(io);
 
+	if (!isodata->bcast)
+		optname = BT_ISO_UNICAST_QOS;
+	else if (isodata->server)
+		optname = BT_ISO_BCAST_SINK_QOS;
+	else
+		optname = BT_ISO_BCAST_SOURCE_QOS;
+
 	len = sizeof(qos);
 	memset(&qos, 0, len);
 
-	err = getsockopt(sk, SOL_BLUETOOTH, BT_ISO_QOS, &qos, &len);
+	err = getsockopt(sk, SOL_BLUETOOTH, optname, &qos, &len);
 	if (err < 0) {
 		tester_warn("Can't get socket option : %s (%d)",
 							strerror(errno), errno);
@@ -1264,7 +1387,14 @@  static gboolean iso_connect(GIOChannel *io, GIOCondition cond,
 		return FALSE;
 	}
 
-	if (!check_qos(&qos, &isodata->qos)) {
+	if (!isodata->bcast)
+		ret = check_unicast_qos(&qos.unicast_qos,
+					&isodata->unicast_qos);
+	else if (!isodata->server)
+		ret = check_bcast_source_qos(&qos.source_qos,
+					&isodata->source_qos);
+
+	if (!ret) {
 		tester_warn("Unexpected QoS parameter");
 		tester_test_failed();
 		return FALSE;
@@ -1579,7 +1709,7 @@  static void setup_listen(struct test_data *data, uint8_t num, GIOFunc func)
 		client = hciemu_get_client(data->hciemu, 0);
 		host = hciemu_client_host(client);
 
-		bthost_set_cig_params(host, 0x01, 0x01, &isodata->qos);
+		bthost_set_cig_params(host, 0x01, 0x01, &isodata->unicast_qos);
 		bthost_create_cis(host, 257, data->acl_handle);
 	}
 }