aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2014-09-03 21:58:37 (GMT)
committerJouni Malinen <j@w1.fi>2014-11-16 15:09:11 (GMT)
commit88cb27c7a5164f8ffe465e4f1a4ae5f5f7bea91c (patch)
treefd527f761d7d0d484be1b4b27e15c8d2350dd39c /src
parentf03996565adad176e1ee4ba9955862edbe98a349 (diff)
downloadhostap-88cb27c7a5164f8ffe465e4f1a4ae5f5f7bea91c.zip
hostap-88cb27c7a5164f8ffe465e4f1a4ae5f5f7bea91c.tar.gz
hostap-88cb27c7a5164f8ffe465e4f1a4ae5f5f7bea91c.tar.bz2
hostapd: Add wowlan_triggers config param
New kernels in wiphy_suspend() will call cfg80211_leave_all() that will eventually end up in cfg80211_stop_ap() unless wowlan_triggers were set. For now, use the parameters from the station mode as-is. It may be desirable to extend (or constraint) this in the future for specific AP mode needs. Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/ap/ap_config.c2
-rw-r--r--src/ap/ap_config.h2
-rw-r--r--src/drivers/driver.h4
-rw-r--r--src/drivers/driver_common.c76
4 files changed, 84 insertions, 0 deletions
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 90f1630..d8021a1 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -542,6 +542,8 @@ void hostapd_config_free_bss(struct hostapd_bss_config *conf)
os_free(conf->sae_groups);
+ os_free(conf->wowlan_triggers);
+
os_free(conf->server_id);
os_free(conf);
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index 8a44401..3441b90 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -535,6 +535,8 @@ struct hostapd_bss_config {
unsigned int sae_anti_clogging_threshold;
int *sae_groups;
+ char *wowlan_triggers; /* Wake-on-WLAN triggers */
+
#ifdef CONFIG_TESTING_OPTIONS
u8 bss_load_test[5];
u8 bss_load_test_set;
diff --git a/src/drivers/driver.h b/src/drivers/driver.h
index 8420a56..3476e8e 100644
--- a/src/drivers/driver.h
+++ b/src/drivers/driver.h
@@ -4362,6 +4362,10 @@ const char * channel_width_to_string(enum chan_width width);
int ht_supported(const struct hostapd_hw_modes *mode);
int vht_supported(const struct hostapd_hw_modes *mode);
+struct wowlan_triggers *
+wpa_get_wowlan_triggers(const char *wowlan_triggers,
+ const struct wpa_driver_capa *capa);
+
/* NULL terminated array of linked in driver wrappers */
extern struct wpa_driver_ops *wpa_drivers[];
diff --git a/src/drivers/driver_common.c b/src/drivers/driver_common.c
index b9a0f5f..e0a7ebb 100644
--- a/src/drivers/driver_common.c
+++ b/src/drivers/driver_common.c
@@ -140,3 +140,79 @@ int vht_supported(const struct hostapd_hw_modes *mode)
*/
return (mode->vht_mcs_set[0] & 0x3) != 3;
}
+
+
+static int wpa_check_wowlan_trigger(const char *start, const char *trigger,
+ int capa_trigger, u8 *param_trigger)
+{
+ if (os_strcmp(start, trigger) != 0)
+ return 0;
+ if (!capa_trigger)
+ return 0;
+
+ *param_trigger = 1;
+ return 1;
+}
+
+
+struct wowlan_triggers *
+wpa_get_wowlan_triggers(const char *wowlan_triggers,
+ const struct wpa_driver_capa *capa)
+{
+ struct wowlan_triggers *triggers;
+ char *start, *end, *buf;
+ int last;
+
+ if (!wowlan_triggers)
+ return NULL;
+
+ buf = os_strdup(wowlan_triggers);
+ if (buf == NULL)
+ return NULL;
+
+ triggers = os_zalloc(sizeof(*triggers));
+ if (triggers == NULL)
+ goto out;
+
+#define CHECK_TRIGGER(trigger) \
+ wpa_check_wowlan_trigger(start, #trigger, \
+ capa->wowlan_triggers.trigger, \
+ &triggers->trigger)
+
+ start = buf;
+ while (*start != '\0') {
+ while (isblank(*start))
+ start++;
+ if (*start == '\0')
+ break;
+ end = start;
+ while (!isblank(*end) && *end != '\0')
+ end++;
+ last = *end == '\0';
+ *end = '\0';
+
+ if (!CHECK_TRIGGER(any) &&
+ !CHECK_TRIGGER(disconnect) &&
+ !CHECK_TRIGGER(magic_pkt) &&
+ !CHECK_TRIGGER(gtk_rekey_failure) &&
+ !CHECK_TRIGGER(eap_identity_req) &&
+ !CHECK_TRIGGER(four_way_handshake) &&
+ !CHECK_TRIGGER(rfkill_release)) {
+ wpa_printf(MSG_DEBUG,
+ "Unknown/unsupported wowlan trigger '%s'",
+ start);
+ os_free(triggers);
+ triggers = NULL;
+ goto out;
+ }
+
+ if (last)
+ break;
+ start = end + 1;
+ }
+#undef CHECK_TRIGGER
+
+out:
+ os_free(buf);
+ return triggers;
+}