Skip to content

Commit ce11e85

Browse files
alwa-nordiccvinayak
authored andcommitted
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 06ae8a9 commit ce11e85

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
@@ -2323,25 +2323,44 @@ static void hci_reset_complete(struct net_buf *buf)
23232323
atomic_set(bt_dev.flags, flags);
23242324
}
23252325

2326-
static void hci_cmd_done(uint16_t opcode, uint8_t status, struct net_buf *buf)
2326+
static void hci_cmd_done(uint16_t opcode, uint8_t status, struct net_buf *evt_buf)
23272327
{
2328-
LOG_DBG("opcode 0x%04x status 0x%02x buf %p", opcode, status, buf);
2328+
/* Original command buffer. */
2329+
struct net_buf *buf = NULL;
23292330

2330-
if (net_buf_pool_get(buf->pool_id) != &hci_cmd_pool) {
2331-
LOG_WRN("opcode 0x%04x pool id %u pool %p != &hci_cmd_pool %p", opcode,
2332-
buf->pool_id, net_buf_pool_get(buf->pool_id), &hci_cmd_pool);
2333-
return;
2331+
LOG_DBG("opcode 0x%04x status 0x%02x buf %p", opcode, status, evt_buf);
2332+
2333+
/* Unsolicited cmd complete. This does not complete a command.
2334+
* The controller can send these for effect of the `ncmd` field.
2335+
*/
2336+
if (opcode == 0) {
2337+
goto exit;
2338+
}
2339+
2340+
/* Take the original command buffer reference. */
2341+
buf = atomic_ptr_clear((atomic_ptr_t *)&bt_dev.sent_cmd);
2342+
2343+
if (!buf) {
2344+
LOG_ERR("No command sent for cmd complete 0x%04x", opcode);
2345+
goto exit;
23342346
}
23352347

23362348
if (cmd(buf)->opcode != opcode) {
2337-
LOG_WRN("OpCode 0x%04x completed instead of expected 0x%04x", opcode,
2349+
LOG_ERR("OpCode 0x%04x completed instead of expected 0x%04x", opcode,
23382350
cmd(buf)->opcode);
2339-
return;
2351+
buf = atomic_ptr_set((atomic_ptr_t *)&bt_dev.sent_cmd, buf);
2352+
__ASSERT_NO_MSG(!buf);
2353+
goto exit;
23402354
}
23412355

2342-
if (bt_dev.sent_cmd) {
2343-
net_buf_unref(bt_dev.sent_cmd);
2344-
bt_dev.sent_cmd = NULL;
2356+
/* Response data is to be delivered in the original command
2357+
* buffer.
2358+
*/
2359+
if (evt_buf != buf) {
2360+
net_buf_reset(buf);
2361+
bt_buf_set_type(buf, BT_BUF_EVT);
2362+
net_buf_reserve(buf, BT_BUF_RESERVE);
2363+
net_buf_add_mem(buf, evt_buf->data, evt_buf->len);
23452364
}
23462365

23472366
if (cmd(buf)->state && !status) {
@@ -2355,6 +2374,11 @@ static void hci_cmd_done(uint16_t opcode, uint8_t status, struct net_buf *buf)
23552374
cmd(buf)->status = status;
23562375
k_sem_give(cmd(buf)->sync);
23572376
}
2377+
2378+
exit:
2379+
if (buf) {
2380+
net_buf_unref(buf);
2381+
}
23582382
}
23592383

23602384
static void hci_cmd_complete(struct net_buf *buf)

0 commit comments

Comments
 (0)