[RFC 27/34] NAN: Support RSSI range limited services
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Aug 13 10:39:11 PDT 2025
Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski at intel.com>
---
src/ap/nan_usd_ap.c | 2 +-
src/common/nan_de.c | 42 +++++++++++++++++++++++++++------
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, 61 insertions(+), 14 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 0fb71edc4e..8917d2c5ed 100644
--- a/src/common/nan_de.c
+++ b/src/common/nan_de.c
@@ -75,8 +75,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];
@@ -97,6 +100,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;
};
@@ -128,6 +134,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;
}
@@ -268,6 +275,9 @@ 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->close_proximity)
+ ctrl |= NAN_SRV_CTRL_DISCOVERY_RANGE_LIMITED;
+
len += NAN_ATTR_HDR_LEN + sda_len;
/* Service Descriptor Extension attribute */
@@ -1089,7 +1099,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)
{
struct wpabuf *buf;
size_t len = 0, sda_len, sdea_len;
@@ -1102,6 +1113,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;
@@ -1284,7 +1305,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;
@@ -1427,7 +1448,10 @@ static void nan_de_rx_sda(struct nan_de *de, const u8 *peer_addr, const u8 *a3,
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,
@@ -1439,7 +1463,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;
@@ -1448,8 +1472,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);
@@ -1461,7 +1485,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);
}
}
@@ -1630,6 +1655,7 @@ int nan_de_publish(struct nan_de *de, const char *service_name,
publish_id, service_name);
srv->id = publish_id;
srv->is_p2p = p2p;
+ srv->close_proximity = params->close_proximity;
nan_de_add_srv(de, srv);
nan_de_run_timer(de);
return publish_id;
@@ -1879,6 +1905,8 @@ int nan_de_subscribe(struct nan_de *de, const char *service_name,
srv->id = subscribe_id;
srv->is_p2p = p2p;
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 f7a90de9f9..733ec4673e 100644
--- a/src/common/nan_de.h
+++ b/src/common/nan_de.h
@@ -77,7 +77,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 {
@@ -120,6 +120,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 */
@@ -175,6 +178,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 18a0c7cb48..6a2a6d4d57 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -12673,6 +12673,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;
@@ -12865,6 +12870,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 fcfce4a511..9ffae048bd 100644
--- a/wpa_supplicant/events.c
+++ b/wpa_supplicant/events.c
@@ -5586,7 +5586,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 1a2c04edbc..06ae41544a 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -498,11 +498,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