[PATCH 28/35] NAN: Support RSSI range limited services
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Mon Oct 20 05:28:03 PDT 2025
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
src/ap/nan_usd_ap.c | 2 +-
src/common/nan_de.c | 61 ++++++++++++++++++++++++++++-----
src/common/nan_de.h | 8 ++++-
wpa_supplicant/ctrl_iface.c | 10 ++++++
wpa_supplicant/events.c | 2 +-
wpa_supplicant/nan_supplicant.c | 5 +--
wpa_supplicant/nan_supplicant.h | 6 ++--
7 files changed, 78 insertions(+), 16 deletions(-)
diff --git a/src/ap/nan_usd_ap.c b/src/ap/nan_usd_ap.c
index 4623f678d8..0be922d735 100644
--- a/src/ap/nan_usd_ap.c
+++ b/src/ap/nan_usd_ap.c
@@ -180,7 +180,7 @@ void hostapd_nan_usd_rx_sdf(struct hostapd_data *hapd, const u8 *src,
{
if (!hapd->nan_de)
return;
- nan_de_rx_sdf(hapd->nan_de, src, a3, freq, buf, len);
+ nan_de_rx_sdf(hapd->nan_de, src, a3, freq, buf, len, 0);
}
diff --git a/src/common/nan_de.c b/src/common/nan_de.c
index 7b16d165d0..c6dd94f1ae 100644
--- a/src/common/nan_de.c
+++ b/src/common/nan_de.c
@@ -76,8 +76,11 @@ struct nan_de_service {
bool srf_type_bloom_filter;
u8 srf_bf_idx;
struct wpabuf *srf;
+ bool close_proximity;
};
+#define NAN_DE_RSSI_CLOSE_PROXIMITY (-70) /* dBm */
+
struct nan_de {
u8 nmi[ETH_ALEN];
u8 cluster_id[ETH_ALEN];
@@ -98,6 +101,9 @@ struct nan_de {
unsigned int tx_wait_end_freq;
int dw_freq;
+
+ /* RSSI threshold for close proximity, or zero if not limited */
+ int rssi_threshold;
};
@@ -129,6 +135,7 @@ struct nan_de * nan_de_init(const u8 *nmi, bool offload, bool ap,
de->max_listen = max_listen ? max_listen : 1000;
os_memcpy(&de->cb, cb, sizeof(*cb));
+ de->rssi_threshold = NAN_DE_RSSI_CLOSE_PROXIMITY;
return de;
}
@@ -269,6 +276,10 @@ static void nan_de_tx_sdf(struct nan_de *de, struct nan_de_service *srv,
ctrl |= NAN_SRV_CTRL_RESP_FILTER;
}
+ if ((srv->type == NAN_DE_SUBSCRIBE || srv->type == NAN_DE_PUBLISH) &&
+ srv->close_proximity)
+ ctrl |= NAN_SRV_CTRL_DISCOVERY_RANGE_LIMITED;
+
len += NAN_ATTR_HDR_LEN + sda_len;
/* Service Descriptor Extension attribute */
@@ -1053,7 +1064,8 @@ static void nan_de_rx_publish(struct nan_de *de, struct nan_de_service *srv,
size_t matching_filter_len,
u8 req_instance_id, u16 sdea_control,
enum nan_service_protocol_type srv_proto_type,
- const u8 *ssi, size_t ssi_len)
+ const u8 *ssi, size_t ssi_len,
+ bool range_limit, int rssi)
{
if (!nan_de_filter_match(srv, matching_filter, matching_filter_len))
return;
@@ -1062,6 +1074,16 @@ static void nan_de_rx_publish(struct nan_de *de, struct nan_de_service *srv,
if (srv->sync)
goto send_event;
+ if ((range_limit || srv->close_proximity) &&
+ de->rssi_threshold && rssi) {
+ if (rssi < de->rssi_threshold) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Discard SDA with RSSI %d below threshold %d",
+ rssi, de->rssi_threshold);
+ return;
+ }
+ }
+
/* Subscribe function processing of a receive Publish message */
if (!os_reltime_initialized(&srv->first_discovered)) {
os_get_reltime(&srv->first_discovered);
@@ -1100,7 +1122,8 @@ static void nan_de_rx_subscribe(struct nan_de *de, struct nan_de_service *srv,
const u8 *matching_filter,
size_t matching_filter_len,
enum nan_service_protocol_type srv_proto_type,
- const u8 *ssi, size_t ssi_len)
+ const u8 *ssi, size_t ssi_len,
+ bool range_limit, int rssi)
{
const u8 *network_id;
@@ -1109,6 +1132,16 @@ static void nan_de_rx_subscribe(struct nan_de *de, struct nan_de_service *srv,
if (!nan_de_filter_match(srv, matching_filter, matching_filter_len))
return;
+ if ((range_limit || srv->close_proximity) &&
+ de->rssi_threshold && rssi) {
+ if (rssi < de->rssi_threshold) {
+ wpa_printf(MSG_DEBUG,
+ "NAN: Discard SDA with RSSI %d below threshold %d",
+ rssi, de->rssi_threshold);
+ return;
+ }
+ }
+
if (!srv->publish.solicited)
return;
@@ -1230,7 +1263,7 @@ static bool nan_srf_match(struct nan_de *de, const u8 *srf, size_t srf_len)
static void nan_de_rx_sda(struct nan_de *de, const u8 *peer_addr, const u8 *a3,
unsigned int freq, const u8 *buf, size_t len,
- const u8 *sda, size_t sda_len)
+ const u8 *sda, size_t sda_len, int rssi)
{
const u8 *service_id;
u8 instance_id, req_instance_id, ctrl;
@@ -1367,14 +1400,20 @@ static void nan_de_rx_sda(struct nan_de *de, const u8 *peer_addr, const u8 *a3,
matching_filter_len,
req_instance_id,
sdea_control, srv_proto_type,
- ssi, ssi_len);
+ ssi, ssi_len,
+ ctrl &
+ NAN_SRV_CTRL_DISCOVERY_RANGE_LIMITED,
+ rssi);
break;
case NAN_SRV_CTRL_SUBSCRIBE:
nan_de_rx_subscribe(de, srv, peer_addr, a3, instance_id,
matching_filter,
matching_filter_len,
srv_proto_type,
- ssi, ssi_len);
+ ssi, ssi_len,
+ ctrl &
+ NAN_SRV_CTRL_DISCOVERY_RANGE_LIMITED,
+ rssi);
break;
case NAN_SRV_CTRL_FOLLOW_UP:
nan_de_rx_follow_up(de, srv, peer_addr, a3, instance_id,
@@ -1386,7 +1425,7 @@ static void nan_de_rx_sda(struct nan_de *de, const u8 *peer_addr, const u8 *a3,
void nan_de_rx_sdf(struct nan_de *de, const u8 *peer_addr, const u8 *a3,
- unsigned int freq, const u8 *buf, size_t len)
+ unsigned int freq, const u8 *buf, size_t len, int rssi)
{
const u8 *sda;
u16 sda_len;
@@ -1395,8 +1434,8 @@ void nan_de_rx_sdf(struct nan_de *de, const u8 *peer_addr, const u8 *a3,
if (!de->num_service)
return;
- wpa_printf(MSG_DEBUG, "NAN: RX SDF from " MACSTR " freq=%u len=%zu",
- MAC2STR(peer_addr), freq, len);
+ wpa_printf(MSG_DEBUG, "NAN: RX SDF from " MACSTR " freq=%u len=%zu rssi=%d",
+ MAC2STR(peer_addr), freq, len, rssi);
wpa_hexdump(MSG_MSGDUMP, "NAN: SDF payload", buf, len);
@@ -1408,7 +1447,8 @@ void nan_de_rx_sdf(struct nan_de *de, const u8 *peer_addr, const u8 *a3,
sda++;
sda_len = WPA_GET_LE16(sda);
sda += 2;
- nan_de_rx_sda(de, peer_addr, a3, freq, buf, len, sda, sda_len);
+ nan_de_rx_sda(de, peer_addr, a3, freq, buf, len, sda, sda_len,
+ rssi);
}
}
@@ -1591,6 +1631,7 @@ int nan_de_publish(struct nan_de *de, const char *service_name,
srv->id = publish_id;
srv->is_p2p = p2p;
srv->is_pr = params->proximity_ranging && params->solicited;
+ srv->close_proximity = params->close_proximity;
nan_de_add_srv(de, srv);
nan_de_run_timer(de);
return publish_id;
@@ -1854,6 +1895,8 @@ int nan_de_subscribe(struct nan_de *de, const char *service_name,
srv->is_p2p = p2p;
srv->is_pr = params->proximity_ranging && params->active;
srv->sync = params->sync;
+ srv->close_proximity = params->close_proximity;
+
nan_de_add_srv(de, srv);
nan_de_run_timer(de);
return subscribe_id;
diff --git a/src/common/nan_de.h b/src/common/nan_de.h
index cb35dd13d6..8c13230666 100644
--- a/src/common/nan_de.h
+++ b/src/common/nan_de.h
@@ -82,7 +82,7 @@ void nan_de_tx_status(struct nan_de *de, unsigned int freq, const u8 *dst);
void nan_de_tx_wait_ended(struct nan_de *de);
void nan_de_rx_sdf(struct nan_de *de, const u8 *peer_addr, const u8 *a3,
- unsigned int freq, const u8 *buf, size_t len);
+ unsigned int freq, const u8 *buf, size_t len, int rssi);
const u8 * nan_de_get_service_id(struct nan_de *de, int id);
struct nan_publish_params {
@@ -128,6 +128,9 @@ struct nan_publish_params {
*/
const char *match_filter_tx;
const char *match_filter_rx;
+
+ /* RSSI range limit */
+ bool close_proximity;
};
/* Returns -1 on failure or >0 publish_id */
@@ -186,6 +189,9 @@ struct nan_subscribe_params {
/* Bloom filter index (0-3) */
u8 srf_bf_idx;
+
+ /* RSSI range limit */
+ bool close_proximity;
};
/* Returns -1 on failure or >0 subscribe_id */
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 680529238e..13f1322791 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -12810,6 +12810,11 @@ static int wpas_ctrl_nan_publish(struct wpa_supplicant *wpa_s, char *cmd,
continue;
}
+ if (os_strcmp(token, "close_proximity=1") == 0) {
+ params.close_proximity = true;
+ continue;
+ }
+
wpa_printf(MSG_INFO, "CTRL: Invalid NAN_PUBLISH parameter: %s",
token);
goto fail;
@@ -13007,6 +13012,11 @@ static int wpas_ctrl_nan_subscribe(struct wpa_supplicant *wpa_s, char *cmd,
continue;
}
+ if (os_strcmp(token, "close_proximity=1") == 0) {
+ params.close_proximity = true;
+ continue;
+ }
+
wpa_printf(MSG_INFO,
"CTRL: Invalid NAN_SUBSCRIBE parameter: %s",
token);
diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c
index a68053d873..09948b6ee4 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -5576,7 +5576,7 @@ static void wpas_event_rx_mgmt_action(struct wpa_supplicant *wpa_s,
payload += 5;
plen -= 5;
wpas_nan_de_rx_sdf(wpa_s, mgmt->sa, mgmt->bssid, freq,
- payload, plen);
+ payload, plen, rssi);
return;
}
#endif /* CONFIG_NAN_USD || CONFIG_NAN */
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index 6e19263017..94226b81e3 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -535,11 +535,12 @@ void wpas_nan_de_deinit(struct wpa_supplicant *wpa_s)
void wpas_nan_de_rx_sdf(struct wpa_supplicant *wpa_s, const u8 *src,
const u8 *a3,
- unsigned int freq, const u8 *buf, size_t len)
+ unsigned int freq, const u8 *buf, size_t len,
+ int rssi)
{
if (!wpa_s->nan_de)
return;
- nan_de_rx_sdf(wpa_s->nan_de, src, a3, freq, buf, len);
+ nan_de_rx_sdf(wpa_s->nan_de, src, a3, freq, buf, len, rssi);
}
diff --git a/wpa_supplicant/nan_supplicant.h b/wpa_supplicant/nan_supplicant.h
index 9bf9713e72..bd76a26eda 100644
--- a/wpa_supplicant/nan_supplicant.h
+++ b/wpa_supplicant/nan_supplicant.h
@@ -66,7 +66,8 @@ int wpas_nan_de_init(struct wpa_supplicant *wpa_s);
void wpas_nan_de_deinit(struct wpa_supplicant *wpa_s);
void wpas_nan_de_rx_sdf(struct wpa_supplicant *wpa_s, const u8 *src,
const u8 *a3,
- unsigned int freq, const u8 *buf, size_t len);
+ unsigned int freq, const u8 *buf, size_t len,
+ int rssi);
void wpas_nan_de_flush(struct wpa_supplicant *wpa_s);
int wpas_nan_publish(struct wpa_supplicant *wpa_s, const char *service_name,
enum nan_service_protocol_type srv_proto_type,
@@ -100,7 +101,8 @@ static inline void wpas_nan_de_deinit(struct wpa_supplicant *wpa_s)
static inline
void wpas_nan_de_rx_sdf(struct wpa_supplicant *wpa_s, const u8 *src,
const u8 *a3,
- unsigned int freq, const u8 *buf, size_t len)
+ unsigned int freq, const u8 *buf, size_t len,
+ int rssi)
{}
static inline void wpas_nan_de_flush(struct wpa_supplicant *wpa_s)
--
2.49.0
More information about the Hostap
mailing list