This is an automated email from the ASF dual-hosted git repository.

acassis pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


The following commit(s) were added to refs/heads/master by this push:
     new debf4aa9052 net/bluetooth: fix HCI receive device lookup
debf4aa9052 is described below

commit debf4aa90528bab6288068bdf0366be872f35fc6
Author: Jackson-gjh <[email protected]>
AuthorDate: Sat Nov 7 13:11:43 2026 +0800

    net/bluetooth: fix HCI receive device lookup
    
    Raw HCI sockets store hci_dev in bc_ldev as a zero-based index among
    Bluetooth devices.  bluetooth_recvmsg() instead looked up the receive
    device using bc_laddr, which is not the device selector for an HCI socket.
    The lookup could therefore fail with ENODEV and prevent the external Host
    stack from receiving Controller events.
    
    Move the existing Bluetooth-index lookup from bluetooth_sendmsg.c into a
    shared helper and use it for both HCI send and receive paths.  Keep the
    address-based lookup for L2CAP sockets.
    
    On an ESP32-C6 with Apache NimBLE as the external Host, the unmodified
    receive path reset the Host with reason 19 and did not advertise.  With the
    fix, the device advertised, connected, completed GATT service discovery,
    negotiated MTU 256, and returned the Battery Level characteristic.
    
    Assisted-by: Codex:gpt-5
    Signed-off-by: Jackson-gjh <[email protected]>
---
 net/bluetooth/bluetooth.h         | 17 +++++++++++
 net/bluetooth/bluetooth_finddev.c | 61 +++++++++++++++++++++++++++++++++++++++
 net/bluetooth/bluetooth_recvmsg.c | 10 ++++++-
 net/bluetooth/bluetooth_sendmsg.c | 54 ++--------------------------------
 4 files changed, 90 insertions(+), 52 deletions(-)

diff --git a/net/bluetooth/bluetooth.h b/net/bluetooth/bluetooth.h
index a83945103be..7693fc9e9d3 100644
--- a/net/bluetooth/bluetooth.h
+++ b/net/bluetooth/bluetooth.h
@@ -341,6 +341,23 @@ FAR struct radio_driver_s *
   bluetooth_find_device(FAR struct bluetooth_conn_s *conn,
                         FAR const bt_addr_t *addr);
 
+/****************************************************************************
+ * Name: bluetooth_find_device_byindex
+ *
+ * Description:
+ *   Select a Bluetooth network driver by its zero-based index among
+ *   Bluetooth devices.
+ *
+ * Input Parameters:
+ *   index - The Bluetooth device index.
+ *
+ * Returned Value:
+ *   A pointer to the network driver to use.  NULL is returned on failure.
+ *
+ ****************************************************************************/
+
+FAR struct radio_driver_s *bluetooth_find_device_byindex(uint8_t index);
+
 /****************************************************************************
  * Name: bluetooth_poll
  *
diff --git a/net/bluetooth/bluetooth_finddev.c 
b/net/bluetooth/bluetooth_finddev.c
index 9d2768226ba..3b723639cf3 100644
--- a/net/bluetooth/bluetooth_finddev.c
+++ b/net/bluetooth/bluetooth_finddev.c
@@ -48,6 +48,13 @@ struct bluetooth_finddev_s
   FAR struct radio_driver_s *bf_radio;
 };
 
+struct bluetooth_findbyidx_s
+{
+  uint8_t                    bf_tgt;
+  uint8_t                    bf_cur;
+  FAR struct radio_driver_s *bf_radio;
+};
+
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
@@ -99,6 +106,33 @@ static int bluetooth_dev_callback(FAR struct net_driver_s 
*dev,
   return 0;
 }
 
+/****************************************************************************
+ * Name: bluetooth_dev_byidx_callback
+ *
+ * Description:
+ *   Find the target device by its zero-based index among Bluetooth devices.
+ *
+ ****************************************************************************/
+
+static int bluetooth_dev_byidx_callback(FAR struct net_driver_s *dev,
+                                        FAR void *arg)
+{
+  FAR struct bluetooth_findbyidx_s *match = arg;
+
+  if (dev->d_lltype == NET_LL_BLUETOOTH)
+    {
+      if (match->bf_cur == match->bf_tgt)
+        {
+          match->bf_radio = (FAR struct radio_driver_s *)dev;
+          return 1;
+        }
+
+      match->bf_cur++;
+    }
+
+  return 0;
+}
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -144,4 +178,31 @@ FAR struct radio_driver_s *
   return NULL;
 }
 
+/****************************************************************************
+ * Name: bluetooth_find_device_byindex
+ *
+ * Description:
+ *   Select a Bluetooth network driver by its zero-based index among
+ *   Bluetooth devices.
+ *
+ * Input Parameters:
+ *   index - The Bluetooth device index.
+ *
+ * Returned Value:
+ *   A pointer to the network driver to use.  NULL is returned on failure.
+ *
+ ****************************************************************************/
+
+FAR struct radio_driver_s *bluetooth_find_device_byindex(uint8_t index)
+{
+  struct bluetooth_findbyidx_s match;
+
+  match.bf_tgt   = index;
+  match.bf_cur   = 0;
+  match.bf_radio = NULL;
+
+  netdev_foreach(bluetooth_dev_byidx_callback, &match);
+  return match.bf_radio;
+}
+
 #endif /* CONFIG_NET_BLUETOOTH */
diff --git a/net/bluetooth/bluetooth_recvmsg.c 
b/net/bluetooth/bluetooth_recvmsg.c
index abdff2ddf75..06fd5cb4397 100644
--- a/net/bluetooth/bluetooth_recvmsg.c
+++ b/net/bluetooth/bluetooth_recvmsg.c
@@ -351,7 +351,15 @@ ssize_t bluetooth_recvmsg(FAR struct socket *psock, FAR 
struct msghdr *msg,
 
   /* Get the device driver that will service this transfer */
 
-  radio = bluetooth_find_device(conn, &conn->bc_laddr);
+  if (psock->s_proto == BTPROTO_HCI)
+    {
+      radio = bluetooth_find_device_byindex(conn->bc_ldev);
+    }
+  else
+    {
+      radio = bluetooth_find_device(conn, &conn->bc_laddr);
+    }
+
   if (radio == NULL)
     {
       ret = -ENODEV;
diff --git a/net/bluetooth/bluetooth_sendmsg.c 
b/net/bluetooth/bluetooth_sendmsg.c
index 78744624801..b9bd8dc486d 100644
--- a/net/bluetooth/bluetooth_sendmsg.c
+++ b/net/bluetooth/bluetooth_sendmsg.c
@@ -75,54 +75,10 @@ struct bluetooth_sendto_s
   ssize_t is_sent;                      /* The number of bytes sent (or error) 
*/
 };
 
-/* Used by bluetooth_dev_byidx_callback to locate the bc_ldev-th BT device */
-
-struct bluetooth_findbyidx_s
-{
-  uint8_t                    bf_tgt;   /* Target index among BT devices 
(bc_ldev) */
-  uint8_t                    bf_cur;   /* Count of BT devices seen so far */
-  FAR struct radio_driver_s *bf_radio; /* Result */
-};
-
 /****************************************************************************
  * Private Functions
  ****************************************************************************/
 
-/****************************************************************************
- * Name: bluetooth_dev_byidx_callback
- *
- * Description:
- *   netdev_foreach callback that finds the bf_tgt-th NET_LL_BLUETOOTH device
- *   (0-based index among BT devices only).
- *
- *   bluetooth_sendto() uses bc_ldev to identify the bound BT device, but
- *   bc_ldev is a 0-based count among Bluetooth devices only — it bears no
- *   fixed relationship to the global netdev interface index.  Walking all
- *   netdevs and counting only NET_LL_BLUETOOTH entries makes the lookup
- *   independent of what other netdevs are registered and in what order.
- *
- ****************************************************************************/
-
-static int bluetooth_dev_byidx_callback(FAR struct net_driver_s *dev,
-                                        FAR void *arg)
-{
-  FAR struct bluetooth_findbyidx_s *match =
-    (FAR struct bluetooth_findbyidx_s *)arg;
-
-  if (dev->d_lltype == NET_LL_BLUETOOTH)
-    {
-      if (match->bf_cur == match->bf_tgt)
-        {
-          match->bf_radio = (FAR struct radio_driver_s *)dev;
-          return 1;
-        }
-
-      match->bf_cur++;
-    }
-
-  return 0;
-}
-
 /****************************************************************************
  * Name: bluetooth_sendto_eventhandler
  ****************************************************************************/
@@ -323,13 +279,7 @@ static ssize_t bluetooth_sendto(FAR struct socket *psock,
     }
   else if (psock->s_proto == BTPROTO_HCI)
     {
-      struct bluetooth_findbyidx_s match;
-      match.bf_tgt   = conn->bc_ldev;
-      match.bf_cur   = 0;
-      match.bf_radio = NULL;
-
-      netdev_foreach(bluetooth_dev_byidx_callback, &match);
-      radio = match.bf_radio;
+      radio = bluetooth_find_device_byindex(conn->bc_ldev);
 
       if (radio == NULL)
         {
@@ -362,12 +312,14 @@ static ssize_t bluetooth_sendto(FAR struct socket *psock,
   if (psock->s_proto == BTPROTO_L2CAP)
     {
       FAR struct sockaddr_l2 *destaddr = (FAR struct sockaddr_l2 *)to;
+
       memcpy(&state.is_destaddr, &destaddr->l2_bdaddr,
              sizeof(bt_addr_t));
     }
   else if (psock->s_proto == BTPROTO_HCI)
     {
       FAR struct sockaddr_hci *destaddr = (FAR struct sockaddr_hci *)to;
+
       state.is_channel = destaddr->hci_channel;
     }
   else

Reply via email to