Bluetooth: Create protocol-specific outgoing ACL buffer pools

With this split we get better control of the buffer sizes and counts.
We also anyway will need a fragments pool so a simple generic ACL_OUT
pool doesn't make sense anymore. The related Kconfig options for that
have been removed.

Change-Id: I616cf49915a1cc0dc0ddc724e2e182bcbe0c80f6
Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
This commit is contained in:
Johan Hedberg 2015-11-05 21:01:20 +02:00 committed by Anas Nashif
commit b9d13664ab
8 changed files with 51 additions and 38 deletions

View file

@ -38,6 +38,11 @@
#include <net/buf.h>
#include <bluetooth/conn.h>
/* Helper to calculate needed outgoing buffer size */
#define BT_L2CAP_BUF_SIZE(mtu) (CONFIG_BLUETOOTH_HCI_SEND_RESERVE + \
sizeof(struct bt_hci_acl_hdr) + \
sizeof(struct bt_l2cap_hdr) + (mtu))
/** @brief L2CAP Endpoint structure. */
struct bt_l2cap_endpoint {
/** Endpoint CID */

View file

@ -102,22 +102,6 @@ config BLUETOOTH_ACL_IN_SIZE
range 32 1300 if !BLUETOOTH_SMP
help
Maximum size of each incoming ACL data buffer.
config BLUETOOTH_ACL_OUT_COUNT
int "Number of incoming ACL data buffers"
default 5
range 2 64
help
Number of buffers available for incoming ACL data.
config BLUETOOTH_ACL_OUT_SIZE
int "Size of incoming ACL data buffers"
default 74 if BLUETOOTH_SMP
default 32 if !BLUETOOTH_SMP
range 74 1300 if BLUETOOTH_SMP
range 32 1300 if !BLUETOOTH_SMP
help
Maximum size of each outgoing ACL data buffer.
endif # BLUETOOTH_CONN
if BLUETOOTH_PERIPHERAL || BLUETOOTH_CENTRAL

View file

@ -80,6 +80,11 @@ struct bt_att {
static struct bt_att bt_att_pool[CONFIG_BLUETOOTH_MAX_CONN];
/* Pool for outgoing ATT packets, default MTU is 23 */
static struct nano_fifo att_buf;
static NET_BUF_POOL(att_pool, CONFIG_BLUETOOTH_MAX_CONN,
BT_L2CAP_BUF_SIZE(23), &att_buf, NULL, 0);
static const struct bt_uuid primary_uuid = {
.type = BT_UUID_16,
.u16 = BT_UUID_GATT_PRIMARY,
@ -1544,7 +1549,7 @@ struct net_buf *bt_att_create_pdu(struct bt_conn *conn, uint8_t op, size_t len)
return NULL;
}
buf = bt_l2cap_create_pdu(conn);
buf = bt_l2cap_create_pdu(&att_buf);
if (!buf) {
return NULL;
}
@ -1641,6 +1646,8 @@ void bt_att_init(void)
.accept = bt_att_accept,
};
net_buf_pool_init(att_pool);
bt_l2cap_fixed_chan_register(&chan);
#if defined(CONFIG_BLUETOOTH_SMP)

View file

@ -43,10 +43,13 @@
#define BT_DBG(fmt, ...)
#endif
/* Pool for outgoing ACL buffers */
static struct nano_fifo avail_acl_out;
static NET_BUF_POOL(acl_out_pool, CONFIG_BLUETOOTH_ACL_OUT_COUNT,
CONFIG_BLUETOOTH_ACL_OUT_SIZE, &avail_acl_out, NULL, 0);
/* Pool for outgoing ACL fragments */
static struct nano_fifo frag;
static NET_BUF_POOL(frag_pool, 1, BT_L2CAP_BUF_SIZE(23), &frag, NULL, 0);
/* Pool for dummy buffers to wake up the tx fibers */
static struct nano_fifo dummy;
static NET_BUF_POOL(dummy_pool, CONFIG_BLUETOOTH_MAX_CONN, 0, &dummy, NULL, 0);
/* How long until we cancel HCI_LE_Create_Connection */
#define CONN_TIMEOUT (3 * sys_clock_ticks_per_sec)
@ -348,7 +351,7 @@ void bt_conn_send(struct bt_conn *conn, struct net_buf *buf)
remaining -= len;
while (remaining) {
buf = bt_conn_create_pdu(conn, 0);
buf = bt_conn_create_pdu(&frag, 0);
len = min(remaining, bt_dev.le.mtu);
@ -524,8 +527,7 @@ void bt_conn_set_state(struct bt_conn *conn, bt_conn_state_t state)
bt_l2cap_disconnected(conn);
notify_disconnected(conn);
nano_fifo_put(&conn->tx_queue,
bt_conn_create_pdu(conn, 0));
nano_fifo_put(&conn->tx_queue, net_buf_get(&dummy, 0));
}
/* Release the reference we took for the very first
@ -774,19 +776,20 @@ uint8_t bt_conn_enc_key_size(struct bt_conn *conn)
return conn->keys ? conn->keys->enc_size : 0;
}
struct net_buf *bt_conn_create_pdu(struct bt_conn *conn, size_t reserve)
struct net_buf *bt_conn_create_pdu(struct nano_fifo *fifo, size_t reserve)
{
size_t head_reserve = reserve + sizeof(struct bt_hci_acl_hdr) +
CONFIG_BLUETOOTH_HCI_SEND_RESERVE;
return net_buf_get(&avail_acl_out, head_reserve);
return net_buf_get(fifo, head_reserve);
}
int bt_conn_init(void)
{
int err;
net_buf_pool_init(acl_out_pool);
net_buf_pool_init(frag_pool);
net_buf_pool_init(dummy_pool);
bt_att_init();

View file

@ -122,7 +122,7 @@ void bt_conn_identity_resolved(struct bt_conn *conn);
void bt_conn_security_changed(struct bt_conn *conn);
/* Prepare a PDU to be sent over a connection */
struct net_buf *bt_conn_create_pdu(struct bt_conn *conn, size_t reserve);
struct net_buf *bt_conn_create_pdu(struct nano_fifo *fifo, size_t reserve);
/* Initialize connection management */
int bt_conn_init(void);

View file

@ -61,6 +61,11 @@ static struct bt_l2cap_fixed_chan *channels;
static struct bt_l2cap_server *servers;
#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */
/* Pool for outgoing LE signaling packets, MTU is 23 */
static struct nano_fifo le_sig;
static NET_BUF_POOL(le_pool, CONFIG_BLUETOOTH_MAX_CONN, BT_L2CAP_BUF_SIZE(23),
&le_sig, NULL, 0);
/* L2CAP signalling channel specific context */
struct bt_l2cap {
/* The channel this context is associated with */
@ -199,9 +204,9 @@ void bt_l2cap_encrypt_change(struct bt_conn *conn)
}
}
struct net_buf *bt_l2cap_create_pdu(struct bt_conn *conn)
struct net_buf *bt_l2cap_create_pdu(struct nano_fifo *fifo)
{
return bt_conn_create_pdu(conn, sizeof(struct bt_l2cap_hdr));
return bt_conn_create_pdu(fifo, sizeof(struct bt_l2cap_hdr));
}
void bt_l2cap_send(struct bt_conn *conn, uint16_t cid, struct net_buf *buf)
@ -222,7 +227,7 @@ static void l2cap_send_reject(struct bt_conn *conn, uint8_t ident,
struct bt_l2cap_sig_hdr *hdr;
struct net_buf *buf;
buf = bt_l2cap_create_pdu(conn);
buf = bt_l2cap_create_pdu(&le_sig);
if (!buf) {
return;
}
@ -279,7 +284,7 @@ static void le_conn_param_update_req(struct bt_l2cap *l2cap, uint8_t ident,
BT_DBG("min 0x%4.4x max 0x%4.4x latency: 0x%4.4x timeout: 0x%4.4x",
min, max, latency, timeout);
buf = bt_l2cap_create_pdu(l2cap->chan.conn);
buf = bt_l2cap_create_pdu(&le_sig);
if (!buf) {
return;
}
@ -370,7 +375,7 @@ static void le_conn_req(struct bt_l2cap *l2cap, uint8_t ident,
return;
}
buf = bt_l2cap_create_pdu(conn);
buf = bt_l2cap_create_pdu(&le_sig);
if (!buf) {
return;
}
@ -490,7 +495,7 @@ static void le_disconn_req(struct bt_l2cap *l2cap, uint8_t ident,
return;
}
buf = bt_l2cap_create_pdu(conn);
buf = bt_l2cap_create_pdu(&le_sig);
if (!buf) {
return;
}
@ -583,7 +588,7 @@ static void l2cap_chan_update_credits(struct bt_l2cap_chan *chan)
credits = L2CAP_LE_MAX_CREDITS - chan->rx.credits;
chan->rx.credits = L2CAP_LE_MAX_CREDITS;
buf = bt_l2cap_create_pdu(chan->conn);
buf = bt_l2cap_create_pdu(&le_sig);
if (!buf) {
BT_ERR("Unable to send credits\n");
return;
@ -686,7 +691,7 @@ int bt_l2cap_update_conn_param(struct bt_conn *conn)
struct bt_l2cap_conn_param_req *req;
struct net_buf *buf;
buf = bt_l2cap_create_pdu(conn);
buf = bt_l2cap_create_pdu(&le_sig);
if (!buf) {
return -ENOBUFS;
}
@ -754,6 +759,8 @@ void bt_l2cap_init(void)
.accept = l2cap_accept,
};
net_buf_pool_init(le_pool);
bt_l2cap_fixed_chan_register(&chan);
}

View file

@ -128,7 +128,7 @@ void bt_l2cap_disconnected(struct bt_conn *conn);
void bt_l2cap_encrypt_change(struct bt_conn *conn);
/* Prepare an L2CAP PDU to be sent over a connection */
struct net_buf *bt_l2cap_create_pdu(struct bt_conn *conn);
struct net_buf *bt_l2cap_create_pdu(struct nano_fifo *fifo);
/* Send L2CAP PDU over a connection */
void bt_l2cap_send(struct bt_conn *conn, uint16_t cid, struct net_buf *buf);

View file

@ -126,6 +126,11 @@ static const uint8_t gen_method[5 /* remote */][5 /* local */] = {
PASSKEY_ROLE },
};
/* Pool for outgoing LE signaling packets, MTU is 65 */
static struct nano_fifo smp_buf;
static NET_BUF_POOL(smp_pool, CONFIG_BLUETOOTH_MAX_CONN,
BT_L2CAP_BUF_SIZE(65), &smp_buf, NULL, 0);
static struct bt_smp bt_smp_pool[CONFIG_BLUETOOTH_MAX_CONN];
static const struct bt_auth_cb *auth_cb;
static uint8_t bt_smp_io_capa = BT_SMP_IO_NO_INPUT_OUTPUT;
@ -476,7 +481,7 @@ struct net_buf *bt_smp_create_pdu(struct bt_conn *conn, uint8_t op, size_t len)
struct bt_smp_hdr *hdr;
struct net_buf *buf;
buf = bt_l2cap_create_pdu(conn);
buf = bt_l2cap_create_pdu(&smp_buf);
if (!buf) {
return NULL;
}
@ -2167,6 +2172,8 @@ int bt_smp_init(void)
.accept = bt_smp_accept,
};
net_buf_pool_init(smp_pool);
bt_l2cap_fixed_chan_register(&chan);
return smp_self_test();