Bluetooth: host: Add handl HCI_LE_Connectionless_IQ_Report

Add handling for HCI_LE_Connectionless_IQ_Report received
from controller.

Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
This commit is contained in:
Piotr Pryga 2021-04-22 11:19:05 +02:00 committed by Carles Cufí
commit 7c834bf19d
6 changed files with 80 additions and 3 deletions

View file

@ -95,11 +95,11 @@ struct bt_df_per_adv_sync_iq_samples_report {
int16_t rssi;
/** Id of antenna used to measure the RSSI. */
uint8_t rssi_ant_id;
/** Type of CTE (@ref BT_DF_CTE_TYPE). */
/** Type of CTE (@ref bt_df_cte_type). */
uint8_t cte_type;
/** Duration of slots when received CTE type is AoA (@ref BT_DF_ANTENNA_SWITCHING_SLOT). */
/** Duration of slots when received CTE type is AoA (@ref bt_df_antenna_switching_slot). */
uint8_t slot_durations;
/** Status of received PDU with CTE (@ref BT_DF_RX_POCKET_STATUS). */
/** Status of received PDU with CTE (@ref bt_df_packet_status). */
uint8_t packet_status;
/** Number of IQ samples in report. */
uint8_t sample_count;

View file

@ -15,6 +15,7 @@
#include <bluetooth/direction.h>
#include "hci_core.h"
#include "scan.h"
#include "conn_internal.h"
#include "direction_internal.h"
@ -308,6 +309,50 @@ static int hci_df_set_cl_cte_rx_enable(struct bt_le_per_adv_sync *sync, bool ena
return 0;
}
void hci_df_prepare_connectionless_iq_report(struct net_buf *buf,
struct bt_df_per_adv_sync_iq_samples_report *report,
struct bt_le_per_adv_sync **per_adv_sync_to_report)
{
struct bt_hci_evt_le_connectionless_iq_report *evt;
struct bt_le_per_adv_sync *per_adv_sync;
if (buf->len < sizeof(*evt)) {
BT_ERR("Unexpected end of buffer");
return;
}
evt = net_buf_pull_mem(buf, sizeof(*evt));
per_adv_sync = bt_hci_get_per_adv_sync(sys_le16_to_cpu(evt->sync_handle));
if (!per_adv_sync) {
BT_ERR("Unknown handle 0x%04X for iq samples report",
sys_le16_to_cpu(evt->sync_handle));
return;
}
if (!atomic_test_bit(per_adv_sync->flags, BT_PER_ADV_SYNC_CTE_ENABLED)) {
BT_ERR("Received PA CTE report when CTE receive disabled");
return;
}
if (!(per_adv_sync->cte_type & BIT(evt->cte_type))) {
BT_DBG("CTE filtered out by cte_type: %u", evt->cte_type);
return;
}
report->chan_idx = evt->chan_idx;
report->rssi = evt->rssi;
report->rssi_ant_id = evt->rssi_ant_id;
report->cte_type = BIT(evt->cte_type);
report->packet_status = evt->packet_status;
report->slot_durations = evt->slot_durations;
report->sample_count = evt->sample_count;
report->sample = &evt->sample[0];
*per_adv_sync_to_report = per_adv_sync;
}
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */
#if defined(CONFIG_BT_CTLR_DF_CONN_CTE_RSP)

View file

@ -6,3 +6,7 @@
/* Performs initialization of Direction Finding in Host */
int le_df_init(void);
void hci_df_prepare_connectionless_iq_report(struct net_buf *buf,
struct bt_df_per_adv_sync_iq_samples_report *report,
struct bt_le_per_adv_sync **per_adv_sync_to_report);

View file

@ -2133,6 +2133,10 @@ static const struct event_handler meta_events[] = {
sizeof(struct bt_hci_evt_le_biginfo_adv_report)),
#endif /* (CONFIG_BT_ISO_BROADCAST) */
#endif /* (CONFIG_BT_ISO) */
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
EVENT_HANDLER(BT_HCI_EVT_LE_CONNECTIONLESS_IQ_REPORT, bt_hci_le_df_connectionless_iq_report,
sizeof(struct bt_hci_evt_le_connectionless_iq_report)),
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */
};
static void hci_le_meta_event(struct net_buf *buf)
@ -2684,6 +2688,11 @@ static int le_set_event_mask(void)
}
}
/* Enable IQ samples report events receiver */
if (IS_ENABLED(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)) {
mask |= BT_EVT_MASK_LE_CONNECTIONLESS_IQ_REPORT;
}
sys_put_le64(mask, cp_mask->events);
return bt_hci_cmd_send_sync(BT_HCI_OP_LE_SET_EVENT_MASK, buf, NULL);
}

View file

@ -402,6 +402,7 @@ void bt_hci_le_per_adv_sync_established(struct net_buf *buf);
void bt_hci_le_per_adv_report(struct net_buf *buf);
void bt_hci_le_per_adv_sync_lost(struct net_buf *buf);
void bt_hci_le_biginfo_adv_report(struct net_buf *buf);
void bt_hci_le_df_connectionless_iq_report(struct net_buf *buf);
void bt_hci_le_past_received(struct net_buf *buf);
/* Adv HCI event handlers */

View file

@ -12,9 +12,11 @@
#include <bluetooth/bluetooth.h>
#include <bluetooth/iso.h>
#include <bluetooth/buf.h>
#include <bluetooth/direction.h>
#include "hci_core.h"
#include "conn_internal.h"
#include "direction_internal.h"
#include "id.h"
#define BT_DBG_ENABLED IS_ENABLED(CONFIG_BT_DEBUG_HCI_CORE)
@ -904,6 +906,22 @@ void bt_hci_le_biginfo_adv_report(struct net_buf *buf)
}
}
#endif /* defined(CONFIG_BT_ISO_BROADCAST) */
#if defined(CONFIG_BT_DF_CONNECTIONLESS_CTE_RX)
void bt_hci_le_df_connectionless_iq_report(struct net_buf *buf)
{
struct bt_df_per_adv_sync_iq_samples_report cte_report;
struct bt_le_per_adv_sync *per_adv_sync;
struct bt_le_per_adv_sync_cb *listener;
hci_df_prepare_connectionless_iq_report(buf, &cte_report, &per_adv_sync);
SYS_SLIST_FOR_EACH_CONTAINER(&pa_sync_cbs, listener, node) {
if (listener->cte_report_cb) {
listener->cte_report_cb(per_adv_sync, &cte_report);
}
}
}
#endif /* CONFIG_BT_DF_CONNECTIONLESS_CTE_RX */
#endif /* defined(CONFIG_BT_PER_ADV_SYNC) */
#endif /* defined(CONFIG_BT_EXT_ADV) */