From patchwork Wed Jun 26 15:02:27 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 807581 Received: from mail-vs1-f53.google.com (mail-vs1-f53.google.com [209.85.217.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 396A41891DB for ; Wed, 26 Jun 2024 15:02:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.217.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719414157; cv=none; b=A7GRJwUJ6yiicVfE2DzSCyART/Tz6vnSesXdclsQbC8x2SUlnQ1hGXidzhcyk11zzeDxlpoDoW0grt/4U0RjSK5Di4tRdOtdjVf6ZXJFz6P9V2OL0ZsonlvCMlIinM1t/S6wljD7dvLAWKnLiQg/WY0iuXsAt9lhb2po6KUS29A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719414157; c=relaxed/simple; bh=uOXJVWuH5fAqZM6wL3b57DttXCg1aabMz6oB+SrXCdA=; h=From:To:Subject:Date:Message-ID:MIME-Version; b=P04ImznJEzR9WQPMj/EHMGBTIK25gOko0f+E4Je5/vjDxw5WcXkC5jhwau0m1i004ggC6jui7XIHlElfM7ie9FrZWwHnP8bmiZrUiwhiGadDGc+ITqFNYVds+r4mxVNn/Cg8fI6I5/WI1JfisKKT6tB1wAlse7zQrsyTDEgvjwc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=HRm00riZ; arc=none smtp.client-ip=209.85.217.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="HRm00riZ" Received: by mail-vs1-f53.google.com with SMTP id ada2fe7eead31-48f5c2f066cso360633137.1 for ; Wed, 26 Jun 2024 08:02:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719414153; x=1720018953; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:from:to:cc:subject:date:message-id:reply-to; bh=asiGyBu+ZM4SkXs/SSvZZtpNfzJbQq8Cupz0myeublI=; b=HRm00riZIX9WQZpnr/DpFFrZa8HdQWrfBiz+xOUQ8SWWoFA+6esPERbUZfVB4cjQWD L/OD+jOao5hFuq0NDKjoLQjNbOrMoXiV7681UkOnipfFrl8ttsJcT9a8E4j8IEH/NS61 9h+OLg2NfpcKv0jtGWO/vBOLid5M8xRDN3Bu1PgpuhEBM8p4fi+zqbVCWjTW4IyR9pmr H3vTe35MoKdDF5TS/d7B2eOtJFLECPBV/SEFW+rfiTWHHK8lJCdnZEb0NBNzfRJY8pd3 UT5zmyBjBGeS2sZjlOqnryFgasQpNvEHjSUv80o6zNdlsFWXYVcR/OxcPU5nMSNzZDBB EfNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719414153; x=1720018953; h=content-transfer-encoding:mime-version:message-id:date:subject:to :from:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=asiGyBu+ZM4SkXs/SSvZZtpNfzJbQq8Cupz0myeublI=; b=aTe3iL3PqbskcU+P+wCB/T5MR+Jw0TLozWwWQOZXxxSI2Hx+I4b/Wz9do6sg9nyZ+c dwxWFm+LipPE4+emmXkL7aGptHlmVu8qCXU1SJczK8X6VXhTu/N/3cEdemk+POczrthE kxTV3ZIkJshu9VCJB3rcTV89Hps95uh//q5ho7y0fH7fiqctqgUFRWWFYoyfFVqJXFP9 b6DnKBehgMhFcW+czIbl9EFrxayFr8zybFkRBq7G8YxWbPmdgPDq5WRxzDLbKpIv4TLP hzai5cDhygaggqwNksnS0ei/9U+cpAsUdxTYOsKgxAdqgcnQ3w7MuYqFW4EHwx2XXofA D9WQ== X-Gm-Message-State: AOJu0Yzhkmqkb4gxCIiQe34zixBFKwTysqxIJ/S4C+zXWlx5LKn5UavU 1WL3rklfoTdAE1veo2+u1nFkEoi+7fJ/Vo5BgVLQmZWEUCvNVuEWy9OFmA== X-Google-Smtp-Source: AGHT+IG3/6UHPChATIZRhwDaf6tfbR/v+oXHcBM7ee9kWOFfHBcH8xZk6G0KGomV4qTlQwczYW3thw== X-Received: by 2002:a67:e941:0:b0:48f:19af:d2a8 with SMTP id ada2fe7eead31-48f690127dfmr5807732137.11.1719414153227; Wed, 26 Jun 2024 08:02:33 -0700 (PDT) Received: from lvondent-mobl4.. (syn-107-146-107-067.res.spectrum.com. [107.146.107.67]) by smtp.gmail.com with ESMTPSA id ada2fe7eead31-48f5cd3cf91sm1203746137.13.2024.06.26.08.02.32 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Jun 2024 08:02:32 -0700 (PDT) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH BlueZ v1 1/3] l2cap-tester: Add tests for multiple data packets Date: Wed, 26 Jun 2024 11:02:27 -0400 Message-ID: <20240626150229.103047-1-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.45.2 Precedence: bulk X-Mailing-List: linux-bluetooth@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Luiz Augusto von Dentz 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(-) 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); From patchwork Wed Jun 26 15:02:28 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 807948 Received: from mail-vs1-f41.google.com (mail-vs1-f41.google.com [209.85.217.41]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6B59E18A92A for ; Wed, 26 Jun 2024 15:02:37 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.217.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719414158; cv=none; b=PwnK+Iy7u2blRd3yYxUlXmiket/iXsBmVxxSp/YLTjFUdnnUfKNCyzJDKE1nP+JLVsAg7uYZJMofwUHVwZE2s9Er+VKnMbWR27MURv40h0e303U+Gy1XWrrZ/1K8vgeNHMBM7LZQSsWJfBwEpbNxtbYLsdJp4lKKKm4/kzld6ts= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719414158; c=relaxed/simple; bh=WwqX7L15Fq+c1Q5yx3SsPTgWNleoDr+ubLQXUolgqDM=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=pRBCoaUNqzXd7vkX4vsgrTpfvQS4Yl7Z4+47PgZcRFoHnUe+lcZhEYQNpy5DpN7BzxZI8Hq4ZCjiVQ0e4Q3LQHckoitlvSn3RGy9TUo13NUEbt/v4HsUPgMoNgwDmZL9Otn8Ytl+E61jyRCNb4VxUTqOhM5GfdftOZCRTLn75fY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=el3u6PB7; arc=none smtp.client-ip=209.85.217.41 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="el3u6PB7" Received: by mail-vs1-f41.google.com with SMTP id ada2fe7eead31-48f4cef1ea5so1266133137.3 for ; Wed, 26 Jun 2024 08:02:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719414156; x=1720018956; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=m5isFdIVM8mV96ILq2nIbsSV5yhFrRvXtbiyDi/DtQs=; b=el3u6PB7Xg+rxbF5KrDousVRfrYkPkw+932taZcrJHfKVBTwr4ZLP0MzBefr2W6cDu DdeajIiD1OWq3JEaBz4HPQGDui8F4ebreET0u2Pinz1C83sQp/GY3oOIOk9Orp/PYWb7 +6Wx+UkgGCxoOz8KNw3JZiLn0obot+bU7PcMsNkMx9yYP8KpEZlQP6ivX+d4zWVF84Sw jJas8lPeuCzFrzc/gyHZdwNv+4ZDBhd2xvwszDlHrzmGYNuWaRmhDImUIaqQYcAKaNAl /jcuPT2YTcLa3qRyq2WyZozfrN40fkBVY9hrD+FUw5xc+hpY0ijnK5/cyZnxHGwkyoYj 0nIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719414156; x=1720018956; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=m5isFdIVM8mV96ILq2nIbsSV5yhFrRvXtbiyDi/DtQs=; b=RdqsLAH0LKr1zTvIN9i6LPkRCRPS6Mqje99TWI1rIKarJKBXGTYjRZSk+8Ut4h0rZn Y5cSTnXYZURjWA/6NSmtUHpzsj+kzFjnC5YvENiI7If4x7B4hDlhUkbRykd8qYqRobVr 3LNY0qNjuG+UPEE8VhDS/YhVyy/nk7L/flViHdCMD8jYaH4T5/br1u5xEgoT2Zi15mUx xOsj6teli0WVbKK145qRY+aM1yW18QlB9rpLl4RyscjHFVoliOSjwQ+RaoA/jtLhJ9Kl z1/RC9G1K2dqqMSgxHcr9ud2YTpmf2igu5m58Yque5+G3jGs8nX8gc9xorj1pgv3uGqs 9xRQ== X-Gm-Message-State: AOJu0YyAczJK31oSA+2pR6rzWHW5DCQPLcvL2isalFCOWUD/nXM7YcuL yvn+/4+Doa9bJWSY0c7bx1KUcETroOCbTD4qAaJpt+4YRgknxFEH65Q66w== X-Google-Smtp-Source: AGHT+IGquN/1t8k4txln6F4unFLILtsndab42OjVvMjhctXLFXW7v+wa+jAJAZd6RLpmjwLWbZQu4A== X-Received: by 2002:a67:bd0f:0:b0:48f:3930:4a82 with SMTP id ada2fe7eead31-48f4f09f918mr8984423137.23.1719414155519; Wed, 26 Jun 2024 08:02:35 -0700 (PDT) Received: from lvondent-mobl4.. (syn-107-146-107-067.res.spectrum.com. [107.146.107.67]) by smtp.gmail.com with ESMTPSA id ada2fe7eead31-48f5cd3cf91sm1203746137.13.2024.06.26.08.02.33 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Jun 2024 08:02:33 -0700 (PDT) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH BlueZ v1 2/3] bthost: Introduce bthost_add_l2cap_server_custom Date: Wed, 26 Jun 2024 11:02:28 -0400 Message-ID: <20240626150229.103047-2-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240626150229.103047-1-luiz.dentz@gmail.com> References: <20240626150229.103047-1-luiz.dentz@gmail.com> Precedence: bulk X-Mailing-List: linux-bluetooth@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Luiz Augusto von Dentz This introduces bthost_add_l2cap_server_custom which can be used to define custom values for MTU, MPS and credits. --- emulator/bthost.c | 29 ++++++++++++++++++++++------- emulator/bthost.h | 5 +++++ 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/emulator/bthost.c b/emulator/bthost.c index d69e3d34ea3c..cc9bf7240531 100644 --- a/emulator/bthost.c +++ b/emulator/bthost.c @@ -195,6 +195,9 @@ struct l2cap_pending_req { struct l2cap_conn_cb_data { uint16_t psm; + uint16_t mtu; + uint16_t mps; + uint16_t credits; bthost_l2cap_connect_cb func; bthost_l2cap_disconnect_cb disconn_func; void *user_data; @@ -2164,14 +2167,13 @@ static bool l2cap_le_conn_req(struct bthost *bthost, struct btconn *conn, memset(&rsp, 0, sizeof(rsp)); - rsp.mtu = 23; - rsp.mps = 23; - rsp.credits = 1; - cb_data = bthost_find_l2cap_cb_by_psm(bthost, psm); - if (cb_data) + if (cb_data) { rsp.dcid = cpu_to_le16(conn->next_cid++); - else + rsp.mtu = cpu_to_le16(cb_data->mtu) ? : cpu_to_le16(23); + rsp.mps = cpu_to_le16(cb_data->mps) ? : cpu_to_le16(23); + rsp.credits = cpu_to_le16(cb_data->credits) ? : cpu_to_le16(1); + } else rsp.result = cpu_to_le16(0x0002); /* PSM Not Supported */ l2cap_sig_send(bthost, conn, BT_L2CAP_PDU_LE_CONN_RSP, ident, &rsp, @@ -3511,7 +3513,8 @@ uint64_t bthost_conn_get_fixed_chan(struct bthost *bthost, uint16_t handle) return conn->fixed_chan; } -void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm, +void bthost_add_l2cap_server_custom(struct bthost *bthost, uint16_t psm, + uint16_t mtu, uint16_t mps, uint16_t credits, bthost_l2cap_connect_cb func, bthost_l2cap_disconnect_cb disconn_func, void *user_data) @@ -3523,6 +3526,9 @@ void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm, return; data->psm = psm; + data->mtu = mtu; + data->mps = mps; + data->credits = credits; data->user_data = user_data; data->func = func; data->disconn_func = disconn_func; @@ -3531,6 +3537,15 @@ void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm, bthost->new_l2cap_conn_data = data; } +void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm, + bthost_l2cap_connect_cb func, + bthost_l2cap_disconnect_cb disconn_func, + void *user_data) +{ + bthost_add_l2cap_server_custom(bthost, psm, 0, 0, 0, func, + disconn_func, user_data); +} + void bthost_set_sc_support(struct bthost *bthost, bool enable) { struct bt_hci_cmd_write_secure_conn_support cmd; diff --git a/emulator/bthost.h b/emulator/bthost.h index 0c488e32afd0..2c5b0d5164cc 100644 --- a/emulator/bthost.h +++ b/emulator/bthost.h @@ -136,6 +136,11 @@ void bthost_add_l2cap_server(struct bthost *bthost, uint16_t psm, bthost_l2cap_connect_cb func, bthost_l2cap_disconnect_cb disconn_func, void *user_data); +void bthost_add_l2cap_server_custom(struct bthost *bthost, uint16_t psm, + uint16_t mtu, uint16_t mps, uint16_t credits, + bthost_l2cap_connect_cb func, + bthost_l2cap_disconnect_cb disconn_func, + void *user_data); void bthost_set_sc_support(struct bthost *bthost, bool enable); From patchwork Wed Jun 26 15:02:29 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 807580 Received: from mail-vs1-f43.google.com (mail-vs1-f43.google.com [209.85.217.43]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75D4B18A946 for ; Wed, 26 Jun 2024 15:02:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.217.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719414161; cv=none; b=RiJvrRqZANoOIRNPmGTAe6cxsd5WM6A9C1AOysfqUb0k9ciKxYcLqiJdyToRSUAP/rOCeZGnE3J1jpcU5Lk4loFtJJ8/YkWFSanywS6Z6V5ghk/ud9xWjNyHYXz5VTA4fZjAwTjfYfDrRV5yIaKRxt7j7pCI70byNHdFuGOS4n8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1719414161; c=relaxed/simple; bh=JvRCmKudBZp8osyME6STdiyD9IPied7S/MLT0sqQwpA=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=Benm9eEY/HwAO1xB9pilTvdySYwZj+Qid2sEhDgGFnB2MV1ZurfXgD2zFNRgyRNCqocWy8QwWkP06ZtRHVt1w2c0Qd/t9NTZ4A+Wm4XZtDaBkfNHABbLYHNoiaUsX/5woFF+Vm3JapzqRV+2ewqtPWD+mj9b7+jBiW4jtO4UITY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=B5Fa9ymO; arc=none smtp.client-ip=209.85.217.43 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="B5Fa9ymO" Received: by mail-vs1-f43.google.com with SMTP id ada2fe7eead31-48f68565fe0so961022137.3 for ; Wed, 26 Jun 2024 08:02:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1719414157; x=1720018957; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to; bh=udenrX245c88FgPuipcNos5kkd8VDEbmhpRG68qOaoo=; b=B5Fa9ymOQ4TRadnTR68ACAyeOeS+7LpitrEkfXLBczYIP3gBuSA/mRxNqdnVtu+buh qezuI9mX1zxJAzJCC3xH7eMBjlUOBEoQRLV1o8XQXYMRDHYrJaJyD/qNB7sWwKs5eRyW Bl7elA2Ai0UOoIeyqS5TGf04d0TNx/LjdZlbBq7iQlMytmd3Ah/X8eGCPbJRt4g0Kev0 NP4dpiYdDU3f8FlODcumzW+xT3+dGp+YTUjd5VpkJfkV7HaW3CBhSZpWMwxb3yZ1Hv7Y V5KyUAJo+//7shYH041jJKTAgSWlXLJYf8hyOGxWOruwsN9LmOpiwIoX5VR+4xucxVzw 7+JQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1719414157; x=1720018957; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=udenrX245c88FgPuipcNos5kkd8VDEbmhpRG68qOaoo=; b=W0MyKeyEDdpZ3fic9a4L5Q5NrIEpambp2y0PKxNLQBxO5bYUgd7ftH4xSyL59Or3Ph /hkmO3GJ7XdG2QSpS+5/XwQU/ebJI1v6BrAXRb5G4UA8TB2u/0fVrvHOU7gG5E5eXp+X xjtHpcjDv1nmwoPeQNgK8erbRGSnnIVcDejs+X2+jdUdafRjM0SgF6RowEL2Jc4LUf0U eZlNxDAPkzOcAkpRefpfJCbgW5jaddKkbDjNM0l4jxGaVvohDlVBXFwSRJYjrtHatxaA 7PZa+BKCRVs1om80/MRTVUSUcBDjYNI8wcSZAogOjSmLttc6aCvaIXgoewbc0hmZxG9+ aNqQ== X-Gm-Message-State: AOJu0YzwLSItylgS/A+gXjYUb88dz8+btOcGl5Nty9asYA7SWAbZJqfH oVybeiDks47LjEKBJpoUY6PUdadhuEm4xvtr9WSVVZE6Mub9V37lgZyB4w== X-Google-Smtp-Source: AGHT+IEhpfejsu3sKqpvp8AesYkIVs1cSG3AHXg88tLi0LTMykwbfWRzzstHVxWjWh8o5ADPeJi2OA== X-Received: by 2002:a05:6102:41a8:b0:48f:3c66:5347 with SMTP id ada2fe7eead31-48f52a43d43mr12956491137.9.1719414157449; Wed, 26 Jun 2024 08:02:37 -0700 (PDT) Received: from lvondent-mobl4.. (syn-107-146-107-067.res.spectrum.com. [107.146.107.67]) by smtp.gmail.com with ESMTPSA id ada2fe7eead31-48f5cd3cf91sm1203746137.13.2024.06.26.08.02.35 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Jun 2024 08:02:36 -0700 (PDT) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH BlueZ v1 3/3] l2cap-tester: Add tests for multiple data packets over LE Date: Wed, 26 Jun 2024 11:02:29 -0400 Message-ID: <20240626150229.103047-3-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.45.2 In-Reply-To: <20240626150229.103047-1-luiz.dentz@gmail.com> References: <20240626150229.103047-1-luiz.dentz@gmail.com> Precedence: bulk X-Mailing-List: linux-bluetooth@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Luiz Augusto von Dentz This adds the following tests which cover the TX/RX of multiple packets (up to 32K) over LE credit based flow control: L2CAP LE Client - Read 32k Success L2CAP LE Client - Write 32k Success --- tools/l2cap-tester.c | 66 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 61 insertions(+), 5 deletions(-) diff --git a/tools/l2cap-tester.c b/tools/l2cap-tester.c index b6b879407115..e1487bc7fd75 100644 --- a/tools/l2cap-tester.c +++ b/tools/l2cap-tester.c @@ -58,6 +58,9 @@ struct l2cap_data { uint16_t server_psm; uint16_t cid; uint8_t mode; + uint16_t mtu; + uint16_t mps; + uint16_t credits; int expect_err; int timeout; @@ -545,6 +548,22 @@ static const struct l2cap_data le_client_connect_read_success_test = { .data_len = sizeof(l2_data), }; +static const struct l2cap_data le_client_connect_read_32k_success_test = { + .client_psm = 0x0080, + .server_psm = 0x0080, + .mtu = 672, + .mps = 251, + /* Given enough credits to complete the transfer without waiting for + * more credits. + * credits = round_up(data size / mtu) * round_up(mtu / mps) + * credits = 49 * 3 + * credits = 147 + */ + .credits = 147, + .read_data = l2_data_32k, + .data_len = sizeof(l2_data_32k), +}; + static const struct l2cap_data le_client_connect_write_success_test = { .client_psm = 0x0080, .server_psm = 0x0080, @@ -552,6 +571,22 @@ static const struct l2cap_data le_client_connect_write_success_test = { .data_len = sizeof(l2_data), }; +static const struct l2cap_data le_client_connect_write_32k_success_test = { + .client_psm = 0x0080, + .server_psm = 0x0080, + .mtu = 672, + .mps = 251, + /* Given enough credits to complete the transfer without waiting for + * more credits. + * credits = round_up(data size / mtu) * round_up(mtu / mps) + * credits = 49 * 3 + * credits = 147 + */ + .credits = 147, + .write_data = l2_data_32k, + .data_len = sizeof(l2_data_32k), +}; + static const struct l2cap_data le_client_connect_tx_timestamping_test = { .client_psm = 0x0080, .server_psm = 0x0080, @@ -1278,6 +1313,10 @@ static bool check_mtu(struct test_data *data, int sk) strerror(errno), errno); return false; } + + /* Take SDU len into account */ + data->l2o.imtu -= 2; + data->l2o.omtu -= 2; } else { /* For non-LE CoC enabled kernels we need to fall back to * L2CAP_OPTIONS, so test support for it as well */ @@ -1673,9 +1712,20 @@ static void test_connect(const void *test_data) if (l2data->shut_sock_wr) host_disconnect_cb = client_l2cap_disconnect_cb; - bthost_add_l2cap_server(bthost, l2data->server_psm, - host_connect_cb, host_disconnect_cb, - data); + if (l2data->mtu || l2data->mps || l2data->credits) + bthost_add_l2cap_server_custom(bthost, + l2data->server_psm, + l2data->mtu, + l2data->mps, + l2data->credits, + host_connect_cb, + host_disconnect_cb, + data); + else + bthost_add_l2cap_server(bthost, l2data->server_psm, + host_connect_cb, + host_disconnect_cb, + data); } if (l2data->direct_advertising) @@ -2534,11 +2584,17 @@ int main(int argc, char *argv[]) &le_client_connect_timeout_test_1, setup_powered_client, test_connect_timeout); test_l2cap_le("L2CAP LE Client - Read Success", - &le_client_connect_read_success_test, - setup_powered_client, test_connect); + &le_client_connect_read_success_test, + setup_powered_client, test_connect); + 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 - Write Success", &le_client_connect_write_success_test, setup_powered_client, test_connect); + test_l2cap_le("L2CAP LE Client - Write 32k Success", + &le_client_connect_write_32k_success_test, + setup_powered_client, test_connect); test_l2cap_le("L2CAP LE Client - TX Timestamping", &le_client_connect_tx_timestamping_test, setup_powered_client, test_connect);