From 990ac856b29feca14acbc9c597477cccd5f2c1cb Mon Sep 17 00:00:00 2001 From: Stephen Fox Date: Mon, 4 May 2026 10:07:45 -0400 Subject: [PATCH] net/bluetooth: fix BTPROTO_HCI socket device lookup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- 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) {