Skip to content

Commit 990ac85

Browse files
Stephen-Fxiaoxiang781216
authored andcommitted
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 <stephenfox@geotab.com>
1 parent 89b4815 commit 990ac85

1 file changed

Lines changed: 50 additions & 3 deletions

File tree

net/bluetooth/bluetooth_sendmsg.c

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,54 @@ struct bluetooth_sendto_s
7575
ssize_t is_sent; /* The number of bytes sent (or error) */
7676
};
7777

78+
/* Used by bluetooth_dev_byidx_callback to locate the bc_ldev-th BT device */
79+
80+
struct bluetooth_findbyidx_s
81+
{
82+
uint8_t bf_tgt; /* Target index among BT devices (bc_ldev) */
83+
uint8_t bf_cur; /* Count of BT devices seen so far */
84+
FAR struct radio_driver_s *bf_radio; /* Result */
85+
};
86+
7887
/****************************************************************************
7988
* Private Functions
8089
****************************************************************************/
8190

91+
/****************************************************************************
92+
* Name: bluetooth_dev_byidx_callback
93+
*
94+
* Description:
95+
* netdev_foreach callback that finds the bf_tgt-th NET_LL_BLUETOOTH device
96+
* (0-based index among BT devices only).
97+
*
98+
* bluetooth_sendto() uses bc_ldev to identify the bound BT device, but
99+
* bc_ldev is a 0-based count among Bluetooth devices only — it bears no
100+
* fixed relationship to the global netdev interface index. Walking all
101+
* netdevs and counting only NET_LL_BLUETOOTH entries makes the lookup
102+
* independent of what other netdevs are registered and in what order.
103+
*
104+
****************************************************************************/
105+
106+
static int bluetooth_dev_byidx_callback(FAR struct net_driver_s *dev,
107+
FAR void *arg)
108+
{
109+
FAR struct bluetooth_findbyidx_s *match =
110+
(FAR struct bluetooth_findbyidx_s *)arg;
111+
112+
if (dev->d_lltype == NET_LL_BLUETOOTH)
113+
{
114+
if (match->bf_cur == match->bf_tgt)
115+
{
116+
match->bf_radio = (FAR struct radio_driver_s *)dev;
117+
return 1;
118+
}
119+
120+
match->bf_cur++;
121+
}
122+
123+
return 0;
124+
}
125+
82126
/****************************************************************************
83127
* Name: bluetooth_sendto_eventhandler
84128
****************************************************************************/
@@ -279,10 +323,13 @@ static ssize_t bluetooth_sendto(FAR struct socket *psock,
279323
}
280324
else if (psock->s_proto == BTPROTO_HCI)
281325
{
282-
/* TODO: should actually look among BT devices */
326+
struct bluetooth_findbyidx_s match;
327+
match.bf_tgt = conn->bc_ldev;
328+
match.bf_cur = 0;
329+
match.bf_radio = NULL;
283330

284-
radio =
285-
(FAR struct radio_driver_s *)netdev_findbyindex(conn->bc_ldev + 1);
331+
netdev_foreach(bluetooth_dev_byidx_callback, &match);
332+
radio = match.bf_radio;
286333

287334
if (radio == NULL)
288335
{

0 commit comments

Comments
 (0)