Skip to content

Commit

Permalink
[nrf fromlist] Bluetooth: Tester: Use BT_L2CAP_SEG_RECV for L2CAP tests
Browse files Browse the repository at this point in the history
This API gives better control on L2CAP COC credits and suits better
for Upper Tester implementation.

Upstream PR #: 80883

Signed-off-by: Lang Xie <lang.xie@nordicsemi.no>
  • Loading branch information
laxiLang committed Nov 5, 2024
1 parent e860b02 commit f50478b
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 8 deletions.
2 changes: 1 addition & 1 deletion tests/bluetooth/tester/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ CONFIG_BT_BONDABLE=y
CONFIG_BT_ATT_PREPARE_COUNT=12
CONFIG_BT_GATT_CLIENT=y
CONFIG_BT_L2CAP_DYNAMIC_CHANNEL=y
CONFIG_BT_L2CAP_SEG_RECV=y
CONFIG_BT_DEVICE_NAME="Tester"
CONFIG_BT_DEVICE_NAME_MAX=32
CONFIG_BT_DEVICE_NAME_DYNAMIC=y
Expand All @@ -33,7 +34,6 @@ CONFIG_BT_GATT_DYNAMIC_DB=y
CONFIG_BT_EXT_ADV=y
CONFIG_BT_PER_ADV=y
CONFIG_BT_PER_ADV_SYNC=y
CONFIG_BT_BUF_ACL_RX_SIZE=100
CONFIG_BT_RX_STACK_SIZE=4096

CONFIG_BT_TESTING=y
Expand Down
77 changes: 70 additions & 7 deletions tests/bluetooth/tester/src/btp_l2cap.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ LOG_MODULE_REGISTER(LOG_MODULE_NAME, CONFIG_BTTESTER_LOG_LEVEL);

#include "btp/btp.h"

#define DATA_MTU_INITIAL 128
#define DATA_MTU 256
#define DATA_BUF_SIZE BT_L2CAP_SDU_BUF_SIZE(DATA_MTU)
#define L2CAP_MPS 96
#define DATA_MTU (3 * L2CAP_MPS)
#define DATA_MTU_INITIAL (2 * L2CAP_MPS)

#define CHANNELS 2
#define SERVERS 1

NET_BUF_POOL_FIXED_DEFINE(data_pool, CHANNELS, DATA_BUF_SIZE, CONFIG_BT_CONN_TX_USER_DATA_SIZE,
NULL);
NET_BUF_POOL_FIXED_DEFINE(data_pool, CHANNELS, BT_L2CAP_SDU_BUF_SIZE(DATA_MTU),
CONFIG_BT_CONN_TX_USER_DATA_SIZE, NULL);

static bool authorize_flag;
static uint8_t req_keysize;
Expand All @@ -36,18 +37,51 @@ static struct channel {
struct bt_l2cap_le_chan le;
bool in_use;
bool hold_credit;
#if defined(CONFIG_BT_L2CAP_SEG_RECV)
unsigned int pending_credits;
uint8_t recv_cb_buf[DATA_MTU + sizeof(struct btp_l2cap_data_received_ev)];
#else
struct net_buf *pending_credit;
#endif
} channels[CHANNELS];

/* TODO Extend to support multiple servers */
static struct bt_l2cap_server servers[SERVERS];

#if defined(CONFIG_BT_L2CAP_SEG_RECV)
static void seg_recv_cb(struct bt_l2cap_chan *l2cap_chan, size_t sdu_len,
off_t seg_offset, struct net_buf_simple *seg)
{
struct btp_l2cap_data_received_ev *ev;
struct bt_l2cap_le_chan *l2cap_le_chan = CONTAINER_OF(
l2cap_chan, struct bt_l2cap_le_chan, chan);
struct channel *chan = CONTAINER_OF(l2cap_le_chan, struct channel, le);

ev = (void *)chan->recv_cb_buf;
memcpy(&ev->data[seg_offset], seg->data, seg->len);

/* complete SDU received */
if (seg_offset + seg->len == sdu_len) {
ev->chan_id = chan->chan_id;
ev->data_length = sys_cpu_to_le16(sdu_len);

tester_event(BTP_SERVICE_ID_L2CAP, BTP_L2CAP_EV_DATA_RECEIVED,
chan->recv_cb_buf, sizeof(*ev) + sdu_len);
}

if (chan->hold_credit) {
chan->pending_credits++;
} else {
bt_l2cap_chan_give_credits(l2cap_chan, 1);
}
}
#else
static struct net_buf *alloc_buf_cb(struct bt_l2cap_chan *chan)
{
return net_buf_alloc(&data_pool, K_FOREVER);
}

static uint8_t recv_cb_buf[DATA_BUF_SIZE + sizeof(struct btp_l2cap_data_received_ev)];
static uint8_t recv_cb_buf[DATA_MTU + sizeof(struct btp_l2cap_data_received_ev)];

static int recv_cb(struct bt_l2cap_chan *l2cap_chan, struct net_buf *buf)
{
Expand All @@ -73,6 +107,7 @@ static int recv_cb(struct bt_l2cap_chan *l2cap_chan, struct net_buf *buf)

return 0;
}
#endif

static void connected_cb(struct bt_l2cap_chan *l2cap_chan)
{
Expand Down Expand Up @@ -111,11 +146,13 @@ static void disconnected_cb(struct bt_l2cap_chan *l2cap_chan)
struct channel *chan = CONTAINER_OF(l2cap_le_chan, struct channel, le);
struct bt_conn_info info;

#if !defined(CONFIG_BT_L2CAP_SEG_RECV)
/* release netbuf on premature disconnection */
if (chan->pending_credit) {
net_buf_unref(chan->pending_credit);
chan->pending_credit = NULL;
}
#endif

(void)memset(&ev, 0, sizeof(struct btp_l2cap_disconnected_ev));

Expand Down Expand Up @@ -160,8 +197,12 @@ static void reconfigured_cb(struct bt_l2cap_chan *l2cap_chan)
#endif

static const struct bt_l2cap_chan_ops l2cap_ops = {
#if defined(CONFIG_BT_L2CAP_SEG_RECV)
.seg_recv = seg_recv_cb,
#else
.alloc_buf = alloc_buf_cb,
.recv = recv_cb,
#endif
.connected = connected_cb,
.disconnected = disconnected_cb,
#if defined(CONFIG_BT_L2CAP_ECRED)
Expand Down Expand Up @@ -222,10 +263,15 @@ static uint8_t connect(const void *cmd, uint16_t cmd_len,
}
chan->le.chan.ops = &l2cap_ops;
chan->le.rx.mtu = mtu;
#if defined(CONFIG_BT_L2CAP_SEG_RECV)
chan->le.rx.mps = L2CAP_MPS;
#endif
rp->chan_id[i] = chan->chan_id;
allocated_channels[i] = &chan->le.chan;

chan->hold_credit = cp->options & BTP_L2CAP_CONNECT_OPT_HOLD_CREDIT;

bt_l2cap_chan_give_credits(&chan->le.chan, 1);
}

if (cp->num == 1 && !ecfc) {
Expand Down Expand Up @@ -289,6 +335,7 @@ static uint8_t reconfigure(const void *cmd, uint16_t cmd_len,
{
const struct btp_l2cap_reconfigure_cmd *cp = cmd;
uint16_t mtu;
uint16_t mps;
struct bt_conn *conn;
int err;
struct bt_l2cap_chan *reconf_channels[CHANNELS + 1] = {};
Expand Down Expand Up @@ -321,7 +368,8 @@ static uint8_t reconfigure(const void *cmd, uint16_t cmd_len,
return BTP_STATUS_FAILED;
}

err = bt_l2cap_ecred_chan_reconfigure(reconf_channels, mtu);
mps = MIN(L2CAP_MPS, BT_L2CAP_RX_MTU);
err = bt_l2cap_ecred_chan_reconfigure(reconf_channels, mtu, mps);
if (err) {
bt_conn_unref(conn);
return BTP_STATUS_FAILED;
Expand Down Expand Up @@ -454,9 +502,14 @@ static int accept(struct bt_conn *conn, struct bt_l2cap_server *server,

chan->le.chan.ops = &l2cap_ops;
chan->le.rx.mtu = DATA_MTU_INITIAL;
#if defined(CONFIG_BT_L2CAP_SEG_RECV)
chan->le.rx.mps = L2CAP_MPS;
#endif

*l2cap_chan = &chan->le.chan;

bt_l2cap_chan_give_credits(&chan->le.chan, 1);

return 0;
}

Expand Down Expand Up @@ -524,7 +577,16 @@ static uint8_t credits(const void *cmd, uint16_t cmd_len,
if (!chan->in_use) {
return BTP_STATUS_FAILED;
}
#if defined(CONFIG_BT_L2CAP_SEG_RECV)
if (chan->pending_credits) {
if (bt_l2cap_chan_give_credits(&chan->le.chan,
chan->pending_credits) < 0) {
return BTP_STATUS_FAILED;
}

chan->pending_credits = 0;
}
#else
if (chan->pending_credit) {
if (bt_l2cap_chan_recv_complete(&chan->le.chan,
chan->pending_credit) < 0) {
Expand All @@ -533,6 +595,7 @@ static uint8_t credits(const void *cmd, uint16_t cmd_len,

chan->pending_credit = NULL;
}
#endif

return BTP_STATUS_SUCCESS;
}
Expand Down

0 comments on commit f50478b

Please sign in to comment.