diff mbox series

[BlueZ,v1,1/3] l2cap-tester: Add tests for multiple data packets

Message ID 20240626150229.103047-1-luiz.dentz@gmail.com (mailing list archive)
State New, archived
Headers show
Series [BlueZ,v1,1/3] l2cap-tester: Add tests for multiple data packets | expand

Checks

Context Check Description
tedd_an/pre-ci_am success Success
tedd_an/CheckPatch warning WARNING:SUSPECT_CODE_INDENT: suspect code indent for conditional statements (16, 25) #351: FILE: tools/l2cap-tester.c:1285: + if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &data->l2o, [...] tester_warn("getsockopt(L2CAP_OPTIONS): %s (%d)", /github/workspace/src/src/13713119.patch total: 0 errors, 1 warnings, 431 lines checked NOTE: For some of the reported defects, checkpatch may be able to mechanically convert to the typical style using --fix or --fix-inplace. /github/workspace/src/src/13713119.patch has style problems, please review. NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO NOTE: If any of the errors are false positives, please report them to the maintainer, see CHECKPATCH in MAINTAINERS.
tedd_an/GitLint success Gitlint PASS
tedd_an/BuildEll success Build ELL PASS
tedd_an/BluezMake success Bluez Make PASS
tedd_an/MakeCheck success Bluez Make Check PASS
tedd_an/MakeDistcheck success Make Distcheck PASS
tedd_an/CheckValgrind success Check Valgrind PASS
tedd_an/CheckSmatch warning CheckSparse WARNING emulator/bthost.c:613:28: warning: Variable length array is used.emulator/bthost.c:787:28: warning: Variable length array is used.
tedd_an/bluezmakeextell success Make External ELL PASS
tedd_an/IncrementalBuild success Incremental Build PASS
tedd_an/ScanBuild success Scan Build PASS

Commit Message

Luiz Augusto von Dentz June 26, 2024, 3:02 p.m. UTC
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>

This adds the following tests which cover the TX/RX of multiple
packets (up to 32K):

L2CAP BR/EDR Client - Read 32k Success
L2CAP BR/EDR Client - Write 32k Success
L2CAP BR/EDR Server - Read 32k Success
L2CAP BR/EDR Server - Write 32k Success
---
 tools/l2cap-tester.c | 294 ++++++++++++++++++++++++++-----------------
 1 file changed, 180 insertions(+), 114 deletions(-)

Comments

bluez.test.bot@gmail.com June 26, 2024, 5:39 p.m. UTC | #1
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=865811

---Test result---

Test Summary:
CheckPatch                    FAIL      9.80 seconds
GitLint                       PASS      0.60 seconds
BuildEll                      PASS      24.62 seconds
BluezMake                     PASS      1809.27 seconds
MakeCheck                     PASS      13.20 seconds
MakeDistcheck                 PASS      184.30 seconds
CheckValgrind                 PASS      256.07 seconds
CheckSmatch                   WARNING   358.51 seconds
bluezmakeextell               PASS      122.75 seconds
IncrementalBuild              PASS      4778.15 seconds
ScanBuild                     PASS      1033.97 seconds

Details
##############################
Test: CheckPatch - FAIL
Desc: Run checkpatch.pl script
Output:
[BlueZ,v1,1/3] l2cap-tester: Add tests for multiple data packets
WARNING:SUSPECT_CODE_INDENT: suspect code indent for conditional statements (16, 25)
#351: FILE: tools/l2cap-tester.c:1285:
+		if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &data->l2o,
[...]
 			 tester_warn("getsockopt(L2CAP_OPTIONS): %s (%d)",

/github/workspace/src/src/13713119.patch total: 0 errors, 1 warnings, 431 lines checked

NOTE: For some of the reported defects, checkpatch may be able to
      mechanically convert to the typical style using --fix or --fix-inplace.

/github/workspace/src/src/13713119.patch has style problems, please review.

NOTE: Ignored message types: COMMIT_MESSAGE COMPLEX_MACRO CONST_STRUCT FILE_PATH_CHANGES MISSING_SIGN_OFF PREFER_PACKED SPDX_LICENSE_TAG SPLIT_STRING SSCANF_TO_KSTRTO

NOTE: If any of the errors are false positives, please report
      them to the maintainer, see CHECKPATCH in MAINTAINERS.


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


---
Regards,
Linux Bluetooth
patchwork-bot+bluetooth@kernel.org June 27, 2024, 6:40 p.m. UTC | #2
Hello:

This series was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:

On Wed, 26 Jun 2024 11:02:27 -0400 you wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
> 
> This adds the following tests which cover the TX/RX of multiple
> packets (up to 32K):
> 
> L2CAP BR/EDR Client - Read 32k Success
> L2CAP BR/EDR Client - Write 32k Success
> L2CAP BR/EDR Server - Read 32k Success
> L2CAP BR/EDR Server - Write 32k Success
> 
> [...]

Here is the summary with links:
  - [BlueZ,v1,1/3] l2cap-tester: Add tests for multiple data packets
    (no matching commit)
  - [BlueZ,v1,2/3] bthost: Introduce bthost_add_l2cap_server_custom
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=b6f8c0024a87
  - [BlueZ,v1,3/3] l2cap-tester: Add tests for multiple data packets over LE
    https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=72c3f5bf1ce6

You are awesome, thank you!
diff mbox series

Patch

diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c
index c34080654ed6..b6b879407115 100644
--- a/tools/l2cap-tester.c
+++ b/tools/l2cap-tester.c
@@ -45,6 +45,7 @@  struct test_data {
 	uint16_t handle;
 	uint16_t scid;
 	uint16_t dcid;
+	struct l2cap_options l2o;
 	int sk;
 	int sk2;
 	bool host_disconnected;
@@ -332,6 +333,16 @@  static const struct l2cap_data client_connect_pin_success_test = {
 
 static uint8_t l2_data[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
 
+const uint8_t l2_data_32k[32768] = { [0 ... 4095] =  0x00,
+				[4096 ... 8191] =  0x01,
+				[8192 ... 12287] =  0x02,
+				[12288 ... 16383] =  0x03,
+				[16384 ... 20479] =  0x04,
+				[20480 ... 24575] =  0x05,
+				[24576 ... 28671] =  0x06,
+				[28672 ... 32767] =  0x07,
+};
+
 static const struct l2cap_data client_connect_read_success_test = {
 	.client_psm = 0x1001,
 	.server_psm = 0x1001,
@@ -339,6 +350,13 @@  static const struct l2cap_data client_connect_read_success_test = {
 	.data_len = sizeof(l2_data),
 };
 
+static const struct l2cap_data client_connect_read_32k_success_test = {
+	.client_psm = 0x1001,
+	.server_psm = 0x1001,
+	.read_data = l2_data_32k,
+	.data_len = sizeof(l2_data_32k),
+};
+
 static const struct l2cap_data client_connect_write_success_test = {
 	.client_psm = 0x1001,
 	.server_psm = 0x1001,
@@ -346,6 +364,13 @@  static const struct l2cap_data client_connect_write_success_test = {
 	.data_len = sizeof(l2_data),
 };
 
+static const struct l2cap_data client_connect_write_32k_success_test = {
+	.client_psm = 0x1001,
+	.server_psm = 0x1001,
+	.write_data = l2_data_32k,
+	.data_len = sizeof(l2_data_32k),
+};
+
 static const struct l2cap_data client_connect_tx_timestamping_test = {
 	.client_psm = 0x1001,
 	.server_psm = 0x1001,
@@ -399,6 +424,16 @@  static const struct l2cap_data l2cap_server_read_success_test = {
 	.data_len = sizeof(l2_data),
 };
 
+static const struct l2cap_data l2cap_server_read_32k_success_test = {
+	.server_psm = 0x1001,
+	.send_cmd_code = BT_L2CAP_PDU_CONN_REQ,
+	.send_cmd = l2cap_connect_req,
+	.send_cmd_len = sizeof(l2cap_connect_req),
+	.expect_cmd_code = BT_L2CAP_PDU_CONN_RSP,
+	.read_data = l2_data_32k,
+	.data_len = sizeof(l2_data_32k),
+};
+
 static const struct l2cap_data l2cap_server_write_success_test = {
 	.server_psm = 0x1001,
 	.send_cmd_code = BT_L2CAP_PDU_CONN_REQ,
@@ -409,6 +444,16 @@  static const struct l2cap_data l2cap_server_write_success_test = {
 	.data_len = sizeof(l2_data),
 };
 
+static const struct l2cap_data l2cap_server_write_32k_success_test = {
+	.server_psm = 0x1001,
+	.send_cmd_code = BT_L2CAP_PDU_CONN_REQ,
+	.send_cmd = l2cap_connect_req,
+	.send_cmd_len = sizeof(l2cap_connect_req),
+	.expect_cmd_code = BT_L2CAP_PDU_CONN_RSP,
+	.write_data = l2_data_32k,
+	.data_len = sizeof(l2_data_32k),
+};
+
 static const uint8_t l2cap_sec_block_rsp[] = {	0x00, 0x00,	/* dcid */
 						0x41, 0x00,	/* scid */
 						0x03, 0x00,	/* Sec Block */
@@ -1104,50 +1149,54 @@  static void test_basic(const void *test_data)
 	tester_test_passed();
 }
 
-static gboolean client_received_data(GIOChannel *io, GIOCondition cond,
-							gpointer user_data)
+static void received_data(struct test_data *tdata, const void *buf,
+					uint16_t len, const void *data,
+					uint16_t data_len)
 {
-	struct test_data *data = tester_get_data();
-	const struct l2cap_data *l2data = data->test_data;
-	char buf[1024];
-	int sk;
+	static struct iovec iov;
 
-	tester_debug("Client received data");
+	util_iov_append(&iov, buf, len);
 
-	sk = g_io_channel_unix_get_fd(io);
-	if (read(sk, buf, l2data->data_len) != l2data->data_len) {
-		tester_warn("Unable to read %u bytes", l2data->data_len);
+	tester_debug("read: %d/%zu", len, iov.iov_len);
+
+	/* Check if all the data has been received */
+	if (iov.iov_len < data_len)
+		return;
+
+	--tdata->step;
+
+	if (iov.iov_len != data_len || memcmp(iov.iov_base, data, data_len))
 		tester_test_failed();
-		return FALSE;
-	}
-
-	if (memcmp(buf, l2data->read_data, l2data->data_len))
-		tester_test_failed();
-	else
+	else if (!tdata->step)
 		tester_test_passed();
 
-	return FALSE;
+	free(iov.iov_base);
+	iov.iov_base = NULL;
+	iov.iov_len = 0;
 }
 
-static gboolean server_received_data(GIOChannel *io, GIOCondition cond,
+static gboolean sock_received_data(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
 	struct test_data *data = tester_get_data();
 	const struct l2cap_data *l2data = data->test_data;
 	char buf[1024];
 	int sk;
+	ssize_t len;
 
 	sk = g_io_channel_unix_get_fd(io);
-	if (read(sk, buf, l2data->data_len) != l2data->data_len) {
-		tester_warn("Unable to read %u bytes", l2data->data_len);
+
+	len = read(sk, buf, sizeof(buf));
+	if (len < 0) {
+		tester_warn("Unable to read: %s (%d)", strerror(errno), errno);
 		tester_test_failed();
 		return FALSE;
 	}
 
-	if (memcmp(buf, l2data->read_data, l2data->data_len))
-		tester_test_failed();
-	else
-		tester_test_passed();
+	received_data(data, buf, len, l2data->read_data, l2data->data_len);
+
+	if (data->step)
+		return TRUE;
 
 	return FALSE;
 }
@@ -1158,36 +1207,7 @@  static void bthost_received_data(const void *buf, uint16_t len,
 	struct test_data *data = tester_get_data();
 	const struct l2cap_data *l2data = data->test_data;
 
-	tester_debug("BTHost received data: %u bytes", len);
-
-	--data->step;
-
-	if (len != l2data->data_len) {
-		tester_test_failed();
-		return;
-	}
-
-	if (memcmp(buf, l2data->write_data, l2data->data_len))
-		tester_test_failed();
-	else if (!data->step)
-		tester_test_passed();
-}
-
-static void server_bthost_received_data(const void *buf, uint16_t len,
-							void *user_data)
-{
-	struct test_data *data = tester_get_data();
-	const struct l2cap_data *l2data = data->test_data;
-
-	if (len != l2data->data_len) {
-		tester_test_failed();
-		return;
-	}
-
-	if (memcmp(buf, l2data->write_data, l2data->data_len))
-		tester_test_failed();
-	else
-		tester_test_passed();
+	received_data(data, buf, len, l2data->write_data, l2data->data_len);
 }
 
 static gboolean socket_closed_cb(GIOChannel *io, GIOCondition cond,
@@ -1234,27 +1254,26 @@  static gboolean socket_closed_cb(GIOChannel *io, GIOCondition cond,
 static bool check_mtu(struct test_data *data, int sk)
 {
 	const struct l2cap_data *l2data = data->test_data;
-	struct l2cap_options l2o;
 	socklen_t len;
 
-	memset(&l2o, 0, sizeof(l2o));
+	memset(&data->l2o, 0, sizeof(data->l2o));
 
 	if (data->hciemu_type == HCIEMU_TYPE_LE &&
 				(l2data->client_psm || l2data->server_psm)) {
 		/* LE CoC enabled kernels should support BT_RCVMTU and
 		 * BT_SNDMTU.
 		 */
-		len = sizeof(l2o.imtu);
+		len = sizeof(data->l2o.imtu);
 		if (getsockopt(sk, SOL_BLUETOOTH, BT_RCVMTU,
-							&l2o.imtu, &len) < 0) {
+						&data->l2o.imtu, &len) < 0) {
 			tester_warn("getsockopt(BT_RCVMTU): %s (%d)",
 					strerror(errno), errno);
 			return false;
 		}
 
-		len = sizeof(l2o.omtu);
+		len = sizeof(data->l2o.omtu);
 		if (getsockopt(sk, SOL_BLUETOOTH, BT_SNDMTU,
-							&l2o.omtu, &len) < 0) {
+						&data->l2o.omtu, &len) < 0) {
 			tester_warn("getsockopt(BT_SNDMTU): %s (%d)",
 					strerror(errno), errno);
 			return false;
@@ -1262,8 +1281,9 @@  static bool check_mtu(struct test_data *data, int sk)
 	} else {
 		/* For non-LE CoC enabled kernels we need to fall back to
 		 * L2CAP_OPTIONS, so test support for it as well */
-		len = sizeof(l2o);
-		if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &l2o, &len) < 0) {
+		len = sizeof(data->l2o);
+		if (getsockopt(sk, SOL_L2CAP, L2CAP_OPTIONS, &data->l2o,
+						&len) < 0) {
 			 tester_warn("getsockopt(L2CAP_OPTIONS): %s (%d)",
 						strerror(errno), errno);
 			 return false;
@@ -1326,6 +1346,84 @@  static void l2cap_tx_timestamping(struct test_data *data, GIOChannel *io)
 	data->err_io_id = g_io_add_watch(io, G_IO_ERR, recv_errqueue, data);
 }
 
+static int l2cap_send(int sk, const void *data, size_t len, uint16_t mtu)
+{
+	struct iovec iov = { (void *)data, len };
+	int err;
+	size_t total = 0;
+
+	len = MIN(mtu, len);
+
+	while (iov.iov_len) {
+		size_t l = MIN(iov.iov_len, len);
+
+		err = write(sk, util_iov_pull_mem(&iov, l), l);
+		if (err < 0)
+			return -errno;
+
+		total += err;
+		tester_debug("write: %d/%zu", err, total);
+	}
+
+	return total;
+}
+
+static void l2cap_read_data(struct test_data *data, GIOChannel *io,
+							uint16_t cid)
+{
+	const struct l2cap_data *l2data = data->test_data;
+	struct bthost *bthost;
+	struct iovec iov = { (void *)l2data->read_data, l2data->data_len };
+	size_t len;
+
+	data->step = 0;
+
+	bthost = hciemu_client_get_host(data->hciemu);
+	g_io_add_watch(io, G_IO_IN, sock_received_data, NULL);
+
+	len = MIN(iov.iov_len, data->l2o.imtu);
+
+	while (iov.iov_len) {
+		size_t l = MIN(iov.iov_len, len);
+
+		bthost_send_cid(bthost, data->handle, cid,
+					util_iov_pull_mem(&iov, l), l);
+	}
+
+	++data->step;
+}
+
+static void l2cap_write_data(struct test_data *data, GIOChannel *io,
+							uint16_t cid)
+{
+	const struct l2cap_data *l2data = data->test_data;
+	struct bthost *bthost;
+	ssize_t ret;
+	int sk;
+	unsigned int count;
+
+	sk = g_io_channel_unix_get_fd(io);
+
+	data->step = 0;
+
+	bthost = hciemu_client_get_host(data->hciemu);
+	bthost_add_cid_hook(bthost, data->handle, cid, bthost_received_data,
+							NULL);
+
+	l2cap_tx_timestamping(data, io);
+
+	for (count = 0; count < l2data->repeat_send + 1; ++count) {
+		ret = l2cap_send(sk, l2data->write_data, l2data->data_len,
+							data->l2o.omtu);
+		if (ret != l2data->data_len) {
+			tester_warn("Unable to write all data: "
+					"%zd != %u", ret, l2data->data_len);
+			tester_test_failed();
+		}
+		++data->step;
+	}
+}
+
 static gboolean l2cap_connect_cb(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
@@ -1356,37 +1454,10 @@  static gboolean l2cap_connect_cb(GIOChannel *io, GIOCondition cond,
 	}
 
 	if (l2data->read_data) {
-		struct bthost *bthost;
-
-		bthost = hciemu_client_get_host(data->hciemu);
-		g_io_add_watch(io, G_IO_IN, client_received_data, NULL);
-
-		bthost_send_cid(bthost, data->handle, data->dcid,
-					l2data->read_data, l2data->data_len);
-
+		l2cap_read_data(data, io, data->dcid);
 		return FALSE;
 	} else if (l2data->write_data) {
-		struct bthost *bthost;
-		ssize_t ret;
-		unsigned int count;
-
-		data->step = 0;
-
-		bthost = hciemu_client_get_host(data->hciemu);
-		bthost_add_cid_hook(bthost, data->handle, data->dcid,
-					bthost_received_data, NULL);
-
-		l2cap_tx_timestamping(data, io);
-
-		for (count = 0; count < l2data->repeat_send + 1; ++count) {
-			ret = write(sk, l2data->write_data, l2data->data_len);
-			if (ret != l2data->data_len) {
-				tester_warn("Unable to write all data");
-				tester_test_failed();
-			}
-			++data->step;
-		}
-
+		l2cap_write_data(data, io, data->dcid);
 		return FALSE;
 	} else if (l2data->shut_sock_wr) {
 		g_io_add_watch(io, G_IO_HUP, socket_closed_cb, NULL);
@@ -2087,31 +2158,10 @@  static gboolean l2cap_accept_cb(GIOChannel *io, GIOCondition cond,
 	}
 
 	if (l2data->read_data) {
-		struct bthost *bthost;
-
-		bthost = hciemu_client_get_host(data->hciemu);
-		g_io_add_watch(io, G_IO_IN, server_received_data, NULL);
-		bthost_send_cid(bthost, data->handle, data->dcid,
-					l2data->read_data, l2data->data_len);
-
-		g_io_channel_unref(io);
-
+		l2cap_read_data(data, io, data->dcid);
 		return FALSE;
 	} else if (l2data->write_data) {
-		struct bthost *bthost;
-		ssize_t ret;
-
-		bthost = hciemu_client_get_host(data->hciemu);
-		bthost_add_cid_hook(bthost, data->handle, data->scid,
-					server_bthost_received_data, NULL);
-
-		ret = write(sk, l2data->write_data, l2data->data_len);
-
-		if (ret != l2data->data_len) {
-			tester_warn("Unable to write all data");
-			tester_test_failed();
-		}
-
+		l2cap_write_data(data, io, data->scid);
 		return FALSE;
 	}
 
@@ -2405,10 +2455,18 @@  int main(int argc, char *argv[])
 					&client_connect_read_success_test,
 					setup_powered_client, test_connect);
 
+	test_l2cap_bredr("L2CAP BR/EDR Client - Read 32k Success",
+					&client_connect_read_32k_success_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);
 
+	test_l2cap_bredr("L2CAP BR/EDR Client - Write 32k Success",
+					&client_connect_write_32k_success_test,
+					setup_powered_client, test_connect);
+
 	test_l2cap_bredr("L2CAP BR/EDR Client - TX Timestamping",
 					&client_connect_tx_timestamping_test,
 					setup_powered_client, test_connect);
@@ -2437,10 +2495,18 @@  int main(int argc, char *argv[])
 					&l2cap_server_read_success_test,
 					setup_powered_server, test_server);
 
+	test_l2cap_bredr("L2CAP BR/EDR Server - Read 32k Success",
+					&l2cap_server_read_32k_success_test,
+					setup_powered_server, test_server);
+
 	test_l2cap_bredr("L2CAP BR/EDR Server - Write Success",
 					&l2cap_server_write_success_test,
 					setup_powered_server, test_server);
 
+	test_l2cap_bredr("L2CAP BR/EDR Server - Write 32k Success",
+					&l2cap_server_write_32k_success_test,
+					setup_powered_server, test_server);
+
 	test_l2cap_bredr("L2CAP BR/EDR Server - Security Block",
 					&l2cap_server_sec_block_test,
 					setup_powered_server, test_server);