From bd525934e5f4cde3be2cd4c4def46ebaba3eaa0f Mon Sep 17 00:00:00 2001 From: Luciano Coelho Date: Tue, 27 Sep 2011 22:21:36 +0300 Subject: [PATCH] nl80211: Add support for sched_scan filtering Use the SSID filter list passed in the scheduled scan request down to the kernel driver, so it can use the list to return only the wanted SSIDs. Some kernel drivers can use this information to offload the SSID filter to the hardware, helping with reducing the power consumption. Signed-off-by: Luciano Coelho --- src/drivers/driver_nl80211.c | 33 ++++++++++++++++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 5326087ad..37d72a09b 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -1703,6 +1703,7 @@ struct wiphy_info_data { int max_remain_on_chan; int firmware_roam; int sched_scan_supported; + int max_match_sets; }; @@ -1735,6 +1736,10 @@ static int wiphy_info_handler(struct nl_msg *msg, void *arg) info->max_sched_scan_ssids = nla_get_u8(tb[NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS]); + if (tb[NL80211_ATTR_MAX_MATCH_SETS]) + info->max_match_sets = + nla_get_u8(tb[NL80211_ATTR_MAX_MATCH_SETS]); + if (tb[NL80211_ATTR_SUPPORTED_IFTYPES]) { struct nlattr *nl_mode; int i; @@ -1893,6 +1898,7 @@ static int wpa_driver_nl80211_capa(struct wpa_driver_nl80211_data *drv) drv->capa.max_scan_ssids = info.max_scan_ssids; drv->capa.max_sched_scan_ssids = info.max_sched_scan_ssids; drv->capa.sched_scan_supported = info.sched_scan_supported; + drv->capa.max_match_sets = info.max_match_sets; if (info.ap_supported) drv->capa.flags |= WPA_DRIVER_FLAGS_AP; @@ -2651,7 +2657,7 @@ static int wpa_driver_nl80211_sched_scan(void *priv, struct i802_bss *bss = priv; struct wpa_driver_nl80211_data *drv = bss->drv; int ret = 0; - struct nl_msg *msg, *ssids, *freqs; + struct nl_msg *msg, *ssids, *freqs, *match_set_ssid, *match_sets; size_t i; msg = nlmsg_alloc(); @@ -2676,6 +2682,31 @@ static int wpa_driver_nl80211_sched_scan(void *priv, NLA_PUT_U32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, interval); + if (drv->num_filter_ssids) { + match_sets = nlmsg_alloc(); + + for (i = 0; i < drv->num_filter_ssids; i++) { + wpa_hexdump_ascii(MSG_MSGDUMP, + "nl80211: Sched scan filter SSID", + drv->filter_ssids[i].ssid, + drv->filter_ssids[i].ssid_len); + + match_set_ssid = nlmsg_alloc(); + nla_put(match_set_ssid, + NL80211_ATTR_SCHED_SCAN_MATCH_SSID, + drv->filter_ssids[i].ssid_len, + drv->filter_ssids[i].ssid); + + nla_put_nested(match_sets, i + 1, match_set_ssid); + + nlmsg_free(match_set_ssid); + } + + nla_put_nested(msg, NL80211_ATTR_SCHED_SCAN_MATCH, + match_sets); + nlmsg_free(match_sets); + } + for (i = 0; i < params->num_ssids; i++) { wpa_hexdump_ascii(MSG_MSGDUMP, "nl80211: Sched scan SSID", params->ssids[i].ssid,