diff --git a/include/bluetooth/l2cap.h b/include/bluetooth/l2cap.h index 7ba11f359fa..b02bae68eca 100644 --- a/include/bluetooth/l2cap.h +++ b/include/bluetooth/l2cap.h @@ -38,6 +38,11 @@ #include #include +/* 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 */ diff --git a/net/bluetooth/Kconfig b/net/bluetooth/Kconfig index 95f6017f9dd..332bdc10703 100644 --- a/net/bluetooth/Kconfig +++ b/net/bluetooth/Kconfig @@ -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 diff --git a/net/bluetooth/att.c b/net/bluetooth/att.c index bfca8725bb3..b0535824cc8 100644 --- a/net/bluetooth/att.c +++ b/net/bluetooth/att.c @@ -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) diff --git a/net/bluetooth/conn.c b/net/bluetooth/conn.c index 877d644ac75..c596d4d628a 100644 --- a/net/bluetooth/conn.c +++ b/net/bluetooth/conn.c @@ -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(); diff --git a/net/bluetooth/conn_internal.h b/net/bluetooth/conn_internal.h index 81a5b769bd4..7f6fe1ce58c 100644 --- a/net/bluetooth/conn_internal.h +++ b/net/bluetooth/conn_internal.h @@ -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); diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c index 35b1bff904c..446e869e08f 100644 --- a/net/bluetooth/l2cap.c +++ b/net/bluetooth/l2cap.c @@ -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); } diff --git a/net/bluetooth/l2cap_internal.h b/net/bluetooth/l2cap_internal.h index 8384ae05610..b6eae76a1d5 100644 --- a/net/bluetooth/l2cap_internal.h +++ b/net/bluetooth/l2cap_internal.h @@ -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); diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 60974453b97..45a0eb3ff69 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c @@ -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();