Skip to content

Bluetooth: HCI: Use H:4 encoding for buffers #88710

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 6 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions doc/releases/migration-guide-4.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,14 @@ Bluetooth Audio
* ``CONFIG_BT_CSIP_SET_MEMBER_NOTIFIABLE`` has been renamed to
:kconfig:option:`CONFIG_BT_CSIP_SET_MEMBER_SIRK_NOTIFIABLE``. (:github:`86763``)

Bluetooth HCI
=============

* The buffer types passing through the HCI driver interface are now indicated as H:4 encoded prefix
bytes as part of the buffer payload itself. The bt_buf_set_type() and bt_buf_get_type() functions
have been deprecated, but are still usable, with the exception that they can only be
called once per buffer.

Bluetooth Host
==============

Expand Down
36 changes: 1 addition & 35 deletions drivers/bluetooth/hci/h4.c
Original file line number Diff line number Diff line change
Expand Up @@ -348,12 +348,6 @@ static inline void read_payload(const struct device *dev)
buf = h4->rx.buf;
h4->rx.buf = NULL;

if (h4->rx.type == BT_HCI_H4_EVT) {
bt_buf_set_type(buf, BT_BUF_EVT);
} else {
bt_buf_set_type(buf, BT_BUF_ACL_IN);
}

reset_rx(h4);

LOG_DBG("Putting buf %p to rx fifo", buf);
Expand Down Expand Up @@ -411,33 +405,6 @@ static inline void process_tx(const struct device *dev)
}
}

if (!h4->tx.type) {
switch (bt_buf_get_type(h4->tx.buf)) {
case BT_BUF_ACL_OUT:
h4->tx.type = BT_HCI_H4_ACL;
break;
case BT_BUF_CMD:
h4->tx.type = BT_HCI_H4_CMD;
break;
case BT_BUF_ISO_OUT:
if (IS_ENABLED(CONFIG_BT_ISO)) {
h4->tx.type = BT_HCI_H4_ISO;
break;
}
__fallthrough;
default:
LOG_ERR("Unknown buffer type");
goto done;
}

bytes = uart_fifo_fill(cfg->uart, &h4->tx.type, 1);
if (bytes != 1) {
LOG_WRN("Unable to send H:4 type");
h4->tx.type = BT_HCI_H4_NONE;
return;
}
}

bytes = uart_fifo_fill(cfg->uart, h4->tx.buf->data, h4->tx.buf->len);
if (unlikely(bytes < 0)) {
LOG_ERR("Unable to write to UART (err %d)", bytes);
Expand All @@ -449,7 +416,6 @@ static inline void process_tx(const struct device *dev)
return;
}

done:
h4->tx.type = BT_HCI_H4_NONE;
net_buf_unref(h4->tx.buf);
h4->tx.buf = k_fifo_get(&h4->tx.fifo, K_NO_WAIT);
Expand Down Expand Up @@ -499,7 +465,7 @@ static int h4_send(const struct device *dev, struct net_buf *buf)
const struct h4_config *cfg = dev->config;
struct h4_data *h4 = dev->data;

LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);
LOG_DBG("buf %p type %u len %u", buf, buf->data[0], buf->len);

k_fifo_put(&h4->tx.fifo, buf);
uart_irq_tx_enable(cfg->uart);
Expand Down
20 changes: 1 addition & 19 deletions drivers/bluetooth/hci/h5.c
Original file line number Diff line number Diff line change
Expand Up @@ -598,26 +598,8 @@ static uint8_t h5_get_type(struct net_buf *buf)
static int h5_queue(const struct device *dev, struct net_buf *buf)
{
struct h5_data *h5 = dev->data;
uint8_t type;

LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);

switch (bt_buf_get_type(buf)) {
case BT_BUF_CMD:
type = HCI_COMMAND_PKT;
break;
case BT_BUF_ACL_OUT:
type = HCI_ACLDATA_PKT;
break;
case BT_BUF_ISO_OUT:
type = HCI_ISODATA_PKT;
break;
default:
LOG_ERR("Unknown packet type %u", bt_buf_get_type(buf));
return -1;
}

memcpy(net_buf_push(buf, sizeof(type)), &type, sizeof(type));
LOG_DBG("buf %p type %u len %u", buf, buf->data[0], buf->len);

k_fifo_put(&h5->tx_queue, buf);

Expand Down
18 changes: 2 additions & 16 deletions drivers/bluetooth/hci/hci_ambiq.c
Original file line number Diff line number Diff line change
Expand Up @@ -344,27 +344,13 @@ static void bt_spi_rx_thread(void *p1, void *p2, void *p3)

static int bt_apollo_send(const struct device *dev, struct net_buf *buf)
{
int ret = 0;
int ret;

/* Buffer needs an additional byte for type */
if (buf->len >= SPI_MAX_TX_MSG_LEN) {
if (buf->len > SPI_MAX_TX_MSG_LEN) {
LOG_ERR("Message too long");
return -EINVAL;
}

switch (bt_buf_get_type(buf)) {
case BT_BUF_ACL_OUT:
net_buf_push_u8(buf, BT_HCI_H4_ACL);
break;
case BT_BUF_CMD:
net_buf_push_u8(buf, BT_HCI_H4_CMD);
break;
default:
LOG_ERR("Unsupported type");
net_buf_unref(buf);
return -EINVAL;
}

/* Send the SPI packet */
ret = spi_send_packet(buf->data, buf->len);

Expand Down
20 changes: 0 additions & 20 deletions drivers/bluetooth/hci/hci_da1469x.c
Original file line number Diff line number Diff line change
Expand Up @@ -330,12 +330,6 @@ static inline void read_payload(void)
buf = rx.buf;
rx.buf = NULL;

if (rx.type == BT_HCI_H4_EVT) {
bt_buf_set_type(buf, BT_BUF_EVT);
} else {
bt_buf_set_type(buf, BT_BUF_ACL_IN);
}

reset_rx();

LOG_DBG("Putting buf %p to rx fifo", buf);
Expand Down Expand Up @@ -474,20 +468,6 @@ static int bt_da1469x_send(const struct device *dev, struct net_buf *buf)
{
ARG_UNUSED(dev);

switch (bt_buf_get_type(buf)) {
case BT_BUF_ACL_OUT:
LOG_DBG("ACL: buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);
net_buf_push_u8(buf, BT_HCI_H4_ACL);
break;
case BT_BUF_CMD:
LOG_DBG("CMD: buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);
net_buf_push_u8(buf, BT_HCI_H4_CMD);
break;
default:
LOG_ERR("Unsupported type");
return -EINVAL;
}

cmac_mbox_write(buf->data, buf->len);

net_buf_unref(buf);
Expand Down
20 changes: 1 addition & 19 deletions drivers/bluetooth/hci/hci_esp32.c
Original file line number Diff line number Diff line change
Expand Up @@ -237,25 +237,8 @@ static esp_vhci_host_callback_t vhci_host_cb = {
static int bt_esp32_send(const struct device *dev, struct net_buf *buf)
{
int err = 0;
uint8_t pkt_indicator;

LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);

switch (bt_buf_get_type(buf)) {
case BT_BUF_ACL_OUT:
pkt_indicator = BT_HCI_H4_ACL;
break;
case BT_BUF_CMD:
pkt_indicator = BT_HCI_H4_CMD;
break;
case BT_BUF_ISO_OUT:
pkt_indicator = BT_HCI_H4_ISO;
break;
default:
LOG_ERR("Unknown type %u", bt_buf_get_type(buf));
goto done;
}
net_buf_push_u8(buf, pkt_indicator);
LOG_DBG("buf %p type %u len %u", buf, buf->data[0], buf->len);

LOG_HEXDUMP_DBG(buf->data, buf->len, "Final HCI buffer:");

Expand All @@ -270,7 +253,6 @@ static int bt_esp32_send(const struct device *dev, struct net_buf *buf)
err = -ETIMEDOUT;
}

done:
net_buf_unref(buf);
k_sem_give(&hci_send_sem);

Expand Down
17 changes: 10 additions & 7 deletions drivers/bluetooth/hci/hci_ifx_cyw208xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -257,32 +257,36 @@ static int cyw208xx_close(const struct device *dev)

static int cyw208xx_send(const struct device *dev, struct net_buf *buf)
{
uint8_t type;

ARG_UNUSED(dev);

int ret = 0;

k_sem_take(&hci_sem, K_FOREVER);

LOG_DBG("buf %p type %u len %u", buf, bt_buf_get_type(buf), buf->len);
type = net_buf_pull_u8(buf);

LOG_DBG("buf %p type %u len %u", buf, type, buf->len);

switch (bt_buf_get_type(buf)) {
case BT_BUF_ACL_OUT:
switch (type) {
case BT_HCI_H4_ACL:
uint8_t *bt_msg = host_stack_get_acl_to_lower_buffer(BT_TRANSPORT_LE, buf->len);

memcpy(bt_msg, buf->data, buf->len);
ret = host_stack_send_acl_to_lower(BT_TRANSPORT_LE, bt_msg, buf->len);
break;

case BT_BUF_CMD:
case BT_HCI_H4_CMD:
ret = host_stack_send_cmd_to_lower(buf->data, buf->len);
break;

case BT_BUF_ISO_OUT:
case BT_HCI_H4_ISO:
ret = host_stack_send_iso_to_lower(buf->data, buf->len);
break;

default:
LOG_ERR("Unknown type %u", bt_buf_get_type(buf));
LOG_ERR("Unknown type %u", type);
ret = EIO;
goto done;
}
Expand Down Expand Up @@ -376,7 +380,6 @@ void wiced_bt_process_hci(hci_packet_type_t pti, uint8_t *data, uint32_t length)
LOG_ERR("Failed to allocate the buffer for RX: ACL ");
return;
}
bt_buf_set_type(buf, BT_BUF_ACL_IN);
break;

case HCI_PACKET_TYPE_SCO:
Expand Down
15 changes: 1 addition & 14 deletions drivers/bluetooth/hci/hci_ifx_psoc6_bless.c
Original file line number Diff line number Diff line change
Expand Up @@ -126,10 +126,8 @@ static void psoc6_bless_events_handler(uint32_t eventCode, void *eventParam)
LOG_ERR("Failed to allocate the buffer for RX: ACL ");
return;
}
bt_buf_set_type(buf, BT_BUF_ACL_IN);

break;

default:
LOG_WRN("Unsupported HCI Packet Received");
return;
Expand Down Expand Up @@ -168,21 +166,10 @@ static int psoc6_bless_send(const struct device *dev, struct net_buf *buf)

memset(&hci_tx_pkt, 0, sizeof(cy_stc_ble_hci_tx_packet_info_t));

hci_tx_pkt.packetType = net_buf_pull_u8(buf);
hci_tx_pkt.dataLength = buf->len;
hci_tx_pkt.data = buf->data;

switch (bt_buf_get_type(buf)) {
case BT_BUF_ACL_OUT:
hci_tx_pkt.packetType = BT_HCI_H4_ACL;
break;
case BT_BUF_CMD:
hci_tx_pkt.packetType = BT_HCI_H4_CMD;
break;
default:
net_buf_unref(buf);
return -ENOTSUP;
}

if (k_sem_take(&psoc6_bless_operation_sem, K_MSEC(BLE_LOCK_TMOUT_MS)) != 0) {
LOG_ERR("Failed to acquire BLE DRV Semaphore");
net_buf_unref(buf);
Expand Down
15 changes: 0 additions & 15 deletions drivers/bluetooth/hci/hci_nxp.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,23 +403,8 @@ static void hci_rx_cb(uint8_t packetType, uint8_t *data, uint16_t len)

static int bt_nxp_send(const struct device *dev, struct net_buf *buf)
{
uint8_t packetType;

ARG_UNUSED(dev);

switch (bt_buf_get_type(buf)) {
case BT_BUF_CMD:
packetType = BT_HCI_H4_CMD;
break;
case BT_BUF_ACL_OUT:
packetType = BT_HCI_H4_ACL;
break;
default:
LOG_ERR("Not supported type");
return -1;
}

net_buf_push_u8(buf, packetType);
#if defined(HCI_NXP_LOCK_STANDBY_BEFORE_SEND)
/* Sending an HCI message requires to wake up the controller core if it's asleep.
* Platform controllers may send reponses using non wakeable interrupts which can
Expand Down
18 changes: 1 addition & 17 deletions drivers/bluetooth/hci/hci_silabs_efr32.c
Original file line number Diff line number Diff line change
Expand Up @@ -195,28 +195,12 @@ uint32_t hci_common_transport_transmit(uint8_t *data, int16_t len)

static int slz_bt_send(const struct device *dev, struct net_buf *buf)
{
int rv = 0;
int rv;

ARG_UNUSED(dev);

switch (bt_buf_get_type(buf)) {
case BT_BUF_ACL_OUT:
net_buf_push_u8(buf, BT_HCI_H4_ACL);
break;
case BT_BUF_CMD:
net_buf_push_u8(buf, BT_HCI_H4_CMD);
break;
default:
rv = -EINVAL;
goto done;
}

rv = hci_common_transport_receive(buf->data, buf->len, true);
if (!rv) {
goto done;
}

done:
net_buf_unref(buf);
return rv;
}
Expand Down
16 changes: 1 addition & 15 deletions drivers/bluetooth/hci/hci_silabs_siwx91x.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,22 +36,8 @@ static int siwx91x_bt_send(const struct device *dev, struct net_buf *buf)
{
struct hci_data *hci = dev->data;
int sc = -EOVERFLOW;
uint8_t packet_type = BT_HCI_H4_NONE;

switch (bt_buf_get_type(buf)) {
case BT_BUF_ACL_OUT:
packet_type = BT_HCI_H4_ACL;
break;
case BT_BUF_CMD:
packet_type = BT_HCI_H4_CMD;
break;
default:
sc = -EINVAL;
break;
}

if ((packet_type != BT_HCI_H4_NONE) && (buf->len < sizeof(hci->rsi_data_packet.data))) {
net_buf_push_u8(buf, packet_type);
if (buf->len < sizeof(hci->rsi_data_packet.data)) {
memcpy(&hci->rsi_data_packet, buf->data, buf->len);
sc = rsi_bt_driver_send_cmd(RSI_BLE_REQ_HCI_RAW, &hci->rsi_data_packet, NULL);
/* TODO SILABS ZEPHYR Convert to errno. A common function from rsi/sl_status should
Expand Down
17 changes: 0 additions & 17 deletions drivers/bluetooth/hci/hci_spi_st.c
Original file line number Diff line number Diff line change
Expand Up @@ -569,23 +569,6 @@ static int bt_spi_send(const struct device *dev, struct net_buf *buf)
return -EINVAL;
}

switch (bt_buf_get_type(buf)) {
case BT_BUF_ACL_OUT:
net_buf_push_u8(buf, BT_HCI_H4_ACL);
break;
case BT_BUF_CMD:
net_buf_push_u8(buf, BT_HCI_H4_CMD);
break;
#if defined(CONFIG_BT_ISO)
case BT_BUF_ISO_OUT:
net_buf_push_u8(buf, BT_HCI_H4_ISO);
break;
#endif /* CONFIG_BT_ISO */
default:
LOG_ERR("Unsupported type");
return -EINVAL;
}

/* Wait for SPI bus to be available */
k_sem_take(&sem_busy, K_FOREVER);
data_ptr = buf->data;
Expand Down
Loading