diff --git a/drivers/bluetooth/hci/h4.c b/drivers/bluetooth/hci/h4.c index 7ecbd20ebbb..77942b479aa 100644 --- a/drivers/bluetooth/hci/h4.c +++ b/drivers/bluetooth/hci/h4.c @@ -154,7 +154,8 @@ static inline void get_evt_hdr(void) if (!rx.remaining) { if (rx.evt.evt == BT_HCI_EVT_LE_META_EVENT && - rx.hdr[sizeof(*hdr)] == BT_HCI_EVT_LE_ADVERTISING_REPORT) { + (rx.hdr[sizeof(*hdr)] == BT_HCI_EVT_LE_ADVERTISING_REPORT || + rx.hdr[sizeof(*hdr)] == BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT)) { BT_DBG("Marking adv report as discardable"); rx.discardable = true; } diff --git a/drivers/bluetooth/hci/ipm_stm32wb.c b/drivers/bluetooth/hci/ipm_stm32wb.c index 75d7a56a2a9..7df8310fdc3 100644 --- a/drivers/bluetooth/hci/ipm_stm32wb.c +++ b/drivers/bluetooth/hci/ipm_stm32wb.c @@ -152,10 +152,13 @@ void TM_EvtReceivedCb(TL_EvtPacket_t *hcievt) static void bt_ipm_rx_thread(void) { while (true) { + bool discardable = false; + k_timeout_t timeout = K_FOREVER; static TL_EvtPacket_t *hcievt; struct net_buf *buf = NULL; struct bt_hci_acl_hdr acl_hdr; TL_AclDataSerial_t *acl; + struct bt_hci_evt_le_meta_event *mev; hcievt = k_fifo_get(&ipm_rx_events_fifo, K_FOREVER); @@ -173,10 +176,23 @@ static void bt_ipm_rx_thread(void) TL_MM_EvtDone(hcievt); goto end_loop; default: + mev = (void *)&hcievt->evtserial.evt.payload; + if (hcievt->evtserial.evt.evtcode == BT_HCI_EVT_LE_META_EVENT && + (mev->subevent == BT_HCI_EVT_LE_ADVERTISING_REPORT || + mev->subevent == BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT)) { + discardable = true; + timeout = K_NO_WAIT; + } + buf = bt_buf_get_evt( hcievt->evtserial.evt.evtcode, - false, K_FOREVER); + discardable, timeout); + if (!buf) { + BT_DBG("Discard adv report due to insufficient buf"); + goto end_loop; + } } + tryfix_event(&hcievt->evtserial.evt); net_buf_add_mem(buf, &hcievt->evtserial.evt, hcievt->evtserial.evt.plen + 2); diff --git a/drivers/bluetooth/hci/rpmsg.c b/drivers/bluetooth/hci/rpmsg.c index 4789aa7aeca..786f701922b 100644 --- a/drivers/bluetooth/hci/rpmsg.c +++ b/drivers/bluetooth/hci/rpmsg.c @@ -39,6 +39,8 @@ static bool is_hci_event_discardable(const uint8_t *evt_data) switch (subevt_type) { case BT_HCI_EVT_LE_ADVERTISING_REPORT: return true; + case BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT: + return true; default: return false; } diff --git a/drivers/bluetooth/hci/spi.c b/drivers/bluetooth/hci/spi.c index 2fccd5cb77e..d7b5e8ea1b0 100644 --- a/drivers/bluetooth/hci/spi.c +++ b/drivers/bluetooth/hci/spi.c @@ -307,6 +307,8 @@ static int bt_spi_send_aci_config_data_controller_mode(void) static void bt_spi_rx_thread(void) { + bool discardable = false; + k_timeout_t timeout = K_FOREVER; struct net_buf *buf; uint8_t header_master[5] = { SPI_READ, 0x00, 0x00, 0x00, 0x00 }; uint8_t header_slave[5]; @@ -367,9 +369,19 @@ static void bt_spi_rx_thread(void) bt_spi_handle_vendor_evt(rxmsg); continue; default: + if (rxmsg[1] == BT_HCI_EVT_LE_META_EVENT && + (rxmsg[3] == BT_HCI_EVT_LE_ADVERTISING_REPORT || + rxmsg[3] == BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT)) { + discardable = true; + timeout = K_NO_WAIT; + } + buf = bt_buf_get_evt(rxmsg[EVT_HEADER_EVENT], - false, K_FOREVER); - break; + discardable, timeout); + if (!buf) { + BT_DBG("Discard adv report due to insufficient buf"); + continue; + } } net_buf_add_mem(buf, &rxmsg[1], diff --git a/drivers/bluetooth/hci/userchan.c b/drivers/bluetooth/hci/userchan.c index 7039bdfa75c..26fb4668b0e 100644 --- a/drivers/bluetooth/hci/userchan.c +++ b/drivers/bluetooth/hci/userchan.c @@ -58,9 +58,19 @@ static int bt_dev_index = -1; static struct net_buf *get_rx(const uint8_t *buf) { + bool discardable = false; + k_timeout_t timeout = K_FOREVER; + switch (buf[0]) { case H4_EVT: - return bt_buf_get_evt(buf[1], false, K_FOREVER); + if (buf[1] == BT_HCI_EVT_LE_META_EVENT && + (buf[3] == BT_HCI_EVT_LE_ADVERTISING_REPORT || + buf[3] == BT_HCI_EVT_LE_EXT_ADVERTISING_REPORT)) { + discardable = true; + timeout = K_NO_WAIT; + } + + return bt_buf_get_evt(buf[1], discardable, timeout); case H4_ACL: return bt_buf_get_rx(BT_BUF_ACL_IN, K_FOREVER); case H4_ISO: @@ -116,6 +126,11 @@ static void rx_thread(void *p1, void *p2, void *p3) } buf = get_rx(frame); + if (!buf) { + BT_DBG("Discard adv report due to insufficient buf"); + continue; + } + net_buf_add_mem(buf, &frame[1], len - 1); BT_DBG("Calling bt_recv(%p)", buf);