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

xiaoxiang781216 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 990ac856b29 net/bluetooth: fix BTPROTO_HCI socket device lookup
990ac856b29 is described below

commit 990ac856b29feca14acbc9c597477cccd5f2c1cb
Author: Stephen Fox <[email protected]>
AuthorDate: Mon May 4 10:07:45 2026 -0400

    net/bluetooth: fix BTPROTO_HCI socket device lookup
    
    bluetooth_sendto() uses netdev_findbyindex(conn->bc_ldev + 1) to find
    the Bluetooth network device for an HCI socket.  netdev_findbyindex
    searches by global interface index, but bc_ldev is a 0-based count of
    Bluetooth devices only — it bears no fixed relationship to the global
    interface index.  If any netdev other than a Bluetooth device is
    registered before it (e.g. loopback or Ethernet), the Bluetooth device
    will not be at global index bc_ldev + 1 and the lookup will return NULL
    or the wrong device.
    
    Fix this by replacing netdev_findbyindex with a netdev_foreach walk
    using a small callback (bluetooth_dev_byidx_callback) that counts only
    NET_LL_BLUETOOTH devices and returns the bc_ldev-th one, regardless of
    what else is registered or in what order.
    
    Signed-off-by: Stephen Fox <[email protected]>
---
 net/bluetooth/bluetooth_sendmsg.c | 53 ++++++++++++++++++++++++++++++++++++---
 1 file changed, 50 insertions(+), 3 deletions(-)

diff --git a/net/bluetooth/bluetooth_sendmsg.c 
b/net/bluetooth/bluetooth_sendmsg.c
index 20ea320a585..78744624801 100644
--- a/net/bluetooth/bluetooth_sendmsg.c
+++ b/net/bluetooth/bluetooth_sendmsg.c
@@ -75,10 +75,54 @@ 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
  ****************************************************************************/
@@ -279,10 +323,13 @@ static ssize_t bluetooth_sendto(FAR struct socket *psock,
     }
   else if (psock->s_proto == BTPROTO_HCI)
     {
-      /* TODO: should actually look among BT devices */
+      struct bluetooth_findbyidx_s match;
+      match.bf_tgt   = conn->bc_ldev;
+      match.bf_cur   = 0;
+      match.bf_radio = NULL;
 
-      radio =
-          (FAR struct radio_driver_s *)netdev_findbyindex(conn->bc_ldev + 1);
+      netdev_foreach(bluetooth_dev_byidx_callback, &match);
+      radio = match.bf_radio;
 
       if (radio == NULL)
         {

Reply via email to