Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp1903323rwd; Sun, 21 May 2023 08:32:16 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7fail23CTp4WQlv6yIhw1L1rYTdl66D1EstSsX9bfNmDur4TfwBkCIC6OuvGAlR5gXcOYN X-Received: by 2002:a17:90a:7f91:b0:253:6e6f:f5cd with SMTP id m17-20020a17090a7f9100b002536e6ff5cdmr7892983pjl.26.1684683136525; Sun, 21 May 2023 08:32:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1684683136; cv=none; d=google.com; s=arc-20160816; b=SRjBPvBGU68+zL8KR+O6OL8iC+cNZZzvodP4fX6OlNGCmNMqD7yCA6YXQWt26Z5P3T gkTDeoLmUobvhpuGrPzIcbOGxSyhIAm5dqGF8MF2HpY77eVN5QBiOEGx+kBoZ0pu5khP dLWRIePQsam3bT01bhYrIZ3bQrLttPz8JSkfapLFZB7dW0tz3r/nfWSJnaeIEOvB7pkE Fcm4TOuLYj6eF33BugINtc8aBKZPOtH8QQTA8YNs8pmHSCApJM5CIPcxLbYaxBiGT1fH xHy15X3KrNkwDNhvWw7jUi3Mf9BAI5o0AZqqg4UYGfHaUeCfqfqH+3KW3QHUYz+D0ykb xoIw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :message-id:date:subject:cc:to:from; bh=bXeh8z64HeXGRZsfr69VfU8JAzi03lRF2oXMEzzx91o=; b=1Grtr0g2YYn0aiZiwfUPNFy2S9uKy4KeHT9AqelNSIDkMhfW2gmjDHQFTu3kq8bdzx vEhKH0wnTot86/z9jSvPew755cOR/fmglnMKTJJ78W0MqkLnlXHparEYKzdv6QUnS1Rt r4tFpXROsh/XzJM9XikBkt1k7lAXtmwEbRYnAGoCOCs5g8MDO/KUc+6TSCtWenCG6L/F zUL+UAUNw9EOn2LzqZpGKYbdR1nKjQOyXOgaBLymEAdzrASfTeUe0l/B5wNA48f4w/0e H2xZnCxEl9XAiHXL2dbSYm6bDAbu9BNuekqkrvVKrGTVzP952eJM6IFSITL+HTFm8eDJ hubg== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id v26-20020a637a1a000000b0051b5de41857si3367414pgc.101.2023.05.21.08.32.04; Sun, 21 May 2023 08:32:16 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-bluetooth-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-bluetooth-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229891AbjEUP1t (ORCPT + 99 others); Sun, 21 May 2023 11:27:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50268 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229794AbjEUP1q (ORCPT ); Sun, 21 May 2023 11:27:46 -0400 Received: from mout01.posteo.de (mout01.posteo.de [185.67.36.141]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 43B72DE for ; Sun, 21 May 2023 08:27:44 -0700 (PDT) Received: from submission (posteo.de [185.67.36.169]) by mout01.posteo.de (Postfix) with ESMTPS id D2A19240029 for ; Sun, 21 May 2023 17:27:40 +0200 (CEST) Received: from customer (localhost [127.0.0.1]) by submission (posteo.de) with ESMTPSA id 4QPPbJ2Q4yz9rxG; Sun, 21 May 2023 17:27:40 +0200 (CEST) From: Pauli Virtanen To: linux-bluetooth@vger.kernel.org Cc: Pauli Virtanen Subject: [PATCH BlueZ 1/5] iso-tester: always use DEFER_SETUP for multiple CIS in same CIG Date: Sun, 21 May 2023 15:27:34 +0000 Message-Id: <024df2d86c14fc811701ba27bfa576476bc9c0d6.1684682575.git.pav@iki.fi> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-3.4 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_MED, SPF_HELO_NONE,SPF_NEUTRAL,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org There is a race between multiple connect() for CIS in the same CIG. connect() will both reconfigure the CIG and connect the CIS, but CIG cannot be reconfigured once one CIS has already connected. That these tests pass currently relies on some timing/event ordering in the emulator. Connecting multiple CIS in same CIG is meant to be done using DEFER_SETUP, so change the tests to use it, so we test the intended usage. --- tools/iso-tester.c | 150 +++++++++++++++++++++++++++++++-------------- 1 file changed, 104 insertions(+), 46 deletions(-) diff --git a/tools/iso-tester.c b/tools/iso-tester.c index c5c6f0aec..164cb465f 100644 --- a/tools/iso-tester.c +++ b/tools/iso-tester.c @@ -740,6 +740,12 @@ static const struct iso_client_data defer_16_2_1 = { .defer = true, }; +static const struct iso_client_data defer_1_16_2_1 = { + .qos = QOS_1_16_2_1, + .expect_err = 0, + .defer = true, +}; + static const struct iso_client_data connect_16_2_1_defer_send = { .qos = QOS_16_2_1, .expect_err = 0, @@ -817,6 +823,7 @@ static const struct iso_client_data connect_ac_6i = { .qos_2 = AC_6i_2, .expect_err = 0, .mcis = true, + .defer = true, }; static const struct iso_client_data connect_ac_6ii = { @@ -824,6 +831,7 @@ static const struct iso_client_data connect_ac_6ii = { .qos_2 = AC_6ii_2, .expect_err = 0, .mcis = true, + .defer = true, }; static const struct iso_client_data connect_ac_7i = { @@ -831,6 +839,7 @@ static const struct iso_client_data connect_ac_7i = { .qos_2 = AC_7i_2, .expect_err = 0, .mcis = true, + .defer = true, }; static const struct iso_client_data connect_ac_7ii = { @@ -838,6 +847,7 @@ static const struct iso_client_data connect_ac_7ii = { .qos_2 = AC_7ii_2, .expect_err = 0, .mcis = true, + .defer = true, }; static const struct iso_client_data connect_ac_8i = { @@ -845,6 +855,7 @@ static const struct iso_client_data connect_ac_8i = { .qos_2 = AC_8i_2, .expect_err = 0, .mcis = true, + .defer = true, }; static const struct iso_client_data connect_ac_8ii = { @@ -852,6 +863,7 @@ static const struct iso_client_data connect_ac_8ii = { .qos_2 = AC_8ii_2, .expect_err = 0, .mcis = true, + .defer = true, }; static const struct iso_client_data connect_ac_9i = { @@ -859,6 +871,7 @@ static const struct iso_client_data connect_ac_9i = { .qos_2 = AC_9i_2, .expect_err = 0, .mcis = true, + .defer = true, }; static const struct iso_client_data connect_ac_9ii = { @@ -866,6 +879,7 @@ static const struct iso_client_data connect_ac_9ii = { .qos_2 = AC_9ii_2, .expect_err = 0, .mcis = true, + .defer = true, }; static const struct iso_client_data connect_ac_11i = { @@ -873,6 +887,7 @@ static const struct iso_client_data connect_ac_11i = { .qos_2 = AC_11i_2, .expect_err = 0, .mcis = true, + .defer = true, }; static const struct iso_client_data connect_ac_11ii = { @@ -880,6 +895,7 @@ static const struct iso_client_data connect_ac_11ii = { .qos_2 = AC_11ii_2, .expect_err = 0, .mcis = true, + .defer = true, }; static const struct iso_client_data bcast_16_2_1_send = { @@ -1715,13 +1731,9 @@ static gboolean iso_connect2_cb(GIOChannel *io, GIOCondition cond, return iso_connect(io, cond, user_data); } -static void setup_connect(struct test_data *data, uint8_t num, GIOFunc func) +static int setup_sock(struct test_data *data, uint8_t num) { - const struct iso_client_data *isodata = data->test_data; - GIOChannel *io; int sk, err; - char c; - struct pollfd pfd; sk = create_iso_sock(data); if (sk < 0) { @@ -1729,7 +1741,8 @@ static void setup_connect(struct test_data *data, uint8_t num, GIOFunc func) tester_test_abort(); else tester_test_failed(); - return; + + return sk; } err = connect_iso_sock(data, num, sk); @@ -1743,65 +1756,106 @@ static void setup_connect(struct test_data *data, uint8_t num, GIOFunc func) else tester_test_failed(); - return; + return err; } - if (isodata->defer) { - int defer; - socklen_t len; - - /* Check if socket has DEFER_SETUP set */ - len = sizeof(defer); - if (getsockopt(sk, SOL_BLUETOOTH, BT_DEFER_SETUP, &defer, - &len) < 0) { - tester_warn("getsockopt: %s (%d)", strerror(errno), - errno); + return sk; +} + +static int connect_deferred(int sk) +{ + int defer; + socklen_t len; + struct pollfd pfd; + char c; + + /* Check if socket has DEFER_SETUP set */ + len = sizeof(defer); + if (getsockopt(sk, SOL_BLUETOOTH, BT_DEFER_SETUP, &defer, + &len) < 0) { + tester_warn("getsockopt: %s (%d)", strerror(errno), + errno); + tester_test_failed(); + return 0; + } + + memset(&pfd, 0, sizeof(pfd)); + pfd.fd = sk; + pfd.events = POLLOUT; + + if (poll(&pfd, 1, 0) < 0) { + tester_warn("poll: %s (%d)", strerror(errno), errno); + tester_test_failed(); + return -EIO; + } + + if (!(pfd.revents & POLLOUT)) { + if (read(sk, &c, 1) < 0) { + tester_warn("read: %s (%d)", strerror(errno), + errno); tester_test_failed(); - return; + return -EIO; } + } + + return 0; +} - memset(&pfd, 0, sizeof(pfd)); - pfd.fd = sk; - pfd.events = POLLOUT; +static void setup_connect_many(struct test_data *data, uint8_t n, uint8_t *num, + GIOFunc *func) +{ + const struct iso_client_data *isodata = data->test_data; + int sk[256]; + GIOChannel *io; + unsigned int i; - if (poll(&pfd, 1, 0) < 0) { - tester_warn("poll: %s (%d)", strerror(errno), errno); - tester_test_failed(); + for (i = 0; i < n; ++i) { + sk[i] = setup_sock(data, num[i]); + if (sk[i] < 0) return; - } + } - if (!(pfd.revents & POLLOUT)) { - if (read(sk, &c, 1) < 0) { - tester_warn("read: %s (%d)", strerror(errno), - errno); - tester_test_failed(); + if (isodata->defer) { + for (i = 0; i < n; ++i) + if (connect_deferred(sk[i]) < 0) return; - } - } } - io = g_io_channel_unix_new(sk); - g_io_channel_set_close_on_unref(io, TRUE); + for (i = 0; i < n; ++i) { + io = g_io_channel_unix_new(sk[i]); + g_io_channel_set_close_on_unref(io, TRUE); - data->io_id[num] = g_io_add_watch(io, G_IO_OUT, func, NULL); + data->io_id[num[i]] = g_io_add_watch(io, G_IO_OUT, func[i], + NULL); - g_io_channel_unref(io); + g_io_channel_unref(io); - tester_print("Connect in progress"); + tester_print("Connect %d in progress", num[i]); - data->step++; + data->step++; + } +} + +static void setup_connect(struct test_data *data, uint8_t num, GIOFunc func) +{ + return setup_connect_many(data, 1, &num, &func); } static void test_connect(const void *test_data) { struct test_data *data = tester_get_data(); const struct iso_client_data *isodata = test_data; + uint8_t n = 0; + GIOFunc func[2]; + uint8_t num[2] = {0, 1}; - setup_connect(data, 0, iso_connect_cb); + func[n++] = iso_connect_cb; /* Check if configuration requires multiple CIS setup */ if (!isodata->bcast && isodata->mcis) - setup_connect(data, 1, iso_connect2_cb); + func[n++] = iso_connect2_cb; + + setup_connect_many(data, n, num, func); } static void setup_reconnect(struct test_data *data, uint8_t num, GIOFunc func) @@ -2066,9 +2120,10 @@ static void test_listen(const void *test_data) static void test_connect2(const void *test_data) { struct test_data *data = tester_get_data(); + uint8_t num[2] = {0, 1}; + GIOFunc funcs[2] = {iso_connect_cb, iso_connect2_cb}; - setup_connect(data, 0, iso_connect_cb); - setup_connect(data, 1, iso_connect2_cb); + setup_connect_many(data, 2, num, funcs); } static void test_bcast(const void *test_data) @@ -2212,10 +2267,6 @@ int main(int argc, char *argv[]) test_iso_rej("ISO Connect - Reject", &connect_reject, setup_powered, test_connect, BT_HCI_ERR_CONN_FAILED_TO_ESTABLISH); - test_iso2("ISO Connect2 CIG 0x01 - Success", &connect_1_16_2_1, - setup_powered, - test_connect2); - test_iso("ISO Send - Success", &connect_16_2_1_send, setup_powered, test_connect); @@ -2229,6 +2280,13 @@ int main(int argc, char *argv[]) test_iso("ISO Defer - Success", &defer_16_2_1, setup_powered, test_defer); + test_iso("ISO Defer Connect - Success", &defer_16_2_1, setup_powered, + test_connect); + + test_iso2("ISO Defer Connect2 CIG 0x01 - Success", &defer_1_16_2_1, + setup_powered, + test_connect2); + test_iso("ISO Defer Send - Success", &connect_16_2_1_defer_send, setup_powered, test_connect); -- 2.40.1