Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,5 @@ CONFIG_BT_CTLR_DF=y
# Disable Direction Fiding TX mode
CONFIG_BT_CTLR_DF_ANT_SWITCH_TX=n
CONFIG_BT_CTLR_DF_ADV_CTE_TX=n

CONFIG_BT_CTLR_DF_PER_SCAN_CTE_NUM_MAX=16
2 changes: 1 addition & 1 deletion subsys/bluetooth/common/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ config BT_BUF_ACL_RX_COUNT

config BT_BUF_EVT_RX_SIZE
int "Maximum supported HCI Event buffer length"
default 255 if (BT_EXT_ADV && !(BT_BUF_EVT_DISCARDABLE_COUNT > 0))
default 255 if (BT_EXT_ADV && !(BT_BUF_EVT_DISCARDABLE_COUNT > 0)) || BT_PER_ADV
# LE Read Supported Commands command complete event.
default 68
range 68 255
Expand Down
10 changes: 10 additions & 0 deletions subsys/bluetooth/controller/Kconfig.df
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,16 @@ config BT_CTLR_DF_PER_ADV_CTE_NUM_MAX
periodic advertising chain. The range is taken from BT Core spec 5.1, Vol 4 Part E
section 7.8.82 HCI_LE_Set_Connectionless_IQ_Sampling_Enable Max_Sampled_CTEs parameter.

config BT_CTLR_DF_PER_SCAN_CTE_NUM_MAX
int "Maximum number of received PDUs with Constant Tone Extension in connectionless mode"
depends on BT_CTLR_DF_SCAN_CTE_RX
range 1 16
default 16
help
Maximum supported number of PDUs, that have Constant Tone Extension, received in single
periodic advertising chain. The range is taken from BT Core spec 5.1, Vol 4 Part E
section 7.8.82 HCI_LE_Set_Connectionless_IQ_Sampling_Enable Max_Sampled_CTEs parameter.

config BT_CTLR_DF_DEBUG_ENABLE
bool "Bluetooth Direction Finding debug support enable"
help
Expand Down
283 changes: 127 additions & 156 deletions subsys/bluetooth/controller/hci/hci.c
Original file line number Diff line number Diff line change
Expand Up @@ -5523,222 +5523,193 @@ static void le_per_adv_sync_report(struct pdu_data *pdu_data,
struct net_buf *buf)
{
struct bt_hci_evt_le_per_advertising_report *sep;
struct node_rx_ftr *ftr = &node_rx->hdr.rx_ftr;
int8_t tx_pwr = BT_HCI_LE_ADV_TX_POWER_NO_PREF;
struct pdu_adv *adv = (void *)pdu_data;
struct pdu_adv_aux_ptr *aux_ptr = NULL;
uint8_t cte_type = BT_HCI_LE_NO_CTE;
struct node_rx_pdu *node_rx_curr;
struct node_rx_pdu *node_rx_next;
uint8_t total_data_len = 0U;
struct pdu_adv_com_ext_adv *p;
struct pdu_adv_ext_hdr *h;
uint8_t data_status = 0U;
struct net_buf *evt_buf;
uint8_t data_len = 0U;
uint8_t *data = NULL;
uint8_t data_max_len;
uint8_t hdr_buf_len;
uint8_t hdr_len;
uint8_t *ptr;
int8_t rssi;

if (!(event_mask & BT_EVT_MASK_LE_META_EVENT) ||
!(le_event_mask & BT_EVT_MASK_LE_PER_ADVERTISING_REPORT)) {
node_rx_extra_list_release(node_rx->hdr.rx_ftr.extra);
return;
}

node_rx_curr = node_rx;
node_rx_next = node_rx_curr->hdr.rx_ftr.extra;
do {
struct pdu_adv_com_ext_adv *p;
uint8_t data_len_curr = 0U;
uint8_t *data_curr = NULL;
uint8_t sec_phy_curr = 0U;
struct pdu_adv_ext_hdr *h;
uint8_t hdr_buf_len;
uint8_t hdr_len;
uint8_t *ptr;

/* The Link Layer currently returns RSSI as an absolute value */
rssi = -(node_rx_curr->hdr.rx_ftr.rssi);
/* The Link Layer currently returns RSSI as an absolute value */
rssi = -(node_rx->hdr.rx_ftr.rssi);

BT_DBG("len = %u, rssi = %d", adv->len, rssi);
BT_DBG("len = %u, rssi = %d", adv->len, rssi);

p = (void *)&adv->adv_ext_ind;
h = (void *)p->ext_hdr_adv_data;
ptr = (void *)h;
p = (void *)&adv->adv_ext_ind;
h = (void *)p->ext_hdr_adv_data;
ptr = (void *)h;

BT_DBG(" Ext. adv mode= 0x%x, hdr len= %u", p->adv_mode,
p->ext_hdr_len);
BT_DBG(" Per. adv mode= 0x%x, hdr len= %u", p->adv_mode,
p->ext_hdr_len);

if (!p->ext_hdr_len) {
hdr_len = PDU_AC_EXT_HEADER_SIZE_MIN;
if (!p->ext_hdr_len) {
hdr_len = PDU_AC_EXT_HEADER_SIZE_MIN;

goto no_ext_hdr;
}
goto no_ext_hdr;
}

ptr = h->data;
ptr = h->data;

/* No AdvA */
/* No TargetA */
if (h->adv_addr) {
ptr += BDADDR_SIZE;
}

if (h->cte_info) {
struct pdu_cte_info *cte_info;
if (h->tgt_addr) {
ptr += BDADDR_SIZE;
}

cte_info = (void *)ptr;
cte_type = cte_info->type;
ptr++;
if (h->cte_info) {
struct pdu_cte_info *cte_info;

BT_DBG(" CTE type= %d", cte_type);
}
cte_info = (void *)ptr;
cte_type = cte_info->type;
ptr++;

/* No ADI */
BT_DBG(" CTE type= %d", cte_type);
}

/* AuxPtr */
if (h->aux_ptr) {
struct pdu_adv_aux_ptr *aux_ptr;
uint8_t aux_phy;
if (h->adi) {
ptr += sizeof(struct pdu_adv_adi);
}

aux_ptr = (void *)ptr;
if (aux_ptr->phy > EXT_ADV_AUX_PHY_LE_CODED) {
struct node_rx_ftr *ftr;
/* AuxPtr */
if (h->aux_ptr) {
uint8_t aux_phy;

ftr = &node_rx->hdr.rx_ftr;
node_rx_extra_list_release(ftr->extra);
return;
}
aux_ptr = (void *)ptr;
if (aux_ptr->phy > EXT_ADV_AUX_PHY_LE_CODED) {
struct node_rx_ftr *ftr;

ptr += sizeof(*aux_ptr);
ftr = &node_rx->hdr.rx_ftr;
node_rx_extra_list_release(ftr->extra);
return;
}

sec_phy_curr = aux_ptr->phy + 1;
ptr += sizeof(*aux_ptr);

aux_phy = BIT(aux_ptr->phy);
aux_phy = BIT(aux_ptr->phy);

BT_DBG(" AuxPtr chan_idx = %u, ca = %u, offs_units "
"= %u offs = 0x%x, phy = 0x%x",
aux_ptr->chan_idx, aux_ptr->ca,
aux_ptr->offs_units, aux_ptr->offs, aux_phy);
}
BT_DBG(" AuxPtr chan_idx = %u, ca = %u, offs_units "
"= %u offs = 0x%x, phy = 0x%x",
aux_ptr->chan_idx, aux_ptr->ca,
aux_ptr->offs_units, aux_ptr->offs, aux_phy);
}

/* No SyncInfo */
/* No SyncInfo */
if (h->sync_info) {
ptr += sizeof(struct pdu_adv_sync_info);
}

/* Tx Power */
if (h->tx_pwr) {
tx_pwr = *(int8_t *)ptr;
ptr++;
/* Tx Power */
if (h->tx_pwr) {
tx_pwr = *(int8_t *)ptr;
ptr++;

BT_DBG(" Tx pwr= %d dB", tx_pwr);
}
BT_DBG(" Tx pwr= %d dB", tx_pwr);
}

hdr_len = ptr - (uint8_t *)p;
hdr_len = ptr - (uint8_t *)p;
if (hdr_len <= (PDU_AC_EXT_HEADER_SIZE_MIN +
sizeof(struct pdu_adv_ext_hdr))) {
hdr_len = PDU_AC_EXT_HEADER_SIZE_MIN;
ptr = (uint8_t *)h;
}

hdr_buf_len = PDU_AC_EXT_HEADER_SIZE_MIN + p->ext_hdr_len;
if (hdr_len > hdr_buf_len) {
BT_WARN(" Header length %u/%u, INVALID.", hdr_len,
p->ext_hdr_len);
} else {
uint8_t acad_len = hdr_buf_len - hdr_len;
hdr_buf_len = PDU_AC_EXT_HEADER_SIZE_MIN + p->ext_hdr_len;
if (hdr_len > hdr_buf_len) {
BT_WARN(" Header length %u/%u, INVALID.", hdr_len,
p->ext_hdr_len);
} else {
uint8_t acad_len = hdr_buf_len - hdr_len;

if (acad_len) {
ptr += acad_len;
hdr_len += acad_len;
if (acad_len) {
ptr += acad_len;
hdr_len += acad_len;

BT_DBG("ACAD: <todo>");
}
BT_DBG("ACAD: <todo>");
}
}

no_ext_hdr:
if (hdr_len < adv->len) {
data_len_curr = adv->len - hdr_len;
data_curr = ptr;

BT_DBG(" AD Data (%u): <todo>", data_len);
}

if (node_rx_curr == node_rx) {
data_len = data_len_curr;
total_data_len = data_len;
data = data_curr;
} else {
/* TODO: Validate current value with previous ??
*/

if (!data) {
data_len = data_len_curr;
total_data_len = data_len;
data = data_curr;
} else {
total_data_len += data_len_curr;

/* TODO: construct new HCI event for this
* fragment.
*/
}
}
if (hdr_len < adv->len) {
data_len = adv->len - hdr_len;
data = ptr;

if (!node_rx_next) {
bool has_aux_ptr = !!sec_phy_curr;

if (has_aux_ptr) {
data_status =
BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE;
}

break;
}
BT_DBG(" AD Data (%u): <todo>", data_len);
}

node_rx_curr = node_rx_next;
node_rx_next = node_rx_curr->hdr.rx_ftr.extra;
adv = (void *)node_rx_curr->pdu;
} while (1);
adv = (void *)node_rx->pdu;

/* FIXME: move most of below into above loop to dispatch fragments of
* data in HCI event.
*/
data_max_len = ADV_REPORT_EVT_MAX_LEN -
sizeof(struct bt_hci_evt_le_meta_event) -
sizeof(*sep);

/* If data complete */
if (!data_status) {
/* Only copy data that fit the event buffer size,
* mark it as incomplete
*/
if (data_len > data_max_len) {
data_len = data_max_len;
data_status =
BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL;
}
evt_buf = buf;

/* else, data incomplete */
} else {
/* Data incomplete and no more to come */
if ((tx_pwr == BT_HCI_LE_ADV_TX_POWER_NO_PREF) && !data) {
/* No Tx Power value and no valid AD data parsed in this
* chain of PDUs, skip HCI event generation.
do {
uint8_t data_len_frag;

data_len_frag = MIN(data_len, data_max_len);

/* Start constructing periodic advertising report */
sep = meta_evt(evt_buf,
BT_HCI_EVT_LE_PER_ADVERTISING_REPORT,
sizeof(*sep) + data_len_frag);

memcpy(&sep->data[0], data, data_len_frag);
data += data_len_frag;
data_len -= data_len_frag;

if (data_len > 0) {
/* Some data left in PDU, mark as partial data. */
data_status = BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL;
} 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_w4next) {
/* No data left, but have AuxPtr and scheduled aux scan,
* mark as partial data.
*/
node_rx_extra_list_release(node_rx->hdr.rx_ftr.extra);
return;
}

/* Only copy data that fit the event buffer size */
if (data_len > data_max_len) {
data_len = data_max_len;
data_status = BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_PARTIAL;
} else {
/* No data left, have AuxPtr but not aux scan scheduled,
* mark as incomplete data.
*/
data_status = BT_HCI_LE_ADV_EVT_TYPE_DATA_STATUS_INCOMPLETE;
}
}

/* Start constructing the event */
sep = meta_evt(buf, BT_HCI_EVT_LE_PER_ADVERTISING_REPORT,
sizeof(*sep) + data_len);
sep->handle = sys_cpu_to_le16(node_rx->hdr.handle);
/* TODO: use actual TX power only on 1st report, subsequent
* reports can use 0x7F
*/
sep->tx_power = tx_pwr;
sep->rssi = rssi;
sep->cte_type = cte_type;
sep->data_status = data_status;
sep->length = data_len_frag;

sep->handle = sys_cpu_to_le16(node_rx->hdr.handle);
sep->tx_power = tx_pwr;
sep->rssi = rssi;
sep->cte_type = cte_type;
sep->data_status = data_status;
sep->length = data_len;
memcpy(&sep->data[0], data, data_len);
if (data_len > 0) {
evt_buf = bt_buf_get_rx(BT_BUF_EVT, K_FOREVER);
net_buf_frag_add(buf, evt_buf);

node_rx_extra_list_release(node_rx->hdr.rx_ftr.extra);
tx_pwr = BT_HCI_LE_ADV_TX_POWER_NO_PREF;
}
} while (data_len > 0);
}

static void le_per_adv_sync_lost(struct pdu_data *pdu_data,
Expand Down
4 changes: 3 additions & 1 deletion subsys/bluetooth/controller/ll_sw/lll.h
Original file line number Diff line number Diff line change
Expand Up @@ -276,12 +276,14 @@ struct node_rx_ftr {
*/
void *aux_ptr;
uint8_t aux_phy;
uint8_t aux_sched;
};
uint32_t ticks_anchor;
uint32_t radio_end_us;
uint8_t rssi;
#if defined(CONFIG_BT_CTLR_ADV_EXT) && defined(CONFIG_BT_OBSERVER)
uint8_t aux_lll_sched:1;
uint8_t aux_w4next:1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is w4next ? Wait for Next ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
uint8_t aux_w4next:1;
uint8_t aux_partial:1;


uint8_t phy_flags:1;
uint8_t scan_req:1;
uint8_t scan_rsp:1;
Expand Down
Loading