[PATCH] driver_nl80211: treat RSSI as part of each sched scan matchset

Johannes Berg johannes
Fri Jan 24 04:32:27 PST 2014

From: Johannes Berg <johannes.berg at intel.com>

The original RSSI filter semantics for scheduled scan were
really confusing - a separate matchset was created, but it
wasn't actually treated as a separate matchset in the kernel
but rather used as the global RSSI value. The RSSI matchset
thus behaved like an RSSI filter outside of the matchsets,
being ANDed rather than ORed (as normal between matchsets.)

To make this less confusing, I changed the kernel API a bit
to actually treat the RSSI inside each matchset properly,
but keeping it compatible with the old approach by using a
matchset with only an RSSI value as the default for all the
other matchsets, and adding it as a separate matchset only
if it's the only one.

The proper way for wpa_supplicant to do this then would be
to add the RSSI to each SSID matchset, and only add another
matchset without SSID if there's none with.

However, to keep compatibility with older kernels, always
keep the non-SSID matchset and only add the RSSI to all the
other matchsets. This gets close to the desired behaviour,
the only difference would be that we shouldn't add the RSSI
matchset if there are others, but stays compatible with old
and new kernels, as new ones ignore the RSSI-only matchset
if there are others and those others have an RSSI.

While at it, remove a useless cast and fix indentation.

Signed-hostap: Johannes Berg <johannes.berg at intel.com>
 src/drivers/driver_nl80211.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index b5bf368..1773a29 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -4873,7 +4873,7 @@ static int wpa_driver_nl80211_sched_scan(void *priv,
 	NLA_PUT_U32(msg, NL80211_ATTR_SCHED_SCAN_INTERVAL, interval);
 	if ((drv->num_filter_ssids &&
-	    (int) drv->num_filter_ssids <= drv->capa.max_match_sets) ||
+	     drv->num_filter_ssids <= drv->capa.max_match_sets) ||
 	    params->filter_rssi) {
 		struct nlattr *match_sets;
 		match_sets = nla_nest_start(msg, NL80211_ATTR_SCHED_SCAN_MATCH);
@@ -4893,10 +4893,20 @@ static int wpa_driver_nl80211_sched_scan(void *priv,
+			if (params->filter_rssi)
+				NLA_PUT_U32(msg,
+					    params->filter_rssi);
 			nla_nest_end(msg, match_set_ssid);
+		/*
+		 * Due to backward compatibility code, newer kernels treat this
+		 * matchset (with only an RSSI filter) as the default for all
+		 * other matchsets, unless it's the only one, in which case the
+		 * matchset will actually allow all SSIDs above the RSSI.
+		 */
 		if (params->filter_rssi) {
 			struct nlattr *match_set_rssi;
 			match_set_rssi = nla_nest_start(msg, 0);

More information about the Hostap mailing list