Bluetooth Logical Link Control and Adaptation Protocol (L2CAP) for BR/EDR
L2CAP BR/EDR provides support for Bluetooth Classic L2CAP (Logical Link Control and Adaptation Protocol) features including ECHO request/response and connectionless data channels.
ECHO Request/Response
The L2CAP ECHO feature allows testing the connection by sending ECHO requests and receiving ECHO responses. The stack answers a received ECHO request with an ECHO response without data, unless an application callback handles the request.
The API to send ECHO requests and responses and to register callbacks is intended for testing,
such as qualification testing. It is enabled through the configuration options
CONFIG_BT_CLASSIC and CONFIG_BT_TESTING.
Registering ECHO Callbacks
To monitor ECHO request/response packets, register a bt_l2cap_br_echo_cb callback
structure:
static void echo_req_cb(struct bt_conn *conn, uint8_t identifier, struct net_buf *buf)
{
/* Handle ECHO request, answer with bt_l2cap_br_echo_rsp() */
}
static void echo_rsp_cb(struct bt_conn *conn, struct net_buf *buf)
{
/* Handle ECHO response */
}
static struct bt_l2cap_br_echo_cb echo_cb = {
.req = echo_req_cb,
.rsp = echo_rsp_cb,
};
bt_l2cap_br_echo_cb_register(&echo_cb);
Sending ECHO Request
To send an ECHO request, allocate a buffer with BT_L2CAP_BR_ECHO_REQ_RESERVE
bytes reserved for the L2CAP header:
struct net_buf *buf;
buf = net_buf_alloc(&pool, K_FOREVER);
net_buf_reserve(buf, BT_L2CAP_BR_ECHO_REQ_RESERVE);
net_buf_add_mem(buf, data, data_len);
bt_l2cap_br_echo_req(conn, buf);
Sending ECHO Response
To send an ECHO response (typically in response to a received ECHO request), allocate a buffer with
BT_L2CAP_BR_ECHO_RSP_RESERVE bytes reserved for the L2CAP header:
struct net_buf *buf;
buf = net_buf_alloc(&pool, K_FOREVER);
net_buf_reserve(buf, BT_L2CAP_BR_ECHO_RSP_RESERVE);
net_buf_add_mem(buf, data, data_len);
bt_l2cap_br_echo_rsp(conn, buf);
The identifier parameter must match the identifier from the received ECHO request to properly correlate the response with the request.
Connectionless Data Channel
The connectionless data channel allows sending and receiving data to/from a specific PSM
(Protocol/Service Multiplexer) without establishing a connection-oriented L2CAP channel.
The feature is enabled through the configuration option: CONFIG_BT_L2CAP_CONNLESS.
Registering Connectionless Callbacks
To receive connectionless data, register a bt_l2cap_br_connless_cb callback structure:
static void connless_recv_cb(struct bt_conn *conn, uint16_t psm, struct net_buf *buf)
{
/* Handle received connectionless data */
}
static struct bt_l2cap_br_connless_cb connless_cb = {
.psm = MY_PSM, /* Or 0 to receive all */
.sec_level = BT_SECURITY_L1,
.recv = connless_recv_cb,
};
bt_l2cap_br_connless_register(&connless_cb);
Sending Connectionless Data
To send connectionless data, allocate a buffer with BT_L2CAP_CONNLESS_RESERVE
bytes reserved:
struct net_buf *buf;
buf = net_buf_alloc(&pool, K_FOREVER);
net_buf_reserve(buf, BT_L2CAP_CONNLESS_RESERVE);
net_buf_add_mem(buf, data, data_len);
bt_l2cap_br_connless_send(conn, psm, buf);