Skip to content

Commit da06e84

Browse files
HaavardReicfriedt
authored andcommitted
Bluetooth: Host: bsim: Add fixed L2CAP chan test
Adds a testcase to the send on connect test for sending data over a user-defined fixed L2CAP channel. Signed-off-by: Håvard Reierstad <[email protected]>
1 parent ff17e60 commit da06e84

File tree

4 files changed

+152
-23
lines changed

4 files changed

+152
-23
lines changed
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
.. SPDX-License-Identifier: Apache-2.0
2+
L2CAP send on connect
3+
=====================
4+
5+
Purpose
6+
-------
7+
This test demonstrates and verifies sending data over L2CAP channels on connection. This is done
8+
for both dynamic (ECRED and non-ECRED) and fixed channels.
9+
10+
Test procedure
11+
--------------
12+
The test procedure is similar for dynamic and fixed channels, the differences being:
13+
- For dynamic channels, the connection needs to be established by first registering
14+
a L2CAP server on the peripheral, then sending a connection request from the central.
15+
For fixed channels, the connection is initialized automatically upon connection.
16+
- The fixed and dynamic channels use separate buffer pools.
17+
18+
1. Central and peripheral initialize BT.
19+
Peripheral registers a L2CAP server (Dynamic channels only).
20+
Peripheral starts advertising and central starts scanning.
21+
Central sends a connection request to the peripheral.
22+
23+
2. Both devices wait for the connected callback.
24+
25+
3. Central sends a channel connect request to the peripheral (Dynamic channels only).
26+
On channel connection, both devices will send the same message over the channel,
27+
and verify that the sent callback is called.
28+
29+
4. Both devices wait for the data to be received, and verify that the received data
30+
is correct.
31+
32+
5. Central disconnects and both devices wait for the disconnected callback.

tests/bsim/bluetooth/host/l2cap/send_on_connect/src/main_l2cap_send_on_connect.c

Lines changed: 92 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 2022 Nordic Semiconductor
2+
* Copyright (c) 2022-2025 Nordic Semiconductor
33
*
44
* SPDX-License-Identifier: Apache-2.0
55
*/
@@ -10,6 +10,8 @@
1010

1111
#include "babblekit/testcase.h"
1212
#include "babblekit/flags.h"
13+
#include "bsim_args_runner.h"
14+
#include "argparse.h"
1315

1416
extern enum bst_result_t bst_result;
1517

@@ -20,25 +22,63 @@ static struct bt_conn *default_conn;
2022
DEFINE_FLAG_STATIC(is_connected);
2123
DEFINE_FLAG_STATIC(chan_connected);
2224
DEFINE_FLAG_STATIC(data_received);
25+
DEFINE_FLAG_STATIC(data_sent);
2326

24-
#define DATA_BYTE_VAL 0xBB
27+
static bool fixed;
28+
static const char *l2cap_data = "Hello";
2529

26-
/* L2CAP channel buffer pool */
27-
NET_BUF_POOL_DEFINE(buf_pool, 1, BT_L2CAP_SDU_BUF_SIZE(16), CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
30+
/* L2CAP dynamic channel buffer pool */
31+
NET_BUF_POOL_DEFINE(sdu_buf_pool, 1, BT_L2CAP_SDU_BUF_SIZE(16), CONFIG_BT_CONN_TX_USER_DATA_SIZE,
32+
NULL);
33+
34+
#define FIXED_CID 0x21
35+
36+
/* L2CAP fixed channel buffer pool */
37+
NET_BUF_POOL_DEFINE(pdu_buf_pool, 1, BT_L2CAP_BUF_SIZE(CONFIG_BT_L2CAP_TX_MTU),
38+
CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);
39+
40+
static void test_args(int argc, char *argv[])
41+
{
42+
bs_args_struct_t args_struct[] = {
43+
{
44+
.dest = &fixed,
45+
.type = 'b',
46+
.name = "{0, 1}",
47+
.option = "fixed",
48+
.descript = "Use fixed (true) or dynamic (false) channel."
49+
},
50+
};
51+
52+
bs_args_parse_all_cmd_line(argc, argv, args_struct);
53+
}
2854

2955
static void chan_connected_cb(struct bt_l2cap_chan *l2cap_chan)
3056
{
3157
struct net_buf *buf;
3258
int err;
59+
struct bt_l2cap_le_chan *le_chan = BT_L2CAP_LE_CHAN(l2cap_chan);
60+
61+
/* If we're testing dynamic channels, skip sending data on the fixed channel. */
62+
if (!fixed && le_chan->tx.cid == FIXED_CID) {
63+
return;
64+
}
3365

3466
/* Send data immediately on L2CAP connection */
35-
buf = net_buf_alloc(&buf_pool, K_NO_WAIT);
67+
if (fixed) {
68+
buf = net_buf_alloc(&pdu_buf_pool, K_NO_WAIT);
69+
} else {
70+
buf = net_buf_alloc(&sdu_buf_pool, K_NO_WAIT);
71+
}
3672
if (!buf) {
3773
TEST_FAIL("Buffer allocation failed");
3874
}
3975

40-
(void)net_buf_reserve(buf, BT_L2CAP_SDU_CHAN_SEND_RESERVE);
41-
(void)net_buf_add_u8(buf, DATA_BYTE_VAL);
76+
if (fixed) {
77+
(void)net_buf_reserve(buf, BT_L2CAP_CHAN_SEND_RESERVE);
78+
} else {
79+
(void)net_buf_reserve(buf, BT_L2CAP_SDU_CHAN_SEND_RESERVE);
80+
}
81+
(void)net_buf_add_mem(buf, l2cap_data, strlen(l2cap_data) + 1);
4282

4383
/* Try to send data */
4484
err = bt_l2cap_chan_send(l2cap_chan, buf);
@@ -60,7 +100,7 @@ static int chan_recv_cb(struct bt_l2cap_chan *chan, struct net_buf *buf)
60100
{
61101
(void)chan;
62102

63-
if ((buf->len != 1) || (buf->data[0] != DATA_BYTE_VAL)) {
103+
if (strcmp(buf->data, l2cap_data) != 0) {
64104
TEST_FAIL("Unexpected data received");
65105
}
66106

@@ -69,19 +109,27 @@ static int chan_recv_cb(struct bt_l2cap_chan *chan, struct net_buf *buf)
69109
return 0;
70110
}
71111

112+
static void chan_sent_cb(struct bt_l2cap_chan *chan)
113+
{
114+
(void)chan;
115+
SET_FLAG(data_sent);
116+
}
117+
72118
static const struct bt_l2cap_chan_ops l2cap_ops = {
73119
.connected = chan_connected_cb,
74120
.disconnected = chan_disconnected_cb,
75121
.recv = chan_recv_cb,
122+
.sent = chan_sent_cb,
76123
};
77124

78-
static struct bt_l2cap_le_chan channel;
125+
static struct bt_l2cap_le_chan dyn_chan;
126+
static struct bt_l2cap_chan fixed_chan;
79127

80128
static int accept(struct bt_conn *conn, struct bt_l2cap_server *server,
81129
struct bt_l2cap_chan **l2cap_chan)
82130
{
83-
channel.chan.ops = &l2cap_ops;
84-
*l2cap_chan = &channel.chan;
131+
dyn_chan.chan.ops = &l2cap_ops;
132+
*l2cap_chan = &dyn_chan.chan;
85133

86134
return 0;
87135
}
@@ -92,20 +140,36 @@ static struct bt_l2cap_server server = {
92140
.psm = PSM,
93141
};
94142

143+
static int l2cap_fixed_accept(struct bt_conn *conn, struct bt_l2cap_chan **chan)
144+
{
145+
*chan = &fixed_chan;
146+
147+
**chan = (struct bt_l2cap_chan){
148+
.ops = &l2cap_ops,
149+
};
150+
151+
return 0;
152+
}
153+
154+
BT_L2CAP_FIXED_CHANNEL_DEFINE(fixed_chan_1) = {
155+
.cid = FIXED_CID,
156+
.accept = l2cap_fixed_accept,
157+
};
158+
95159
static void connect_l2cap_channel(void)
96160
{
97-
struct bt_l2cap_chan *chans[] = {&channel.chan, NULL};
161+
struct bt_l2cap_chan *chans[] = {&dyn_chan.chan, NULL};
98162
int err;
99163

100-
channel.chan.ops = &l2cap_ops;
164+
dyn_chan.chan.ops = &l2cap_ops;
101165

102166
if (IS_ENABLED(CONFIG_BT_L2CAP_ECRED)) {
103167
err = bt_l2cap_ecred_chan_connect(default_conn, chans, server.psm);
104168
if (err) {
105169
TEST_FAIL("Failed to send ecred connection request (err %d)", err);
106170
}
107171
} else {
108-
err = bt_l2cap_chan_connect(default_conn, &channel.chan, server.psm);
172+
err = bt_l2cap_chan_connect(default_conn, &dyn_chan.chan, server.psm);
109173
if (err) {
110174
TEST_FAIL("Failed to send connection request (err %d)", err);
111175
}
@@ -187,7 +251,9 @@ static void test_peripheral_main(void)
187251
return;
188252
}
189253

190-
register_l2cap_server();
254+
if (!fixed) {
255+
register_l2cap_server();
256+
}
191257

192258
err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), NULL, 0);
193259
if (err != 0) {
@@ -199,11 +265,13 @@ static void test_peripheral_main(void)
199265

200266
WAIT_FOR_FLAG(chan_connected);
201267

268+
WAIT_FOR_FLAG(data_sent);
269+
202270
WAIT_FOR_FLAG(data_received);
203271

204272
WAIT_FOR_FLAG_UNSET(is_connected);
205273

206-
TEST_PASS("Test passed");
274+
TEST_PASS("Test passed");
207275
}
208276

209277
static void test_central_main(void)
@@ -222,9 +290,14 @@ static void test_central_main(void)
222290

223291
WAIT_FOR_FLAG(is_connected);
224292

225-
connect_l2cap_channel();
293+
if (!fixed) {
294+
connect_l2cap_channel();
295+
}
296+
226297
WAIT_FOR_FLAG(chan_connected);
227298

299+
WAIT_FOR_FLAG(data_sent);
300+
228301
WAIT_FOR_FLAG(data_received);
229302

230303
err = bt_conn_disconnect(default_conn, BT_HCI_ERR_REMOTE_USER_TERM_CONN);
@@ -242,11 +315,13 @@ static const struct bst_test_instance test_def[] = {
242315
{
243316
.test_id = "peripheral",
244317
.test_descr = "Peripheral",
318+
.test_args_f = test_args,
245319
.test_main_f = test_peripheral_main,
246320
},
247321
{
248322
.test_id = "central",
249323
.test_descr = "Central",
324+
.test_args_f = test_args,
250325
.test_main_f = test_central_main,
251326
},
252327
BSTEST_END_MARKER,

tests/bsim/bluetooth/host/l2cap/send_on_connect/tests_scripts/l2cap.sh renamed to tests/bsim/bluetooth/host/l2cap/send_on_connect/tests_scripts/send_on_connect_dynamic.sh

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,34 @@
44

55
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source
66

7-
simulation_id="l2cap_send_on_connect"
7+
simulation_id="l2cap_send_on_connect_dynamic"
88
verbosity_level=2
99
EXECUTE_TIMEOUT=120
1010

1111
cd ${BSIM_OUT_PATH}/bin
1212

1313
Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_host_l2cap_send_on_connect_prj_conf \
14-
-v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central
14+
-v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central -argstest fixed=0
1515

1616
Execute ./bs_${BOARD_TS}_tests_bsim_bluetooth_host_l2cap_send_on_connect_prj_conf \
17-
-v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral
17+
-v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral -argstest fixed=0
1818

1919
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \
2020
-D=2 -sim_length=30e6 $@
2121

2222
wait_for_background_jobs
2323

24-
simulation_id="l2cap_send_on_connect_ecred"
24+
simulation_id="l2cap_send_on_connect_dynamic_ecred"
2525

2626
cd ${BSIM_OUT_PATH}/bin
2727

2828
Execute \
2929
./bs_${BOARD_TS}_tests_bsim_bluetooth_host_l2cap_send_on_connect_prj_conf_overlay-ecred_conf \
30-
-v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central
30+
-v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central -argstest fixed=0
3131

3232
Execute \
3333
./bs_${BOARD_TS}_tests_bsim_bluetooth_host_l2cap_send_on_connect_prj_conf_overlay-ecred_conf \
34-
-v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral
34+
-v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral -argstest fixed=0
3535

3636
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} \
3737
-D=2 -sim_length=30e6 $@
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#!/usr/bin/env bash
2+
# Copyright (c) 2022 Nordic Semiconductor
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
source ${ZEPHYR_BASE}/tests/bsim/sh_common.source
6+
7+
bsim_exe=./bs_${BOARD_TS}_$(guess_test_long_name)_prj_conf
8+
simulation_id="send_on_connect_fixed"
9+
verbosity_level=2
10+
EXECUTE_TIMEOUT=30
11+
12+
cd ${BSIM_OUT_PATH}/bin
13+
14+
Execute "${bsim_exe}" \
15+
-v=${verbosity_level} -s=${simulation_id} -d=0 -testid=central -argstest fixed=1
16+
17+
Execute "${bsim_exe}" \
18+
-v=${verbosity_level} -s=${simulation_id} -d=1 -testid=peripheral -argstest fixed=1
19+
20+
Execute ./bs_2G4_phy_v1 -v=${verbosity_level} -s=${simulation_id} -D=2 -sim_length=30e6 $@
21+
22+
wait_for_background_jobs

0 commit comments

Comments
 (0)