[RFC 31/34] NAN: Support configuring NAN operation
Andrei Otcheretianski
andrei.otcheretianski at intel.com
Wed Aug 13 10:39:15 PDT 2025
From: Ilan Peer <ilan.peer at intel.com>
And support updating NAN configuration after NAN synchronization
has been started.
Signed-off-by: Ilan Peer <ilan.peer at intel.com>
---
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
More information about the Hostap
mailing list