[PATCH BlueZ] tools/iso-tester: add tests for socket shutdown with linger enabled
Pauli Virtanen <[email protected]>
| Newsgroups | org.kernel.vger.linux-bluetooth |
|---|---|
| Message-ID | <f81384d367ad95cbe74338eba688daa46b379feb.1784624911.git.pav@iki.fi> |
Add tests with SO_LINGER enabled, to test kernel sock transitions
properly to BT_CLOSED on shutdown.
Unlike L2CAP, ISO sockets don't have a feature to send POLLHUP only
after HCI Disconnect is received, so only SO_LINGER can be used to test
the sequence is shutdown -> Disconnect, HUP -> release, and not
shutdown -> HUP -> release -> Disconnect.
Add tests:
ISO Defer Linger - Success
ISO Connect Linger - Success
---
tools/iso-tester.c | 68 +++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 67 insertions(+), 1 deletion(-)
diff --git a/tools/iso-tester.c b/tools/iso-tester.c
index fe27eaaf3..a792a804b 100644
--- a/tools/iso-tester.c
+++ b/tools/iso-tester.c
@@ -478,6 +478,7 @@ struct test_data {
bool suspending;
struct tx_tstamp_data tx_ts;
int seqnum;
+ GThread *thread;
};
struct iso_client_data {
@@ -522,6 +523,9 @@ struct iso_client_data {
* Used for testing TX timestamping OPT_ID.
*/
unsigned int repeat_send;
+
+ /* Whether to enable SO_LINGER (for test_connect_wait_close) */
+ bool so_linger;
};
typedef bool (*iso_defer_accept_t)(struct test_data *data, GIOChannel *io,
@@ -717,6 +721,11 @@ static void test_post_teardown(const void *test_data)
hciemu_unref(data->hciemu);
data->hciemu = NULL;
+
+ if (data->thread) {
+ g_thread_unref(data->thread);
+ data->thread = NULL;
+ }
}
static void test_data_free(void *test_data)
@@ -1352,6 +1361,19 @@ static const struct iso_client_data connect_ac_1_2_cig_1_2 = {
.mconn = true,
};
+static const struct iso_client_data linger_16_2_1 = {
+ .qos = QOS_16_2_1,
+ .expect_err = 0,
+ .so_linger = true,
+};
+
+static const struct iso_client_data linger_defer_16_2_1 = {
+ .qos = QOS_16_2_1,
+ .expect_err = 0,
+ .defer = true,
+ .so_linger = true,
+};
+
static const struct iso_client_data bcast_48_1_g = {
.qos = QOS_OUT_48_1_g,
.expect_err = 0,
@@ -3679,6 +3701,19 @@ static void test_connect2_busy(const void *test_data)
setup_connect(data, 0, iso_connect_cb_busy);
}
+static gpointer shutdown_sk_thread_cb(gpointer data)
+{
+ int sk = PTR_TO_UINT(data);
+ struct timespec start, end;
+
+ clock_gettime(CLOCK_MONOTONIC, &start);
+ shutdown(sk, SHUT_RDWR);
+ clock_gettime(CLOCK_MONOTONIC, &end);
+
+ /* Completed before linger timeout? */
+ return UINT_TO_PTR(TS_NSEC(&end) - TS_NSEC(&start) < SEC_NSEC(2));
+}
+
static gboolean iso_connect_close_cb(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
@@ -3688,6 +3723,13 @@ static gboolean iso_connect_close_cb(GIOChannel *io, GIOCondition cond,
tester_print("Disconnected");
+ if (data->thread) {
+ /* Wait for shutdown() to complete, for linger enabled */
+ if (!g_thread_join(data->thread))
+ tester_test_failed();
+ data->thread = NULL;
+ }
+
--data->step;
if (!data->step)
tester_test_passed();
@@ -3737,16 +3779,34 @@ static gboolean iso_connect_wait_close_cb(GIOChannel *io, GIOCondition cond,
gpointer user_data)
{
struct test_data *data = tester_get_data();
+ const struct iso_client_data *isodata = data->test_data;
int sk;
tester_print("Connected");
sk = g_io_channel_unix_get_fd(io);
+ if (isodata->so_linger) {
+ struct linger val = { .l_onoff = 1, .l_linger = 2 };
+
+ if (setsockopt(sk, SOL_SOCKET, SO_LINGER, &val, sizeof(val))) {
+ tester_warn("Can't set socket option : %s (%d)",
+ strerror(errno), errno);
+ tester_test_failed();
+ return FALSE;
+ }
+ }
+
data->io_id[0] = g_io_add_watch(io, G_IO_HUP, iso_connect_close_cb,
data);
- shutdown(sk, SHUT_RDWR);
+ if (!isodata->so_linger)
+ shutdown(sk, SHUT_RDWR);
+ else {
+ /* With linger shutdown() blocks, so run in separate thread */
+ data->thread = g_thread_new("close_sk", shutdown_sk_thread_cb,
+ UINT_TO_PTR(sk));
+ }
return FALSE;
}
@@ -4160,6 +4220,12 @@ int main(int argc, char *argv[])
test_iso("ISO Connect Wait Close - Success", &connect_16_2_1,
setup_powered, test_connect_wait_close);
+ test_iso("ISO Defer Linger - Success", &linger_16_2_1,
+ setup_powered, test_connect_wait_close);
+
+ test_iso("ISO Connect Linger - Success", &linger_defer_16_2_1,
+ setup_powered, test_connect_wait_close);
+
test_iso("ISO Connect Suspend - Success", &connect_suspend,
setup_powered,
test_connect_suspend);
--
2.55.0