2023-07-13 22:51:27

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH BlueZ 1/2] bthost: Add support to set ISO Packet Status

From: Luiz Augusto von Dentz <[email protected]>

This adds support to set ISO Packet Status to bthost_send_iso.
---
emulator/bthost.c | 12 ++++++------
emulator/bthost.h | 4 ++--
tools/iso-tester.c | 2 +-
3 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/emulator/bthost.c b/emulator/bthost.c
index 3179bb3d20fe..c7d59eefc80c 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -732,8 +732,8 @@ void bthost_send_cid_v(struct bthost *bthost, uint16_t handle, uint16_t cid,
}

static void send_iso(struct bthost *bthost, uint16_t handle, bool ts,
- uint16_t sn, uint32_t timestamp,
- const struct iovec *iov, int iovcnt)
+ uint16_t sn, uint32_t timestamp, uint8_t pkt_status,
+ const struct iovec *iov, int iovcnt)
{
struct bt_hci_iso_hdr iso_hdr;
struct bt_hci_iso_data_start data_hdr;
@@ -773,7 +773,7 @@ static void send_iso(struct bthost *bthost, uint16_t handle, bool ts,
}

data_hdr.sn = cpu_to_le16(sn);
- data_hdr.slen = cpu_to_le16(iso_data_len_pack(len, 0));
+ data_hdr.slen = cpu_to_le16(iso_data_len_pack(len, pkt_status));

pdu[3].iov_base = &data_hdr;
pdu[3].iov_len = sizeof(data_hdr);
@@ -782,8 +782,8 @@ static void send_iso(struct bthost *bthost, uint16_t handle, bool ts,
}

void bthost_send_iso(struct bthost *bthost, uint16_t handle, bool ts,
- uint16_t sn, uint32_t timestamp,
- const struct iovec *iov, int iovcnt)
+ uint16_t sn, uint32_t timestamp, uint8_t pkt_status,
+ const struct iovec *iov, int iovcnt)
{
struct btconn *conn;

@@ -791,7 +791,7 @@ void bthost_send_iso(struct bthost *bthost, uint16_t handle, bool ts,
if (!conn)
return;

- send_iso(bthost, handle, ts, sn, timestamp, iov, iovcnt);
+ send_iso(bthost, handle, ts, sn, timestamp, pkt_status, iov, iovcnt);
}

bool bthost_l2cap_req(struct bthost *bthost, uint16_t handle, uint8_t code,
diff --git a/emulator/bthost.h b/emulator/bthost.h
index cdc12dc1ce8e..46781365b283 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -81,8 +81,8 @@ void bthost_send_cid(struct bthost *bthost, uint16_t handle, uint16_t cid,
void bthost_send_cid_v(struct bthost *bthost, uint16_t handle, uint16_t cid,
const struct iovec *iov, int iovcnt);
void bthost_send_iso(struct bthost *bthost, uint16_t handle, bool ts,
- uint16_t sn, uint32_t timestamp,
- const struct iovec *iov, int iovcnt);
+ uint16_t sn, uint32_t timestamp, uint8_t pkt_status,
+ const struct iovec *iov, int iovcnt);

typedef void (*bthost_l2cap_rsp_cb) (uint8_t code, const void *data,
uint16_t len, void *user_data);
diff --git a/tools/iso-tester.c b/tools/iso-tester.c
index bbd5a47f6197..7140f83b2236 100644
--- a/tools/iso-tester.c
+++ b/tools/iso-tester.c
@@ -1715,7 +1715,7 @@ static void iso_recv(struct test_data *data, GIOChannel *io)

host = hciemu_client_get_host(data->hciemu);
bthost_send_iso(host, data->handle, isodata->ts, sn++, 0,
- isodata->recv, 1);
+ isodata->pkt_status, isodata->recv, 1);

data->io_id[0] = g_io_add_watch(io, G_IO_IN, iso_recv_data, data);
}
--
2.40.1



2023-07-13 22:54:08

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: [PATCH BlueZ 2/2] iso-tester: Add test for BT_PKT_STATUS sockopt

From: Luiz Augusto von Dentz <[email protected]>

This adds a test for setting BT_PKT_STATUS sockopt and checks if
BT_SCM_PKT_STATUS is properly received.
---
tools/iso-tester.c | 89 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 88 insertions(+), 1 deletion(-)

diff --git a/tools/iso-tester.c b/tools/iso-tester.c
index 7140f83b2236..8f43d7becf16 100644
--- a/tools/iso-tester.c
+++ b/tools/iso-tester.c
@@ -400,6 +400,7 @@ struct iso_client_data {
bool disconnect;
bool ts;
bool mconn;
+ uint8_t pkt_status;
const uint8_t *base;
size_t base_len;
};
@@ -833,6 +834,14 @@ static const struct iso_client_data listen_16_2_1_recv_ts = {
.ts = true,
};

+static const struct iso_client_data listen_16_2_1_recv_pkt_status = {
+ .qos = QOS_16_2_1,
+ .expect_err = 0,
+ .recv = &send_16_2_1,
+ .server = true,
+ .pkt_status = 0x02,
+};
+
static const struct iso_client_data defer_16_2_1 = {
.qos = QOS_16_2_1,
.expect_err = 0,
@@ -1322,6 +1331,7 @@ static void test_setsockopt(const void *test_data)
int sk, err;
socklen_t len;
struct bt_iso_qos qos = QOS_16_1_2;
+ int pkt_status = 1;

sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_ISO);
if (sk < 0) {
@@ -1350,6 +1360,26 @@ static void test_setsockopt(const void *test_data)
goto end;
}

+ err = setsockopt(sk, SOL_BLUETOOTH, BT_PKT_STATUS, &pkt_status,
+ sizeof(pkt_status));
+ if (err < 0) {
+ tester_warn("Can't set socket BT_PKT_STATUS option: "
+ "%s (%d)", strerror(errno), errno);
+ tester_test_failed();
+ goto end;
+ }
+
+ len = sizeof(pkt_status);
+ memset(&pkt_status, 0, len);
+
+ err = getsockopt(sk, SOL_BLUETOOTH, BT_PKT_STATUS, &pkt_status, &len);
+ if (err < 0) {
+ tester_warn("Can't get socket option : %s (%d)",
+ strerror(errno), errno);
+ tester_test_failed();
+ goto end;
+ }
+
tester_test_passed();

end:
@@ -1678,12 +1708,24 @@ static gboolean iso_recv_data(GIOChannel *io, GIOCondition cond,
struct test_data *data = user_data;
const struct iso_client_data *isodata = data->test_data;
int sk = g_io_channel_unix_get_fd(io);
+ unsigned char control[64];
ssize_t ret;
char buf[1024];
+ struct msghdr msg;
+ struct iovec iov;

data->io_id[0] = 0;

- ret = read(sk, buf, isodata->recv->iov_len);
+ iov.iov_base = buf;
+ iov.iov_len = isodata->recv->iov_len;
+
+ memset(&msg, 0, sizeof(msg));
+ msg.msg_iov = &iov;
+ msg.msg_iovlen = 1;
+ msg.msg_control = control;
+ msg.msg_controllen = sizeof(control);
+
+ ret = recvmsg(sk, &msg, MSG_DONTWAIT);
if (ret < 0 || isodata->recv->iov_len != (size_t) ret) {
tester_warn("Failed to read %zu bytes: %s (%d)",
isodata->recv->iov_len, strerror(errno), errno);
@@ -1691,6 +1733,35 @@ static gboolean iso_recv_data(GIOChannel *io, GIOCondition cond,
return FALSE;
}

+ if (isodata->pkt_status) {
+ struct cmsghdr *cmsg;
+ uint8_t pkt_status = 0;
+
+ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL;
+ cmsg = CMSG_NXTHDR(&msg, cmsg)) {
+ if (cmsg->cmsg_level != SOL_BLUETOOTH)
+ continue;
+
+ if (cmsg->cmsg_type == BT_SCM_PKT_STATUS) {
+ memcpy(&pkt_status, CMSG_DATA(cmsg),
+ sizeof(pkt_status));
+ tester_debug("BT_SCM_PKT_STATUS = 0x%2.2x",
+ pkt_status);
+ break;
+ }
+ }
+
+ if (isodata->pkt_status != pkt_status) {
+ tester_warn("isodata->pkt_status 0x%2.2x != 0x%2.2x "
+ "pkt_status", isodata->pkt_status,
+ pkt_status);
+ tester_test_failed();
+ } else
+ tester_test_passed();
+
+ return FALSE;
+ }
+
if (memcmp(buf, isodata->recv->iov_base, ret))
tester_test_failed();
else
@@ -2250,6 +2321,18 @@ static gboolean iso_accept_cb(GIOChannel *io, GIOCondition cond,
return false;
}

+ if (isodata->pkt_status) {
+ int opt = 1;
+
+ if (setsockopt(new_sk, SOL_BLUETOOTH, BT_PKT_STATUS, &opt,
+ sizeof(opt)) < 0) {
+ tester_print("Can't set socket BT_PKT_STATUS option: "
+ "%s (%d)", strerror(errno), errno);
+ tester_test_failed();
+ return false;
+ }
+ }
+
return iso_connect(io, cond, user_data);
}

@@ -2448,6 +2531,10 @@ int main(int argc, char *argv[])
setup_powered,
test_listen);

+ test_iso("ISO Receive Packet Status - Success",
+ &listen_16_2_1_recv_pkt_status,
+ setup_powered, test_listen);
+
test_iso("ISO Defer - Success", &defer_16_2_1, setup_powered,
test_defer);

--
2.40.1