Skip to content

Commit b9e1f53

Browse files
lylezhu2012kartben
authored andcommitted
Bluetooth: tester: Add BTP command BTP_L2CAP_LISTEN_V2
Add a new BTP L2CAP command BTP_L2CAP_LISTEN_V2 to extend the L2CAP server feature. Compared with BTP command `listen`, two fields are added, including `mode` and `options`. Signed-off-by: Lyle Zhu <[email protected]>
1 parent 3588a11 commit b9e1f53

File tree

2 files changed

+140
-13
lines changed

2 files changed

+140
-13
lines changed

tests/bluetooth/tester/src/btp/btp_l2cap.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,30 @@ struct btp_l2cap_connect_v2_rp {
124124
uint8_t chan_id[];
125125
} __packed;
126126

127+
#define BTP_L2CAP_LISTEN_V2_MODE_NONE 0x00
128+
#define BTP_L2CAP_LISTEN_V2_MODE_BASIC BTP_L2CAP_LISTEN_V2_MODE_NONE
129+
#define BTP_L2CAP_LISTEN_V2_MODE_RET 0x01
130+
#define BTP_L2CAP_LISTEN_V2_MODE_FC 0x02
131+
#define BTP_L2CAP_LISTEN_V2_MODE_ERET 0x03
132+
#define BTP_L2CAP_LISTEN_V2_MODE_STREAM 0x04
133+
#define BTP_L2CAP_LISTEN_V2_MODE_VALID BTP_L2CAP_LISTEN_V2_MODE_STREAM
134+
135+
#define BTP_L2CAP_LISTEN_V2_OPT_ECFC BIT(0)
136+
#define BTP_L2CAP_LISTEN_V2_OPT_HOLD_CREDIT BIT(1)
137+
#define BTP_L2CAP_LISTEN_V2_OPT_MODE_OPTIONAL BIT(2)
138+
#define BTP_L2CAP_LISTEN_V2_OPT_EXT_WIN_SIZE BIT(3)
139+
#define BTP_L2CAP_LISTEN_V2_OPT_NO_FCS BIT(4)
140+
141+
#define BTP_L2CAP_LISTEN_V2 0x0c
142+
struct btp_l2cap_listen_v2_cmd {
143+
uint16_t psm;
144+
uint8_t transport;
145+
uint16_t mtu;
146+
uint16_t response;
147+
uint8_t mode;
148+
uint32_t options;
149+
} __packed;
150+
127151
/* events */
128152
#define BTP_L2CAP_EV_CONNECTION_REQ 0x80
129153
struct btp_l2cap_connection_req_ev {

tests/bluetooth/tester/src/btp_l2cap.c

Lines changed: 116 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,11 @@ static struct br_channel {
6666

6767
/* TODO Extend to support multiple servers */
6868
static struct bt_l2cap_server servers[SERVERS];
69+
struct server_settings {
70+
uint8_t mode;
71+
uint32_t options;
72+
};
73+
static struct server_settings server_settings[SERVERS];
6974

7075
#if defined(CONFIG_BT_L2CAP_SEG_RECV)
7176
static void seg_recv_cb(struct bt_l2cap_chan *l2cap_chan, size_t sdu_len, off_t seg_offset,
@@ -862,6 +867,15 @@ static struct bt_l2cap_server *get_free_server(void)
862867
return NULL;
863868
}
864869

870+
static uint8_t get_server_index(struct bt_l2cap_server *server)
871+
{
872+
ptrdiff_t index = 0;
873+
874+
index = server - servers;
875+
876+
return (uint8_t)index;
877+
}
878+
865879
static bool is_free_psm(uint16_t psm)
866880
{
867881
uint8_t i;
@@ -911,6 +925,9 @@ static int br_accept(struct bt_conn *conn, struct bt_l2cap_server *server,
911925
struct bt_l2cap_chan **l2cap_chan)
912926
{
913927
struct br_channel *chan;
928+
__maybe_unused uint16_t options = 0;
929+
__maybe_unused uint8_t mode = BTP_L2CAP_LISTEN_V2_MODE_NONE;
930+
__maybe_unused uint8_t index;
914931

915932
if (bt_conn_enc_key_size(conn) < req_keysize) {
916933
return -EPERM;
@@ -928,6 +945,56 @@ static int br_accept(struct bt_conn *conn, struct bt_l2cap_server *server,
928945
chan->br.chan.ops = &br_l2cap_ops;
929946
chan->br.rx.mtu = DATA_MTU_INITIAL;
930947

948+
#if defined(CONFIG_BT_L2CAP_RET_FC)
949+
index = get_server_index(server);
950+
if (index < ARRAY_SIZE(server_settings)) {
951+
options = server_settings[index].options;
952+
mode = server_settings[index].mode;
953+
}
954+
955+
switch (mode) {
956+
case BTP_L2CAP_LISTEN_V2_MODE_RET:
957+
chan->br.rx.mode = BT_L2CAP_BR_LINK_MODE_RET;
958+
chan->br.rx.max_transmit = 3;
959+
break;
960+
case BTP_L2CAP_LISTEN_V2_MODE_FC:
961+
chan->br.rx.mode = BT_L2CAP_BR_LINK_MODE_FC;
962+
chan->br.rx.max_transmit = 3;
963+
break;
964+
case BTP_L2CAP_LISTEN_V2_MODE_ERET:
965+
chan->br.rx.mode = BT_L2CAP_BR_LINK_MODE_ERET;
966+
chan->br.rx.max_transmit = 3;
967+
break;
968+
case BTP_L2CAP_LISTEN_V2_MODE_STREAM:
969+
chan->br.rx.mode = BT_L2CAP_BR_LINK_MODE_STREAM;
970+
chan->br.rx.max_transmit = 0;
971+
break;
972+
default:
973+
chan->br.rx.mode = BT_L2CAP_BR_LINK_MODE_BASIC;
974+
chan->br.rx.max_transmit = 0;
975+
break;
976+
}
977+
978+
if (options & BTP_L2CAP_LISTEN_V2_OPT_EXT_WIN_SIZE) {
979+
chan->br.rx.extended_control = true;
980+
} else {
981+
chan->br.rx.extended_control = false;
982+
}
983+
984+
if (options & BTP_L2CAP_LISTEN_V2_OPT_MODE_OPTIONAL) {
985+
chan->br.rx.optional = true;
986+
} else {
987+
chan->br.rx.optional = false;
988+
}
989+
990+
chan->br.rx.max_window = CONFIG_BT_L2CAP_MAX_WINDOW_SIZE;
991+
if (options & BTP_L2CAP_LISTEN_V2_OPT_NO_FCS) {
992+
chan->br.rx.fcs = BT_L2CAP_BR_FCS_NO;
993+
} else {
994+
chan->br.rx.fcs = BT_L2CAP_BR_FCS_16BIT;
995+
}
996+
#endif /* CONFIG_BT_L2CAP_RET_FC */
997+
931998
*l2cap_chan = &chan->br.chan;
932999

9331000
return 0;
@@ -940,25 +1007,29 @@ static int br_accept(struct bt_conn *conn, struct bt_l2cap_server *server,
9401007
}
9411008
#endif /* CONFIG_BT_CLASSIC */
9421009

943-
static uint8_t listen(const void *cmd, uint16_t cmd_len,
944-
void *rsp, uint16_t *rsp_len)
1010+
static uint8_t _listen(uint16_t psm, uint8_t transport, uint16_t response, uint8_t mode,
1011+
uint32_t options)
9451012
{
946-
const struct btp_l2cap_listen_cmd *cp = cmd;
9471013
struct bt_l2cap_server *server;
948-
uint16_t psm = sys_le16_to_cpu(cp->psm);
9491014

9501015
if (psm == 0 || !is_free_psm(psm)) {
9511016
return BTP_STATUS_FAILED;
9521017
}
9531018

1019+
if (mode > BTP_L2CAP_LISTEN_V2_MODE_VALID) {
1020+
return BTP_STATUS_FAILED;
1021+
}
1022+
9541023
server = get_free_server();
9551024
if (!server) {
9561025
return BTP_STATUS_FAILED;
9571026
}
9581027

9591028
server->psm = psm;
1029+
server_settings[get_server_index(server)].mode = mode;
1030+
server_settings[get_server_index(server)].options = options;
9601031

961-
switch (cp->response) {
1032+
switch (response) {
9621033
case BTP_L2CAP_CONNECTION_RESPONSE_SUCCESS:
9631034
break;
9641035
case BTP_L2CAP_CONNECTION_RESPONSE_INSUFF_ENC_KEY:
@@ -978,26 +1049,53 @@ static uint8_t listen(const void *cmd, uint16_t cmd_len,
9781049
server->sec_level = BT_SECURITY_L4;
9791050
break;
9801051
default:
981-
return BTP_STATUS_FAILED;
1052+
goto failed;
9821053
}
9831054

984-
if (cp->transport == BTP_L2CAP_TRANSPORT_LE) {
1055+
if (transport == BTP_L2CAP_TRANSPORT_LE) {
1056+
if (mode != BTP_L2CAP_LISTEN_V2_MODE_NONE) {
1057+
goto failed;
1058+
}
1059+
9851060
server->accept = accept;
9861061
if (bt_l2cap_server_register(server) < 0) {
987-
server->psm = 0U;
988-
return BTP_STATUS_FAILED;
1062+
goto failed;
9891063
}
990-
} else if (IS_ENABLED(CONFIG_BT_CLASSIC) && (cp->transport == BTP_L2CAP_TRANSPORT_BREDR)) {
1064+
} else if (IS_ENABLED(CONFIG_BT_CLASSIC) && (transport == BTP_L2CAP_TRANSPORT_BREDR)) {
9911065
server->accept = br_accept;
9921066
if (bt_l2cap_br_server_register(server) < 0) {
993-
server->psm = 0U;
994-
return BTP_STATUS_FAILED;
1067+
goto failed;
9951068
}
9961069
} else {
997-
return BTP_STATUS_FAILED;
1070+
goto failed;
9981071
}
9991072

10001073
return BTP_STATUS_SUCCESS;
1074+
1075+
failed:
1076+
server_settings[get_server_index(server)].mode = 0;
1077+
server_settings[get_server_index(server)].options = 0;
1078+
server->psm = 0U;
1079+
return BTP_STATUS_FAILED;
1080+
}
1081+
1082+
static uint8_t listen(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
1083+
{
1084+
const struct btp_l2cap_listen_cmd *cp = cmd;
1085+
uint16_t psm = sys_le16_to_cpu(cp->psm);
1086+
uint16_t response = sys_le16_to_cpu(cp->response);
1087+
1088+
return _listen(psm, cp->transport, response, BTP_L2CAP_LISTEN_V2_MODE_NONE, 0);
1089+
}
1090+
1091+
static uint8_t listen_v2(const void *cmd, uint16_t cmd_len, void *rsp, uint16_t *rsp_len)
1092+
{
1093+
const struct btp_l2cap_listen_v2_cmd *cp = cmd;
1094+
uint16_t psm = sys_le16_to_cpu(cp->psm);
1095+
uint16_t response = sys_le16_to_cpu(cp->response);
1096+
uint32_t options = sys_le32_to_cpu(cp->options);
1097+
1098+
return _listen(psm, cp->transport, response, cp->mode, options);
10011099
}
10021100

10031101
static uint8_t credits(const void *cmd, uint16_t cmd_len,
@@ -1122,6 +1220,11 @@ static const struct btp_handler handlers[] = {
11221220
.expect_len = sizeof(struct btp_l2cap_listen_cmd),
11231221
.func = listen,
11241222
},
1223+
{
1224+
.opcode = BTP_L2CAP_LISTEN_V2,
1225+
.expect_len = sizeof(struct btp_l2cap_listen_v2_cmd),
1226+
.func = listen_v2,
1227+
},
11251228
{
11261229
.opcode = BTP_L2CAP_RECONFIGURE,
11271230
.expect_len = BTP_HANDLER_LENGTH_VARIABLE,

0 commit comments

Comments
 (0)