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