diff --git a/arch/sim/src/sim/up_hcisocket.c b/arch/sim/src/sim/up_hcisocket.c index 42125bd2b4a..d68630412d0 100644 --- a/arch/sim/src/sim/up_hcisocket.c +++ b/arch/sim/src/sim/up_hcisocket.c @@ -120,8 +120,6 @@ static int bthcisock_send(FAR const struct bt_driver_s *dev, return -1; } - bt_buf_release(buf); - return buf->len; } diff --git a/wireless/bluetooth/bt_conn.c b/wireless/bluetooth/bt_conn.c index 0c13f8bb04c..0b2e628a3fd 100644 --- a/wireless/bluetooth/bt_conn.c +++ b/wireless/bluetooth/bt_conn.c @@ -180,7 +180,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); } diff --git a/wireless/bluetooth/bt_hcicore.c b/wireless/bluetooth/bt_hcicore.c index feaa5bb739c..9ce667de761 100644 --- a/wireless/bluetooth/bt_hcicore.c +++ b/wireless/bluetooth/bt_hcicore.c @@ -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); } diff --git a/wireless/bluetooth/bt_hcicore.h b/wireless/bluetooth/bt_hcicore.h index 343dfc27239..f034b5fa8e8 100644 --- a/wireless/bluetooth/bt_hcicore.h +++ b/wireless/bluetooth/bt_hcicore.h @@ -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 diff --git a/wireless/bluetooth/bt_netdev.c b/wireless/bluetooth/bt_netdev.c index 899bc0da15c..cb834ad01b0 100644 --- a/wireless/bluetooth/bt_netdev.c +++ b/wireless/bluetooth/bt_netdev.c @@ -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. */