mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 13:18:50 +08:00
Bluetooth: Fix bt_buff lifecycle
Signed-off-by: Brennan Ashton <bashton@brennanashton.com>
This commit is contained in:
parent
ec73a4e69c
commit
c6947199b2
5 changed files with 90 additions and 36 deletions
|
@ -120,8 +120,6 @@ static int bthcisock_send(FAR const struct bt_driver_s *dev,
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
bt_buf_release(buf);
|
|
||||||
|
|
||||||
return buf->len;
|
return buf->len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -178,7 +178,7 @@ static int conn_tx_kthread(int argc, FAR char *argv[])
|
||||||
}
|
}
|
||||||
|
|
||||||
wlinfo("passing buf %p len %u to driver\n", buf, buf->len);
|
wlinfo("passing buf %p len %u to driver\n", buf, buf->len);
|
||||||
g_btdev.btdev->send(g_btdev.btdev, buf);
|
bt_send(g_btdev.btdev, buf);
|
||||||
bt_buf_release(buf);
|
bt_buf_release(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -124,30 +124,6 @@ static struct work_s g_hp_work;
|
||||||
* Private Functions
|
* Private Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Name: bt_send
|
|
||||||
*
|
|
||||||
* Description:
|
|
||||||
* Add the provided buffer 'buf' to the head selected buffer list 'list'
|
|
||||||
*
|
|
||||||
* Input Parameters:
|
|
||||||
* btdev - An instance of the low-level drivers interface structure.
|
|
||||||
* buf - The buffer to be sent by the driver
|
|
||||||
*
|
|
||||||
* Returned Value:
|
|
||||||
* Zero is returned on success; a negated errno value is returned on any
|
|
||||||
* failure.
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
static int bt_send(FAR const struct bt_driver_s *btdev,
|
|
||||||
FAR struct bt_buf_s *buf)
|
|
||||||
{
|
|
||||||
/* TODDO: Hook here to notify hci monitor */
|
|
||||||
|
|
||||||
return btdev->send(btdev, buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: bt_enqueue_bufwork
|
* Name: bt_enqueue_bufwork
|
||||||
*
|
*
|
||||||
|
@ -354,9 +330,17 @@ static void hci_cmd_done(uint16_t opcode, uint8_t status,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (g_btdev.sent_cmd == NULL)
|
||||||
|
{
|
||||||
|
wlerr("ERROR: Request cmd missing!\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (g_btdev.sent_cmd->u.hci.opcode != opcode)
|
if (g_btdev.sent_cmd->u.hci.opcode != opcode)
|
||||||
{
|
{
|
||||||
wlerr("ERROR: Unexpected completion of opcode 0x%04x\n", opcode);
|
wlerr("ERROR: Unexpected completion of opcode 0x%04x " \
|
||||||
|
"expected 0x%04x\n",
|
||||||
|
opcode, g_btdev.sent_cmd->u.hci.opcode);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -380,10 +364,8 @@ static void hci_cmd_done(uint16_t opcode, uint8_t status,
|
||||||
|
|
||||||
nxsem_post(sem);
|
nxsem_post(sem);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
bt_buf_release(sent);
|
||||||
bt_buf_release(sent);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void hci_cmd_complete(FAR struct bt_buf_s *buf)
|
static void hci_cmd_complete(FAR struct bt_buf_s *buf)
|
||||||
|
@ -1045,12 +1027,13 @@ static int hci_tx_kthread(int argc, FAR char *argv[])
|
||||||
g_btdev.sent_cmd = NULL;
|
g_btdev.sent_cmd = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_btdev.sent_cmd = buf;
|
g_btdev.sent_cmd = bt_buf_addref(buf);
|
||||||
|
|
||||||
wlinfo("Sending command %04x buf %p to driver\n",
|
wlinfo("Sending command %04x buf %p to driver\n",
|
||||||
buf->u.hci.opcode, buf);
|
buf->u.hci.opcode, buf);
|
||||||
|
|
||||||
btdev->send(btdev, buf);
|
bt_send(btdev, buf);
|
||||||
|
bt_buf_release(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
return EXIT_SUCCESS; /* Can't get here */
|
return EXIT_SUCCESS; /* Can't get here */
|
||||||
|
@ -1104,6 +1087,7 @@ static void hci_rx_work(FAR void *arg)
|
||||||
#else
|
#else
|
||||||
g_hci_cb->received(buf, g_hci_cb->context);
|
g_hci_cb->received(buf, g_hci_cb->context);
|
||||||
#endif
|
#endif
|
||||||
|
bt_buf_release(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1171,6 +1155,7 @@ static void priority_rx_work(FAR void *arg)
|
||||||
|
|
||||||
g_hci_cb->received(buf, g_hci_cb->context);
|
g_hci_cb->received(buf, g_hci_cb->context);
|
||||||
#endif
|
#endif
|
||||||
|
bt_buf_release(buf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1486,6 +1471,36 @@ static void cmd_queue_init(void)
|
||||||
* Public Functions
|
* Public Functions
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: bt_send
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Send the provided buffer to the bluetooth driver
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* btdev - An instance of the low-level drivers interface structure.
|
||||||
|
* buf - The buffer to be sent by the driver
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero is returned on success; a negated errno value is returned on any
|
||||||
|
* failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int bt_send(FAR const struct bt_driver_s *btdev,
|
||||||
|
FAR struct bt_buf_s *buf)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
/* Send to driver */
|
||||||
|
|
||||||
|
ret = btdev->send(btdev, buf);
|
||||||
|
|
||||||
|
/* TODO: Hook here to notify hci monitor */
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: bt_initialize
|
* Name: bt_initialize
|
||||||
*
|
*
|
||||||
|
@ -1731,6 +1746,15 @@ int bt_hci_cmd_send(uint16_t opcode, FAR struct bt_buf_s *buf)
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* We manage the refcount the same for supplied and created
|
||||||
|
* buffers so increment the supplied count so we can manage
|
||||||
|
* it as-if we crated it.
|
||||||
|
*/
|
||||||
|
|
||||||
|
bt_buf_addref(buf);
|
||||||
|
}
|
||||||
|
|
||||||
wlinfo("opcode %04x len %u\n", opcode, buf->len);
|
wlinfo("opcode %04x len %u\n", opcode, buf->len);
|
||||||
|
|
||||||
|
@ -1774,6 +1798,10 @@ int bt_hci_cmd_send_sync(uint16_t opcode, FAR struct bt_buf_s *buf,
|
||||||
return -ENOBUFS;
|
return -ENOBUFS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bt_buf_addref(buf);
|
||||||
|
}
|
||||||
|
|
||||||
wlinfo("opcode %04x len %u\n", opcode, buf->len);
|
wlinfo("opcode %04x len %u\n", opcode, buf->len);
|
||||||
|
|
||||||
|
@ -1850,12 +1878,21 @@ int bt_hci_cmd_send_sync(uint16_t opcode, FAR struct bt_buf_s *buf,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Note: if ret < 0 the packet might just be delayed and could still
|
||||||
|
* be sent. We cannot decrease the ref count since it if it was sent
|
||||||
|
* it buf could be pointed a completely different request.
|
||||||
|
*/
|
||||||
|
|
||||||
if (rsp != NULL)
|
if (rsp != NULL)
|
||||||
{
|
{
|
||||||
|
/* If the response is expected provide the sync response */
|
||||||
|
|
||||||
*rsp = buf->u.hci.sync;
|
*rsp = buf->u.hci.sync;
|
||||||
}
|
}
|
||||||
else if (buf->u.hci.sync != NULL)
|
else if (buf->u.hci.sync != NULL)
|
||||||
{
|
{
|
||||||
|
/* If a sync response was given but not requested drop it */
|
||||||
|
|
||||||
bt_buf_release(buf->u.hci.sync);
|
bt_buf_release(buf->u.hci.sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -302,6 +302,25 @@ int bt_driver_register(FAR const struct bt_driver_s *btdev);
|
||||||
|
|
||||||
void bt_driver_unregister(FAR const struct bt_driver_s *btdev);
|
void bt_driver_unregister(FAR const struct bt_driver_s *btdev);
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* Name: bt_send
|
||||||
|
*
|
||||||
|
* Description:
|
||||||
|
* Add the provided buffer 'buf' to the head selected buffer list 'list'
|
||||||
|
*
|
||||||
|
* Input Parameters:
|
||||||
|
* btdev - An instance of the low-level drivers interface structure.
|
||||||
|
* buf - The buffer to be sent by the driver
|
||||||
|
*
|
||||||
|
* Returned Value:
|
||||||
|
* Zero is returned on success; a negated errno value is returned on any
|
||||||
|
* failure.
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
|
||||||
|
int bt_send(FAR const struct bt_driver_s *btdev,
|
||||||
|
FAR struct bt_buf_s *buf);
|
||||||
|
|
||||||
#ifdef CONFIG_WIRELESS_BLUETOOTH_HOST
|
#ifdef CONFIG_WIRELESS_BLUETOOTH_HOST
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Name: bt_hci_cmd_create
|
* Name: bt_hci_cmd_create
|
||||||
|
|
|
@ -615,7 +615,6 @@ drop:
|
||||||
|
|
||||||
/* Release our reference on the buffer */
|
/* Release our reference on the buffer */
|
||||||
|
|
||||||
bt_buf_release(buf);
|
|
||||||
net_unlock();
|
net_unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1222,7 +1221,8 @@ static int btnet_req_hci_data(FAR struct btnet_driver_s *priv,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
g_btdev.btdev->send(g_btdev.btdev, buf);
|
bt_send(g_btdev.btdev, buf);
|
||||||
|
bt_buf_release(buf);
|
||||||
|
|
||||||
/* Transfer the frame to the Bluetooth stack. */
|
/* Transfer the frame to the Bluetooth stack. */
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue