Skip to content

Commit b462852

Browse files
alwa-nordiccvinayak
authored andcommitted
[nrf fromtree] Bluetooth: Host: Remove use of bt_buf_get_cmd_complete
`bt_buf_get_cmd_complete` is broken due to zephyrproject-rtos/zephyr#64158, and fixing it would require changing its signature and put even more complexity into the HCI drivers, as it would require the drivers to perform an even deeper peek into the event in order to observe the opcode. Instead of the above, this patch removes the use of `bt_buf_get_cmd_complete` and adds logic to allow the host to accept command complete events in normal event buffers. The above means performing a copy into the destination buffer, which is the original command buffer. This is a small inefficiency for now, but we should strive to redesign the host into a streaming architecture as much as possible and handle events immediately instead of retaining buffers. This fixes zephyrproject-rtos/zephyr#64158: Like all command completed events, the completion event for `BT_HCI_OP_HOST_NUM_COMPLETED_PACKETS` is now placed in normal event buffers. The the logic where the host discards this event is already present. Since it's discarded, it will not interfere with the logic around `bt_dev.cmd_send`. Signed-off-by: Aleksander Wasaznik <[email protected]> (cherry picked from commit 1cb83a8) Signed-off-by: Vinayak Kariappa Chettimada <[email protected]>
1 parent d170de6 commit b462852

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

subsys/bluetooth/host/buf.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,6 @@ struct net_buf *bt_buf_get_evt(uint8_t evt, bool discardable,
120120
return buf;
121121
}
122122
#endif /* CONFIG_BT_CONN || CONFIG_BT_ISO */
123-
case BT_HCI_EVT_CMD_COMPLETE:
124-
case BT_HCI_EVT_CMD_STATUS:
125-
return bt_buf_get_cmd_complete(timeout);
126123
default:
127124
if (discardable) {
128125
struct net_buf *buf;

subsys/bluetooth/host/hci_core.c

Lines changed: 35 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2304,25 +2304,44 @@ static void hci_reset_complete(struct net_buf *buf)
23042304
atomic_set(bt_dev.flags, flags);
23052305
}
23062306

2307-
static void hci_cmd_done(uint16_t opcode, uint8_t status, struct net_buf *buf)
2307+
static void hci_cmd_done(uint16_t opcode, uint8_t status, struct net_buf *evt_buf)
23082308
{
2309-
LOG_DBG("opcode 0x%04x status 0x%02x buf %p", opcode, status, buf);
2309+
/* Original command buffer. */
2310+
struct net_buf *buf = NULL;
23102311

2311-
if (net_buf_pool_get(buf->pool_id) != &hci_cmd_pool) {
2312-
LOG_WRN("opcode 0x%04x pool id %u pool %p != &hci_cmd_pool %p", opcode,
2313-
buf->pool_id, net_buf_pool_get(buf->pool_id), &hci_cmd_pool);
2314-
return;
2312+
LOG_DBG("opcode 0x%04x status 0x%02x buf %p", opcode, status, evt_buf);
2313+
2314+
/* Unsolicited cmd complete. This does not complete a command.
2315+
* The controller can send these for effect of the `ncmd` field.
2316+
*/
2317+
if (opcode == 0) {
2318+
goto exit;
2319+
}
2320+
2321+
/* Take the original command buffer reference. */
2322+
buf = atomic_ptr_clear((atomic_ptr_t *)&bt_dev.sent_cmd);
2323+
2324+
if (!buf) {
2325+
LOG_ERR("No command sent for cmd complete 0x%04x", opcode);
2326+
goto exit;
23152327
}
23162328

23172329
if (cmd(buf)->opcode != opcode) {
2318-
LOG_WRN("OpCode 0x%04x completed instead of expected 0x%04x", opcode,
2330+
LOG_ERR("OpCode 0x%04x completed instead of expected 0x%04x", opcode,
23192331
cmd(buf)->opcode);
2320-
return;
2332+
buf = atomic_ptr_set((atomic_ptr_t *)&bt_dev.sent_cmd, buf);
2333+
__ASSERT_NO_MSG(!buf);
2334+
goto exit;
23212335
}
23222336

2323-
if (bt_dev.sent_cmd) {
2324-
net_buf_unref(bt_dev.sent_cmd);
2325-
bt_dev.sent_cmd = NULL;
2337+
/* Response data is to be delivered in the original command
2338+
* buffer.
2339+
*/
2340+
if (evt_buf != buf) {
2341+
net_buf_reset(buf);
2342+
bt_buf_set_type(buf, BT_BUF_EVT);
2343+
net_buf_reserve(buf, BT_BUF_RESERVE);
2344+
net_buf_add_mem(buf, evt_buf->data, evt_buf->len);
23262345
}
23272346

23282347
if (cmd(buf)->state && !status) {
@@ -2336,6 +2355,11 @@ static void hci_cmd_done(uint16_t opcode, uint8_t status, struct net_buf *buf)
23362355
cmd(buf)->status = status;
23372356
k_sem_give(cmd(buf)->sync);
23382357
}
2358+
2359+
exit:
2360+
if (buf) {
2361+
net_buf_unref(buf);
2362+
}
23392363
}
23402364

23412365
static void hci_cmd_complete(struct net_buf *buf)

0 commit comments

Comments
 (0)