All of lore.kernel.org
 help / color / mirror / Atom feed
* [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.