2023-03-31 15:43:09

by Iulia Tanasescu

[permalink] [raw]
Subject: [PATCH BlueZ v3 0/1] Split bt_iso_qos into dedicated structures

This patch adds support for additional ISO broadcast QoS parameters,
that the user can set before performing broadcast procedures
using an ISO socket.

This patch splits the "bt_iso_qos" structure into dedicated
unicast and broadcast structures, so that ISO sockets
can be configured with dedicated QoS options depending
on the type of ISO procedures to run.

This patch depends on the bluetooth-next patch
[v3,1/1] Bluetooth: Split bt_iso_qos into dedicated structures.

Iulia Tanasescu (1):
Split bt_iso_qos into dedicated structures

btio/btio.c | 7 +-
client/player.c | 7 +-
emulator/bthost.c | 31 ++++---
lib/bluetooth.h | 46 +++++++---
profiles/audio/bap.c | 19 +++--
tools/btiotest.c | 17 ++--
tools/iso-tester.c | 199 +++++++++++++++++++++++++++++++++++++------
tools/isotest.c | 157 +++++++++++++++++++++++-----------
8 files changed, 359 insertions(+), 124 deletions(-)


base-commit: 54601cbcf283468ecb867d3db14ddbd1badbe858
--
2.34.1


2023-03-31 15:43:09

by Iulia Tanasescu

[permalink] [raw]
Subject: [PATCH BlueZ v3 1/1] Split bt_iso_qos into dedicated structures

Split bt_iso_qos into dedicated unicast and broadcast
structures and add additional broadcast parameters.

---
btio/btio.c | 7 +-
client/player.c | 7 +-
emulator/bthost.c | 31 ++++---
lib/bluetooth.h | 46 +++++++---
profiles/audio/bap.c | 19 +++--
tools/btiotest.c | 17 ++--
tools/iso-tester.c | 199 +++++++++++++++++++++++++++++++++++++------
tools/isotest.c | 157 +++++++++++++++++++++++-----------
8 files changed, 359 insertions(+), 124 deletions(-)

diff --git a/btio/btio.c b/btio/btio.c
index 1ad42728d..6f6d76dc8 100644
--- a/btio/btio.c
+++ b/btio/btio.c
@@ -5,6 +5,7 @@
*
* Copyright (C) 2009-2010 Marcel Holtmann <[email protected]>
* Copyright (C) 2009-2010 Nokia Corporation
+ * Copyright 2023 NXP
*
*
*/
@@ -1608,13 +1609,13 @@ static gboolean iso_get(int sock, GError **err, BtIOOption opt1, va_list args)
*(va_arg(args, uint8_t *)) = dst.iso_bdaddr_type;
break;
case BT_IO_OPT_MTU:
- *(va_arg(args, uint16_t *)) = qos.out.sdu;
+ *(va_arg(args, uint16_t *)) = qos.ucast.out.sdu;
break;
case BT_IO_OPT_IMTU:
- *(va_arg(args, uint16_t *)) = qos.in.sdu;
+ *(va_arg(args, uint16_t *)) = qos.ucast.in.sdu;
break;
case BT_IO_OPT_OMTU:
- *(va_arg(args, uint16_t *)) = qos.out.sdu;
+ *(va_arg(args, uint16_t *)) = qos.ucast.out.sdu;
break;
case BT_IO_OPT_PHY:
if (get_phy(sock, &phy) < 0) {
diff --git a/client/player.c b/client/player.c
index 63e11db09..5572cc566 100644
--- a/client/player.c
+++ b/client/player.c
@@ -4,6 +4,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2020 Intel Corporation. All rights reserved.
+ * Copyright 2023 NXP
*
*
*/
@@ -3534,7 +3535,7 @@ static bool transport_timer_read(struct io *io, void *user_data)
}

/* num of packets = latency (ms) / interval (us) */
- num = (qos.out.latency * 1000 / qos.out.interval);
+ num = (qos.ucast.out.latency * 1000 / qos.ucast.out.interval);

ret = transport_send_seq(transport, transport->fd, num);
if (ret < 0) {
@@ -3570,8 +3571,8 @@ static int transport_send(struct transport *transport, int fd,
return -errno;

memset(&ts, 0, sizeof(ts));
- ts.it_value.tv_nsec = qos->out.latency * 1000000;
- ts.it_interval.tv_nsec = qos->out.latency * 1000000;
+ ts.it_value.tv_nsec = qos->ucast.out.latency * 1000000;
+ ts.it_interval.tv_nsec = qos->ucast.out.latency * 1000000;

if (timerfd_settime(timer_fd, TFD_TIMER_ABSTIME, &ts, NULL) < 0)
return -errno;
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 4671fe17d..8cdfa0c06 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -5,6 +5,7 @@
*
* Copyright (C) 2011-2012 Intel Corporation
* Copyright (C) 2004-2010 Marcel Holtmann <[email protected]>
+ * Copyright 2023 NXP
*
*
*/
@@ -3178,22 +3179,24 @@ void bthost_set_cig_params(struct bthost *bthost, uint8_t cig_id,
cp = malloc(sizeof(*cp) + sizeof(*cp->cis));
memset(cp, 0, sizeof(*cp) + sizeof(*cp->cis));
cp->cig_id = cig_id;
- put_le24(qos->in.interval ? qos->in.interval : qos->out.interval,
- cp->c_interval);
- put_le24(qos->out.interval ? qos->out.interval : qos->in.interval,
- cp->p_interval);
- cp->c_latency = cpu_to_le16(qos->in.latency ? qos->in.latency :
- qos->out.latency);
- cp->p_latency = cpu_to_le16(qos->out.latency ? qos->out.latency :
- qos->in.latency);
+ put_le24(qos->ucast.in.interval ? qos->ucast.in.interval :
+ qos->ucast.out.interval, cp->c_interval);
+ put_le24(qos->ucast.out.interval ? qos->ucast.out.interval :
+ qos->ucast.in.interval, cp->p_interval);
+ cp->c_latency = cpu_to_le16(qos->ucast.in.latency ?
+ qos->ucast.in.latency : qos->ucast.out.latency);
+ cp->p_latency = cpu_to_le16(qos->ucast.out.latency ?
+ qos->ucast.out.latency : qos->ucast.in.latency);
cp->num_cis = 0x01;
cp->cis[0].cis_id = cis_id;
- cp->cis[0].c_sdu = qos->in.sdu;
- cp->cis[0].p_sdu = qos->out.sdu;
- cp->cis[0].c_phy = qos->in.phy ? qos->in.phy : qos->out.phy;
- cp->cis[0].p_phy = qos->out.phy ? qos->out.phy : qos->in.phy;
- cp->cis[0].c_rtn = qos->in.rtn;
- cp->cis[0].p_rtn = qos->out.rtn;
+ cp->cis[0].c_sdu = qos->ucast.in.sdu;
+ cp->cis[0].p_sdu = qos->ucast.out.sdu;
+ cp->cis[0].c_phy = qos->ucast.in.phy ? qos->ucast.in.phy :
+ qos->ucast.out.phy;
+ cp->cis[0].p_phy = qos->ucast.out.phy ? qos->ucast.out.phy :
+ qos->ucast.in.phy;
+ cp->cis[0].c_rtn = qos->ucast.in.rtn;
+ cp->cis[0].p_rtn = qos->ucast.out.rtn;

send_command(bthost, BT_HCI_CMD_LE_SET_CIG_PARAMS, cp,
sizeof(*cp) + sizeof(*cp->cis));
diff --git a/lib/bluetooth.h b/lib/bluetooth.h
index af5fbcfbc..b4bb6748f 100644
--- a/lib/bluetooth.h
+++ b/lib/bluetooth.h
@@ -6,6 +6,7 @@
* Copyright (C) 2000-2001 Qualcomm Incorporated
* Copyright (C) 2002-2003 Maxim Krasnyansky <[email protected]>
* Copyright (C) 2002-2010 Marcel Holtmann <[email protected]>
+ * Copyright 2023 NXP
*
*
*/
@@ -146,6 +147,9 @@ struct bt_voice {
#define BT_ISO_QOS_CIG_UNSET 0xff
#define BT_ISO_QOS_CIS_UNSET 0xff

+#define BT_ISO_QOS_BIG_UNSET 0xff
+#define BT_ISO_QOS_BIS_UNSET 0xff
+
struct bt_iso_io_qos {
uint32_t interval;
uint16_t latency;
@@ -154,25 +158,41 @@ struct bt_iso_io_qos {
uint8_t rtn;
};

-struct bt_iso_qos {
- union {
- uint8_t cig;
- uint8_t big;
- };
- union {
- uint8_t cis;
- uint8_t bis;
- };
- union {
- uint8_t sca;
- uint8_t sync_interval;
- };
+struct bt_iso_ucast_qos {
+ uint8_t cig;
+ uint8_t cis;
+ uint8_t sca;
uint8_t packing;
uint8_t framing;
struct bt_iso_io_qos in;
struct bt_iso_io_qos out;
};

+struct bt_iso_bcast_qos {
+ uint8_t big;
+ uint8_t bis;
+ uint8_t sync_interval;
+ uint8_t packing;
+ uint8_t framing;
+ struct bt_iso_io_qos in;
+ struct bt_iso_io_qos out;
+ uint8_t encryption;
+ uint8_t bcode[16];
+ uint8_t options;
+ uint16_t skip;
+ uint16_t sync_timeout;
+ uint8_t sync_cte_type;
+ uint8_t mse;
+ uint16_t timeout;
+};
+
+struct bt_iso_qos {
+ union {
+ struct bt_iso_ucast_qos ucast;
+ struct bt_iso_bcast_qos bcast;
+ };
+};
+
#define BT_CODEC 19
struct bt_codec {
uint8_t id;
diff --git a/profiles/audio/bap.c b/profiles/audio/bap.c
index cfe685466..a5e253577 100644
--- a/profiles/audio/bap.c
+++ b/profiles/audio/bap.c
@@ -4,6 +4,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2022 Intel Corporation. All rights reserved.
+ * Copyright 2023 NXP
*
*
*/
@@ -748,10 +749,10 @@ static bool match_stream_qos(const void *data, const void *user_data)

qos = bt_bap_stream_get_qos((void *)stream);

- if (iso_qos->cig != qos->cig_id)
+ if (iso_qos->ucast.cig != qos->cig_id)
return false;

- return iso_qos->cis == qos->cis_id;
+ return iso_qos->ucast.cis == qos->cis_id;
}

static void iso_confirm_cb(GIOChannel *io, void *user_data)
@@ -773,7 +774,7 @@ static void iso_confirm_cb(GIOChannel *io, void *user_data)
}

DBG("ISO: incoming connect from %s (CIG 0x%02x CIS 0x%02x)",
- address, qos.cig, qos.cis);
+ address, qos.ucast.cig, qos.ucast.cis);

stream = queue_remove_if(data->streams, match_stream_qos, &qos);
if (!stream) {
@@ -992,11 +993,11 @@ static void bap_create_io(struct bap_data *data, struct bap_ep *ep,
}

memset(&iso_qos, 0, sizeof(iso_qos));
- iso_qos.cig = qos[0] ? qos[0]->cig_id : qos[1]->cig_id;
- iso_qos.cis = qos[0] ? qos[0]->cis_id : qos[1]->cis_id;
+ iso_qos.ucast.cig = qos[0] ? qos[0]->cig_id : qos[1]->cig_id;
+ iso_qos.ucast.cis = qos[0] ? qos[0]->cis_id : qos[1]->cis_id;

- bap_iso_qos(qos[0], &iso_qos.in);
- bap_iso_qos(qos[1], &iso_qos.out);
+ bap_iso_qos(qos[0], &iso_qos.ucast.in);
+ bap_iso_qos(qos[1], &iso_qos.ucast.out);

if (ep)
bap_connect_io(data, ep, stream, &iso_qos, defer);
@@ -1191,8 +1192,8 @@ static void bap_connecting(struct bt_bap_stream *stream, bool state, int fd,
return;
}

- ep->qos.cig_id = qos.cig;
- ep->qos.cis_id = qos.cis;
+ ep->qos.cig_id = qos.ucast.cig;
+ ep->qos.cis_id = qos.ucast.cis;
}

DBG("stream %p fd %d: CIG 0x%02x CIS 0x%02x", stream, fd,
diff --git a/tools/btiotest.c b/tools/btiotest.c
index 193e1395b..75af90543 100644
--- a/tools/btiotest.c
+++ b/tools/btiotest.c
@@ -5,6 +5,7 @@
*
* Copyright (C) 2009-2010 Marcel Holtmann <[email protected]>
* Copyright (C) 2009-2010 Nokia Corporation
+ * Copyright 2023 NXP
*
*
*/
@@ -39,13 +40,15 @@ static int opt_update_sec = 0;
}

struct bt_iso_qos qos = {
- .cig = BT_ISO_QOS_CIG_UNSET,
- .cis = BT_ISO_QOS_CIG_UNSET,
- .sca = 0x07,
- .packing = 0x00,
- .framing = 0x00,
- .in = DEFAULT_IO_QOS,
- .out = DEFAULT_IO_QOS,
+ .ucast = {
+ .cig = BT_ISO_QOS_CIG_UNSET,
+ .cis = BT_ISO_QOS_CIG_UNSET,
+ .sca = 0x07,
+ .packing = 0x00,
+ .framing = 0x00,
+ .in = DEFAULT_IO_QOS,
+ .out = DEFAULT_IO_QOS,
+ },
};

struct io_data {
diff --git a/tools/iso-tester.c b/tools/iso-tester.c
index e4582573a..0f10f8940 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
*
*/

@@ -42,13 +43,15 @@

#define QOS_FULL(_cig, _cis, _in, _out) \
{ \
- .cig = _cig, \
- .cis = _cis, \
- .sca = 0x07, \
- .packing = 0x00, \
- .framing = 0x00, \
- .in = _in, \
- .out = _out, \
+ .ucast = { \
+ .cig = _cig, \
+ .cis = _cis, \
+ .sca = 0x07, \
+ .packing = 0x00, \
+ .framing = 0x00, \
+ .in = _in, \
+ .out = _out, \
+ },\
}

#define QOS(_interval, _latency, _sdu, _phy, _rtn) \
@@ -119,10 +122,47 @@
#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_BCAST_FULL(_big, _bis, _in, _out) \
+{ \
+ .bcast = { \
+ .big = _big, \
+ .bis = _bis, \
+ .sync_interval = 0x07, \
+ .packing = 0x00, \
+ .framing = 0x00, \
+ .in = _in, \
+ .out = _out, \
+ .encryption = 0x00, \
+ .bcode = {0}, \
+ .options = 0x00, \
+ .skip = 0x0000, \
+ .sync_timeout = 0x4000, \
+ .sync_cte_type = 0x00, \
+ .mse = 0x00, \
+ .timeout = 0x4000, \
+ }, \
+}
+
+#define BCAST_QOS_OUT(_interval, _latency, _sdu, _phy, _rtn) \
+ QOS_BCAST_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_BCAST_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_BCAST_FULL(0x01, 0x01, \
+ {}, QOS_IO(_interval, _latency, _sdu, _phy, _rtn))
+
+#define BCAST_QOS_IN(_interval, _latency, _sdu, _phy, _rtn) \
+ QOS_BCAST_FULL(BT_ISO_QOS_BIG_UNSET, BT_ISO_QOS_BIS_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;
@@ -670,6 +710,7 @@ static const struct iso_client_data bcast_16_2_1_recv = {
.expect_err = 0,
.recv = &send_16_2_1,
.bcast = true,
+ .server = true,
};

static void client_connectable_complete(uint16_t opcode, uint8_t status,
@@ -1080,43 +1121,43 @@ static bool check_io_qos(const struct bt_iso_io_qos *io1,
return true;
}

-static bool check_qos(const struct bt_iso_qos *qos1,
+static bool check_ucast_qos(const struct bt_iso_qos *qos1,
const struct bt_iso_qos *qos2)
{
- if (qos1->cig != BT_ISO_QOS_CIG_UNSET &&
- qos2->cig != BT_ISO_QOS_CIG_UNSET &&
- qos1->cig != qos2->cig) {
+ if (qos1->ucast.cig != BT_ISO_QOS_CIG_UNSET &&
+ qos2->ucast.cig != BT_ISO_QOS_CIG_UNSET &&
+ qos1->ucast.cig != qos2->ucast.cig) {
tester_warn("Unexpected CIG ID: 0x%02x != 0x%02x",
- qos1->cig, qos2->cig);
+ qos1->ucast.cig, qos2->ucast.cig);
return false;
}

- if (qos1->cis != BT_ISO_QOS_CIS_UNSET &&
- qos2->cis != BT_ISO_QOS_CIS_UNSET &&
- qos1->cis != qos2->cis) {
+ if (qos1->ucast.cis != BT_ISO_QOS_CIS_UNSET &&
+ qos2->ucast.cis != BT_ISO_QOS_CIS_UNSET &&
+ qos1->ucast.cis != qos2->ucast.cis) {
tester_warn("Unexpected CIS ID: 0x%02x != 0x%02x",
- qos1->cis, qos2->cis);
+ qos1->ucast.cis, qos2->ucast.cis);
return false;
}

- if (qos1->packing != qos2->packing) {
+ if (qos1->ucast.packing != qos2->ucast.packing) {
tester_warn("Unexpected QoS packing: 0x%02x != 0x%02x",
- qos1->packing, qos2->packing);
+ qos1->ucast.packing, qos2->ucast.packing);
return false;
}

- if (qos1->framing != qos2->framing) {
+ if (qos1->ucast.framing != qos2->ucast.framing) {
tester_warn("Unexpected QoS framing: 0x%02x != 0x%02x",
- qos1->framing, qos2->framing);
+ qos1->ucast.framing, qos2->ucast.framing);
return false;
}

- if (!check_io_qos(&qos1->in, &qos2->in)) {
+ if (!check_io_qos(&qos1->ucast.in, &qos2->ucast.in)) {
tester_warn("Unexpected Input QoS");
return false;
}

- if (!check_io_qos(&qos1->out, &qos2->out)) {
+ if (!check_io_qos(&qos1->ucast.out, &qos2->ucast.out)) {
tester_warn("Unexpected Output QoS");
return false;
}
@@ -1124,6 +1165,104 @@ static bool check_qos(const struct bt_iso_qos *qos1,
return true;
}

+static bool check_bcast_qos(const struct bt_iso_qos *qos1,
+ const struct bt_iso_qos *qos2)
+{
+ if (qos1->bcast.big != BT_ISO_QOS_BIG_UNSET &&
+ qos2->bcast.big != BT_ISO_QOS_BIG_UNSET &&
+ qos1->bcast.big != qos2->bcast.big) {
+ tester_warn("Unexpected BIG ID: 0x%02x != 0x%02x",
+ qos1->bcast.big, qos2->bcast.big);
+ return false;
+ }
+
+ if (qos1->bcast.bis != BT_ISO_QOS_BIS_UNSET &&
+ qos2->bcast.bis != BT_ISO_QOS_BIS_UNSET &&
+ qos1->bcast.bis != qos2->bcast.bis) {
+ tester_warn("Unexpected BIS ID: 0x%02x != 0x%02x",
+ qos1->bcast.bis, qos2->bcast.bis);
+ return false;
+ }
+
+ if (qos1->bcast.sync_interval != qos2->bcast.sync_interval) {
+ tester_warn("Unexpected QoS sync interval: 0x%02x != 0x%02x",
+ qos1->bcast.sync_interval, qos2->bcast.sync_interval);
+ return false;
+ }
+
+ if (qos1->bcast.packing != qos2->bcast.packing) {
+ tester_warn("Unexpected QoS packing: 0x%02x != 0x%02x",
+ qos1->bcast.packing, qos2->bcast.packing);
+ return false;
+ }
+
+ if (qos1->bcast.framing != qos2->bcast.framing) {
+ tester_warn("Unexpected QoS framing: 0x%02x != 0x%02x",
+ qos1->bcast.framing, qos2->bcast.framing);
+ return false;
+ }
+
+ if (!check_io_qos(&qos1->ucast.in, &qos2->ucast.in)) {
+ tester_warn("Unexpected Input QoS");
+ return false;
+ }
+
+ if (!check_io_qos(&qos1->ucast.out, &qos2->ucast.out)) {
+ tester_warn("Unexpected Output QoS");
+ return false;
+ }
+
+ if (qos1->bcast.encryption != qos2->bcast.encryption) {
+ tester_warn("Unexpected QoS encryption: 0x%02x != 0x%02x",
+ qos1->bcast.encryption, qos2->bcast.encryption);
+ return false;
+ }
+
+ if (memcmp(qos1->bcast.bcode, qos2->bcast.bcode,
+ sizeof(qos1->bcast.bcode))) {
+ tester_warn("Unexpected QoS Broadcast Code");
+ return false;
+ }
+
+ if (qos1->bcast.options != qos2->bcast.options) {
+ tester_warn("Unexpected QoS options: 0x%02x != 0x%02x",
+ qos1->bcast.options, qos2->bcast.options);
+ return false;
+ }
+
+ if (qos1->bcast.skip != qos2->bcast.skip) {
+ tester_warn("Unexpected QoS skip: 0x%04x != 0x%04x",
+ qos1->bcast.skip, qos2->bcast.skip);
+ return false;
+ }
+
+ if (qos1->bcast.sync_timeout != qos2->bcast.sync_timeout) {
+ tester_warn("Unexpected QoS sync timeout: 0x%04x != 0x%04x",
+ qos1->bcast.sync_timeout, qos2->bcast.sync_timeout);
+ return false;
+ }
+
+ if (qos1->bcast.sync_cte_type != qos2->bcast.sync_cte_type) {
+ tester_warn("Unexpected QoS sync cte type: 0x%02x != 0x%02x",
+ qos1->bcast.sync_cte_type, qos2->bcast.sync_cte_type);
+ return false;
+ }
+
+ if (qos1->bcast.mse != qos2->bcast.mse) {
+ tester_warn("Unexpected QoS MSE: 0x%02x != 0x%02x",
+ qos1->bcast.mse, qos2->bcast.mse);
+ return false;
+ }
+
+ if (qos1->bcast.timeout != qos2->bcast.timeout) {
+ tester_warn("Unexpected QoS MSE: 0x%04x != 0x%04x",
+ qos1->bcast.timeout, qos2->bcast.timeout);
+ return false;
+ }
+
+ return true;
+}
+
static gboolean iso_recv_data(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
@@ -1250,6 +1389,7 @@ static gboolean iso_connect(GIOChannel *io, GIOCondition cond,
int err, sk_err, sk;
socklen_t len;
struct bt_iso_qos qos;
+ bool ret = true;

sk = g_io_channel_unix_get_fd(io);

@@ -1264,7 +1404,12 @@ static gboolean iso_connect(GIOChannel *io, GIOCondition cond,
return FALSE;
}

- if (!check_qos(&qos, &isodata->qos)) {
+ if (!isodata->bcast)
+ ret = check_ucast_qos(&qos, &isodata->qos);
+ else if (!isodata->server)
+ ret = check_bcast_qos(&qos, &isodata->qos);
+
+ if (!ret) {
tester_warn("Unexpected QoS parameter");
tester_test_failed();
return FALSE;
diff --git a/tools/isotest.c b/tools/isotest.c
index 2b5f164de..cd7094b1c 100644
--- a/tools/isotest.c
+++ b/tools/isotest.c
@@ -4,6 +4,7 @@
* BlueZ - Bluetooth protocol stack for Linux
*
* Copyright (C) 2022 Intel Corporation.
+ * Copyright 2023 NXP
*
*/

@@ -239,7 +240,7 @@ fail:
return err < 0 ? err : 0;
}

-static void print_qos(int sk, struct sockaddr_iso *addr)
+static void print_ucast_qos(int sk)
{
struct bt_iso_qos qos;
socklen_t len;
@@ -254,21 +255,63 @@ static void print_qos(int sk, struct sockaddr_iso *addr)
return;
}

- if (!bacmp(&addr->iso_bdaddr, BDADDR_ANY)) {
- syslog(LOG_INFO, "QoS BIG 0x%02x BIS 0x%02x Packing 0x%02x "
- "Framing 0x%02x]", qos.big, qos.bis, qos.packing,
- qos.framing);
- } else {
- syslog(LOG_INFO, "QoS CIG 0x%02x CIS 0x%02x Packing 0x%02x "
- "Framing 0x%02x]", qos.cig, qos.cis, qos.packing,
- qos.framing);
- syslog(LOG_INFO, "Input QoS [Interval %u us Latency %u "
- "ms SDU %u PHY 0x%02x RTN %u]", qos.in.interval,
- qos.in.latency, qos.in.sdu, qos.in.phy, qos.in.rtn);
+ syslog(LOG_INFO, "QoS CIG 0x%02x CIS 0x%02x Packing 0x%02x "
+ "Framing 0x%02x]", qos.ucast.cig, qos.ucast.cis,
+ qos.ucast.packing, qos.ucast.framing);
+
+ syslog(LOG_INFO, "Input QoS [Interval %u us Latency %u "
+ "ms SDU %u PHY 0x%02x RTN %u]", qos.ucast.in.interval,
+ qos.ucast.in.latency, qos.ucast.in.sdu, qos.ucast.in.phy,
+ qos.ucast.in.rtn);
+
+ syslog(LOG_INFO, "Output QoS [Interval %u us Latency %u "
+ "ms SDU %u PHY 0x%02x RTN %u]", qos.ucast.out.interval,
+ qos.ucast.out.latency, qos.ucast.out.sdu, qos.ucast.out.phy,
+ qos.ucast.out.rtn);
+}
+
+static void print_bcast_qos(int sk)
+{
+ struct bt_iso_qos qos;
+ socklen_t len;
+
+ /* Read Out QOS */
+ memset(&qos, 0, sizeof(qos));
+ len = sizeof(qos);
+
+ if (getsockopt(sk, SOL_BLUETOOTH, BT_ISO_QOS, &qos, &len) < 0) {
+ syslog(LOG_ERR, "Can't get QoS socket option: %s (%d)",
+ strerror(errno), errno);
+ return;
}
+
+ syslog(LOG_INFO, "QoS BIG 0x%02x BIS 0x%02x Packing 0x%02x "
+ "Framing 0x%02x]", qos.bcast.big, qos.bcast.bis,
+ qos.bcast.packing, qos.bcast.framing);
+
+ syslog(LOG_INFO, "Input QoS [Interval %u us Latency %u "
+ "ms SDU %u PHY 0x%02x RTN %u]", qos.bcast.in.interval,
+ qos.bcast.in.latency, qos.bcast.in.sdu,
+ qos.bcast.in.phy, qos.bcast.in.rtn);
+
syslog(LOG_INFO, "Output QoS [Interval %u us Latency %u "
- "ms SDU %u PHY 0x%02x RTN %u]", qos.out.interval,
- qos.out.latency, qos.out.sdu, qos.out.phy, qos.out.rtn);
+ "ms SDU %u PHY 0x%02x RTN %u]", qos.bcast.out.interval,
+ qos.bcast.out.latency, qos.bcast.out.sdu,
+ qos.bcast.out.phy, qos.bcast.out.rtn);
+}
+
+static void convert_ucast_qos_to_bcast(struct bt_iso_qos *qos)
+{
+ iso_qos->bcast.in.phy = 0x00;
+ iso_qos->bcast.in.sdu = 0;
+ qos->bcast.encryption = 0x00;
+ memset(qos->bcast.bcode, 0, sizeof(qos->bcast.bcode));
+ qos->bcast.options = 0x00;
+ qos->bcast.skip = 0x0000;
+ qos->bcast.sync_timeout = 0x4000;
+ qos->bcast.sync_cte_type = 0x00;
+ qos->bcast.mse = 0x00;
+ qos->bcast.timeout = 0x4000;
}

static int do_connect(char *peer)
@@ -301,9 +344,13 @@ static int do_connect(char *peer)

/* Set QoS if available */
if (iso_qos) {
- if (!inout || !strcmp(peer, "00:00:00:00:00:00")) {
- iso_qos->in.phy = 0x00;
- iso_qos->in.sdu = 0;
+ if (!strcmp(peer, "00:00:00:00:00:00")) {
+ convert_ucast_qos_to_bcast(iso_qos);
+ } else {
+ if (!inout) {
+ iso_qos->ucast.in.phy = 0x00;
+ iso_qos->ucast.in.sdu = 0;
+ }
}

if (setsockopt(sk, SOL_BLUETOOTH, BT_ISO_QOS, iso_qos,
@@ -338,7 +385,10 @@ static int do_connect(char *peer)

syslog(LOG_INFO, "Connected [%s]", peer);

- print_qos(sk, &addr);
+ if (!strcmp(peer, "00:00:00:00:00:00"))
+ print_bcast_qos(sk);
+ else
+ print_ucast_qos(sk);

return sk;

@@ -441,7 +491,10 @@ static void do_listen(char *filename, void (*handler)(int fd, int sk),
ba2str(&addr->iso_bdaddr, ba);
syslog(LOG_INFO, "Connected [%s]", ba);

- print_qos(nsk, addr);
+ if (peer)
+ print_bcast_qos(nsk);
+ else
+ print_ucast_qos(nsk);

/* Handle deferred setup */
if (defer_setup) {
@@ -648,7 +701,7 @@ static int read_file(int fd, ssize_t count, bool rewind)
return len;
}

-static void do_send(int sk, int fd, struct bt_iso_qos *qos, uint32_t num,
+static void do_send(int sk, int fd, struct bt_iso_io_qos *out, uint32_t num,
bool repeat)
{
uint32_t seq;
@@ -662,14 +715,14 @@ static void do_send(int sk, int fd, struct bt_iso_qos *qos, uint32_t num,

for (seq = 0; ; seq++) {
if (fd >= 0) {
- len = read_file(fd, qos->out.sdu, repeat);
+ len = read_file(fd, out->sdu, repeat);
if (len < 0) {
syslog(LOG_ERR, "read failed: %s (%d)",
strerror(-len), -len);
exit(1);
}
} else
- len = qos->out.sdu;
+ len = out->sdu;

len = send(sk, buf, len, 0);
if (len <= 0) {
@@ -686,7 +739,7 @@ static void do_send(int sk, int fd, struct bt_iso_qos *qos, uint32_t num,
seq, len, used / len, used);

if (seq && !((seq + 1) % num))
- send_wait(&t_start, num * qos->out.interval);
+ send_wait(&t_start, num * out->interval);
}
}

@@ -696,6 +749,7 @@ static void send_mode(char *filename, char *peer, int i, bool repeat)
socklen_t len;
int sk, fd = -1;
uint32_t num;
+ struct bt_iso_io_qos *out;

if (filename) {
char altername[PATH_MAX];
@@ -728,16 +782,21 @@ static void send_mode(char *filename, char *peer, int i, bool repeat)
syslog(LOG_INFO, "Sending ...");

/* Read QoS */
+ if (!strcmp(peer, "00:00:00:00:00:00"))
+ out = &qos.bcast.out;
+ else
+ out = &qos.ucast.out;
+
memset(&qos, 0, sizeof(qos));
len = sizeof(qos);
if (getsockopt(sk, SOL_BLUETOOTH, BT_ISO_QOS, &qos, &len) < 0) {
syslog(LOG_ERR, "Can't get Output QoS socket option: %s (%d)",
strerror(errno), errno);
- qos.out.sdu = ISO_DEFAULT_MTU;
+ out->sdu = ISO_DEFAULT_MTU;
}

/* num of packets = latency (ms) / interval (us) */
- num = (qos.out.latency * 1000 / qos.out.interval);
+ num = (out->latency * 1000 / out->interval);

syslog(LOG_INFO, "Number of packets: %d", num);

@@ -746,8 +805,8 @@ static void send_mode(char *filename, char *peer, int i, bool repeat)
* latency:
* jitter buffer = 2 * (SDU * subevents)
*/
- sndbuf = 2 * ((qos.out.latency * 1000 / qos.out.interval) *
- qos.out.sdu);
+ sndbuf = 2 * ((out->latency * 1000 / out->interval) *
+ out->sdu);

len = sizeof(sndbuf);
if (setsockopt(sk, SOL_SOCKET, SO_SNDBUF, &sndbuf, len) < 0) {
@@ -768,10 +827,10 @@ static void send_mode(char *filename, char *peer, int i, bool repeat)
}
}

- for (i = 6; i < qos.out.sdu; i++)
+ for (i = 6; i < out->sdu; i++)
buf[i] = 0x7f;

- do_send(sk, fd, &qos, num, repeat);
+ do_send(sk, fd, out, num, repeat);
}

static void reconnect_mode(char *peer)
@@ -826,12 +885,14 @@ static void multy_connect_mode(char *peer)

#define QOS(_interval, _latency, _sdu, _phy, _rtn) \
{ \
- .cig = BT_ISO_QOS_CIG_UNSET, \
- .cis = BT_ISO_QOS_CIS_UNSET, \
- .sca = 0x07, \
- .packing = 0x00, \
- .framing = 0x00, \
- .out = QOS_IO(_interval, _latency, _sdu, _phy, _rtn), \
+ .ucast = { \
+ .cig = BT_ISO_QOS_CIG_UNSET, \
+ .cis = BT_ISO_QOS_CIS_UNSET, \
+ .sca = 0x07, \
+ .packing = 0x00, \
+ .framing = 0x00, \
+ .out = QOS_IO(_interval, _latency, _sdu, _phy, _rtn), \
+ }, \
}

#define QOS_PRESET(_name, _inout, _interval, _latency, _sdu, _phy, _rtn) \
@@ -1057,43 +1118,43 @@ int main(int argc, char *argv[])

case 'M':
if (optarg)
- iso_qos->out.sdu = atoi(optarg);
+ iso_qos->ucast.out.sdu = atoi(optarg);
break;

case 'S':
if (optarg)
- iso_qos->sca = atoi(optarg);
+ iso_qos->ucast.sca = atoi(optarg);
break;


case 'P':
if (optarg)
- iso_qos->packing = atoi(optarg);
+ iso_qos->ucast.packing = atoi(optarg);
break;

case 'F':
if (optarg)
- iso_qos->framing = atoi(optarg);
+ iso_qos->ucast.framing = atoi(optarg);
break;

case 'I':
if (optarg)
- iso_qos->out.interval = atoi(optarg);
+ iso_qos->ucast.out.interval = atoi(optarg);
break;

case 'L':
if (optarg)
- iso_qos->out.latency = atoi(optarg);
+ iso_qos->ucast.out.latency = atoi(optarg);
break;

case 'Y':
if (optarg)
- iso_qos->out.phy = atoi(optarg);
+ iso_qos->ucast.out.phy = atoi(optarg);
break;

case 'R':
if (optarg)
- iso_qos->out.rtn = atoi(optarg);
+ iso_qos->ucast.out.rtn = atoi(optarg);
break;

case 'B':
@@ -1112,12 +1173,12 @@ int main(int argc, char *argv[])

case 'G':
if (optarg)
- iso_qos->cig = atoi(optarg);
+ iso_qos->ucast.cig = atoi(optarg);
break;

case 'T':
if (optarg)
- iso_qos->cis = atoi(optarg);
+ iso_qos->ucast.cis = atoi(optarg);
break;

/* fall through */
@@ -1128,11 +1189,11 @@ int main(int argc, char *argv[])
}

if (inout) {
- iso_qos->in = iso_qos->out;
+ iso_qos->ucast.in = iso_qos->ucast.out;
} else {
/* Align interval and latency even if is unidirectional */
- iso_qos->in.interval = iso_qos->out.interval;
- iso_qos->in.latency = iso_qos->out.latency;
+ iso_qos->ucast.in.interval = iso_qos->ucast.out.interval;
+ iso_qos->ucast.in.latency = iso_qos->ucast.out.latency;
}

buf = malloc(data_size);
--
2.34.1

2023-03-31 17:20:17

by bluez.test.bot

[permalink] [raw]
Subject: RE: Split bt_iso_qos into dedicated structures

This is automated email and please do not reply to this email!

Dear submitter,

Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=735877

---Test result---

Test Summary:
CheckPatch PASS 0.87 seconds
GitLint PASS 0.33 seconds
BuildEll PASS 26.26 seconds
BluezMake PASS 761.90 seconds
MakeCheck PASS 10.89 seconds
MakeDistcheck PASS 150.00 seconds
CheckValgrind PASS 240.87 seconds
CheckSmatch WARNING 323.20 seconds
bluezmakeextell PASS 97.50 seconds
IncrementalBuild PASS 609.39 seconds
ScanBuild PASS 964.60 seconds

Details
##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
emulator/bthost.c:584:28: warning: Variable length array is used.emulator/bthost.c:741:28: warning: Variable length array is used.


---
Regards,
Linux Bluetooth

2023-03-31 22:14:44

by patchwork-bot+bluetooth

[permalink] [raw]
Subject: Re: [PATCH BlueZ v3 0/1] Split bt_iso_qos into dedicated structures

Hello:

This patch was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <[email protected]>:

On Fri, 31 Mar 2023 18:39:26 +0300 you wrote:
> This patch adds support for additional ISO broadcast QoS parameters,
> that the user can set before performing broadcast procedures
> using an ISO socket.
>
> This patch splits the "bt_iso_qos" structure into dedicated
> unicast and broadcast structures, so that ISO sockets
> can be configured with dedicated QoS options depending
> on the type of ISO procedures to run.
>
> [...]

Here is the summary with links:
- [BlueZ,v3,1/1] Split bt_iso_qos into dedicated structures
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=c4d9b99db5a6

You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html