Bluetooth: host: Add IQ reports handing in DF connecte mode
Add reception of IQ sample report from controller. Add applications notification about received reports. Signed-off-by: Piotr Pryga <piotr.pryga@nordicsemi.no>
This commit is contained in:
parent
f18637fe30
commit
a26ee7ce73
7 changed files with 123 additions and 0 deletions
|
@ -23,6 +23,7 @@
|
|||
#include <bluetooth/hci_err.h>
|
||||
#include <bluetooth/addr.h>
|
||||
#include <bluetooth/gap.h>
|
||||
#include <bluetooth/direction.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
@ -927,6 +928,17 @@ struct bt_conn_cb {
|
|||
struct bt_conn_le_data_len_info *info);
|
||||
#endif /* defined(CONFIG_BT_USER_DATA_LEN_UPDATE) */
|
||||
|
||||
#if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
|
||||
/** @brief Callback for IQ samples report collected when sampling
|
||||
* CTE received by data channel PDU.
|
||||
*
|
||||
* @param conn The connection object.
|
||||
* @param iq_report Report data for collected IQ samples.
|
||||
*/
|
||||
void (*cte_report_cb)(struct bt_conn *conn,
|
||||
const struct bt_df_conn_iq_samples_report *iq_report);
|
||||
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
|
||||
|
||||
struct bt_conn_cb *_next;
|
||||
};
|
||||
|
||||
|
|
|
@ -120,6 +120,28 @@ struct bt_df_conn_cte_rx_param {
|
|||
const uint8_t *ant_ids;
|
||||
};
|
||||
|
||||
struct bt_df_conn_iq_samples_report {
|
||||
/** PHY that was used to receive PDU with CTE that was sampled. */
|
||||
uint8_t rx_phy;
|
||||
/** Channel index used to receive PDU with CTE that was sampled. */
|
||||
uint8_t chan_idx;
|
||||
/** The RSSI of the PDU with CTE (excluding CTE). */
|
||||
int16_t rssi;
|
||||
/** Id of antenna used to measure the RSSI. */
|
||||
uint8_t rssi_ant_id;
|
||||
/** 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). */
|
||||
uint8_t slot_durations;
|
||||
/** Status of received PDU with CTE (@ref bt_df_packet_status). */
|
||||
uint8_t packet_status;
|
||||
/** Value of connection event counter when the CTE was received and sampled. */
|
||||
uint16_t conn_evt_counter;
|
||||
/** Number of IQ samples in report. */
|
||||
uint8_t sample_count;
|
||||
/** Pinter to IQ samples data. */
|
||||
struct bt_hci_le_iq_sample const *sample;
|
||||
};
|
||||
/**
|
||||
* @brief Set or update the Constant Tone Extension parameters for periodic advertising set.
|
||||
*
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include <bluetooth/hci.h>
|
||||
#include <bluetooth/bluetooth.h>
|
||||
#include <bluetooth/direction.h>
|
||||
#include <bluetooth/conn.h>
|
||||
#include <drivers/bluetooth/hci_driver.h>
|
||||
#include <bluetooth/att.h>
|
||||
|
@ -38,6 +39,7 @@
|
|||
#include "att_internal.h"
|
||||
#include "gatt_internal.h"
|
||||
#include "iso_internal.h"
|
||||
#include "direction_internal.h"
|
||||
|
||||
struct tx_meta {
|
||||
struct bt_conn_tx *tx;
|
||||
|
@ -2921,4 +2923,33 @@ int bt_conn_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
|
||||
void bt_hci_le_df_connection_iq_report(struct net_buf *buf)
|
||||
{
|
||||
struct bt_df_conn_iq_samples_report iq_report;
|
||||
struct bt_conn *conn;
|
||||
struct bt_conn_cb *cb;
|
||||
int err;
|
||||
|
||||
err = hci_df_prepare_connection_iq_report(buf, &iq_report, &conn);
|
||||
if (err) {
|
||||
BT_ERR("Prepare CTE conn IQ report failed %d", err);
|
||||
return;
|
||||
}
|
||||
|
||||
for (cb = callback_list; cb; cb = cb->_next) {
|
||||
if (cb->cte_report_cb) {
|
||||
cb->cte_report_cb(conn, &iq_report);
|
||||
}
|
||||
}
|
||||
|
||||
STRUCT_SECTION_FOREACH(bt_conn_cb, cb)
|
||||
{
|
||||
if (cb->cte_report_cb) {
|
||||
cb->cte_report_cb(conn, &iq_report);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
|
||||
|
||||
#endif /* CONFIG_BT_CONN */
|
||||
|
|
|
@ -542,6 +542,55 @@ static int hci_df_set_conn_cte_rx_enable(struct bt_conn *conn, bool enable,
|
|||
|
||||
return err;
|
||||
}
|
||||
|
||||
int hci_df_prepare_connection_iq_report(struct net_buf *buf,
|
||||
struct bt_df_conn_iq_samples_report *report,
|
||||
struct bt_conn **conn_to_report)
|
||||
{
|
||||
struct bt_hci_evt_le_connection_iq_report *evt;
|
||||
struct bt_conn *conn;
|
||||
|
||||
if (buf->len < sizeof(*evt)) {
|
||||
BT_ERR("Unexpected end of buffer");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
evt = net_buf_pull_mem(buf, sizeof(*evt));
|
||||
|
||||
conn = bt_conn_lookup_handle(sys_le16_to_cpu(evt->conn_handle));
|
||||
|
||||
if (!conn) {
|
||||
BT_ERR("Unknown conn handle 0x%04X for iq samples report",
|
||||
sys_le16_to_cpu(evt->conn_handle));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!atomic_test_bit(conn->flags, BT_CONN_CTE_RX_ENABLED)) {
|
||||
BT_ERR("Received conn CTE report when CTE receive disabled");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!(conn->cte_type & BIT(evt->cte_type))) {
|
||||
BT_DBG("CTE filtered out by cte_type: %u", evt->cte_type);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
report->chan_idx = evt->data_chan_idx;
|
||||
report->rx_phy = evt->rx_phy;
|
||||
report->chan_idx = evt->data_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->conn_evt_counter = sys_le16_to_cpu(evt->conn_evt_counter);
|
||||
report->sample_count = evt->sample_count;
|
||||
report->sample = evt->sample;
|
||||
|
||||
*conn_to_report = conn;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
|
||||
|
||||
/* @brief Function initializes Direction Finding in Host
|
||||
|
|
|
@ -10,3 +10,6 @@ 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);
|
||||
int hci_df_prepare_connection_iq_report(struct net_buf *buf,
|
||||
struct bt_df_conn_iq_samples_report *report,
|
||||
struct bt_conn **conn_to_report);
|
||||
|
|
|
@ -2225,6 +2225,10 @@ static const struct event_handler meta_events[] = {
|
|||
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 */
|
||||
#if defined(CONFIG_BT_DF_CONNECTION_CTE_RX)
|
||||
EVENT_HANDLER(BT_HCI_EVT_LE_CONNECTION_IQ_REPORT, bt_hci_le_df_connection_iq_report,
|
||||
sizeof(struct bt_hci_evt_le_connection_iq_report)),
|
||||
#endif /* CONFIG_BT_DF_CONNECTION_CTE_RX */
|
||||
};
|
||||
|
||||
static void hci_le_meta_event(struct net_buf *buf)
|
||||
|
|
|
@ -450,3 +450,5 @@ void bt_hci_read_remote_features_complete(struct net_buf *buf);
|
|||
void bt_hci_read_remote_ext_features_complete(struct net_buf *buf);
|
||||
void bt_hci_role_change(struct net_buf *buf);
|
||||
void bt_hci_synchronous_conn_complete(struct net_buf *buf);
|
||||
|
||||
void bt_hci_le_df_connection_iq_report(struct net_buf *buf);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue