[RFC 31/34] NAN: Support configuring NAN operation

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

 



From: Ilan Peer <ilan.peer@xxxxxxxxx>

And support updating NAN configuration after NAN synchronization
has been started.

Signed-off-by: Ilan Peer <ilan.peer@xxxxxxxxx>
---
 src/nan/nan.c                     |  20 ++++
 src/nan/nan.h                     |   9 ++
 wpa_supplicant/ctrl_iface.c       |   6 ++
 wpa_supplicant/driver_i.h         |   8 ++
 wpa_supplicant/nan_supplicant.c   | 158 ++++++++++++++++++++++++++----
 wpa_supplicant/nan_supplicant.h   |  12 +++
 wpa_supplicant/wpa_supplicant_i.h |   1 +
 7 files changed, 195 insertions(+), 19 deletions(-)

diff --git a/src/nan/nan.c b/src/nan/nan.c
index 4030e5d698..0a3e1c8588 100644
--- a/src/nan/nan.c
+++ b/src/nan/nan.c
@@ -65,6 +65,26 @@ int nan_start(struct nan_data *nan, struct nan_cluster_config *config)
 }
 
 
+int nan_update_config(struct nan_data *nan, struct nan_cluster_config *config)
+{
+	int ret;
+
+	wpa_printf(MSG_DEBUG, "NAN: Update configuration");
+
+	if (!nan->nan_started) {
+		wpa_printf(MSG_DEBUG, "NAN: not started yet");
+		return -1;
+	}
+
+	ret = nan->cfg->update_config(nan->cfg->cb_ctx, config);
+	if (ret)
+		wpa_printf(MSG_DEBUG, "NAN: Failed to update config. ret=%d",
+			   ret);
+
+	return ret;
+}
+
+
 void nan_flush(struct nan_data *nan)
 {
 	wpa_printf(MSG_DEBUG, "NAN: Reset internal state");
diff --git a/src/nan/nan.h b/src/nan/nan.h
index 0c447605ec..597d510691 100644
--- a/src/nan/nan.h
+++ b/src/nan/nan.h
@@ -26,11 +26,20 @@ struct nan_config {
 	 * @ctx: Callback context from cb_ctx
 	 */
 	void (*stop)(void *ctx);
+
+	/**
+	 * update_config - Update NAN configuration
+	 * @ctx: Callback context from cb_ctx
+	 * @config: NAN cluster configuration
+	 */
+	int (*update_config)(void *ctx, struct nan_cluster_config *config);
+
 };
 
 struct nan_data * nan_init(const struct nan_config *cfg);
 void nan_deinit(struct nan_data *nan);
 int nan_start(struct nan_data *nan, struct nan_cluster_config *config);
+int nan_update_config(struct nan_data *nan, struct nan_cluster_config *config);
 void nan_stop(struct nan_data *nan);
 void nan_flush(struct nan_data *nan);
 
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 6a2a6d4d57..f8c97e8677 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -14113,6 +14113,12 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
 	} else if (os_strncmp(buf, "NAN_STOP", 8) == 0) {
 		if (wpas_nan_stop(wpa_s) < 0)
 			reply_len = -1;
+	} else if (os_strncmp(buf, "NAN_SET ", 8) == 0) {
+		if (wpas_nan_set(wpa_s, buf + 8) < 0)
+			reply_len = -1;
+	} else if (os_strncmp(buf, "NAN_UPDATE_CONF", 15) == 0) {
+		if (wpas_nan_update_conf(wpa_s) < 0)
+			reply_len = -1;
 #endif /* CONFIG_NAN */
 	} else {
 		os_memcpy(reply, "UNKNOWN COMMAND\n", 16);
diff --git a/wpa_supplicant/driver_i.h b/wpa_supplicant/driver_i.h
index 4b253e7c9b..76e1e41178 100644
--- a/wpa_supplicant/driver_i.h
+++ b/wpa_supplicant/driver_i.h
@@ -1284,6 +1284,14 @@ static inline void wpa_drv_nan_stop(struct wpa_supplicant *wpa_s)
 	wpa_s->driver->nan_stop(wpa_s->drv_priv);
 }
 
+static inline int wpa_drv_nan_update_config(struct wpa_supplicant *wpa_s,
+					    struct nan_cluster_config *conf)
+{
+	if (!wpa_s->driver->nan_change_config)
+		return -1;
+	return wpa_s->driver->nan_change_config(wpa_s->drv_priv, conf);
+}
+
 #endif /* CONFIG_NAN */
 
 #endif /* DRIVER_I_H */
diff --git a/wpa_supplicant/nan_supplicant.c b/wpa_supplicant/nan_supplicant.c
index 8fca3e9fb9..039393a8c7 100644
--- a/wpa_supplicant/nan_supplicant.c
+++ b/wpa_supplicant/nan_supplicant.c
@@ -20,7 +20,16 @@
 
 #define DEFAULT_NAN_MASTER_PREF 2
 #define DEFAULT_NAN_DUAL_BAND   0
-
+#define DEFAULT_NAN_SCAN_PERIOD 60
+#define DEFAULT_NAN_SCAN_DWELL_TIME 150
+#define DEFAULT_NAN_DISCOVERY_BEACON_INTERVAL 100
+#define DEFAULT_NAN_LOW_BAND_FREQUENCY 2437
+#define DEFAULT_NAN_HIGH_BAND_FREQUENCY 5745
+#define DEFAULT_NAN_RSSI_CLOSE -50
+#define DEFAULT_NAN_RSSI_MIDDLE -65
+
+#define NAN_MIN_RSSI_CLOSE  -60
+#define NAN_MIN_RSSI_MIDDLE -75
 #ifdef CONFIG_NAN
 
 static int wpas_nan_start_cb(void *ctx, struct nan_cluster_config *config)
@@ -31,6 +40,15 @@ static int wpas_nan_start_cb(void *ctx, struct nan_cluster_config *config)
 }
 
 
+static int wpas_nan_update_config_cb(void *ctx,
+				     struct nan_cluster_config *config)
+{
+	struct wpa_supplicant *wpa_s = ctx;
+
+	return wpa_drv_nan_update_config(wpa_s, config);
+}
+
+
 static void wpas_nan_stop_cb(void *ctx)
 {
 	struct wpa_supplicant *wpa_s = ctx;
@@ -54,6 +72,7 @@ int wpas_nan_init(struct wpa_supplicant *wpa_s)
 
 	nan.start = wpas_nan_start_cb;
 	nan.stop = wpas_nan_stop_cb;
+	nan.update_config = wpas_nan_update_config_cb;
 
 	wpa_s->nan = nan_init(&nan);
 	if (!wpa_s->nan) {
@@ -61,6 +80,35 @@ int wpas_nan_init(struct wpa_supplicant *wpa_s)
 		return -1;
 	}
 
+	/* Set the default configuration */
+	os_memset(&wpa_s->nan_config, 0, sizeof(wpa_s->nan_config));
+
+	wpa_s->nan_config.master_pref = DEFAULT_NAN_MASTER_PREF;
+	wpa_s->nan_config.dual_band = DEFAULT_NAN_DUAL_BAND;
+	os_memset(wpa_s->nan_config.cluster_id, 0, ETH_ALEN);
+	wpa_s->nan_config.scan_period = DEFAULT_NAN_SCAN_PERIOD;
+	wpa_s->nan_config.scan_dwell_time = DEFAULT_NAN_SCAN_DWELL_TIME;
+	wpa_s->nan_config.discovery_beacon_interval =
+		DEFAULT_NAN_DISCOVERY_BEACON_INTERVAL;
+
+	wpa_s->nan_config.low_band_cfg.frequency =
+		DEFAULT_NAN_LOW_BAND_FREQUENCY;
+	wpa_s->nan_config.low_band_cfg.rssi_close = DEFAULT_NAN_RSSI_CLOSE;
+	wpa_s->nan_config.low_band_cfg.rssi_middle = DEFAULT_NAN_RSSI_MIDDLE;
+	wpa_s->nan_config.low_band_cfg.awake_dw_interval = true;
+
+	wpa_s->nan_config.high_band_cfg.frequency =
+		DEFAULT_NAN_HIGH_BAND_FREQUENCY;
+	wpa_s->nan_config.high_band_cfg.rssi_close = DEFAULT_NAN_RSSI_CLOSE;
+	wpa_s->nan_config.high_band_cfg.rssi_middle = DEFAULT_NAN_RSSI_MIDDLE;
+	wpa_s->nan_config.high_band_cfg.awake_dw_interval = true;
+
+	/* TODO: Optimize this, so that the notification are enabled only when
+	 * needed, i.e., when the DE is configured with unsolicited publish or
+	 * active subscribe
+	 */
+	wpa_s->nan_config.enable_dw_notif = !!(wpa_s->nan_drv_flags &
+					       WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE);
 	return 0;
 }
 
@@ -85,27 +133,10 @@ static int wpas_nan_ready(struct wpa_supplicant *wpa_s)
 /* Join a cluster using current configuration */
 int wpas_nan_start(struct wpa_supplicant *wpa_s)
 {
-	struct nan_cluster_config cluster_config;
-
 	if (!wpas_nan_ready(wpa_s))
 		return -1;
 
-	if (!(wpa_s->nan_drv_flags &
-	      WPA_DRIVER_FLAGS_NAN_SUPPORT_SYNC_CONFIG)) {
-		wpa_printf(MSG_DEBUG,
-			   "NAN: Driver doesn't support configurable NAN sync");
-		return -1;
-	}
-
-	cluster_config.master_pref = DEFAULT_NAN_MASTER_PREF;
-	cluster_config.dual_band = DEFAULT_NAN_DUAL_BAND;
-
-	if (wpa_s->nan_drv_flags & WPA_DRIVER_FLAGS_NAN_SUPPORT_USERSPACE_DE) {
-		wpa_printf(MSG_DEBUG, "NAN: Enable DW notifications");
-		cluster_config.enable_dw_notif = true;
-	}
-
-	return nan_start(wpa_s->nan, &cluster_config);
+	return nan_start(wpa_s->nan, &wpa_s->nan_config);
 }
 
 
@@ -129,6 +160,95 @@ void wpas_nan_flush(struct wpa_supplicant *wpa_s)
 }
 
 
+int wpas_nan_set(struct wpa_supplicant *wpa_s, char *cmd)
+{
+	struct nan_cluster_config *config = &wpa_s->nan_config;
+	char *param = os_strchr(cmd, ' ');
+
+	if (!param)
+		return -1;
+
+	*param++ = '\0';
+
+#define NAN_PARSE_INT(_str, _min, _max)                              \
+	if (os_strcmp(#_str, cmd) == 0) {                            \
+		int val = atoi(param);                               \
+								     \
+		if (val < (_min) || val > (_max)) {                  \
+			wpa_printf(MSG_DEBUG,                        \
+				   "NAN: Invalid value for " #_str); \
+			return -1;                                   \
+		}                                                    \
+		config->_str = val;                                  \
+		return 0;                                            \
+	}
+
+#define NAN_PARSE_BAND(_str)                                                    \
+	if (os_strcmp(#_str, cmd) == 0) {                                       \
+		int a, b, c, d;                                                 \
+										 \
+		if (sscanf(param, "%d,%d,%d,%d", &a, &b, &c, &d) != 4) {        \
+			wpa_printf(MSG_DEBUG, "NAN: Invalid value for " #_str); \
+			return -1;                                              \
+		}                                                               \
+										\
+		if (a < NAN_MIN_RSSI_CLOSE || b < NAN_MIN_RSSI_MIDDLE ||        \
+		    a <= b) {							\
+			wpa_printf(MSG_DEBUG, "NAN: Invalid value for " #_str); \
+			return -1;						\
+		}								\
+		config->_str.rssi_close = a;					\
+		config->_str.rssi_middle = b;					\
+		config->_str.awake_dw_interval = c;                             \
+		config->_str.disable_scan = !!d;                                \
+		return 0;                                                       \
+	}
+
+	/* 0 and 255 are reserved */
+	NAN_PARSE_INT(master_pref, 1, 254);
+	NAN_PARSE_INT(dual_band, 0, 1);
+	NAN_PARSE_INT(scan_period, 0, 0xffff);
+	NAN_PARSE_INT(scan_dwell_time, 10, 150);
+	NAN_PARSE_INT(discovery_beacon_interval, 50, 200);
+
+	NAN_PARSE_BAND(low_band_cfg);
+	NAN_PARSE_BAND(high_band_cfg);
+
+	if (os_strcmp("cluster_id", cmd) == 0) {
+		u8 cluster_id[ETH_ALEN];
+
+		if (hwaddr_aton(param, cluster_id) < 0) {
+			wpa_printf(MSG_DEBUG, "NAN: Invalid cluster ID");
+			return -1;
+		}
+
+		if (cluster_id[0] != 0x50 || cluster_id[1] != 0x6f ||
+		    cluster_id[2] != 0x9a || cluster_id[3] != 0x01) {
+			wpa_printf(MSG_DEBUG, "NAN: Invalid cluster ID format");
+			return -1;
+		}
+
+		return 0;
+	}
+
+#undef NAN_PARSE
+#undef NAN_PARSE_BAND
+
+	wpa_printf(MSG_DEBUG, "NAN: Unknown NAN_SET cmd='%s'", cmd);
+	return -1;
+}
+
+
+int wpas_nan_update_conf(struct wpa_supplicant *wpa_s)
+{
+	if (!wpas_nan_ready(wpa_s))
+		return -1;
+
+	wpa_printf(MSG_DEBUG, "NAN: Update NAN configuration");
+	return nan_update_config(wpa_s->nan, &wpa_s->nan_config);
+}
+
+
 void wpas_nan_cluster_join(struct wpa_supplicant *wpa_s,
 			   const u8 *cluster_id,
 			   bool new_cluster)
diff --git a/wpa_supplicant/nan_supplicant.h b/wpa_supplicant/nan_supplicant.h
index bd76a26eda..88891ac7c8 100644
--- a/wpa_supplicant/nan_supplicant.h
+++ b/wpa_supplicant/nan_supplicant.h
@@ -16,6 +16,8 @@
 int wpas_nan_init(struct wpa_supplicant *wpa_s);
 void wpas_nan_deinit(struct wpa_supplicant *wpa_s);
 int wpas_nan_start(struct wpa_supplicant *wpa_s);
+int wpas_nan_set(struct wpa_supplicant *wpa_s, char *cmd);
+int wpas_nan_update_conf(struct wpa_supplicant *wpa_s);
 int wpas_nan_stop(struct wpa_supplicant *wpa_s);
 void wpas_nan_flush(struct wpa_supplicant *wpa_s);
 void wpas_nan_cluster_join(struct wpa_supplicant *wpa_s,
@@ -38,6 +40,16 @@ static inline int wpas_nan_start(struct wpa_supplicant *wpa_s)
 	return -1;
 }
 
+static inline int wpas_nan_set(struct wpa_supplicant *wpa_s, char *cmd)
+{
+	return -1;
+}
+
+static inline int wpas_nan_update_conf(struct wpa_supplicant *wpa_s)
+{
+	return -1;
+}
+
 static inline int wpas_nan_stop(struct wpa_supplicant *wpa_s)
 {
 	return -1;
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 46f841aeba..7037c8d40d 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -1642,6 +1642,7 @@ struct wpa_supplicant {
 #ifdef CONFIG_NAN
 	u32 nan_drv_flags;
 	struct nan_data *nan;
+	struct nan_cluster_config nan_config;
 #endif
 };
 
-- 
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