summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMilissaImeneBOUDIAF <milissa.boudiaf@qorvo.com>2022-11-22 14:36:14 +0100
committerVictor Liu <victorliu@google.com>2023-02-21 19:43:28 +0000
commit62ee18c195a66fcd9e95bf7c564b8b0b381d3503 (patch)
treecf2255bed8d3fdffc581d42bea4980ec266caa9e
parentf4694a5f271d859756057ad3caff4e6c5e1e3a2b (diff)
downloaduwb-62ee18c195a66fcd9e95bf7c564b8b0b381d3503.tar.gz
mac: AoA bound to proximity feature
Add AoA Azimuth and Elevation PROXIMITY NTF thresholds along with the existing distance thresholds. This provides UWB framework more granular controls for ranging notifications which helps reduce host wakeups. Notifications can come when: - When the device moves inside the specified threshold. - When the device moves outside of the specified threshold. Bug: 235354865 Change-Id: I2d14ece55471a71bca38763a59948695994c80e7 Signed-off-by: Clément Viel <clement.viel@qorvo.com> (cherry picked from commit 9d77ce7385af67f1be13b35fb3da0c9c2a865017)
-rw-r--r--mac/fira_access.c55
-rw-r--r--mac/fira_frame.c3
-rw-r--r--mac/fira_region.h63
-rw-r--r--mac/fira_region_call.c88
-rw-r--r--mac/fira_session.c384
-rw-r--r--mac/fira_session.h49
-rw-r--r--mac/fira_session_fsm_active.c9
-rw-r--r--mac/include/net/fira_region_nl.h45
-rw-r--r--mac/include/net/fira_region_params.h46
9 files changed, 594 insertions, 148 deletions
diff --git a/mac/fira_access.c b/mac/fira_access.c
index 1eab75b..c8292e9 100644
--- a/mac/fira_access.c
+++ b/mac/fira_access.c
@@ -242,7 +242,8 @@ static bool fira_rx_sts_good(struct fira_local *local,
return true;
}
-static void fira_ranging_info_set_status(struct fira_ranging_info *ranging_info,
+static void fira_ranging_info_set_status(const struct fira_session *session,
+ struct fira_ranging_info *ranging_info,
enum fira_ranging_status status,
u8 slot_index)
{
@@ -251,6 +252,7 @@ static void fira_ranging_info_set_status(struct fira_ranging_info *ranging_info,
return;
ranging_info->status = status;
ranging_info->slot_index = slot_index;
+ fira_session_set_range_data_ntf_status(session, ranging_info);
}
static void
@@ -417,15 +419,15 @@ static void fira_rx_frame_ranging(struct fira_local *local,
if (!fira_rx_sts_good(local, info)) {
fira_ranging_info_set_status(
- ranging_info, FIRA_STATUS_RANGING_RX_PHY_STS_FAILED,
- slot->index);
+ session, ranging_info,
+ FIRA_STATUS_RANGING_RX_PHY_STS_FAILED, slot->index);
return;
}
if (!(info->flags & MCPS802154_RX_FRAME_INFO_TIMESTAMP_RCTU)) {
fira_ranging_info_set_status(
- ranging_info, FIRA_STATUS_RANGING_RX_PHY_TOA_FAILED,
- slot->index);
+ session, ranging_info,
+ FIRA_STATUS_RANGING_RX_PHY_TOA_FAILED, slot->index);
return;
}
ranging_info->timestamps_rctu[slot->message_id] = info->timestamp_rctu;
@@ -509,7 +511,7 @@ static void fira_rx_frame_ranging(struct fira_local *local,
!fira_frame_rframe_payload_check(local, slot, skb,
&ie_get)) {
fira_ranging_info_set_status(
- ranging_info,
+ session, ranging_info,
FIRA_STATUS_RANGING_RX_MAC_IE_DEC_FAILED,
slot->index);
}
@@ -539,7 +541,8 @@ static void fira_rx_frame_control(struct fira_local *local,
if (!(info->flags & MCPS802154_RX_FRAME_INFO_TIMESTAMP_DTU)) {
fira_ranging_info_set_status(
- ri, FIRA_STATUS_RANGING_RX_PHY_DEC_FAILED, slot->index);
+ local->current_session, ri,
+ FIRA_STATUS_RANGING_RX_PHY_DEC_FAILED, slot->index);
return;
}
@@ -617,11 +620,32 @@ static void fira_rx_frame_control(struct fira_local *local,
return;
failed:
+ session = local->current_session;
params = &local->current_session->params;
access->duration_dtu =
offset_in_access_duration_dtu + params->slot_duration_dtu;
- fira_ranging_info_set_status(
- ri, FIRA_STATUS_RANGING_RX_MAC_IE_DEC_FAILED, slot->index);
+ fira_ranging_info_set_status(session, ri,
+ FIRA_STATUS_RANGING_RX_MAC_IE_DEC_FAILED,
+ slot->index);
+}
+
+static void
+fira_rx_frame_control_update(struct fira_local *local,
+ const struct fira_slot *slot, struct sk_buff *skb,
+ const struct mcps802154_rx_frame_info *info)
+{
+ struct fira_ranging_info *ranging_info =
+ &local->ranging_info[slot->ranging_index];
+ struct mcps802154_ie_get_context ie_get = {};
+
+ if (fira_frame_header_check_decrypt(local, slot, skb, &ie_get))
+ goto failed;
+
+ return;
+failed:
+ fira_ranging_info_set_status(local->current_session, ranging_info,
+ FIRA_STATUS_RANGING_RX_MAC_IE_DEC_FAILED,
+ slot->index);
}
static void fira_rx_frame_measurement_report(
@@ -641,7 +665,7 @@ static void fira_rx_frame_measurement_report(
return;
failed:
- fira_ranging_info_set_status(ranging_info,
+ fira_ranging_info_set_status(local->current_session, ranging_info,
FIRA_STATUS_RANGING_RX_MAC_IE_DEC_FAILED,
slot->index);
}
@@ -663,12 +687,13 @@ fira_rx_frame_result_report(struct fira_local *local,
return;
failed:
- fira_ranging_info_set_status(ranging_info,
+ fira_ranging_info_set_status(local->current_session, ranging_info,
FIRA_STATUS_RANGING_RX_MAC_IE_DEC_FAILED,
slot->index);
}
-static bool fira_do_process_rx_frame(enum mcps802154_rx_error_type error,
+static bool fira_do_process_rx_frame(const struct fira_session *session,
+ enum mcps802154_rx_error_type error,
struct fira_ranging_info *ranging_info,
u8 slot_index)
{
@@ -692,7 +717,7 @@ static bool fira_do_process_rx_frame(enum mcps802154_rx_error_type error,
status = FIRA_STATUS_RANGING_RX_PHY_DEC_FAILED;
break;
}
- fira_ranging_info_set_status(ranging_info, status, slot_index);
+ fira_ranging_info_set_status(session, ranging_info, status, slot_index);
return false;
}
@@ -720,7 +745,8 @@ static void fira_rx_frame(struct mcps802154_access *access, int frame_idx,
info->rssi < FIRA_RSSI_MAX ? info->rssi : FIRA_RSSI_MAX;
}
- if (fira_do_process_rx_frame(error, ri, slot->index)) {
+ if (fira_do_process_rx_frame(local->current_session, error, ri,
+ slot->index)) {
switch (slot->message_id) {
case FIRA_MESSAGE_ID_RANGING_INITIATION:
case FIRA_MESSAGE_ID_RANGING_RESPONSE:
@@ -738,6 +764,7 @@ static void fira_rx_frame(struct mcps802154_access *access, int frame_idx,
fira_rx_frame_result_report(local, slot, skb, info);
break;
case FIRA_MESSAGE_ID_CONTROL_UPDATE:
+ fira_rx_frame_control_update(local, slot, skb, info);
break;
default:
WARN_UNREACHABLE_DEFAULT();
diff --git a/mac/fira_frame.c b/mac/fira_frame.c
index 6ebefbe..987cb72 100644
--- a/mac/fira_frame.c
+++ b/mac/fira_frame.c
@@ -285,7 +285,6 @@ void fira_frame_result_report_payload_put(const struct fira_local *local,
ranging_info->local_aoa_elevation.aoa_fom) &&
params->report_aoa_fom;
neg_tof_present = tof_present && (ranging_info->tof_rctu < 0);
-
p = fira_frame_common_payload_put(
skb,
FIRA_IE_PAYLOAD_RESULT_REPORT_LEN(
@@ -669,7 +668,6 @@ fira_frame_measurement_report_fill_ranging_info(struct fira_local *local,
}
ranging_info->tof_rctu = (!slot->controller_tx) ? -tof_rctu : tof_rctu;
ranging_info->tof_present = true;
-
session->controlee.hopping_mode = hopping_mode;
return true;
}
@@ -782,7 +780,6 @@ fira_frame_result_report_fill_ranging_info(struct fira_local *local,
if (aoa_elevation_present)
ranging_info->remote_aoa_elevation_fom = *p++;
}
-
return true;
}
diff --git a/mac/fira_region.h b/mac/fira_region.h
index 8ec9d84..6038d09 100644
--- a/mac/fira_region.h
+++ b/mac/fira_region.h
@@ -26,6 +26,7 @@
#include <linux/kernel.h>
#include <linux/workqueue.h>
+#include <linux/math64.h>
#include <net/mcps802154_schedule.h>
#include "net/fira_region_params.h"
@@ -47,6 +48,20 @@
/* FiRa Tx should arrive between 0 and 10 us, always add 2 us. */
#define FIRA_TX_MARGIN_US 2
+/*
+ * FIRA_SESSION_DATA_NTF_LOWER_/UPPER_BOUND_AOA min/max :
+ * Azimuth in rad_2pi_q16 : -32768 / 32767 (equal to -180 / ~180 degrees)
+ * Elevation in rad_2pi_q16 : -16384 / 16384 (equal to -90 / 90 degrees)
+ */
+#define FIRA_SESSION_DATA_NTF_LOWER_BOUND_AOA_AZIMUTH_2PI_MIN -32768
+#define FIRA_SESSION_DATA_NTF_LOWER_BOUND_AOA_AZIMUTH_2PI_MAX 32767
+#define FIRA_SESSION_DATA_NTF_UPPER_BOUND_AOA_AZIMUTH_2PI_MIN -32768
+#define FIRA_SESSION_DATA_NTF_UPPER_BOUND_AOA_AZIMUTH_2PI_MAX 32767
+#define FIRA_SESSION_DATA_NTF_LOWER_BOUND_AOA_ELEVATION_2PI_MIN -16384
+#define FIRA_SESSION_DATA_NTF_LOWER_BOUND_AOA_ELEVATION_2PI_MAX 16384
+#define FIRA_SESSION_DATA_NTF_UPPER_BOUND_AOA_ELEVATION_2PI_MIN -16384
+#define FIRA_SESSION_DATA_NTF_UPPER_BOUND_AOA_ELEVATION_2PI_MAX 16384
+
/**
* enum fira_message_id - Message identifiers, used in internal state and in
* messages.
@@ -172,6 +187,31 @@ struct fira_local_aoa_info {
};
/**
+ * enum fira_range_data_ntf_status - Device (controller or controlee)
+ * status, used for range_data_ntf.
+ * @FIRA_RANGE_DATA_NTF_NONE: Undetermined, no ranging data for this
+ * device yet, or N/A (not applicable).
+ * @FIRA_RANGE_DATA_NTF_IN: Last ranging data for this device
+ * were inside given boudaries.
+ * @FIRA_RANGE_DATA_NTF_OUT: Last ranging data for this device
+ * were outside given boudaries.
+ * @FIRA_RANGE_DATA_NTF_ERROR: Last ranging round(s) for this device
+ * failed (timeout, error, ...). No info about a previous state or N/A.
+ * @FIRA_RANGE_DATA_NTF_IN_ERROR: Last ranging round(s) for this device
+ * failed (timeout, error, ...). Previous data were inside given boudaries.
+ * @FIRA_RANGE_DATA_NTF_OUT_ERROR: Last ranging round(s) for this device
+ * failed (timeout, error, ...). Previous data were inside given boudaries.
+*/
+enum fira_range_data_ntf_status {
+ FIRA_RANGE_DATA_NTF_NONE,
+ FIRA_RANGE_DATA_NTF_IN,
+ FIRA_RANGE_DATA_NTF_OUT,
+ FIRA_RANGE_DATA_NTF_ERROR,
+ FIRA_RANGE_DATA_NTF_IN_ERROR,
+ FIRA_RANGE_DATA_NTF_OUT_ERROR,
+};
+
+/**
* struct fira_ranging_info - Ranging information.
*/
struct fira_ranging_info {
@@ -267,6 +307,14 @@ struct fira_ranging_info {
* @rx_ctx: Pointer to the current rx_ctx context controlee.
*/
void *rx_ctx;
+ /**
+ * @range_data_ntf_status: range_data_ntf status of the remote device.
+ */
+ enum fira_range_data_ntf_status range_data_ntf_status;
+ /**
+ * @notify: if true, add this ranging to the notification report.
+ */
+ bool notify;
};
/**
@@ -374,6 +422,21 @@ struct fira_local {
int n_stopped_controlees;
};
+static const s64 speed_of_light_mm_per_s = 299702547000ull;
+
+static inline s64 fira_rctu_to_mm(s64 rctu_freq_hz, s32 rctu)
+{
+ s64 temp = speed_of_light_mm_per_s * rctu + rctu_freq_hz / 2;
+ return div64_s64(temp, rctu_freq_hz);
+}
+
+static inline s64 fira_mm_to_rctu(struct fira_local *local, s32 mm)
+{
+ s64 temp = (s64)mm * local->llhw->dtu_freq_hz * local->llhw->dtu_rctu +
+ speed_of_light_mm_per_s / 2;
+ return div64_s64(temp, speed_of_light_mm_per_s);
+}
+
static inline struct fira_local *
region_to_local(struct mcps802154_region *region)
{
diff --git a/mac/fira_region_call.c b/mac/fira_region_call.c
index 1438d4b..fdc6fdc 100644
--- a/mac/fira_region_call.c
+++ b/mac/fira_region_call.c
@@ -130,11 +130,27 @@ static const struct nla_policy fira_session_param_nla_policy[FIRA_SESSION_PARAM_
[FIRA_SESSION_PARAM_ATTR_STS_LENGTH] =
NLA_POLICY_MAX(NLA_U8, FIRA_STS_LENGTH_128),
[FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_CONFIG] =
- NLA_POLICY_MAX(NLA_U8, FIRA_RANGE_DATA_NTF_PROXIMITY),
- [FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_NEAR] =
+ NLA_POLICY_MAX(NLA_U8, FIRA_RANGE_DATA_NTF_PROXIMITY_AND_AOA_CROSSING),
+ [FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_NEAR_MM] =
{ .type = NLA_U32 },
- [FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_FAR] =
+ [FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_FAR_MM] =
{ .type = NLA_U32 },
+ [FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_LOWER_BOUND_AOA_AZIMUTH_2PI] =
+ NLA_POLICY_RANGE(NLA_S16,
+ FIRA_SESSION_DATA_NTF_LOWER_BOUND_AOA_AZIMUTH_2PI_MIN,
+ FIRA_SESSION_DATA_NTF_LOWER_BOUND_AOA_AZIMUTH_2PI_MAX),
+ [FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_UPPER_BOUND_AOA_AZIMUTH_2PI] =
+ NLA_POLICY_RANGE(NLA_S16,
+ FIRA_SESSION_DATA_NTF_UPPER_BOUND_AOA_AZIMUTH_2PI_MIN,
+ FIRA_SESSION_DATA_NTF_UPPER_BOUND_AOA_AZIMUTH_2PI_MAX),
+ [FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_LOWER_BOUND_AOA_ELEVATION_2PI] =
+ NLA_POLICY_RANGE(NLA_S16,
+ FIRA_SESSION_DATA_NTF_LOWER_BOUND_AOA_ELEVATION_2PI_MIN,
+ FIRA_SESSION_DATA_NTF_LOWER_BOUND_AOA_ELEVATION_2PI_MAX),
+ [FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_UPPER_BOUND_AOA_ELEVATION_2PI] =
+ NLA_POLICY_RANGE(NLA_S16,
+ FIRA_SESSION_DATA_NTF_UPPER_BOUND_AOA_ELEVATION_2PI_MIN,
+ FIRA_SESSION_DATA_NTF_UPPER_BOUND_AOA_ELEVATION_2PI_MAX),
};
/**
@@ -373,35 +389,6 @@ static int fira_session_params_set_measurement_sequence(
}
/**
- * check_parameter_proximity_range() - Check proximity range concistency.
- * @params: Current session parameters.
- * @set_attrs: Updated session parameters.
- *
- * Return: 0 or error.
- */
-static inline int
-check_parameter_proximity_range(const struct fira_session_params *params,
- struct nlattr *const *set_attrs)
-{
- uint32_t proximity_near = params->range_data_ntf_proximity_near_mm;
- uint32_t proximity_far = params->range_data_ntf_proximity_far_mm;
- const struct nlattr *near_attr =
- set_attrs[FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_NEAR];
- const struct nlattr *far_attr =
- set_attrs[FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_FAR];
- if (near_attr) {
- proximity_near = nla_get_u32(near_attr);
- }
- if (far_attr) {
- proximity_far = nla_get_u32(far_attr);
- }
- if (proximity_near > proximity_far) {
- return -ERANGE;
- }
- return 0;
-}
-
-/**
* fira_session_set_parameters() - Set FiRa session parameters.
* @local: FiRa context.
* @session_id: FiRa session id.
@@ -432,10 +419,6 @@ static int fira_session_set_parameters(struct fira_local *local, u32 session_id,
if (r)
return r;
/* Check attribute validity. */
- r = check_parameter_proximity_range(&session->params, attrs);
- if (r)
- return r;
-
if (attrs[FIRA_SESSION_PARAM_ATTR_MEASUREMENT_SEQUENCE]) {
r = fira_session_params_set_measurement_sequence(
attrs[FIRA_SESSION_PARAM_ATTR_MEASUREMENT_SEQUENCE],
@@ -542,10 +525,18 @@ static int fira_session_set_parameters(struct fira_local *local, u32 session_id,
/* Misc */
P(STS_LENGTH, sts_length, u8, x);
P(RANGE_DATA_NTF_CONFIG, range_data_ntf_config, u8, x);
- P(RANGE_DATA_NTF_PROXIMITY_NEAR, range_data_ntf_proximity_near_mm, u32,
- x);
- P(RANGE_DATA_NTF_PROXIMITY_FAR, range_data_ntf_proximity_far_mm, u32,
- x);
+ P(RANGE_DATA_NTF_PROXIMITY_NEAR_MM, range_data_ntf_proximity_near_rctu,
+ u32, fira_mm_to_rctu(local, x));
+ P(RANGE_DATA_NTF_PROXIMITY_FAR_MM, range_data_ntf_proximity_far_rctu,
+ u32, fira_mm_to_rctu(local, x));
+ P(RANGE_DATA_NTF_LOWER_BOUND_AOA_AZIMUTH_2PI,
+ range_data_ntf_lower_bound_aoa_azimuth_2pi, s16, x);
+ P(RANGE_DATA_NTF_UPPER_BOUND_AOA_AZIMUTH_2PI,
+ range_data_ntf_upper_bound_aoa_azimuth_2pi, s16, x);
+ P(RANGE_DATA_NTF_LOWER_BOUND_AOA_ELEVATION_2PI,
+ range_data_ntf_lower_bound_aoa_elevation_2pi, s16, x);
+ P(RANGE_DATA_NTF_UPPER_BOUND_AOA_ELEVATION_2PI,
+ range_data_ntf_upper_bound_aoa_elevation_2pi, s16, x);
#undef PMEMNCPY
#undef PMEMCPY
#undef P
@@ -779,10 +770,18 @@ static int fira_session_get_parameters(struct fira_local *local, u32 session_id)
/* Misc */
P(STS_LENGTH, sts_length, u8, x);
P(RANGE_DATA_NTF_CONFIG, range_data_ntf_config, u8, x);
- P(RANGE_DATA_NTF_PROXIMITY_NEAR, range_data_ntf_proximity_near_mm, u32,
- x);
- P(RANGE_DATA_NTF_PROXIMITY_FAR, range_data_ntf_proximity_far_mm, u32,
- x);
+ P(RANGE_DATA_NTF_PROXIMITY_NEAR_MM, range_data_ntf_proximity_near_rctu,
+ u32, fira_rctu_to_mm((s64)local->llhw->dtu_freq_hz * local->llhw->dtu_rctu, x));
+ P(RANGE_DATA_NTF_PROXIMITY_FAR_MM, range_data_ntf_proximity_far_rctu,
+ u32, fira_rctu_to_mm((s64)local->llhw->dtu_freq_hz * local->llhw->dtu_rctu, x));
+ P(RANGE_DATA_NTF_LOWER_BOUND_AOA_AZIMUTH_2PI,
+ range_data_ntf_lower_bound_aoa_azimuth_2pi, s16, x);
+ P(RANGE_DATA_NTF_UPPER_BOUND_AOA_AZIMUTH_2PI,
+ range_data_ntf_upper_bound_aoa_azimuth_2pi, s16, x);
+ P(RANGE_DATA_NTF_LOWER_BOUND_AOA_ELEVATION_2PI,
+ range_data_ntf_lower_bound_aoa_elevation_2pi, s16, x);
+ P(RANGE_DATA_NTF_UPPER_BOUND_AOA_ELEVATION_2PI,
+ range_data_ntf_upper_bound_aoa_elevation_2pi, s16, x);
#undef P
#undef PMEMCPY
@@ -878,6 +877,7 @@ static int fira_manage_controlees(struct fira_local *local,
} else {
controlee->sub_session = false;
}
+ controlee->range_data_ntf_status = FIRA_RANGE_DATA_NTF_NONE;
controlee->state = FIRA_CONTROLEE_STATE_RUNNING;
/* Check and reject a duplication of short_addr. */
list_for_each_entry (tmp_controlee, &controlees, entry) {
diff --git a/mac/fira_session.c b/mac/fira_session.c
index cca4252..e5f2e3a 100644
--- a/mac/fira_session.c
+++ b/mac/fira_session.c
@@ -26,7 +26,6 @@
#include <linux/ieee802154.h>
#include <linux/string.h>
#include <linux/limits.h>
-#include <linux/math64.h>
#include <net/mcps802154_frame.h>
#include <net/fira_region_nl.h>
@@ -129,11 +128,8 @@ inline static int fira_session_report_measurement(
return 0;
}
if (ranging_data->tof_present) {
- static const s64 speed_of_light_mm_per_s = 299702547000ull;
- s32 distance_mm = div64_s64(ranging_data->tof_rctu *
- speed_of_light_mm_per_s,
- rctu_freq_hz);
- if (nla_put_s32(msg, A(DISTANCE_MM), distance_mm))
+ if (nla_put_s32(msg, A(DISTANCE_MM),
+ fira_rctu_to_mm(rctu_freq_hz, ranging_data->tof_rctu)))
goto nla_put_failure;
}
if (ranging_data->local_aoa.present) {
@@ -222,6 +218,7 @@ fira_session_report_ranging_data(const struct fira_session *session,
s64 rctu_freq_hz = (s64)dtu_freq_hz * dtu_rctu;
int i;
+ int n_ranging_to_send = 0;
data = nla_nest_start(msg, FIRA_CALL_ATTR_RANGING_DATA);
if (!data)
@@ -261,13 +258,20 @@ fira_session_report_ranging_data(const struct fira_session *session,
goto end_report;
}
- if (report_info->n_ranging_data + report_info->n_stopped_controlees) {
+ for (i = 0; i < report_info->n_ranging_data; i++) {
+ if (report_info->ranging_data[i].notify)
+ n_ranging_to_send++;
+ }
+
+ if (n_ranging_to_send + report_info->n_stopped_controlees) {
measurements = nla_nest_start(
msg, FIRA_RANGING_DATA_ATTR_MEASUREMENTS);
if (!measurements)
goto nla_put_failure;
for (i = 0; i < report_info->n_ranging_data; i++) {
+ if (!report_info->ranging_data[i].notify)
+ continue;
measurement = nla_nest_start(msg, 1);
if (fira_session_report_measurement(
session, msg, &report_info->ranging_data[i],
@@ -568,9 +572,17 @@ struct fira_session *fira_session_new(struct fira_local *local, u32 session_id)
params->report_tof = true;
params->result_report_phase = true;
params->range_data_ntf_config = FIRA_RANGE_DATA_NTF_ALWAYS;
- params->range_data_ntf_proximity_near_mm = 0;
- params->range_data_ntf_proximity_far_mm =
- FIRA_RANGE_DATA_NTF_PROXIMITY_FAR_DEFAULT;
+ params->range_data_ntf_proximity_near_rctu = 0;
+ params->range_data_ntf_proximity_far_rctu = fira_mm_to_rctu(
+ local, FIRA_RANGE_DATA_NTF_PROXIMITY_FAR_MM_DEFAULT);
+ params->range_data_ntf_lower_bound_aoa_azimuth_2pi =
+ FIRA_SESSION_DATA_NTF_LOWER_BOUND_AOA_AZIMUTH_2PI_DEFAULT;
+ params->range_data_ntf_upper_bound_aoa_azimuth_2pi =
+ FIRA_SESSION_DATA_NTF_UPPER_BOUND_AOA_AZIMUTH_2PI_DEFAULT;
+ params->range_data_ntf_lower_bound_aoa_elevation_2pi =
+ FIRA_SESSION_DATA_NTF_LOWER_BOUND_AOA_ELEVATION_2PI_DEFAULT;
+ params->range_data_ntf_upper_bound_aoa_elevation_2pi =
+ FIRA_SESSION_DATA_NTF_UPPER_BOUND_AOA_ELEVATION_2PI_DEFAULT;
if (fira_round_hopping_sequence_init(session))
goto failed;
@@ -762,6 +774,51 @@ void fira_session_update_controlees(struct fira_local *local,
}
}
+/**
+ * check_parameter_proximity_range() - Check proximity range consistency.
+ * @params: Current session parameters.
+ *
+ * Return: 0 or error.
+ */
+static inline int
+check_parameter_proximity_range(const struct fira_session_params *params)
+{
+ return (params->range_data_ntf_proximity_near_rctu >
+ params->range_data_ntf_proximity_far_rctu) ?
+ -ERANGE :
+ 0;
+}
+
+/**
+ * check_parameter_bound_aoa_azimuth() - Check aoa azimuth range consistency.
+ * @params: Current session parameters.
+ *
+ * Return: 0 or error.
+ */
+static inline int
+check_parameter_bound_aoa_azimuth(const struct fira_session_params *params)
+{
+ return (params->range_data_ntf_lower_bound_aoa_azimuth_2pi >
+ params->range_data_ntf_upper_bound_aoa_azimuth_2pi) ?
+ -ERANGE :
+ 0;
+}
+
+/**
+ * check_parameter_bound_aoa_elevation() - Check aoa elevation range consistency.
+ * @params: Current session parameters.
+ *
+ * Return: 0 or error.
+ */
+static inline int
+check_parameter_bound_aoa_elevation(const struct fira_session_params *params)
+{
+ return (params->range_data_ntf_lower_bound_aoa_elevation_2pi >
+ params->range_data_ntf_upper_bound_aoa_elevation_2pi) ?
+ -ERANGE :
+ 0;
+}
+
bool fira_session_is_ready(const struct fira_local *local,
const struct fira_session *session)
{
@@ -816,6 +873,29 @@ bool fira_session_is_ready(const struct fira_local *local,
(params->number_of_sts_segments == FIRA_STS_SEGMENTS_0))
return false;
+ /* Check range data ntf parameters consistency. */
+ switch (params->range_data_ntf_config) {
+ case FIRA_RANGE_DATA_NTF_PROXIMITY:
+ case FIRA_RANGE_DATA_NTF_PROXIMITY_AND_AOA:
+ case FIRA_RANGE_DATA_NTF_PROXIMITY_CROSSING:
+ case FIRA_RANGE_DATA_NTF_PROXIMITY_AND_AOA_CROSSING:
+ if (check_parameter_proximity_range(&session->params))
+ return false;
+ default:
+ break;
+ }
+ switch (params->range_data_ntf_config) {
+ case FIRA_RANGE_DATA_NTF_AOA:
+ case FIRA_RANGE_DATA_NTF_PROXIMITY_AND_AOA:
+ case FIRA_RANGE_DATA_NTF_AOA_CROSSING:
+ case FIRA_RANGE_DATA_NTF_PROXIMITY_AND_AOA_CROSSING:
+ if (check_parameter_bound_aoa_azimuth(&session->params))
+ return false;
+ if (check_parameter_bound_aoa_elevation(&session->params))
+ return false;
+ default:
+ break;
+ }
round_duration_dtu =
params->slot_duration_dtu * params->round_duration_slots;
return params->slot_duration_dtu != 0 &&
@@ -825,79 +905,253 @@ bool fira_session_is_ready(const struct fira_local *local,
}
/**
- * proximity_enable_report() - Check proximity range to enable/disable report.
- * @report_info: report info to be enabled/disabled
- * @min_distance_mm: minimum distance in mm, value included
- * @max_distance_mm: maximum distance in mm, value included
- * @dtu_freq_hz: Frequency, to be used to compute distance from report
- * @dtu_rctu: RCTU, to be used to compute distance from report
- *
- * Return: true if the report should be sent
+ * is_ranging_in_proximity_bounds() - Check if ranging data are in
+ * range_data_ntf proximity boundaries.
+ * @session: FiRa session.
+ * @ranging_data: Ranging data to be evaluated.
*
- * Report notification is sent with all of its measurements when:
- * - it contains a stopped condition
- * - it contains stopped controlees
- * - it contains a measurement error
- * - one of its measurement is inside of the configured proximity range
+ * Return: true if the ranging data are inside proximity boundaries.
+ */
+static inline bool
+is_ranging_in_proximity_bounds(const struct fira_session *session,
+ const struct fira_ranging_info *ranging_data)
+{
+ return (ranging_data->tof_rctu >=
+ session->params.range_data_ntf_proximity_near_rctu &&
+ ranging_data->tof_rctu <=
+ session->params.range_data_ntf_proximity_far_rctu);
+}
+
+/**
+ * is_ranging_in_aoa_bounds() - Check if ranging data are in
+ * range_data_ntf AoA boundaries.
+ * @session: FiRa local session.
+ * @ranging_data: Ranging data to be evaluated.
*
- * Report notification is not sent when all of its measurements are valid
- * and outside of the configured proximity range.
+ * Return: true if ranging data are inside AoA boundaries.
*/
-static bool proximity_enable_report(const struct fira_report_info *report_info,
- u32 min_distance_mm, u32 max_distance_mm,
- int dtu_freq_hz, int dtu_rctu)
-{
- static const s64 speed_of_light_mm_per_s = 299702547000ull;
- const s64 rctu_freq_hz = (s64)dtu_freq_hz * dtu_rctu;
- s32 distance_mm;
- const struct fira_ranging_info *ranging_data;
- int i;
+static inline bool
+is_ranging_in_aoa_bounds(const struct fira_session *session,
+ const struct fira_ranging_info *ranging_data)
+{
+ if (ranging_data->local_aoa_azimuth.present &&
+ ((ranging_data->local_aoa_azimuth.aoa_2pi <
+ session->params.range_data_ntf_lower_bound_aoa_azimuth_2pi) ||
+ (ranging_data->local_aoa_azimuth.aoa_2pi >
+ session->params.range_data_ntf_upper_bound_aoa_azimuth_2pi)))
+ return false;
- if (report_info->stopped || report_info->n_stopped_controlees) {
+ if (ranging_data->local_aoa_elevation.present &&
+ ((ranging_data->local_aoa_elevation.aoa_2pi <
+ session->params.range_data_ntf_lower_bound_aoa_elevation_2pi) ||
+ (ranging_data->local_aoa_elevation.aoa_2pi >
+ session->params.range_data_ntf_upper_bound_aoa_elevation_2pi)))
+ return false;
+ return true;
+}
+
+void fira_session_set_range_data_ntf_status(const struct fira_session *session,
+ struct fira_ranging_info *ri)
+{
+ switch (session->params.range_data_ntf_config) {
+ default:
+ case FIRA_RANGE_DATA_NTF_DISABLED:
+ case FIRA_RANGE_DATA_NTF_ALWAYS:
+ ri->range_data_ntf_status = FIRA_RANGE_DATA_NTF_NONE;
+ break;
+ case FIRA_RANGE_DATA_NTF_PROXIMITY:
+ case FIRA_RANGE_DATA_NTF_PROXIMITY_CROSSING:
+ if (ri->status != FIRA_STATUS_RANGING_SUCCESS ||
+ !ri->tof_present)
+ ri->range_data_ntf_status = FIRA_RANGE_DATA_NTF_ERROR;
+ else
+ ri->range_data_ntf_status =
+ is_ranging_in_proximity_bounds(session, ri) ?
+ FIRA_RANGE_DATA_NTF_IN :
+ FIRA_RANGE_DATA_NTF_OUT;
+ break;
+ case FIRA_RANGE_DATA_NTF_AOA:
+ case FIRA_RANGE_DATA_NTF_AOA_CROSSING:
+ if (ri->status != FIRA_STATUS_RANGING_SUCCESS)
+ ri->range_data_ntf_status = FIRA_RANGE_DATA_NTF_ERROR;
+ else
+ ri->range_data_ntf_status =
+ is_ranging_in_aoa_bounds(session, ri) ?
+ FIRA_RANGE_DATA_NTF_IN :
+ FIRA_RANGE_DATA_NTF_OUT;
+ break;
+ case FIRA_RANGE_DATA_NTF_PROXIMITY_AND_AOA:
+ case FIRA_RANGE_DATA_NTF_PROXIMITY_AND_AOA_CROSSING:
+ if (FIRA_STATUS_RANGING_SUCCESS || !ri->tof_present)
+ ri->range_data_ntf_status = FIRA_RANGE_DATA_NTF_ERROR;
+ else
+ ri->range_data_ntf_status =
+ is_ranging_in_proximity_bounds(session, ri) &&
+ is_ranging_in_aoa_bounds(
+ session, ri) ?
+ FIRA_RANGE_DATA_NTF_IN :
+ FIRA_RANGE_DATA_NTF_OUT;
+ break;
+ }
+}
+
+/**
+ * send_ranging_data -- Compute if a device has data to report.
+ * @config: range_data_ntf_config session parameter.
+ * @ranging_status: Ranging range_data_ntf_status for the device this round.
+ * @device_status: Previous device range_data_ntf_status.
+ *
+ * Return: true if the device has data to report, else false.
+ */
+static inline bool
+send_ranging_data(enum fira_range_data_ntf_config config,
+ enum fira_range_data_ntf_status ranging_status,
+ enum fira_range_data_ntf_status device_status)
+{
+ switch (config) {
+ default:
+ case FIRA_RANGE_DATA_NTF_DISABLED:
+ return false;
+ case FIRA_RANGE_DATA_NTF_ALWAYS:
return true;
+ case FIRA_RANGE_DATA_NTF_PROXIMITY:
+ case FIRA_RANGE_DATA_NTF_AOA:
+ case FIRA_RANGE_DATA_NTF_PROXIMITY_AND_AOA:
+ return (ranging_status == FIRA_RANGE_DATA_NTF_IN) ||
+ (ranging_status == FIRA_RANGE_DATA_NTF_ERROR) ||
+ (ranging_status == FIRA_RANGE_DATA_NTF_IN_ERROR) ||
+ (ranging_status == FIRA_RANGE_DATA_NTF_OUT_ERROR);
+ case FIRA_RANGE_DATA_NTF_PROXIMITY_CROSSING:
+ case FIRA_RANGE_DATA_NTF_AOA_CROSSING:
+ case FIRA_RANGE_DATA_NTF_PROXIMITY_AND_AOA_CROSSING:
+ return (((ranging_status == FIRA_RANGE_DATA_NTF_IN) &&
+ ((device_status == FIRA_RANGE_DATA_NTF_OUT) ||
+ (device_status == FIRA_RANGE_DATA_NTF_OUT_ERROR) ||
+ (device_status == FIRA_RANGE_DATA_NTF_IN_ERROR) ||
+ (device_status == FIRA_RANGE_DATA_NTF_ERROR) ||
+ (device_status == FIRA_RANGE_DATA_NTF_NONE))) ||
+ ((ranging_status == FIRA_RANGE_DATA_NTF_OUT) &&
+ ((device_status == FIRA_RANGE_DATA_NTF_IN) ||
+ (device_status == FIRA_RANGE_DATA_NTF_IN_ERROR))) ||
+ ((ranging_status == FIRA_RANGE_DATA_NTF_ERROR) &&
+ (device_status == FIRA_RANGE_DATA_NTF_IN)));
}
+}
- for (i = 0; i < report_info->n_ranging_data; i++) {
- ranging_data = &report_info->ranging_data[i];
- if (ranging_data->status != FIRA_STATUS_RANGING_SUCCESS) {
- return true;
+/**
+ * get_range_data_status_update -- Compute new device's range_data_ntf_status,
+ * given the ranging status and previous device status.
+ * @ranging_status: Ranging range_data_ntf_status for the device this round.
+ * @device_status: Previous device range_data_ntf_status.
+ *
+ * Return: new device range_data_ntf_status.
+ */
+static inline enum fira_range_data_ntf_status
+get_range_data_status_update(enum fira_range_data_ntf_status ranging_status,
+ enum fira_range_data_ntf_status device_status)
+{
+ enum fira_range_data_ntf_status ret = FIRA_RANGE_DATA_NTF_NONE;
+ switch (ranging_status) {
+ case FIRA_RANGE_DATA_NTF_NONE:
+ case FIRA_RANGE_DATA_NTF_IN:
+ case FIRA_RANGE_DATA_NTF_OUT:
+ ret = ranging_status;
+ break;
+ case FIRA_RANGE_DATA_NTF_ERROR:
+ switch (device_status) {
+ case FIRA_RANGE_DATA_NTF_NONE:
+ case FIRA_RANGE_DATA_NTF_ERROR:
+ ret = FIRA_RANGE_DATA_NTF_ERROR;
+ break;
+ case FIRA_RANGE_DATA_NTF_IN:
+ case FIRA_RANGE_DATA_NTF_IN_ERROR:
+ ret = FIRA_RANGE_DATA_NTF_IN_ERROR;
+ break;
+ case FIRA_RANGE_DATA_NTF_OUT:
+ case FIRA_RANGE_DATA_NTF_OUT_ERROR:
+ ret = FIRA_RANGE_DATA_NTF_OUT_ERROR;
+ break;
}
- if (!ranging_data->tof_present) {
- return true;
+ break;
+ /* defensive check, should not happened */
+ /* LCOV_EXCL_START */
+ case FIRA_RANGE_DATA_NTF_IN_ERROR:
+ case FIRA_RANGE_DATA_NTF_OUT_ERROR:
+ default:
+ ret = FIRA_RANGE_DATA_NTF_NONE;
+ break;
+ }
+ /* LCOV_EXCL_STOP */
+ return ret;
+}
+
+/**
+ * range_data_notif_update -- Update remote device(s) range_data_ntf_status
+ * and determine if report is to be sent.
+ * @local: FiRa context.
+ * @session: FiRa session.
+ * @report_info: Report info to be analysed.
+ *
+ * Return: true if there is actually data to report, else false.
+ */
+static bool range_data_notif_update(struct fira_local *local,
+ struct fira_session *session,
+ struct fira_report_info *report_info)
+{
+ bool send_report = false;
+ enum fira_range_data_ntf_config config =
+ session->params.range_data_ntf_config;
+
+ if (report_info->stopped || report_info->n_stopped_controlees)
+ send_report = true;
+
+ if (session->params.device_type == FIRA_DEVICE_TYPE_CONTROLLER) {
+ int i;
+
+ for (i = 0; i < report_info->n_ranging_data; i++) {
+ enum fira_range_data_ntf_status ctlee_status;
+ struct fira_ranging_info *ri =
+ &report_info->ranging_data[i];
+ struct fira_controlee *controlee =
+ fira_session_get_controlee(session,
+ ri->short_addr);
+
+ fira_session_set_range_data_ntf_status(session, ri);
+ ctlee_status = controlee->range_data_ntf_status;
+ ri->notify = send_ranging_data(
+ config, ri->range_data_ntf_status,
+ ctlee_status);
+ controlee->range_data_ntf_status =
+ get_range_data_status_update(
+ ri->range_data_ntf_status,
+ ctlee_status);
+ send_report |= ri->notify;
}
- /* Computation needs to be kept in sync with fira_session_report_measurement() */
- distance_mm = div64_s64(ranging_data->tof_rctu *
- speed_of_light_mm_per_s,
- rctu_freq_hz);
- if (distance_mm >= min_distance_mm &&
- distance_mm <= max_distance_mm) {
- return true;
+ } else {
+ /* Controlee, so we can assume n_ranging_data == 0 or 1 */
+ if (report_info->n_ranging_data) {
+ enum fira_range_data_ntf_status ctlr_status =
+ session->controlee.ctlr_range_data_ntf_status;
+ struct fira_ranging_info *ri =
+ &report_info->ranging_data[0];
+ fira_session_set_range_data_ntf_status(session, ri);
+ ri->notify = send_report = send_ranging_data(
+ config, ri->range_data_ntf_status, ctlr_status);
+ session->controlee.ctlr_range_data_ntf_status =
+ get_range_data_status_update(
+ ri->range_data_ntf_status, ctlr_status);
}
}
-
- return false;
+ return send_report;
}
void fira_session_report(struct fira_local *local, struct fira_session *session,
- const struct fira_report_info *report_info)
+ struct fira_report_info *report_info)
{
struct sk_buff *msg;
- const struct fira_session_params *params = &session->params;
- if (params->range_data_ntf_config == FIRA_RANGE_DATA_NTF_DISABLED &&
- !report_info->stopped && !report_info->n_stopped_controlees) {
+ if (!range_data_notif_update(local, session, report_info))
return;
- }
-
- if (params->range_data_ntf_config == FIRA_RANGE_DATA_NTF_PROXIMITY) {
- if (!proximity_enable_report(
- report_info,
- params->range_data_ntf_proximity_near_mm,
- params->range_data_ntf_proximity_far_mm,
- local->llhw->dtu_freq_hz, local->llhw->dtu_rctu)) {
- return;
- }
- }
trace_region_fira_session_report(session, report_info);
msg = mcps802154_region_event_alloc_skb(local->llhw, &local->region,
diff --git a/mac/fira_session.h b/mac/fira_session.h
index 4f02596..d890f31 100644
--- a/mac/fira_session.h
+++ b/mac/fira_session.h
@@ -81,6 +81,10 @@ struct fira_controlee {
*/
enum fira_controlee_state state;
/**
+ * @range_data_ntf_status: range_data_ntf status of the controlee.
+ */
+ enum fira_range_data_ntf_status range_data_ntf_status;
+ /**
* @entry: Entry in list of controlees.
*/
struct list_head entry;
@@ -154,8 +158,12 @@ struct fira_session_params {
/* Misc */
enum fira_sts_length sts_length;
enum fira_range_data_ntf_config range_data_ntf_config;
- u32 range_data_ntf_proximity_near_mm;
- u32 range_data_ntf_proximity_far_mm;
+ u32 range_data_ntf_proximity_near_rctu;
+ u32 range_data_ntf_proximity_far_rctu;
+ s16 range_data_ntf_lower_bound_aoa_azimuth_2pi;
+ s16 range_data_ntf_upper_bound_aoa_azimuth_2pi;
+ s16 range_data_ntf_lower_bound_aoa_elevation_2pi;
+ s16 range_data_ntf_upper_bound_aoa_elevation_2pi;
};
/**
@@ -282,6 +290,11 @@ struct fira_session {
* is present in measurement report frame.
*/
bool next_round_index_valid;
+ /**
+ * @ctlr_range_data_ntf_status: range_data_ntf status of the
+ * controller.
+ */
+ enum fira_range_data_ntf_status ctlr_range_data_ntf_status;
} controlee;
/**
* @controller: Group of persistent variable(s) used when session
@@ -412,7 +425,7 @@ struct fira_report_info {
* @ranging_data: Base address of ranging data per peer, or null
* pointer.
*/
- const struct fira_ranging_info *ranging_data;
+ struct fira_ranging_info *ranging_data;
/**
* @n_ranging_data: Number of entry in ranging_data above.
*/
@@ -505,6 +518,24 @@ int fira_session_del_controlees(struct fira_session *session,
struct list_head *controlees, bool async);
/**
+ * fira_session_get_controlee() - Get controlee info from short address.
+ * @session: Session.
+ * @short_addr: Short address of the controlee.
+ *
+ * Return: The corresponding controlee object or NULL.
+ */
+static inline struct fira_controlee *
+fira_session_get_controlee(struct fira_session *session, u16 short_addr)
+{
+ struct fira_controlee *controlee;
+ list_for_each_entry (controlee, &session->current_controlees, entry) {
+ if (controlee->short_addr == short_addr)
+ return controlee;
+ }
+ return NULL;
+}
+
+/**
* fira_session_stop_controlees() - Stop controlees.
* @session: Session.
*/
@@ -590,13 +621,23 @@ fira_session_get_rx_ant_set(const struct fira_session *session,
}
/**
+ * fira_session_set_range_data_ntf_status() - Update range_data_ntf_status
+ * for a given ranging.
+ * @session: FiRa session.
+ * @ranging_info: ranging data to be evaluated.
+ */
+void fira_session_set_range_data_ntf_status(
+ const struct fira_session *session,
+ struct fira_ranging_info *ranging_info);
+
+/**
* fira_session_report() - Report state change and ranging result for a session.
* @local: FiRa context.
* @session: Session to report.
* @report_info: report information to exploit for the reporting.
*/
void fira_session_report(struct fira_local *local, struct fira_session *session,
- const struct fira_report_info *report_info);
+ struct fira_report_info *report_info);
/**
* fira_session_controlee_active() - Return whether the controlee is currently active.
diff --git a/mac/fira_session_fsm_active.c b/mac/fira_session_fsm_active.c
index 90ddc94..dc86393 100644
--- a/mac/fira_session_fsm_active.c
+++ b/mac/fira_session_fsm_active.c
@@ -346,9 +346,12 @@ fira_session_fsm_active_check_parameters(const struct fira_session *session,
case FIRA_SESSION_PARAM_ATTR_MEASUREMENT_SEQUENCE:
case FIRA_SESSION_PARAM_ATTR_DATA_PAYLOAD:
case FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_CONFIG:
- case FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_NEAR:
- case FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_FAR:
- /* Allowed for all device type. */
+ case FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_NEAR_MM:
+ case FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_FAR_MM:
+ case FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_LOWER_BOUND_AOA_AZIMUTH_2PI:
+ case FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_UPPER_BOUND_AOA_AZIMUTH_2PI:
+ case FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_LOWER_BOUND_AOA_ELEVATION_2PI:
+ case FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_UPPER_BOUND_AOA_ELEVATION_2PI: /* Allowed for all device type. */
break;
case FIRA_SESSION_PARAM_ATTR_BLOCK_STRIDE_LENGTH:
/* Allowed only for controller. */
diff --git a/mac/include/net/fira_region_nl.h b/mac/include/net/fira_region_nl.h
index a78788c..07c3fb5 100644
--- a/mac/include/net/fira_region_nl.h
+++ b/mac/include/net/fira_region_nl.h
@@ -410,13 +410,36 @@ enum fira_call_attrs {
* Minimum for contention access period size
* @FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_CONFIG:
* Configure range data notification
- * @FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_NEAR:
- * Lower bound in cm above which the ranging notifications
- * should be enabled when RANGE_DATA_NTF_CONFIG is set to "proximity"
- * @FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_FAR:
- * Upper bound in cm above which the ranging notifications
- * should be disabled when RANGE_DATA_NTF_CONFIG is set to "proximity"
- *
+ * @FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_NEAR_MM:
+ * Lower bound in mm above which the ranging notifications
+ * should be enabled when RANGE_DATA_NTF_CONFIG is set to "proximity" or "aoa_proximity"
+ * @FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_FAR_MM:
+ * Upper bound in mm above which the ranging notifications
+ * should be disabled when RANGE_DATA_NTF_CONFIG is set to "proximity" or "aoa_proximity"
+ * @FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_LOWER_BOUND_AOA_AZIMUTH_2PI:
+ * Lower bound in rad_2pi_q16 for AOA azimuth above which the ranging notifications
+ * should automatically be enabled if RANGE_DATA_NTF_CONFIG is set to "aoa" or "aoa_proximity".
+ * It is a signed value on 16 bits (rad_2pi_q16). Allowed values range from -180° to ~180°.
+ * should be less than or equal to RANGE_DATA_NTF_UPPER_BOUND_AOA_AZIMUTH value.
+ * (default = -180)
+ * @FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_UPPER_BOUND_AOA_AZIMUTH_2PI:
+ * Upper bound in rad_2pi_q16 for AOA azimuth above which the ranging notifications
+ * should automatically be disabled if RANGE_DATA_NTF_CONFIG is set to "aoa" or "aoa_proximity".
+ * It is a signed value on 16 bits (rad_2pi_q16). Allowed values range from -180° to ~180°.
+ * Should be greater than or equal to RANGE_DATA_NTF_LOWER_BOUND_AOA_AZIMUTH value.
+ * (default = ~180)
+ * @FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_LOWER_BOUND_AOA_ELEVATION_2PI:
+ * Lower bound in rad_2pi_q16 for AOA elevation above which the ranging notifications
+ * should automatically be enabled if RANGE_DATA_NTF_CONFIG is set to "aoa" or "aoa_proximity".
+ * It is a signed value on 16 bits (rad_2pi_q16). Allowed values range from -90° to +90°.
+ * Should be less than or equal to RANGE_DATA_NTF_PROXIMITY_UPPER_BOUND_A_ELEVATION value.
+ * (default = -90)
+ * @FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_UPPER_BOUND_AOA_ELEVATION_2PI:
+ * Upper bound in rad_2pi_q16 for AOA elevation above which the ranging notifications
+ * should automatically be disabled if RANGE_DATA_NTF_CONFIG has bit is set to "aoa" or "aoa_proximity".
+ * It is a signed value on 16 bits (rad_2pi_q16). Allowed values range from -90° to +90°.
+ * Should be greater than or equal to RANGE_DATA_NTF_LOWER_BOUND_AOA_ELEVATION value.
+ * (default = +90)
* @FIRA_SESSION_PARAM_ATTR_UNSPEC: Invalid command.
* @__FIRA_SESSION_PARAM_ATTR_AFTER_LAST: Internal use.
* @FIRA_SESSION_PARAM_ATTR_MAX: Internal use.
@@ -487,8 +510,12 @@ enum fira_session_param_attrs {
FIRA_SESSION_PARAM_ATTR_CAP_SIZE_MIN,
/* Range data notification enable */
FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_CONFIG,
- FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_NEAR,
- FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_FAR,
+ FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_NEAR_MM,
+ FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_PROXIMITY_FAR_MM,
+ FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_LOWER_BOUND_AOA_AZIMUTH_2PI,
+ FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_UPPER_BOUND_AOA_AZIMUTH_2PI,
+ FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_LOWER_BOUND_AOA_ELEVATION_2PI,
+ FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_UPPER_BOUND_AOA_ELEVATION_2PI,
__FIRA_SESSION_PARAM_ATTR_AFTER_LAST,
FIRA_SESSION_PARAM_ATTR_MAX = __FIRA_SESSION_PARAM_ATTR_AFTER_LAST - 1
};
diff --git a/mac/include/net/fira_region_params.h b/mac/include/net/fira_region_params.h
index bd4f650..d289f11 100644
--- a/mac/include/net/fira_region_params.h
+++ b/mac/include/net/fira_region_params.h
@@ -38,8 +38,19 @@
*/
#define FIRA_DATA_PAYLOAD_SIZE_MAX 84
-/* From UCI spec v1.1.0 (converted to mm) */
-#define FIRA_RANGE_DATA_NTF_PROXIMITY_FAR_DEFAULT 200000
+/* From UCI spec v1.1.0 (converted to mm).
+ * Need a 2mm margin to avoid errors when converting to and from RCTU */
+#define FIRA_RANGE_DATA_NTF_PROXIMITY_FAR_MM_DEFAULT 200002
+
+/*
+ * FIRA_SESSION_DATA_NTF_LOWER_/UPPER_BOUND_AOA default values :
+ * Azimuth in rad_2pi_q16 : -32768 / 32767 (equal to -180 / ~180 degrees)
+ * Elevation in rad_2pi_q16 : -16384 / 16384 (equal to -90 / 90 degrees)
+ */
+#define FIRA_SESSION_DATA_NTF_LOWER_BOUND_AOA_AZIMUTH_2PI_DEFAULT -32768
+#define FIRA_SESSION_DATA_NTF_UPPER_BOUND_AOA_AZIMUTH_2PI_DEFAULT 32767
+#define FIRA_SESSION_DATA_NTF_LOWER_BOUND_AOA_ELEVATION_2PI_DEFAULT -16384
+#define FIRA_SESSION_DATA_NTF_UPPER_BOUND_AOA_ELEVATION_2PI_DEFAULT 16384
/**
* enum fira_device_type - Type of a device.
@@ -371,13 +382,36 @@ enum fira_sts_length {
* enum fira_range_data_ntf_config - Configure range data notification.
* @FIRA_RANGE_DATA_NTF_DISABLED: Do not report range data.
* @FIRA_RANGE_DATA_NTF_ALWAYS: Report range data.
- * @FIRA_RANGE_DATA_NTF_PROXIMITY: Report range data if it is within range
+ * @FIRA_RANGE_DATA_NTF_CONFIG_PROXIMITY: Report range data if it is within
+ * proximity range defined by proximity parameters.
* defined by proximity parameters (RANGE_DATA_NTF_PROXIMITY_NEAR/FAR).
+ * @FIRA_RANGE_DATA_NTF_CONFIG_AOA: Report range data in AoA upper and lower bound.
+ * defined by AOA parameters (FIRA_SESSION_PARAM_ATTR_RANGE_DATA_NTF_UPPER/
+ * LOWER_BOUND_AOA_AZIMUTH/ELEVATION)
+ * @FIRA_RANGE_DATA_NTF_CONFIG_PROXIMITY_AND_AOA: Report range data in AoA upper
+ * and lower bound as well as in proximity range.
+ * @FIRA_RANGE_DATA_NTF_CONFIG_PROXIMITY_CROSSING: Same as
+ * FIRA_RANGE_DATA_NTF_CONFIG_PROXIMITY, but issues notification on crossing of
+ * boundaries. As for now, same notif is sent for "enter" and "exit" events.
+ * @FIRA_RANGE_DATA_NTF_CONFIG_AOA_CROSSING: Same as
+ * FIRA_RANGE_DATA_NTF_CONFIG_AOA, but issues notification on crossing of boundaries.
+ * As for now, same notif is sent for "enter" and "exit" events.
+ * @FIRA_RANGE_DATA_NTF_CONFIG_PROXIMITY_AND_AOA_CROSSING: Same as
+ * FIRA_RANGE_DATA_NTF_CONFIG_PROXIMITY_AND_AOA, but issues notification on crossing of
+ * As for now, same notif is sent for "enter" and "exit" events.
+ * @FIRA_RANGE_DATA_NTF_PROXIMITY_AND_AOA_CROSSING: Same as
+ * FIRA_RANGE_DATA_NTF_PROXIMITY_AND_AOA, but issues notification on crossing of
+ * boundaries. As for now, same notif is sent for "enter" and "exit" events.
*/
enum fira_range_data_ntf_config {
- FIRA_RANGE_DATA_NTF_DISABLED = 0,
- FIRA_RANGE_DATA_NTF_ALWAYS = 1,
- FIRA_RANGE_DATA_NTF_PROXIMITY = 2
+ FIRA_RANGE_DATA_NTF_DISABLED = 0x00,
+ FIRA_RANGE_DATA_NTF_ALWAYS = 0x01,
+ FIRA_RANGE_DATA_NTF_PROXIMITY = 0x02,
+ FIRA_RANGE_DATA_NTF_AOA = 0x03,
+ FIRA_RANGE_DATA_NTF_PROXIMITY_AND_AOA = 0x04,
+ FIRA_RANGE_DATA_NTF_PROXIMITY_CROSSING = 0x05,
+ FIRA_RANGE_DATA_NTF_AOA_CROSSING = 0x06,
+ FIRA_RANGE_DATA_NTF_PROXIMITY_AND_AOA_CROSSING = 0x07,
};
#endif /* NET_FIRA_REGION_PARAMS_H */