mirror of
https://github.com/apache/nuttx.git
synced 2025-01-13 09:49:21 +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;
|
||||
}
|
||||
|
||||
bt_buf_release(buf);
|
||||
|
||||
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);
|
||||
g_btdev.btdev->send(g_btdev.btdev, buf);
|
||||
bt_send(g_btdev.btdev, buf);
|
||||
bt_buf_release(buf);
|
||||
}
|
||||
|
||||
|
|
|
@ -124,30 +124,6 @@ static struct work_s g_hp_work;
|
|||
* 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
|
||||
*
|
||||
|
@ -354,9 +330,17 @@ static void hci_cmd_done(uint16_t opcode, uint8_t status,
|
|||
return;
|
||||
}
|
||||
|
||||
if (g_btdev.sent_cmd == NULL)
|
||||
{
|
||||
wlerr("ERROR: Request cmd missing!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -380,10 +364,8 @@ static void hci_cmd_done(uint16_t opcode, uint8_t status,
|
|||
|
||||
nxsem_post(sem);
|
||||
}
|
||||
else
|
||||
{
|
||||
bt_buf_release(sent);
|
||||
}
|
||||
|
||||
bt_buf_release(sent);
|
||||
}
|
||||
|
||||
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 = buf;
|
||||
g_btdev.sent_cmd = bt_buf_addref(buf);
|
||||
|
||||
wlinfo("Sending command %04x buf %p to driver\n",
|
||||
buf->u.hci.opcode, buf);
|
||||
|
||||
btdev->send(btdev, buf);
|
||||
bt_send(btdev, buf);
|
||||
bt_buf_release(buf);
|
||||
}
|
||||
|
||||
return EXIT_SUCCESS; /* Can't get here */
|
||||
|
@ -1104,6 +1087,7 @@ static void hci_rx_work(FAR void *arg)
|
|||
#else
|
||||
g_hci_cb->received(buf, g_hci_cb->context);
|
||||
#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);
|
||||
#endif
|
||||
bt_buf_release(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1486,6 +1471,36 @@ static void cmd_queue_init(void)
|
|||
* 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
|
||||
*
|
||||
|
@ -1731,6 +1746,15 @@ int bt_hci_cmd_send(uint16_t opcode, FAR struct bt_buf_s *buf)
|
|||
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);
|
||||
|
||||
|
@ -1774,6 +1798,10 @@ int bt_hci_cmd_send_sync(uint16_t opcode, FAR struct bt_buf_s *buf,
|
|||
return -ENOBUFS;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
bt_buf_addref(buf);
|
||||
}
|
||||
|
||||
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 the response is expected provide the sync response */
|
||||
|
||||
*rsp = buf->u.hci.sync;
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
/****************************************************************************
|
||||
* 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
|
||||
/****************************************************************************
|
||||
* Name: bt_hci_cmd_create
|
||||
|
|
|
@ -615,7 +615,6 @@ drop:
|
|||
|
||||
/* Release our reference on the buffer */
|
||||
|
||||
bt_buf_release(buf);
|
||||
net_unlock();
|
||||
}
|
||||
|
||||
|
@ -1222,7 +1221,8 @@ static int btnet_req_hci_data(FAR struct btnet_driver_s *priv,
|
|||
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. */
|
||||
|
||||
|
|
Loading…
Reference in a new issue