Bluetooth: Controller: Fix periodic adv data truncation

Advertising data has to be truncated at a PDU boundary

Similar to earlier fix for extended advertising reports

Found in several EBQ tests, including LL/DDI/SCN/BV-25-C,
LL/DDI/SCN/BV-21-C and LL/DDI/SCN/BV-46-C

Signed-off-by: Troels Nilsson <trnn@demant.com>
This commit is contained in:
Troels Nilsson 2024-01-31 11:20:32 +01:00 committed by Carles Cufí
commit 8acca664d2
2 changed files with 24 additions and 10 deletions

View file

@ -7484,8 +7484,10 @@ static void le_per_adv_sync_report(struct pdu_data *pdu_data,
return;
}
data_len_total = node_rx->hdr.rx_ftr.aux_data_len;
if ((le_event_mask & BT_EVT_MASK_LE_PER_ADVERTISING_REPORT) &&
node_rx->hdr.rx_ftr.aux_failed) {
(node_rx->hdr.rx_ftr.aux_failed || data_len_total > CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX)) {
struct bt_hci_evt_le_per_advertising_report *sep;
sep = meta_evt(buf,
@ -7629,12 +7631,10 @@ no_ext_hdr:
data_len_max = CONFIG_BT_BUF_EVT_RX_SIZE -
sizeof(struct bt_hci_evt_le_meta_event) -
sizeof(struct bt_hci_evt_le_per_advertising_report);
data_len_total = node_rx->hdr.rx_ftr.aux_data_len;
evt_buf = buf;
if ((le_event_mask & BT_EVT_MASK_LE_PER_ADVERTISING_REPORT) && accept &&
((data_len_total - data_len) < CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX)) {
if ((le_event_mask & BT_EVT_MASK_LE_PER_ADVERTISING_REPORT) && accept) {
/* Pass verdict in LL.TS.p19 section 4.2.3.6 Extended Scanning,
* Passive, Periodic Advertising Report, RSSI and TX_Power
@ -7655,9 +7655,6 @@ no_ext_hdr:
tx_pwr = BT_HCI_LE_ADV_TX_POWER_NO_PREF;
}
data_len = MIN(data_len, (CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX +
data_len - data_len_total));
do {
struct bt_hci_evt_le_per_advertising_report *sep;
uint8_t data_len_frag;
@ -7690,8 +7687,7 @@ no_ext_hdr:
net_buf_frag_add(buf, evt_buf);
tx_pwr = BT_HCI_LE_ADV_TX_POWER_NO_PREF;
} else if (!aux_ptr &&
(data_len_total <= CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX)) {
} else if (!aux_ptr) {
/* No data left, no AuxPtr, mark as complete data. */
data_status = BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_COMPLETE;
} else if (ftr->aux_sched &&

View file

@ -535,7 +535,7 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx)
rx_incomplete = NULL;
#endif /* CONFIG_BT_CTLR_SYNC_PERIODIC */
} else {
} else if (!(IS_ENABLED(CONFIG_BT_CTLR_SYNC_PERIODIC) && sync_lll)) {
aux->data_len += data_len;
/* Flush auxiliary PDU receptions and stop any more ULL
@ -565,6 +565,24 @@ void ull_scan_aux_setup(memq_link_t *link, struct node_rx_hdr *rx)
sync_set = HDR_LLL2ULL(sync_lll);
sync_set->data_len += data_len;
ftr->aux_data_len = sync_set->data_len;
/* Flush auxiliary PDU receptions and stop any more ULL
* scheduling if accumulated data length exceeds configured
* maximum supported.
*/
if (sync_set->data_len >= CONFIG_BT_CTLR_SCAN_DATA_LEN_MAX) {
/* If LLL has already scheduled, then let it proceed.
*
* TODO: LLL to check accumulated data length and
* stop further reception.
* Currently LLL will schedule as long as there
* are free node rx available.
*/
if (!ftr->aux_lll_sched) {
sync_set->data_len = 0U;
goto ull_scan_aux_rx_flush;
}
}
} else {
if (aux->rx_last) {
aux->rx_last->rx_ftr.extra = rx;