Skip to content

Commit 3a46e25

Browse files
lylezhu2012jhedberg
authored andcommitted
Bluetooth: Classic: Shell: Add connectionless command set
Add connectionless shell commands, `register`, `unregister`, and `send`. Signed-off-by: Lyle Zhu <[email protected]>
1 parent 0b3f572 commit 3a46e25

File tree

2 files changed

+104
-0
lines changed

2 files changed

+104
-0
lines changed

subsys/bluetooth/host/classic/shell/bredr.c

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,6 +1281,97 @@ static int cmd_set_role_switchable(const struct shell *sh, size_t argc, char *ar
12811281
return 0;
12821282
}
12831283

1284+
#if defined(CONFIG_BT_L2CAP_CONNLESS)
1285+
static void connless_recv(struct bt_conn *conn, uint16_t psm, struct net_buf *buf)
1286+
{
1287+
bt_shell_print("Incoming connectionless data psm 0x%04x len %u", psm, buf->len);
1288+
1289+
if (buf->len > 0) {
1290+
bt_shell_hexdump(buf->data, buf->len);
1291+
}
1292+
}
1293+
1294+
static struct bt_l2cap_br_connless_cb connless_cb = {
1295+
.recv = connless_recv,
1296+
};
1297+
1298+
static int cmd_l2cap_connless_reg(const struct shell *sh, size_t argc, char *argv[])
1299+
{
1300+
int err;
1301+
uint16_t psm;
1302+
1303+
psm = (uint16_t)strtoul(argv[1], NULL, 16);
1304+
shell_print(sh, "Register connectionless callbacks with PSM 0x%04x", psm);
1305+
1306+
connless_cb.psm = psm;
1307+
1308+
if (argc > 2) {
1309+
connless_cb.sec_level = (bt_security_t)strtoul(argv[2], NULL, 0);
1310+
} else {
1311+
connless_cb.sec_level = BT_SECURITY_L1;
1312+
}
1313+
1314+
err = bt_l2cap_br_connless_register(&connless_cb);
1315+
if (err) {
1316+
shell_error(sh, "Failed to register connectionless callback: %d", err);
1317+
return err;
1318+
}
1319+
1320+
return 0;
1321+
}
1322+
1323+
static int cmd_l2cap_connless_unreg(const struct shell *sh, size_t argc, char *argv[])
1324+
{
1325+
int err;
1326+
1327+
err = bt_l2cap_br_connless_unregister(&connless_cb);
1328+
if (err) {
1329+
shell_error(sh, "Failed to unregister connectionless callback: %d", err);
1330+
return err;
1331+
}
1332+
1333+
return 0;
1334+
}
1335+
1336+
static int cmd_l2cap_connless_send(const struct shell *sh, size_t argc, char *argv[])
1337+
{
1338+
static uint8_t buf_data[DATA_BREDR_MTU];
1339+
int err, len = DATA_BREDR_MTU;
1340+
struct net_buf *buf;
1341+
uint16_t psm;
1342+
1343+
psm = (uint16_t)strtoul(argv[1], NULL, 16);
1344+
1345+
len = (int)strtoul(argv[2], NULL, 10);
1346+
if (len > DATA_BREDR_MTU) {
1347+
shell_error(sh, "Length exceeds TX MAX length for the channel");
1348+
return -ENOEXEC;
1349+
}
1350+
1351+
buf = net_buf_alloc(&data_tx_pool, K_SECONDS(2));
1352+
if (!buf) {
1353+
shell_error(sh, "Allocation timeout, stopping TX");
1354+
return -EAGAIN;
1355+
}
1356+
net_buf_reserve(buf, BT_L2CAP_CONNLESS_RESERVE);
1357+
for (int i = 0; i < len; i++) {
1358+
buf_data[i] = (uint8_t)i;
1359+
}
1360+
1361+
net_buf_add_mem(buf, buf_data, len);
1362+
1363+
shell_print(sh, "Sending connectionless data with PSM 0x%04x", psm);
1364+
err = bt_l2cap_br_connless_send(default_conn, psm, buf);
1365+
if (err < 0) {
1366+
shell_error(sh, "Unable to send connectionless data: %d", err);
1367+
net_buf_unref(buf);
1368+
return -ENOEXEC;
1369+
}
1370+
1371+
return 0;
1372+
}
1373+
#endif /* CONFIG_BT_L2CAP_CONNLESS */
1374+
12841375
static int cmd_default_handler(const struct shell *sh, size_t argc, char **argv)
12851376
{
12861377
if (argc == 1) {
@@ -1311,6 +1402,15 @@ SHELL_STATIC_SUBCMD_SET_CREATE(echo_cmds,
13111402
SHELL_SUBCMD_SET_END
13121403
);
13131404

1405+
#if defined(CONFIG_BT_L2CAP_CONNLESS)
1406+
SHELL_STATIC_SUBCMD_SET_CREATE(connless_cmds,
1407+
SHELL_CMD_ARG(register, NULL, "<psm> [sec level]", cmd_l2cap_connless_reg, 2, 1),
1408+
SHELL_CMD_ARG(unregister, NULL, HELP_NONE, cmd_l2cap_connless_unreg, 1, 0),
1409+
SHELL_CMD_ARG(send, NULL, "<psm> <length of data>", cmd_l2cap_connless_send, 3, 0),
1410+
SHELL_SUBCMD_SET_END
1411+
);
1412+
#endif /* CONFIG_BT_L2CAP_CONNLESS */
1413+
13141414
SHELL_STATIC_SUBCMD_SET_CREATE(l2cap_cmds,
13151415
#if defined(CONFIG_BT_L2CAP_RET_FC)
13161416
SHELL_CMD_ARG(register, NULL, HELP_REG, cmd_l2cap_register, 3, 3),
@@ -1326,6 +1426,9 @@ SHELL_STATIC_SUBCMD_SET_CREATE(l2cap_cmds,
13261426
SHELL_CMD_ARG(credits, NULL, HELP_NONE, cmd_l2cap_credits, 1, 0),
13271427
#endif /* CONFIG_BT_L2CAP_RET_FC */
13281428
SHELL_CMD(echo, &echo_cmds, "L2CAP BR ECHO commands", cmd_default_handler),
1429+
#if defined(CONFIG_BT_L2CAP_CONNLESS)
1430+
SHELL_CMD(connless, &connless_cmds, "L2CAP connectionless commands", cmd_default_handler),
1431+
#endif /* CONFIG_BT_L2CAP_CONNLESS */
13291432
SHELL_SUBCMD_SET_END
13301433
);
13311434

tests/bluetooth/shell/prj_br.conf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ CONFIG_BT_L2CAP_STREAM=y
2424
CONFIG_BT_L2CAP_FCS=y
2525
CONFIG_BT_L2CAP_EXT_WIN_SIZE=y
2626
CONFIG_BT_L2CAP_MAX_WINDOW_SIZE=5
27+
CONFIG_BT_L2CAP_CONNLESS=y
2728

2829
CONFIG_BT_HFP_HF=y
2930
CONFIG_BT_HFP_AG=y

0 commit comments

Comments
 (0)