[RFC 27/34] NAN: Support RSSI range limited services

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Signed-off-by: Andrei Otcheretianski <andrei.otcheretianski@xxxxxxxxx>
---
 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


_______________________________________________
Hostap mailing list
Hostap@xxxxxxxxxxxxxxxxxxx
http://lists.infradead.org/mailman/listinfo/hostap



[Index of Archives]     [Linux Wireless]     [Linux Kernel]     [ATH6KL]     [Linux Bluetooth]     [Linux Netdev]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Samba]     [Device Mapper]

  Powered by Linux