* [PATCH BlueZ 1/5] tools: add tests for RX timestamping
@ 2025-04-27 10:44 Pauli Virtanen
2025-04-27 10:44 ` [PATCH BlueZ 2/5] bthost: implement fragmenting to ACL MTU Pauli Virtanen
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Pauli Virtanen @ 2025-04-27 10:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pauli Virtanen
Add tests:
ISO Receive - RX Timestamping
L2CAP BR/EDR Client - RX Timestamping
L2CAP BR/EDR Client - RX Timestamping 32k
L2CAP LE Client - RX Timestamping
L2CAP LE Client - RX Timestamping 32k
---
tools/iso-tester.c | 22 +++++++++++-
tools/l2cap-tester.c | 60 ++++++++++++++++++++++++++++++++-
tools/tester.h | 80 ++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 160 insertions(+), 2 deletions(-)
diff --git a/tools/iso-tester.c b/tools/iso-tester.c
index 63f6951e3..ff6418ce9 100644
--- a/tools/iso-tester.c
+++ b/tools/iso-tester.c
@@ -1118,6 +1118,15 @@ static const struct iso_client_data listen_16_2_1_recv_pkt_status = {
.pkt_status = 0x02,
};
+static const struct iso_client_data listen_16_2_1_recv_rx_timestamping = {
+ .qos = QOS_16_2_1,
+ .expect_err = 0,
+ .recv = &send_16_2_1,
+ .server = true,
+ .so_timestamping = (SOF_TIMESTAMPING_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE),
+};
+
static const struct iso_client_data defer_16_2_1 = {
.qos = QOS_16_2_1,
.expect_err = 0,
@@ -2148,7 +2157,7 @@ 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];
+ unsigned char control[256];
ssize_t ret;
char buf[1024];
struct msghdr msg;
@@ -2202,6 +2211,9 @@ static gboolean iso_recv_data(GIOChannel *io, GIOCondition cond,
return FALSE;
}
+ if (isodata->so_timestamping & SOF_TIMESTAMPING_RX_SOFTWARE)
+ rx_timestamp_check(&msg);
+
if (memcmp(buf, isodata->recv->iov_base, ret))
tester_test_failed();
else
@@ -2224,6 +2236,10 @@ static void iso_recv(struct test_data *data, GIOChannel *io)
return;
}
+ if (rx_timestamping_init(g_io_channel_unix_get_fd(io),
+ isodata->so_timestamping))
+ return;
+
host = hciemu_client_get_host(data->hciemu);
bthost_send_iso(host, data->handle, isodata->ts, sn++, 0,
isodata->pkt_status, isodata->recv, 1);
@@ -3704,6 +3720,10 @@ int main(int argc, char *argv[])
&listen_16_2_1_recv_pkt_status,
setup_powered, test_listen);
+ test_iso("ISO Receive - RX Timestamping",
+ &listen_16_2_1_recv_rx_timestamping,
+ setup_powered, test_listen);
+
test_iso("ISO Defer - Success", &defer_16_2_1, setup_powered,
test_defer);
diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index 41ef62578..9087d635d 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -357,6 +357,24 @@ static const struct l2cap_data client_connect_read_32k_success_test = {
.data_len = sizeof(l2_data_32k),
};
+static const struct l2cap_data client_connect_rx_timestamping_test = {
+ .client_psm = 0x1001,
+ .server_psm = 0x1001,
+ .read_data = l2_data,
+ .data_len = sizeof(l2_data),
+ .so_timestamping = (SOF_TIMESTAMPING_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE),
+};
+
+static const struct l2cap_data client_connect_rx_timestamping_32k_test = {
+ .client_psm = 0x1001,
+ .server_psm = 0x1001,
+ .read_data = l2_data_32k,
+ .data_len = sizeof(l2_data_32k),
+ .so_timestamping = (SOF_TIMESTAMPING_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE),
+};
+
static const struct l2cap_data client_connect_write_success_test = {
.client_psm = 0x1001,
.server_psm = 0x1001,
@@ -575,6 +593,27 @@ static const struct l2cap_data le_client_connect_read_32k_success_test = {
.data_len = sizeof(l2_data_32k),
};
+static const struct l2cap_data le_client_connect_rx_timestamping_test = {
+ .client_psm = 0x0080,
+ .server_psm = 0x0080,
+ .read_data = l2_data,
+ .data_len = sizeof(l2_data),
+ .so_timestamping = (SOF_TIMESTAMPING_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE),
+};
+
+static const struct l2cap_data le_client_connect_rx_timestamping_32k_test = {
+ .client_psm = 0x0080,
+ .server_psm = 0x0080,
+ .mtu = 672,
+ .mps = 251,
+ .credits = 147,
+ .read_data = l2_data_32k,
+ .data_len = sizeof(l2_data_32k),
+ .so_timestamping = (SOF_TIMESTAMPING_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE),
+};
+
static const struct l2cap_data le_client_connect_write_success_test = {
.client_psm = 0x0080,
.server_psm = 0x0080,
@@ -1227,13 +1266,14 @@ static gboolean sock_received_data(GIOChannel *io, GIOCondition cond,
{
struct test_data *data = tester_get_data();
const struct l2cap_data *l2data = data->test_data;
+ bool tstamp = l2data->so_timestamping & SOF_TIMESTAMPING_RX_SOFTWARE;
char buf[1024];
int sk;
ssize_t len;
sk = g_io_channel_unix_get_fd(io);
- len = read(sk, buf, sizeof(buf));
+ len = recv_tstamp(sk, buf, sizeof(buf), tstamp);
if (len < 0) {
tester_warn("Unable to read: %s (%d)", strerror(errno), errno);
tester_test_failed();
@@ -1430,6 +1470,10 @@ static void l2cap_read_data(struct test_data *data, GIOChannel *io,
data->step = 0;
+ if (rx_timestamping_init(g_io_channel_unix_get_fd(io),
+ l2data->so_timestamping))
+ return;
+
bthost = hciemu_client_get_host(data->hciemu);
g_io_add_watch(io, G_IO_IN, sock_received_data, NULL);
@@ -2535,6 +2579,14 @@ int main(int argc, char *argv[])
&client_connect_read_32k_success_test,
setup_powered_client, test_connect);
+ test_l2cap_bredr("L2CAP BR/EDR Client - RX Timestamping",
+ &client_connect_rx_timestamping_test,
+ setup_powered_client, test_connect);
+
+ test_l2cap_bredr("L2CAP BR/EDR Client - RX Timestamping 32k",
+ &client_connect_rx_timestamping_32k_test,
+ setup_powered_client, test_connect);
+
test_l2cap_bredr("L2CAP BR/EDR Client - Write Success",
&client_connect_write_success_test,
setup_powered_client, test_connect);
@@ -2619,6 +2671,12 @@ int main(int argc, char *argv[])
test_l2cap_le("L2CAP LE Client - Read 32k Success",
&le_client_connect_read_32k_success_test,
setup_powered_client, test_connect);
+ test_l2cap_le("L2CAP LE Client - RX Timestamping",
+ &le_client_connect_rx_timestamping_test,
+ setup_powered_client, test_connect);
+ test_l2cap_le("L2CAP LE Client - RX Timestamping 32k",
+ &le_client_connect_rx_timestamping_32k_test,
+ setup_powered_client, test_connect);
test_l2cap_le("L2CAP LE Client - Write Success",
&le_client_connect_write_success_test,
setup_powered_client, test_connect);
diff --git a/tools/tester.h b/tools/tester.h
index 4e7d7226b..bdfff356f 100644
--- a/tools/tester.h
+++ b/tools/tester.h
@@ -198,3 +198,83 @@ static inline int tx_tstamp_recv(struct tx_tstamp_data *data, int sk, int len)
return data->count - data->pos;
}
+
+static inline int rx_timestamp_check(struct msghdr *msg)
+{
+ struct cmsghdr *cmsg;
+ struct timespec now;
+ int64_t t = 0;
+
+ for (cmsg = CMSG_FIRSTHDR(msg); cmsg; cmsg = CMSG_NXTHDR(msg, cmsg)) {
+ struct scm_timestamping *tss;
+
+ if (cmsg->cmsg_level != SOL_SOCKET)
+ continue;
+ if (cmsg->cmsg_type != SCM_TIMESTAMPING)
+ continue;
+
+ tss = (struct scm_timestamping *)CMSG_DATA(cmsg);
+ t = TS_NSEC(&tss->ts[0]);
+ break;
+ }
+ if (!cmsg) {
+ tester_warn("RX timestamp missing");
+ return -EINVAL;
+ }
+
+ clock_gettime(CLOCK_REALTIME, &now);
+
+ if (TS_NSEC(&now) < t || TS_NSEC(&now) > t + SEC_NSEC(10)) {
+ tester_warn("RX timestamp bad time");
+ return -EINVAL;
+ }
+
+ tester_print("Got valid RX timestamp");
+ return 0;
+}
+
+static inline ssize_t recv_tstamp(int sk, void *buf, size_t size, bool tstamp)
+{
+ union {
+ char buf[2 * CMSG_SPACE(sizeof(struct scm_timestamping))];
+ struct cmsghdr align;
+ } control;
+ struct iovec data = {
+ .iov_base = buf,
+ .iov_len = size
+ };
+ struct msghdr msg = {
+ .msg_iov = &data,
+ .msg_iovlen = 1,
+ .msg_control = control.buf,
+ .msg_controllen = sizeof(control.buf),
+ };
+ ssize_t ret;
+
+ ret = recvmsg(sk, &msg, 0);
+ if (ret < 0 || !tstamp)
+ return ret;
+
+ if (rx_timestamp_check(&msg)) {
+ errno = EIO;
+ return -1;
+ }
+
+ return ret;
+}
+
+static inline int rx_timestamping_init(int fd, int flags)
+{
+ socklen_t len = sizeof(flags);
+
+ if (!(flags & SOF_TIMESTAMPING_RX_SOFTWARE))
+ return 0;
+
+ if (setsockopt(fd, SOL_SOCKET, SO_TIMESTAMPING, &flags, len) < 0) {
+ tester_warn("failed to set SO_TIMESTAMPING");
+ tester_test_failed();
+ return -EIO;
+ }
+
+ return 0;
+}
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ 2/5] bthost: implement fragmenting to ACL MTU
2025-04-27 10:44 [PATCH BlueZ 1/5] tools: add tests for RX timestamping Pauli Virtanen
@ 2025-04-27 10:44 ` Pauli Virtanen
2025-04-27 10:44 ` [PATCH BlueZ 3/5] hciemu: set bthost ACL MTU to match btdev Pauli Virtanen
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Pauli Virtanen @ 2025-04-27 10:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pauli Virtanen
Support fragmenting ACL packets to given ACL MTU.
---
emulator/bthost.c | 94 +++++++++++++++++++++++++++++++++++++++--------
emulator/bthost.h | 2 +
2 files changed, 80 insertions(+), 16 deletions(-)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 5db750aae..1ae33ba6b 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -255,6 +255,7 @@ struct bthost {
bthost_accept_conn_cb accept_iso_cb;
bthost_new_conn_cb new_iso_cb;
void *new_iso_data;
+ uint16_t acl_mtu;
struct rfcomm_connection_data *rfcomm_conn_data;
struct l2cap_conn_cb_data *new_l2cap_conn_data;
struct rfcomm_conn_cb_data *new_rfcomm_conn_data;
@@ -294,6 +295,7 @@ struct bthost *bthost_create(void)
/* Set defaults */
bthost->io_capability = 0x03;
+ bthost->acl_mtu = UINT16_MAX;
return bthost;
}
@@ -572,6 +574,14 @@ void bthost_set_send_handler(struct bthost *bthost, bthost_send_func handler,
bthost->send_data = user_data;
}
+void bthost_set_acl_mtu(struct bthost *bthost, uint16_t mtu)
+{
+ if (!bthost)
+ return;
+
+ bthost->acl_mtu = mtu;
+}
+
static void queue_command(struct bthost *bthost, const struct iovec *iov,
int iovlen)
{
@@ -619,37 +629,89 @@ static void send_packet(struct bthost *bthost, const struct iovec *iov,
bthost->send_handler(iov, iovlen, bthost->send_data);
}
+static void iov_pull_n(struct iovec *src, unsigned int *src_cnt,
+ struct iovec *dst, unsigned int *dst_cnt, unsigned int max_dst,
+ size_t len)
+{
+ unsigned int i;
+ size_t count;
+
+ *dst_cnt = 0;
+
+ while (len && *dst_cnt < max_dst && *src_cnt) {
+ count = len;
+ if (count > src[0].iov_len)
+ count = src[0].iov_len;
+
+ dst[*dst_cnt].iov_base = src[0].iov_base;
+ dst[*dst_cnt].iov_len = count;
+ *dst_cnt += 1;
+
+ util_iov_pull(&src[0], count);
+ len -= count;
+
+ if (!src[0].iov_len) {
+ for (i = 1; i < *src_cnt; ++i)
+ src[i - 1] = src[i];
+ *src_cnt -= 1;
+ }
+ }
+}
+
static void send_iov(struct bthost *bthost, uint16_t handle, uint16_t cid,
- const struct iovec *iov, int iovcnt)
+ const struct iovec *iov, unsigned int iovcnt)
{
struct bt_hci_acl_hdr acl_hdr;
struct bt_l2cap_hdr l2_hdr;
uint8_t pkt = BT_H4_ACL_PKT;
struct iovec pdu[3 + iovcnt];
- int i, len = 0;
+ struct iovec payload[1 + iovcnt];
+ size_t payload_mtu, len;
+ int flag;
+ unsigned int i;
+ len = 0;
for (i = 0; i < iovcnt; i++) {
- pdu[3 + i].iov_base = iov[i].iov_base;
- pdu[3 + i].iov_len = iov[i].iov_len;
+ payload[1 + i].iov_base = iov[i].iov_base;
+ payload[1 + i].iov_len = iov[i].iov_len;
len += iov[i].iov_len;
}
- pdu[0].iov_base = &pkt;
- pdu[0].iov_len = sizeof(pkt);
-
- acl_hdr.handle = acl_handle_pack(handle, 0);
- acl_hdr.dlen = cpu_to_le16(len + sizeof(l2_hdr));
-
- pdu[1].iov_base = &acl_hdr;
- pdu[1].iov_len = sizeof(acl_hdr);
-
l2_hdr.cid = cpu_to_le16(cid);
l2_hdr.len = cpu_to_le16(len);
+ payload[0].iov_base = &l2_hdr;
+ payload[0].iov_len = sizeof(l2_hdr);
- pdu[2].iov_base = &l2_hdr;
- pdu[2].iov_len = sizeof(l2_hdr);
+ len += sizeof(l2_hdr);
+ iovcnt++;
- send_packet(bthost, pdu, 3 + iovcnt);
+ /* Fragment to ACL MTU */
+
+ payload_mtu = bthost->acl_mtu - pdu[0].iov_len - pdu[1].iov_len;
+
+ flag = 0x00;
+ do {
+ size_t count = (len > payload_mtu) ? payload_mtu : len;
+ unsigned int pdu_iovcnt;
+
+ pdu[0].iov_base = &pkt;
+ pdu[0].iov_len = sizeof(pkt);
+
+ acl_hdr.dlen = cpu_to_le16(count);
+ acl_hdr.handle = acl_handle_pack(handle, flag);
+
+ pdu[1].iov_base = &acl_hdr;
+ pdu[1].iov_len = sizeof(acl_hdr);
+
+ iov_pull_n(payload, &iovcnt, &pdu[2], &pdu_iovcnt,
+ ARRAY_SIZE(pdu) - 2, count);
+ pdu_iovcnt += 2;
+
+ send_packet(bthost, pdu, pdu_iovcnt);
+
+ len -= count;
+ flag = 0x01;
+ } while (len);
}
static void send_acl(struct bthost *bthost, uint16_t handle, uint16_t cid,
diff --git a/emulator/bthost.h b/emulator/bthost.h
index 405d66bf0..583a8b6df 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -36,6 +36,8 @@ void bthost_debug(struct bthost *bthost, const char *format, ...)
void bthost_set_send_handler(struct bthost *bthost, bthost_send_func handler,
void *user_data);
+void bthost_set_acl_mtu(struct bthost *bthost, uint16_t mtu);
+
void bthost_receive_h4(struct bthost *bthost, const void *data, uint16_t len);
typedef void (*bthost_cmd_complete_cb) (uint16_t opcode, uint8_t status,
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ 3/5] hciemu: set bthost ACL MTU to match btdev
2025-04-27 10:44 [PATCH BlueZ 1/5] tools: add tests for RX timestamping Pauli Virtanen
2025-04-27 10:44 ` [PATCH BlueZ 2/5] bthost: implement fragmenting to ACL MTU Pauli Virtanen
@ 2025-04-27 10:44 ` Pauli Virtanen
2025-04-27 10:44 ` [PATCH BlueZ 4/5] bthost: support sending SCO packets Pauli Virtanen
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Pauli Virtanen @ 2025-04-27 10:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pauli Virtanen
Set the bthost ACL MTU to avoid generating larger packets than the btdev
ACL MTU.
This tests RX timestamping on ACL fragmentation.
---
emulator/btdev.c | 11 +++++++++++
emulator/btdev.h | 3 +++
emulator/hciemu.c | 4 ++++
3 files changed, 18 insertions(+)
diff --git a/emulator/btdev.c b/emulator/btdev.c
index 76bae5ea1..cf5c36bb4 100644
--- a/emulator/btdev.c
+++ b/emulator/btdev.c
@@ -7460,6 +7460,17 @@ const uint8_t *btdev_get_adv_addr(struct btdev *btdev, uint8_t handle)
return ext_adv_addr(btdev, ext_adv);
}
+void btdev_get_mtu(struct btdev *btdev, uint16_t *acl, uint16_t *sco,
+ uint16_t *iso)
+{
+ if (acl)
+ *acl = btdev->acl_mtu;
+ if (sco)
+ *acl = btdev->sco_mtu;
+ if (iso)
+ *iso = btdev->iso_mtu;
+}
+
void btdev_set_le_states(struct btdev *btdev, const uint8_t *le_states)
{
memcpy(btdev->le_states, le_states, sizeof(btdev->le_states));
diff --git a/emulator/btdev.h b/emulator/btdev.h
index a96c1a325..c7b3b468a 100644
--- a/emulator/btdev.h
+++ b/emulator/btdev.h
@@ -84,6 +84,9 @@ uint8_t btdev_get_le_scan_enable(struct btdev *btdev);
const uint8_t *btdev_get_adv_addr(struct btdev *btdev, uint8_t handle);
+void btdev_get_mtu(struct btdev *btdev, uint16_t *acl, uint16_t *sco,
+ uint16_t *iso);
+
void btdev_set_le_states(struct btdev *btdev, const uint8_t *le_states);
void btdev_set_al_len(struct btdev *btdev, uint8_t len);
diff --git a/emulator/hciemu.c b/emulator/hciemu.c
index ccc57aada..8529caae8 100644
--- a/emulator/hciemu.c
+++ b/emulator/hciemu.c
@@ -308,6 +308,7 @@ static struct hciemu_client *hciemu_client_new(struct hciemu *hciemu,
{
struct hciemu_client *client;
int sv[2];
+ uint16_t mtu;
client = new0(struct hciemu_client, 1);
if (!client)
@@ -342,6 +343,9 @@ static struct hciemu_client *hciemu_client_new(struct hciemu *hciemu,
client->host_source = create_source_bthost(sv[1], client->host);
client->start_source = g_idle_add(start_host, client);
+ btdev_get_mtu(client->dev, &mtu, NULL, NULL);
+ bthost_set_acl_mtu(client->host, mtu);
+
return client;
}
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ 4/5] bthost: support sending SCO packets
2025-04-27 10:44 [PATCH BlueZ 1/5] tools: add tests for RX timestamping Pauli Virtanen
2025-04-27 10:44 ` [PATCH BlueZ 2/5] bthost: implement fragmenting to ACL MTU Pauli Virtanen
2025-04-27 10:44 ` [PATCH BlueZ 3/5] hciemu: set bthost ACL MTU to match btdev Pauli Virtanen
@ 2025-04-27 10:44 ` Pauli Virtanen
2025-04-27 10:44 ` [PATCH BlueZ 5/5] sco-tester: add SCO receive and RX timestamping tests Pauli Virtanen
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Pauli Virtanen @ 2025-04-27 10:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pauli Virtanen
Add function to send SCO packets via bthost.
---
emulator/bthost.c | 32 ++++++++++++++++++++++++++++++++
emulator/bthost.h | 2 ++
2 files changed, 34 insertions(+)
diff --git a/emulator/bthost.c b/emulator/bthost.c
index 1ae33ba6b..214583cc5 100644
--- a/emulator/bthost.c
+++ b/emulator/bthost.c
@@ -40,6 +40,7 @@
#define acl_flags(h) (h >> 12)
#define sco_flags_status(f) (f & 0x03)
+#define sco_flags_pack(status) (status & 0x03)
#define iso_flags_pb(f) (f & 0x0003)
#define iso_flags_ts(f) ((f >> 2) & 0x0001)
@@ -878,6 +879,37 @@ void bthost_send_cid_v(struct bthost *bthost, uint16_t handle, uint16_t cid,
send_iov(bthost, handle, cid, iov, iovcnt);
}
+void bthost_send_sco(struct bthost *bthost, uint16_t handle, uint8_t pkt_status,
+ const struct iovec *iov, int iovcnt)
+{
+ uint8_t pkt = BT_H4_SCO_PKT;
+ struct iovec pdu[2 + iovcnt];
+ struct bt_hci_sco_hdr sco_hdr;
+ struct btconn *conn;
+ int i, len = 0;
+
+ conn = bthost_find_conn(bthost, handle);
+ if (!conn)
+ return;
+
+ for (i = 0; i < iovcnt; i++) {
+ pdu[2 + i].iov_base = iov[i].iov_base;
+ pdu[2 + i].iov_len = iov[i].iov_len;
+ len += iov[i].iov_len;
+ }
+
+ pdu[0].iov_base = &pkt;
+ pdu[0].iov_len = sizeof(pkt);
+
+ sco_hdr.handle = acl_handle_pack(handle, sco_flags_pack(pkt_status));
+ sco_hdr.dlen = len;
+
+ pdu[1].iov_base = &sco_hdr;
+ pdu[1].iov_len = sizeof(sco_hdr);
+
+ send_packet(bthost, pdu, 2 + iovcnt);
+}
+
static void send_iso(struct bthost *bthost, uint16_t handle, bool ts,
uint16_t sn, uint32_t timestamp, uint8_t pkt_status,
const struct iovec *iov, int iovcnt)
diff --git a/emulator/bthost.h b/emulator/bthost.h
index 583a8b6df..db640daff 100644
--- a/emulator/bthost.h
+++ b/emulator/bthost.h
@@ -92,6 +92,8 @@ void bthost_send_cid(struct bthost *bthost, uint16_t handle, uint16_t cid,
const void *data, uint16_t len);
void bthost_send_cid_v(struct bthost *bthost, uint16_t handle, uint16_t cid,
const struct iovec *iov, int iovcnt);
+void bthost_send_sco(struct bthost *bthost, uint16_t handle, uint8_t pkt_status,
+ const struct iovec *iov, int iovcnt);
void bthost_send_iso(struct bthost *bthost, uint16_t handle, bool ts,
uint16_t sn, uint32_t timestamp, uint8_t pkt_status,
const struct iovec *iov, int iovcnt);
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ 5/5] sco-tester: add SCO receive and RX timestamping tests
2025-04-27 10:44 [PATCH BlueZ 1/5] tools: add tests for RX timestamping Pauli Virtanen
` (2 preceding siblings ...)
2025-04-27 10:44 ` [PATCH BlueZ 4/5] bthost: support sending SCO packets Pauli Virtanen
@ 2025-04-27 10:44 ` Pauli Virtanen
2025-04-27 12:07 ` [BlueZ,1/5] tools: add tests for RX timestamping bluez.test.bot
2025-04-28 15:00 ` [PATCH BlueZ 1/5] " patchwork-bot+bluetooth
5 siblings, 0 replies; 7+ messages in thread
From: Pauli Virtanen @ 2025-04-27 10:44 UTC (permalink / raw)
To: linux-bluetooth; +Cc: Pauli Virtanen
Add tests:
SCO CVSD Recv - Success
SCO CVSD Recv - RX Timestamping
---
tools/sco-tester.c | 84 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 83 insertions(+), 1 deletion(-)
diff --git a/tools/sco-tester.c b/tools/sco-tester.c
index 650f8bab3..fc89d1d29 100644
--- a/tools/sco-tester.c
+++ b/tools/sco-tester.c
@@ -52,6 +52,7 @@ struct test_data {
struct sco_client_data {
int expect_err;
+ const uint8_t *recv_data;
const uint8_t *send_data;
uint16_t data_len;
@@ -300,6 +301,20 @@ static const struct sco_client_data connect_failure_reset = {
const uint8_t data[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
+static const struct sco_client_data connect_recv_success = {
+ .expect_err = 0,
+ .data_len = sizeof(data),
+ .recv_data = data,
+};
+
+static const struct sco_client_data connect_recv_rx_ts_success = {
+ .expect_err = 0,
+ .data_len = sizeof(data),
+ .recv_data = data,
+ .so_timestamping = (SOF_TIMESTAMPING_SOFTWARE |
+ SOF_TIMESTAMPING_RX_SOFTWARE),
+};
+
static const struct sco_client_data connect_send_success = {
.expect_err = 0,
.data_len = sizeof(data),
@@ -401,7 +416,7 @@ static void setup_powered_callback(uint8_t status, uint16_t length,
bthost_set_cmd_complete_cb(bthost, client_connectable_complete, data);
bthost_write_scan_enable(bthost, 0x03);
- if (scodata && scodata->send_data)
+ if (scodata && (scodata->send_data || scodata->recv_data))
bthost_set_sco_cb(bthost, sco_new_conn, data);
}
@@ -783,6 +798,64 @@ static void sco_tx_timestamping(struct test_data *data, GIOChannel *io)
data->err_io_id = g_io_add_watch(io, G_IO_ERR, recv_errqueue, data);
}
+static gboolean sock_received_data(GIOChannel *io, GIOCondition cond,
+ gpointer user_data)
+{
+ struct test_data *data = tester_get_data();
+ const struct sco_client_data *scodata = data->test_data;
+ bool tstamp = scodata->so_timestamping & SOF_TIMESTAMPING_RX_SOFTWARE;
+ char buf[1024];
+ int sk;
+ ssize_t len;
+
+ sk = g_io_channel_unix_get_fd(io);
+
+ len = recv_tstamp(sk, buf, sizeof(buf), tstamp);
+ if (len < 0) {
+ tester_warn("Unable to read: %s (%d)", strerror(errno), errno);
+ tester_test_failed();
+ return FALSE;
+ }
+
+ tester_debug("read: %d", (int)len);
+
+ if (len != scodata->data_len) {
+ tester_test_failed();
+ return FALSE;
+ }
+
+ --data->step;
+
+ if (len != scodata->data_len ||
+ memcmp(buf, scodata->recv_data, scodata->data_len))
+ tester_test_failed();
+ else if (!data->step)
+ tester_test_passed();
+ else
+ return TRUE;
+
+ return FALSE;
+}
+
+static void sco_recv_data(struct test_data *data, GIOChannel *io)
+{
+ const struct sco_client_data *scodata = data->test_data;
+ struct iovec iov = { (void *)scodata->recv_data, scodata->data_len };
+ struct bthost *bthost;
+
+ data->step = 0;
+
+ if (rx_timestamping_init(g_io_channel_unix_get_fd(io),
+ scodata->so_timestamping))
+ return;
+
+ bthost = hciemu_client_get_host(data->hciemu);
+ g_io_add_watch(io, G_IO_IN, sock_received_data, NULL);
+
+ bthost_send_sco(bthost, data->handle, 0x00, &iov, 1);
+ ++data->step;
+}
+
static gboolean sco_connect_cb(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
@@ -805,6 +878,9 @@ static gboolean sco_connect_cb(GIOChannel *io, GIOCondition cond,
else
tester_print("Successfully connected");
+ if (scodata->recv_data)
+ sco_recv_data(data, io);
+
if (scodata->send_data) {
ssize_t ret = 0;
unsigned int count;
@@ -1137,6 +1213,12 @@ int main(int argc, char *argv[])
test_sco_11("SCO mSBC 1.1 - Failure", &connect_failure, setup_powered,
test_connect_transp);
+ test_sco("SCO CVSD Recv - Success", &connect_recv_success,
+ setup_powered, test_connect);
+
+ test_sco("SCO CVSD Recv - RX Timestamping", &connect_recv_rx_ts_success,
+ setup_powered, test_connect);
+
test_sco("SCO CVSD Send - Success", &connect_send_success,
setup_powered, test_connect);
--
2.49.0
^ permalink raw reply related [flat|nested] 7+ messages in thread
* RE: [BlueZ,1/5] tools: add tests for RX timestamping
2025-04-27 10:44 [PATCH BlueZ 1/5] tools: add tests for RX timestamping Pauli Virtanen
` (3 preceding siblings ...)
2025-04-27 10:44 ` [PATCH BlueZ 5/5] sco-tester: add SCO receive and RX timestamping tests Pauli Virtanen
@ 2025-04-27 12:07 ` bluez.test.bot
2025-04-28 15:00 ` [PATCH BlueZ 1/5] " patchwork-bot+bluetooth
5 siblings, 0 replies; 7+ messages in thread
From: bluez.test.bot @ 2025-04-27 12:07 UTC (permalink / raw)
To: linux-bluetooth, pav
[-- Attachment #1: Type: text/plain, Size: 2116 bytes --]
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=957482
---Test result---
Test Summary:
CheckPatch PENDING 0.31 seconds
GitLint PENDING 0.29 seconds
BuildEll PASS 20.42 seconds
BluezMake PASS 2589.99 seconds
MakeCheck PASS 20.54 seconds
MakeDistcheck PASS 199.06 seconds
CheckValgrind PASS 275.68 seconds
CheckSmatch WARNING 303.73 seconds
bluezmakeextell PASS 128.74 seconds
IncrementalBuild PENDING 0.35 seconds
ScanBuild PASS 907.22 seconds
Details
##############################
Test: CheckPatch - PENDING
Desc: Run checkpatch.pl script
Output:
##############################
Test: GitLint - PENDING
Desc: Run gitlint
Output:
##############################
Test: CheckSmatch - WARNING
Desc: Run smatch tool with source
Output:
emulator/bthost.c:668:28: warning: Variable length array is used.emulator/bthost.c:669:32: warning: Variable length array is used.emulator/bthost.c:886:28: warning: Variable length array is used.emulator/bthost.c:920:28: warning: Variable length array is used.emulator/btdev.c:453:29: warning: Variable length array is used.emulator/bthost.c:668:28: warning: Variable length array is used.emulator/bthost.c:669:32: warning: Variable length array is used.emulator/bthost.c:886:28: warning: Variable length array is used.emulator/bthost.c:920:28: warning: Variable length array is used.tools/sco-tester.c: note: in included file:./lib/bluetooth.h:232:15: warning: array of flexible structures./lib/bluetooth.h:237:31: warning: array of flexible structures
##############################
Test: IncrementalBuild - PENDING
Desc: Incremental build with the patches in the series
Output:
---
Regards,
Linux Bluetooth
^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH BlueZ 1/5] tools: add tests for RX timestamping
2025-04-27 10:44 [PATCH BlueZ 1/5] tools: add tests for RX timestamping Pauli Virtanen
` (4 preceding siblings ...)
2025-04-27 12:07 ` [BlueZ,1/5] tools: add tests for RX timestamping bluez.test.bot
@ 2025-04-28 15:00 ` patchwork-bot+bluetooth
5 siblings, 0 replies; 7+ messages in thread
From: patchwork-bot+bluetooth @ 2025-04-28 15:00 UTC (permalink / raw)
To: Pauli Virtanen; +Cc: linux-bluetooth
Hello:
This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Sun, 27 Apr 2025 13:44:35 +0300 you wrote:
> Add tests:
>
> ISO Receive - RX Timestamping
> L2CAP BR/EDR Client - RX Timestamping
> L2CAP BR/EDR Client - RX Timestamping 32k
> L2CAP LE Client - RX Timestamping
> L2CAP LE Client - RX Timestamping 32k
>
> [...]
Here is the summary with links:
- [BlueZ,1/5] tools: add tests for RX timestamping
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=7763584f6d01
- [BlueZ,2/5] bthost: implement fragmenting to ACL MTU
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=a112d4345771
- [BlueZ,3/5] hciemu: set bthost ACL MTU to match btdev
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=aeeb4fd64adf
- [BlueZ,4/5] bthost: support sending SCO packets
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=682e9252def9
- [BlueZ,5/5] sco-tester: add SCO receive and RX timestamping tests
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=f1d167215935
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2025-04-28 14:59 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-04-27 10:44 [PATCH BlueZ 1/5] tools: add tests for RX timestamping Pauli Virtanen
2025-04-27 10:44 ` [PATCH BlueZ 2/5] bthost: implement fragmenting to ACL MTU Pauli Virtanen
2025-04-27 10:44 ` [PATCH BlueZ 3/5] hciemu: set bthost ACL MTU to match btdev Pauli Virtanen
2025-04-27 10:44 ` [PATCH BlueZ 4/5] bthost: support sending SCO packets Pauli Virtanen
2025-04-27 10:44 ` [PATCH BlueZ 5/5] sco-tester: add SCO receive and RX timestamping tests Pauli Virtanen
2025-04-27 12:07 ` [BlueZ,1/5] tools: add tests for RX timestamping bluez.test.bot
2025-04-28 15:00 ` [PATCH BlueZ 1/5] " patchwork-bot+bluetooth
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.