diff --git a/drivers/wireless/bluetooth/bt_uart.c b/drivers/wireless/bluetooth/bt_uart.c index 1f062db1b0..40e3b6cd7f 100644 --- a/drivers/wireless/bluetooth/bt_uart.c +++ b/drivers/wireless/bluetooth/bt_uart.c @@ -148,7 +148,7 @@ static FAR struct bt_buf_s *btuart_evt_recv(FAR struct btuart_upperhalf_s *upper *remaining = hdr.len; - buf = bt_buf_alloc(BT_EVT, 0); + buf = bt_buf_alloc(BT_EVT, NULL, 0); if (buf != NULL) { memcpy(bt_buf_extend(buf, sizeof(struct bt_hci_evt_hdr_s)), &hdr, @@ -181,7 +181,7 @@ static FAR struct bt_buf_s *btuart_acl_recv(FAR struct btuart_upperhalf_s *upper return NULL; } - buf = bt_buf_alloc(BT_ACL_IN, 0); + buf = bt_buf_alloc(BT_ACL_IN, NULL, 0); if (buf) { memcpy(bt_buf_extend(buf, sizeof(struct bt_hci_acl_hdr_s)), &hdr, diff --git a/include/nuttx/net/bluetooth.h b/include/nuttx/net/bluetooth.h index 4d56d07225..293b8f59cf 100644 --- a/include/nuttx/net/bluetooth.h +++ b/include/nuttx/net/bluetooth.h @@ -52,7 +52,7 @@ #warning REVISIT -#define BLUETOOTH_HDRLEN 0 +#define BLUETOOTH_HDRLEN 8 /* Size of L2CAP header */ #define BLUETOOTH_ADDRSIZE 6 #define BLUETOOTH_ADDRCOPY(d,s) memcpy((d),(s),BLUETOOTH_ADDRSIZE) #define BLUETOOTH_ADDRCMP(a,b) (memcmp((a),(b),BLUETOOTH_ADDRSIZE) == 0) diff --git a/include/nuttx/wireless/bt_buf.h b/include/nuttx/wireless/bt_buf.h index 8630e50ef0..6170e7ed77 100644 --- a/include/nuttx/wireless/bt_buf.h +++ b/include/nuttx/wireless/bt_buf.h @@ -103,6 +103,8 @@ struct bt_buf_acl_data_s uint16_t handle; }; +struct iob_s; /* Forward reference */ + struct bt_buf_s { FAR struct bt_buf_s *flink; @@ -147,6 +149,8 @@ struct bt_buf_s * * Input Parameters: * type - Buffer type. + * iob - The raw I/O buffer. If NULL, then bt_buf_alloc will + * allocate. * reserve_head - How much headroom to reserve. * * Returned Value: @@ -156,7 +160,10 @@ struct bt_buf_s * ****************************************************************************/ +struct iob_s; /* Forward reference */ + FAR struct bt_buf_s *bt_buf_alloc(enum bt_buf_type_e type, + FAR struct iob_s *iob, size_t reserve_head); /**************************************************************************** diff --git a/wireless/bluetooth/Kconfig b/wireless/bluetooth/Kconfig index 3998911f6c..b2a4b5de22 100644 --- a/wireless/bluetooth/Kconfig +++ b/wireless/bluetooth/Kconfig @@ -120,7 +120,6 @@ config BLUETOOTH_BUFFER_PREALLOC config BLUETOOTH_BUFFER_IRQRESERVE int "Reserved pre-allocated primitive structures" default 0 - depends on EXPERIMENTAL ---help--- If buffer structures can be allocated from interrupt handlers, then this specifies the number of pre-allocated structures that are @@ -139,9 +138,9 @@ config BLUETOOTH_BUFFER_IRQRESERVE dynamically allocate the buffer with an additional cost in performance. - NOTE: Currently marked as experimental and with a default of zero - because there are no interrupt level allocations performed by the - current Bluetooth stack. + NOTE: The Bluetooth stack never allocates buffers from the + interrupt level. This setting only needs to be non-zero if your + low-level Bluetooth driver needs to do such allocations. menu "Kernel Thread Configuration" diff --git a/wireless/bluetooth/bt_buf.c b/wireless/bluetooth/bt_buf.c index 2ab0d833ef..ad8b7b4a96 100644 --- a/wireless/bluetooth/bt_buf.c +++ b/wireless/bluetooth/bt_buf.c @@ -63,11 +63,6 @@ * Pre-processor Definitions ****************************************************************************/ -/* NOTE: The CONFIG_BLUETOOTH_BUFFER_IRQRESERVE options is marked as marked - * 'experimental' and with the default 0 zero because there are no interrupt - * level allocations performed by the current Bluetooth code. - */ - #if !defined(CONFIG_BLUETOOTH_BUFFER_PREALLOC) || \ CONFIG_BLUETOOTH_BUFFER_PREALLOC < 1 # undef CONFIG_BLUETOOTH_BUFFER_PREALLOC @@ -220,6 +215,8 @@ void bt_buf_initialize(void) * * Input Parameters: * type - Buffer type. + * iob - The raw I/O buffer. If NULL, then bt_buf_alloc will + * allocate. * reserve_head - How much headroom to reserve. * * Returned Value: @@ -229,8 +226,9 @@ void bt_buf_initialize(void) * ****************************************************************************/ -FAR struct bt_buf_s *bt_buf_alloc(enum bt_buf_type_e type, size_t - reserve_head) +FAR struct bt_buf_s *bt_buf_alloc(enum bt_buf_type_e type, + FAR struct iob_s *iob, + size_t reserve_head) { FAR struct bt_buf_s *buf; irqstate_t flags; diff --git a/wireless/bluetooth/bt_conn.c b/wireless/bluetooth/bt_conn.c index 493304df96..125e70d35a 100644 --- a/wireless/bluetooth/bt_conn.c +++ b/wireless/bluetooth/bt_conn.c @@ -588,7 +588,8 @@ void bt_conn_set_state(FAR struct bt_conn_s *conn, if (old_state == BT_CONN_CONNECTED || old_state == BT_CONN_DISCONNECT) { - bt_queue_send(conn->tx_queue, bt_buf_alloc(BT_DUMMY, 0), BT_NORMAL_PRIO); + bt_queue_send(conn->tx_queue, bt_buf_alloc(BT_DUMMY, NULL, 0), + BT_NORMAL_PRIO); } /* Release the reference we took for the very first state transition. */ @@ -618,7 +619,7 @@ void bt_conn_set_state(FAR struct bt_conn_s *conn, * * Returned Value: * A reference to the connection state instance is returned on success. - * NULL is returned if the connection is not found. On succes, the + * NULL is returned if the connection is not found. On success, the * caller gets a new reference to the connection object which must be * released with bt_conn_release() once done using the connection. * @@ -658,7 +659,7 @@ FAR struct bt_conn_s *bt_conn_lookup_handle(uint16_t handle) * * Returned Value: * A reference to the connection state instance is returned on success. - * NULL is returned if the connection is not found. On succes, the + * NULL is returned if the connection is not found. On success, the * caller gets a new reference to the connection object which must be * released with bt_conn_release() once done using the connection. * @@ -692,7 +693,7 @@ FAR struct bt_conn_s *bt_conn_lookup_addr_le(FAR const bt_addr_le_t * peer) * * Returned Value: * A reference to the connection state instance is returned on success. - * NULL is returned if the connection is not found. On succes, the + * NULL is returned if the connection is not found. On success, the * caller gets a new reference to the connection object which must be * released with bt_conn_release() once done using the connection. * diff --git a/wireless/bluetooth/bt_conn.h b/wireless/bluetooth/bt_conn.h index 87d0f5aad5..d7ed3404db 100644 --- a/wireless/bluetooth/bt_conn.h +++ b/wireless/bluetooth/bt_conn.h @@ -196,7 +196,7 @@ void bt_conn_set_state(FAR struct bt_conn_s *conn, enum bt_conn_state_e state); * * Returned Value: * A reference to the connection state instance is returned on success. - * NULL is returned if the connection is not found. On succes, the + * NULL is returned if the connection is not found. On success, the * caller gets a new reference to the connection object which must be * released with bt_conn_release() once done using the connection. * @@ -215,7 +215,7 @@ FAR struct bt_conn_s *bt_conn_lookup_handle(uint16_t handle); * * Returned Value: * A reference to the connection state instance is returned on success. - * NULL is returned if the connection is not found. On succes, the + * NULL is returned if the connection is not found. On success, the * caller gets a new reference to the connection object which must be * released with bt_conn_release() once done using the connection. * @@ -236,7 +236,7 @@ FAR struct bt_conn_s *bt_conn_lookup_addr_le(const bt_addr_le_t *peer); * * Returned Value: * A reference to the connection state instance is returned on success. - * NULL is returned if the connection is not found. On succes, the + * NULL is returned if the connection is not found. On success, the * caller gets a new reference to the connection object which must be * released with bt_conn_release() once done using the connection. * diff --git a/wireless/bluetooth/bt_hcicore.c b/wireless/bluetooth/bt_hcicore.c index dde7f7d891..8eef66b202 100644 --- a/wireless/bluetooth/bt_hcicore.c +++ b/wireless/bluetooth/bt_hcicore.c @@ -1387,7 +1387,7 @@ FAR struct bt_buf_s *bt_hci_cmd_create(uint16_t opcode, uint8_t param_len) wlinfo("opcode %x param_len %u\n", opcode, param_len); - buf = bt_buf_alloc(BT_CMD, g_btdev.dev->head_reserve); + buf = bt_buf_alloc(BT_CMD, NULL, g_btdev.dev->head_reserve); if (!buf) { wlerr("ERROR: Cannot get free buffer\n"); diff --git a/wireless/bluetooth/bt_l2cap.c b/wireless/bluetooth/bt_l2cap.c index d86463f3d1..d150d1c32a 100644 --- a/wireless/bluetooth/bt_l2cap.c +++ b/wireless/bluetooth/bt_l2cap.c @@ -182,7 +182,7 @@ struct bt_buf_s *bt_l2cap_create_pdu(FAR struct bt_conn_s *conn) size_t head_reserve = sizeof(struct bt_l2cap_hdr_s) + sizeof(struct bt_hci_acl_hdr_s) + g_btdev.dev->head_reserve; - return bt_buf_alloc(BT_ACL_OUT, head_reserve); + return bt_buf_alloc(BT_ACL_OUT, NULL, head_reserve); } void bt_l2cap_send(FAR struct bt_conn_s *conn, uint16_t cid, @@ -413,7 +413,7 @@ void bt_l2cap_receive(FAR struct bt_conn_s *conn, FAR struct bt_buf_s *buf) return; } - chan->receive(conn, buf, chan->context, chan->cid); + chan->receive(conn, buf, chan->context, cid); } void bt_l2cap_update_conn_param(FAR struct bt_conn_s *conn) diff --git a/wireless/bluetooth/bt_netdev.c b/wireless/bluetooth/bt_netdev.c index df05348dcc..b83326faf3 100644 --- a/wireless/bluetooth/bt_netdev.c +++ b/wireless/bluetooth/bt_netdev.c @@ -861,7 +861,7 @@ static int btnet_rmmac(FAR struct net_driver_s *dev, FAR const uint8_t *mac) static int btnet_get_mhrlen(FAR struct radio_driver_s *netdev, FAR const void *meta) { - return BLUETOOTH_HDRLEN; + return sizeof(struct bt_l2cap_hdr_s); } /**************************************************************************** @@ -885,16 +885,24 @@ static int btnet_get_mhrlen(FAR struct radio_driver_s *netdev, static int btnet_req_data(FAR struct radio_driver_s *netdev, FAR const void *meta, FAR struct iob_s *framelist) { - FAR struct btnet_driver_s *priv = - (FAR struct btnet_driver_s *)netdev; - FAR const struct bluetooth_frame_meta_s *pktmeta = - (FAR const struct bluetooth_frame_meta_s *)meta; + FAR struct btnet_driver_s *priv; + FAR struct bluetooth_frame_meta_s *btmeta; + FAR struct bt_conn_s *conn; + FAR struct bt_buf_s *buf; FAR struct iob_s *iob; - int ret; wlinfo("Received framelist\n"); + DEBUGASSERT(priv != NULL && meta != NULL && framelist != NULL); - DEBUGASSERT(priv != NULL && pktmeta != NULL && framelist != NULL); + priv = (FAR struct btnet_driver_s *)netdev; + btmeta = (FAR struct bluetooth_frame_meta_s *)meta; + + /* Create a connection structure for this peer if one does not already + * exist. + * + * REVISIT: Can we do a handle lookup? ... That would be faster. + */ +#warning Missing logic /* Add the incoming list of frames to the MAC's outgoing queue */ @@ -909,31 +917,18 @@ static int btnet_req_data(FAR struct radio_driver_s *netdev, framelist = iob->io_flink; iob->io_flink = NULL; - /* Transfer the frame to the MAC. */ + /* Allocate a buffer to contain the IOB */ - do + buf = bt_buf_alloc(BT_ACL_OUT, iob, sizeof(struct bt_l2cap_hdr_s)); + if (buf == NULL) { - ret = btnet_req_data(netdev, pktmeta, iob); - } - while (ret == -EINTR); - - if (ret < 0) - { - wlerr("ERROR: btnet_req_data failed: %d\n", ret); - - iob_free(iob); - for (iob = framelist; iob != NULL; iob = framelist) - { - /* Remove the IOB from the queue and free */ - - framelist = iob->io_flink; - iob_free(iob); - } - - NETDEV_TXERRORS(&priv->bd_dev.r_dev); - return ret; + wlerr("ERROR: Failed to allocate buffer container\n"); + return -ENOMEM; } + /* Transfer the frame to the Bluetooth stack. */ + + bt_l2cap_send(conn, (uint16_t)btmeta->bm_channel, buf); NETDEV_TXDONE(&priv->bd_dev.r_dev); }