diff mbox

driver_nl80211: treat RSSI as part of each sched scan matchset

Message ID 1390566747-11598-1-git-send-email-johannes@sipsolutions.net
State Accepted
Headers show

Commit Message

Johannes Berg Jan. 24, 2014, 12:32 p.m. UTC
From: Johannes Berg <johannes.berg@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@intel.com>
---
 src/drivers/driver_nl80211.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

Comments

Jouni Malinen Jan. 30, 2014, 11:52 a.m. UTC | #1
On Fri, Jan 24, 2014 at 01:32:27PM +0100, Johannes Berg wrote:
> While at it, remove a useless cast and fix indentation.

> diff --git 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) {

That's not a useless cast:

../src/drivers/driver_nl80211.c: In function ‘wpa_driver_nl80211_sched_scan’:
../src/drivers/driver_nl80211.c:4979:29: error: comparison between signed and unsigned integer expressions [-Werror=sign-compare]

I'm dropping this part. If you want to get this cleaned up, I could
consider a patch that does this and makes max_match_sets unsigned.. :)
Jouni Malinen Jan. 30, 2014, 1:12 p.m. UTC | #2
On Fri, Jan 24, 2014 at 01:32:27PM +0100, Johannes Berg wrote:
> 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.)

Thanks, applied (with the separate typecast/cleanup change removed).
diff mbox

Patch

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,
 			NLA_PUT(msg, NL80211_ATTR_SCHED_SCAN_MATCH_SSID,
 				drv->filter_ssids[i].ssid_len,
 				drv->filter_ssids[i].ssid);
+			if (params->filter_rssi)
+				NLA_PUT_U32(msg,
+					    NL80211_SCHED_SCAN_MATCH_ATTR_RSSI,
+					    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);