From fd831be2b0a29d78dd12e68c9f881718f49d9a03 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Wed, 24 Oct 2012 04:58:02 +0200 Subject: P2P: cancel action frame offchan wait after recv go neg conf The missing call to scan_action_done keeps us offchan on the listen channel for 250ms following sending go neg resp. In case the oper channel is different from the listen channel and we're GO a race could lead to start beaconing while offchan. This causes the beacons to go out on the listen channel instead of the oper channel. Signed-off-by: Eyal Shapira --- src/p2p/p2p_go_neg.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c index 2d31f4b..0802037 100644 --- a/src/p2p/p2p_go_neg.c +++ b/src/p2p/p2p_go_neg.c @@ -1097,6 +1097,7 @@ void p2p_process_go_neg_conf(struct p2p_data *p2p, const u8 *sa, wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Received GO Negotiation Confirm from " MACSTR, MAC2STR(sa)); + p2p->cfg->send_action_done(p2p->cfg->cb_ctx); dev = p2p_get_device(p2p, sa); if (dev == NULL || dev->wps_method == WPS_NOT_READY || dev != p2p->go_neg_peer) { -- cgit v1.1 From 597e897f23f6d8b0dcafe3fd2416cdcb5f20d0e3 Mon Sep 17 00:00:00 2001 From: Victor Goldenshtein Date: Mon, 29 Oct 2012 10:38:05 +0200 Subject: wpa_s: fix bss selection on identical SSIDs with WEP+AES/TKIP Configuring two identical SSIDs - one with WEP-SHARED security and one with AES/TKIP breaks any authentication attempt with WEP-SHARED SSID. Reason for this behavior is that during BSS selection from the priority group wrong BSS (with AES/TKIP) was selected. Fix this by disallowing "non-WPA/WPA2" BSS selection with defined rsn_ie/wpa_ie. Signed-off-by: Victor Goldenshtein --- wpa_supplicant/events.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index c3e9ed6..0ac8641 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -473,7 +473,7 @@ static int wpa_supplicant_ssid_bss_match(struct wpa_supplicant *wpa_s, return 0; } - if (!wpa_key_mgmt_wpa(ssid->key_mgmt)) { + if (!wpa_key_mgmt_wpa(ssid->key_mgmt) && !rsn_ie && !wpa_ie) { wpa_dbg(wpa_s, MSG_DEBUG, " allow in non-WPA/WPA2"); return 1; } -- cgit v1.1 From 25dec55e99994c197167d5db10d0efc0b04e707d Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Thu, 25 Oct 2012 15:24:10 +0200 Subject: P2P: speed up scans when connecting to persistent GO (UPSTREAM) In the case of a persistent GO invoking a P2P group by invite the P2P client starts scanning for the GO but it might still not be up. If not found the next scan is scheduled for scan_interval secs but this too long. Speed up scans to find GO like it's being done in P2P provisioing. Signed-off-by: Eyal Shapira --- wpa_supplicant/events.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 0ac8641..7f46a4f 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1219,7 +1219,8 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, if (wpas_p2p_scan_no_go_seen(wpa_s) == 1) return 0; - if (wpa_s->p2p_in_provisioning) { + if (wpa_s->p2p_in_provisioning || + wpa_s->show_group_started) { /* * Use shorter wait during P2P Provisioning * state to speed up group formation. -- cgit v1.1 From e62ecda1b94b2b07dfce877654b10c6ff8c46857 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Sun, 28 Oct 2012 20:29:14 +0200 Subject: Revert "Add P2P IEs to probe requests only when in P2P (UPSTREAM)" This is replaced by a recent patch by Jouni in the upstream: "P2P: Allow P2P functionality to be disabled per interface" This reverts commit a56f6df6f8e5dcd650893e8beb4a16a633c179d1. Conflicts: src/p2p/p2p.c --- src/p2p/p2p.c | 8 -------- src/p2p/p2p.h | 10 ---------- wpa_supplicant/p2p_supplicant.c | 7 ------- wpa_supplicant/p2p_supplicant.h | 1 - wpa_supplicant/scan.c | 2 +- 5 files changed, 1 insertion(+), 27 deletions(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index e905e77..824a59e 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -4102,14 +4102,6 @@ int p2p_in_progress(struct p2p_data *p2p) return p2p->state != P2P_IDLE && p2p->state != P2P_PROVISIONING; } -int p2p_non_idle(struct p2p_data *p2p) -{ - if (p2p == NULL) - return 0; - return p2p->state != P2P_IDLE; -} - - void p2p_set_config_timeout(struct p2p_data *p2p, u8 go_timeout, u8 client_timeout) { diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 3f796d0..3c439f3 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -1690,16 +1690,6 @@ int p2p_set_pref_chan(struct p2p_data *p2p, unsigned int num_pref_chan, */ int p2p_in_progress(struct p2p_data *p2p); -/** - * p2p_non_idle - Check whether P2P is not in P2P_IDLE. That - * means we're in either search, GO neg or provisioing. Once connected - * it's back to idle. p2p_in_progress excludes provisioing. - * @p2p: P2P module context from p2p_init() - * Returns: 0 if P2P module is idle or 1 if an operation is in progress - */ -int p2p_non_idle(struct p2p_data *p2p); - - #ifdef ANDROID_P2P /** * p2p_search_in_progress - Check whether a P2P SEARCH is in progress diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index b0eb594..ae23632 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -4973,13 +4973,6 @@ int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s) return p2p_in_progress(wpa_s->global->p2p); } -int wpas_p2p_non_idle(struct wpa_supplicant *wpa_s) -{ - if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) - return 0; - - return p2p_non_idle(wpa_s->global->p2p); -} void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid) diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index f24fb28..8d3bff1 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -137,7 +137,6 @@ int wpas_p2p_disconnect(struct wpa_supplicant *wpa_s); void wpas_p2p_wps_failed(struct wpa_supplicant *wpa_s, struct wps_event_fail *fail); int wpas_p2p_in_progress(struct wpa_supplicant *wpa_s); -int wpas_p2p_non_idle(struct wpa_supplicant *wpa_s); void wpas_p2p_network_removed(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid); struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s, diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index 6b43968..2b468fb 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -66,7 +66,7 @@ static int wpas_wps_in_use(struct wpa_supplicant *wpa_s, } #ifdef CONFIG_P2P - if (wpas_p2p_non_idle(wpa_s)) { + if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p) { wpa_s->wps->dev.p2p = 1; if (!wps) { wps = 1; -- cgit v1.1 From 82a982e0b80aa90ccfbb953aedc44fdc24de02ba Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Wed, 10 Oct 2012 13:08:23 +0300 Subject: P2P: Allow P2P functionality to be disabled per interface By default, P2P is enabled globally for all virtual interfaces and this makes wpa_supplicant include WSC and P2P IEs in Probe Request frames for all scans even if this is for a non-P2P station connection to speed up device discovery. If an interface is dedicated for non-P2P station mode operations, it is now possible to disable addition of WSC and P2P IEs into Probe Request frames with a per-interface p2p_disabled parameter. This can be set either in the configuration file (p2p_disabled=1) or at run time ("wpa_cli -i wlan0 set p2p_disabled 1"). Unlike the previous mechanism ("wpa_cli p2p_set disabled 1"), the new parameter changes the behavior only for the specified interface while other interfaces continue to follow the global P2P enabled/disabled state. Signed-hostap: Jouni Malinen Signed-off-by: Eyal Shapira --- wpa_supplicant/config.c | 1 + wpa_supplicant/config.h | 4 ++++ wpa_supplicant/config_file.c | 3 +++ wpa_supplicant/scan.c | 3 ++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 69eb7d0..c89fb39 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2968,6 +2968,7 @@ static const struct global_parse_data global_fields[] = { { INT_RANGE(p2p_intra_bss, 0, 1), CFG_CHANGED_P2P_INTRA_BSS }, { INT(p2p_group_idle), 0 }, { FUNC(p2p_pref_chan), CFG_CHANGED_P2P_PREF_CHAN }, + { INT(p2p_disabled), 0 }, #endif /* CONFIG_P2P */ #ifdef ANDROID_P2P { STR_RANGE(prioritize, 0, 32), CFG_CHANGED_IFACE_PRIORITY }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index eb7dbf0..31e7a9a 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -743,6 +743,10 @@ struct wpa_config { */ int p2p_conc_mode; #endif + /* + * p2p_disabled - Whether P2P operations are disabled for this interface + */ + int p2p_disabled; }; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index cbece8e..9bb01b4 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -852,6 +852,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) } fprintf(f, "\n"); } + + if (config->p2p_disabled) + fprintf(f, "p2p_disabled=%u\n", config->p2p_disabled); #endif /* CONFIG_P2P */ if (config->country[0] && config->country[1]) { fprintf(f, "country=%c%c\n", diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index 2b468fb..66fd60d 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -66,7 +66,8 @@ static int wpas_wps_in_use(struct wpa_supplicant *wpa_s, } #ifdef CONFIG_P2P - if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p) { + if (!wpa_s->global->p2p_disabled && wpa_s->global->p2p && + !wpa_s->conf->p2p_disabled) { wpa_s->wps->dev.p2p = 1; if (!wps) { wps = 1; -- cgit v1.1 From a54d554ff1495c6989edc093a468b69666564124 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Mon, 29 Oct 2012 07:08:23 +0200 Subject: Disable p2p on wlan0 (JB) This prevents P2P IEs from being added to probes of scans on the STA interface. These are not needed and prolong required channel dwell time and Tx of probes. This is somewhat of a hack but was a preferred approach on adding framework changes to add p2p_disabled=1 to p2p_supplicant.conf and not to wpa_supplicant.conf when both are created from the same template. Signed-off-by: Eyal Shapira --- wpa_supplicant/wpa_supplicant.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 73ffde8..911a593 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -2849,6 +2849,11 @@ next_driver: #ifdef CONFIG_P2P #ifdef ANDROID + if (os_strncmp(iface->ifname, "wlan0", 4) == 0) { + wpa_printf(MSG_DEBUG, "Disable P2P on wlan0"); + wpa_s->conf->p2p_disabled = 1; + } + if (os_strncmp(iface->ifname, "p2p0", 4) == 0) #endif /* ANDROID */ if (wpas_p2p_init(wpa_s->global, wpa_s) < 0) { -- cgit v1.1 From 022c2f963b43baa3fb3f71839c2ff601d0e86424 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Sun, 28 Oct 2012 18:18:06 +0200 Subject: Avoid normal scans before sched scan if max_scan_ssids=1 (UPSTREAM) In the case of max_scan_ssids=1 we may fallback to normal scan if there's a single scan_ssid network. However the normal scan can't add a wildcard SSID to the ssid list as it's limited to a single entry. This delays getting broadcast scan results. Always prefer to do a sched scan in such a case. Signed-off-by: Eyal Shapira --- wpa_supplicant/scan.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index 66fd60d..e50dcfc 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -888,6 +888,7 @@ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s) need_ssids++; if (wpa_s->normal_scans < 3 && + wpa_s->max_scan_ssids > 1 && (need_ssids <= wpa_s->max_scan_ssids || wpa_s->max_scan_ssids >= (int) max_sched_scan_ssids)) { /* @@ -896,6 +897,10 @@ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s) * user space sleep more. We do this only if the normal scan * has functionality that is suitable for this or if the * sched_scan does not have better support for multiple SSIDs. + * max_scan_ssids=1 is a special case where we'd like to avoid + * using normal scan as wpa_supplicant_scan handles this case + * differently and doesn't add a wildcard SSID so broadcast scan + * results would be delayed. */ wpa_dbg(wpa_s, MSG_DEBUG, "Use normal scan instead of " "sched_scan for initial scans (normal_scans=%d)", -- cgit v1.1 From 58a8af2ce379a19364963ec1f94a29871c00bac9 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Sun, 28 Oct 2012 19:45:12 +0200 Subject: Allow concurrent normal scan and sched scan (UPSTREAM) Some drivers support sched scan and normal scan. Enable this by configuration of concurrent_sched_scan=1 This can speed up connection to scan_ssid=1 networks as the sched scan doesn't get interrupted by a normal scan for wildcard SSID. Signed-off-by: Eyal Shapira --- wpa_supplicant/config.c | 1 + wpa_supplicant/config.h | 6 ++++++ wpa_supplicant/config_file.c | 3 +++ wpa_supplicant/ctrl_iface.c | 7 +++++-- 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index c89fb39..9d93161 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -3001,6 +3001,7 @@ static const struct global_parse_data global_fields[] = { MAX_NUM_SCHED_SCAN_SHORT_INTERVALS), 0 }, { INT_RANGE(sched_scan_short_interval, 1, MAX_SCHED_SCAN_INTERVAL), 0 }, { INT_RANGE(sched_scan_long_interval, 1, MAX_SCHED_SCAN_INTERVAL), 0 }, + { INT_RANGE(concurrent_sched_scan, 0, 1), 0 }, }; #undef FUNC diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 31e7a9a..8273f14 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -747,6 +747,12 @@ struct wpa_config { * p2p_disabled - Whether P2P operations are disabled for this interface */ int p2p_disabled; + + /* + * concurrent_sched_scan - sched scan can run concurrently with normal + * scan and no need to stop one to do the other. + */ + int concurrent_sched_scan; }; diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 9bb01b4..cba8604 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -919,6 +919,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) if (config->p2p_conc_mode) fprintf(f, "p2p_conc_mode=%u\n", config->p2p_conc_mode); #endif + if (config->concurrent_sched_scan) + fprintf(f, "concurrent_sched_scan=%u\n", + config->concurrent_sched_scan); } #endif /* CONFIG_NO_CONFIG_WRITE */ diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 8aad951..0f5f431 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -4577,13 +4577,16 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s, if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) reply_len = -1; else { - if (!wpa_s->sched_scanning && !wpa_s->scanning && + if ((wpa_s->conf->concurrent_sched_scan || + !wpa_s->sched_scanning) && + !wpa_s->scanning && ((wpa_s->wpa_state <= WPA_SCANNING) || (wpa_s->wpa_state == WPA_COMPLETED))) { wpa_s->normal_scans = 0; wpa_s->scan_req = 2; wpa_supplicant_req_scan(wpa_s, 0, 0); - } else if (wpa_s->sched_scanning) { + } else if (wpa_s->sched_scanning && + !wpa_s->conf->concurrent_sched_scan) { wpa_printf(MSG_DEBUG, "Stop ongoing " "sched_scan to allow requested " "full scan to proceed"); -- cgit v1.1 From 264e5ef1c6f4cac7ac8eba626692f9a4091132d0 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Sun, 28 Oct 2012 20:37:39 +0200 Subject: android: wpa_s template: enable concurrent_sched_scan (ANDROID) Our solution supports this and it speeds up initial connection to hidden networks. Signed-off-by: Eyal Shapira --- wpa_supplicant/wpa_supplicant_template.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/wpa_supplicant/wpa_supplicant_template.conf b/wpa_supplicant/wpa_supplicant_template.conf index ac1a663..917ff0a 100644 --- a/wpa_supplicant/wpa_supplicant_template.conf +++ b/wpa_supplicant/wpa_supplicant_template.conf @@ -15,3 +15,4 @@ p2p_go_max_inactivity=30 p2p_go_ht40=1 p2p_multi_chan=1 disassoc_low_ack=1 +concurrent_sched_scan=1 -- cgit v1.1 From 76efd31da240ea7204fbb507259680c822b23c8d Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Wed, 24 Oct 2012 17:44:18 +0200 Subject: Trigger sched scan on wpa_s init if enabled networks (INTERNAL) The switch to triggering a normal scan initially was done to prevent interference between sched scan and normal scan. This is no longer an issue. Triggering a sched scan is better as it works better in our case than the normal scan wrt hidden networks. Signed-off-by: Eyal Shapira --- wpa_supplicant/wpa_supplicant.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c index 911a593..39630ad 100644 --- a/wpa_supplicant/wpa_supplicant.c +++ b/wpa_supplicant/wpa_supplicant.c @@ -2375,11 +2375,8 @@ int wpa_supplicant_driver_init(struct wpa_supplicant *wpa_s) wpa_s->prev_scan_wildcard = 0; if (wpa_supplicant_enabled_networks(wpa_s)) { -#ifdef ANDROID - wpa_supplicant_req_scan(wpa_s, wpa_s->scan_interval, 0); -#else - wpa_supplicant_req_scan(wpa_s, interface_count, 100000); -#endif + wpa_supplicant_delayed_sched_scan(wpa_s, + interface_count, 100000); interface_count++; } else wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); -- cgit v1.1 From 80a505accfd177de92259660b3e619822664263f Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Wed, 24 Oct 2012 17:47:30 +0200 Subject: Don't disable and select new network if SETBAND didn't change (ANDROID) Current SETBAND would trigger network selection and as part of this a scan attempt. This is not required in case SETBAND didn't change the existing setting. In Android which sends SETBAND immediately after WiFi startup this would trigger needless scan attempts which would usually fail with -EBUSY as another framework triggers scan was already going on. The retry mechanism would then attempt further scans every 1 sec. Signed-off-by: Eyal Shapira --- wpa_supplicant/ctrl_iface.c | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 0f5f431..4f0aa33 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -4193,6 +4193,7 @@ static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd, ret = pno_stop(wpa_s); else if (os_strncasecmp(cmd, "SETBAND ", 8) == 0) { int val = atoi(cmd + 8); + uint setband = 0; /* * Use driver_cmd for drivers that support it, but ignore the * return value since scan requests from wpa_supplicant will @@ -4203,20 +4204,29 @@ static int wpa_supplicant_driver_cmd(struct wpa_supplicant *wpa_s, char *cmd, wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen); ret = 0; if (val == 0) - wpa_s->setband = WPA_SETBAND_AUTO; + setband = WPA_SETBAND_AUTO; else if (val == 1) - wpa_s->setband = WPA_SETBAND_5G; + setband = WPA_SETBAND_5G; else if (val == 2) - wpa_s->setband = WPA_SETBAND_2G; - else + setband = WPA_SETBAND_2G; + else { ret = -1; + goto out; + } + + if (wpa_s->setband == setband) { + wpa_printf(MSG_DEBUG, "Same setband as before"); + goto out; + } + wpa_s->setband = setband; if (wpa_s->current_bss && !wpa_bss_in_current_band(wpa_s, wpa_s->current_bss)) wpa_supplicant_disable_network(wpa_s, wpa_s->current_ssid); wpa_supplicant_select_network(wpa_s, NULL); } else ret = wpa_drv_driver_cmd(wpa_s, cmd, buf, buflen); +out: if (ret == 0) ret = sprintf(buf, "%s\n", "OK"); return ret; -- cgit v1.1 From c35ef2e7c15e2d42b38347d2be96cc7e4846a4a5 Mon Sep 17 00:00:00 2001 From: Igal Chernobelsky Date: Thu, 1 Nov 2012 11:23:17 +0200 Subject: P2P: set P2P_GO_MAX_INACTIVITY to 100s WiFi Direct certification test 6.1.12 expects GO to be active during 50 sec, so changing P2P_GO_MAX_INACTIVITY from 30 sec to 100 sec to pass the test. Signed-off-by: Igal Chernobelsky --- wpa_supplicant/wpa_supplicant_template.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wpa_supplicant/wpa_supplicant_template.conf b/wpa_supplicant/wpa_supplicant_template.conf index 917ff0a..e577fb9 100644 --- a/wpa_supplicant/wpa_supplicant_template.conf +++ b/wpa_supplicant/wpa_supplicant_template.conf @@ -11,7 +11,7 @@ model_number=wl18xx serial_number=12345 p2p_conc_mode=2 driver_param=use_p2p_group_interface=1 -p2p_go_max_inactivity=30 +p2p_go_max_inactivity=100 p2p_go_ht40=1 p2p_multi_chan=1 disassoc_low_ack=1 -- cgit v1.1 From 1b5944ce67f0930923f624ff499406c19ab85d26 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Fri, 2 Nov 2012 00:14:23 +0200 Subject: P2P: cancel action frame offchan wait after recv go neg resp (UPSTREAM) A wait of 200ms is configured after sending the go neg request. The go neg process can end quickly within less than 200ms. If this wait isn't canceled it can cause the beaconing of the GO to start while mac80211 is still off channel on the listen channel and this may cause beaconing on the wrong channel if oper channel is different from the listen channel. Signed-off-by: Eyal Shapira --- src/p2p/p2p_go_neg.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c index 0802037..60c19c6 100644 --- a/src/p2p/p2p_go_neg.c +++ b/src/p2p/p2p_go_neg.c @@ -827,6 +827,7 @@ void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, return; } dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE; + p2p->cfg->send_action_done(p2p->cfg->cb_ctx); if (msg.dialog_token != dev->dialog_token) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, @@ -860,7 +861,6 @@ void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, "P2P: Stop GO Negotiation attempt"); p2p_go_neg_failed(p2p, dev, *msg.status); } - p2p->cfg->send_action_done(p2p->cfg->cb_ctx); p2p_parse_free(&msg); return; } -- cgit v1.1 From 98fe4079c23456c902525bb7d09a5df6e522c842 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Fri, 2 Nov 2012 10:58:05 +0200 Subject: android: wpa_s template: set p2p_go_max_inactivity to 60s (ANDROID) The previous value of 30s was problematic in passing WiFi Direct certification test 6.1.12. In this test the GO is checked for buffering packets while the client is in PS and doesn't send a trigger to get out of PS for 50s. Any value less than 50s would lead to a failed inactivity check and the GO disconnecting the client in this test. It's important to minimize p2p_go_max_inactivity as it helps the GO detect clients which disconnected despite missing on the deauth frame. This is not uncommon in JB as there are scans on the STA interface which take us off the GO oper channel. Until the GO performs an inactivity check the UI will keep showing the client as "Connected" and the GO will remain operational which creates a bad user experience. [This should supersede "P2P: set P2P_GO_MAX_INACTIVITY to 100s" in the next rebase] Signed-off-by: Eyal Shapira --- wpa_supplicant/wpa_supplicant_template.conf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wpa_supplicant/wpa_supplicant_template.conf b/wpa_supplicant/wpa_supplicant_template.conf index e577fb9..17d4b18 100644 --- a/wpa_supplicant/wpa_supplicant_template.conf +++ b/wpa_supplicant/wpa_supplicant_template.conf @@ -11,7 +11,7 @@ model_number=wl18xx serial_number=12345 p2p_conc_mode=2 driver_param=use_p2p_group_interface=1 -p2p_go_max_inactivity=100 +p2p_go_max_inactivity=60 p2p_go_ht40=1 p2p_multi_chan=1 disassoc_low_ack=1 -- cgit v1.1 From fb634d7768b87e1174d2a21f4c899da3706432e8 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Mon, 5 Nov 2012 04:35:14 +0200 Subject: P2P: Fix duplicate handling of rx action frames (UPSTREAM) When using a separate group iface both p2p device iface and the group iface are registered for action frames. This causes duplicate handling of rx action frames. One side effect of this is getting multiple responses for requests sent over action frames while GO/CLI are up like prov disc and dev disc. Fix this by discarding the duplicate p2p action frames received on the group iface. The code will handle all of these correctly when coming on the p2p dev iface as it looks at the DA when where relevant. Signed-off-by: Eyal Shapira --- wpa_supplicant/p2p_supplicant.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index ae23632..d8d72da 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -4137,6 +4137,12 @@ void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da, if (wpa_s->global->p2p == NULL) return; + if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) { + wpa_printf(MSG_DEBUG, "Discard RX action event on P2P " + "GO/CLI iface. P2P Device interface will handle it"); + return; + } + p2p_rx_action(wpa_s->global->p2p, da, sa, bssid, category, data, len, freq); } -- cgit v1.1 From 0e14818d3e4f9185d30638cb748c396c0f2b1efe Mon Sep 17 00:00:00 2001 From: Nadim Zubidat Date: Mon, 5 Nov 2012 11:18:26 +0800 Subject: hostapd: enable dynamic modification of acl policy add APIs for dynamically changing the macaddr_acl policy and mac addresses lists. once changed, hostapd will deauth stations which do not pass the new policy. Signed-off-by: Nadim Zubidat --- hostapd/config_file.c | 4 ++-- hostapd/config_file.h | 2 ++ hostapd/ctrl_iface.c | 42 ++++++++++++++++++++++++++++++++++++++ src/ap/hostapd.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/ap/hostapd.h | 3 +++ 5 files changed, 105 insertions(+), 2 deletions(-) diff --git a/hostapd/config_file.c b/hostapd/config_file.c index 59745fa..41dd242 100644 --- a/hostapd/config_file.c +++ b/hostapd/config_file.c @@ -116,8 +116,8 @@ static int hostapd_acl_comp(const void *a, const void *b) } -static int hostapd_config_read_maclist(const char *fname, - struct mac_acl_entry **acl, int *num) +int hostapd_config_read_maclist(const char *fname, + struct mac_acl_entry **acl, int *num) { FILE *f; char buf[128], *pos; diff --git a/hostapd/config_file.h b/hostapd/config_file.h index fba57b8..61759f3 100644 --- a/hostapd/config_file.h +++ b/hostapd/config_file.h @@ -13,5 +13,7 @@ struct hostapd_config * hostapd_config_read(const char *fname); int hostapd_set_iface(struct hostapd_config *conf, struct hostapd_bss_config *bss, char *field, char *value); +int hostapd_config_read_maclist(const char *fname, + struct mac_acl_entry **acl, int *num); #endif /* CONFIG_FILE_H */ diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c index 8f42f90..e6a8ced 100644 --- a/hostapd/ctrl_iface.c +++ b/hostapd/ctrl_iface.c @@ -514,6 +514,42 @@ static int hostapd_ctrl_iface_ess_disassoc(struct hostapd_data *hapd, } +static int hostapd_ctrl_iface_set_accept_mac(struct hostapd_data *hapd, + char *fname) +{ + hapd->conf->num_accept_mac = 0; + + if (hostapd_config_read_maclist(fname, &hapd->conf->accept_mac, + &hapd->conf->num_accept_mac)) { + wpa_printf(MSG_ERROR, "Reading mac list from file failed"); + return -1; + } + + /* Accept mac list changed, check if need to deauth stations*/ + hostapd_macaddr_acl_accept_sta(hapd); + + return 0; +} + + +static int hostapd_ctrl_iface_set_deny_mac(struct hostapd_data *hapd, + char *fname) +{ + hapd->conf->num_deny_mac = 0; + + if (hostapd_config_read_maclist(fname, &hapd->conf->deny_mac, + &hapd->conf->num_deny_mac)) { + wpa_printf(MSG_ERROR, "Reading mac list from file failed"); + return -1; + } + + /* Deny mac list changed, check if need to deauth stations*/ + hostapd_macaddr_acl_deny_sta(hapd); + + return 0; +} + + static int hostapd_ctrl_iface_get_config(struct hostapd_data *hapd, char *buf, size_t buflen) { @@ -723,6 +759,12 @@ static int hostapd_ctrl_iface_set(struct hostapd_data *hapd, char *cmd) else hapd->gas_frag_limit = val; #endif /* CONFIG_INTERWORKING */ + } else if (os_strcasecmp(cmd, "macaddr_acl") == 0) { + ret = hostapd_macaddr_acl_command(hapd, value); + } else if (os_strcasecmp(cmd, "accept_mac_file") == 0) { + ret = hostapd_ctrl_iface_set_accept_mac(hapd, value); + } else if (os_strcasecmp(cmd, "deny_mac_file") == 0) { + ret = hostapd_ctrl_iface_set_deny_mac(hapd, value); } else { ret = hostapd_set_iface(hapd->iconf, hapd->conf, cmd, value); } diff --git a/src/ap/hostapd.c b/src/ap/hostapd.c index 4e06808..ac9ef26 100644 --- a/src/ap/hostapd.c +++ b/src/ap/hostapd.c @@ -1137,3 +1137,59 @@ hostapd_channel_data *hostapd_get_valid_channel(struct hostapd_data *hapd, wpa_printf(MSG_WARNING, "Could't get requested channel"); return NULL; } + +void hostapd_macaddr_acl_accept_sta(struct hostapd_data *hapd) +{ + struct sta_info *sta = NULL; + + if (hapd->conf->macaddr_acl != DENY_UNLESS_ACCEPTED) + return; + + for (sta = hapd->sta_list; sta; sta = sta->next) { + if (!hostapd_maclist_found(hapd->conf->accept_mac, + hapd->conf->num_accept_mac, sta->addr, NULL)) { + hostapd_drv_sta_deauth(hapd, sta->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); + ap_sta_deauthenticate(hapd, sta, + WLAN_REASON_PREV_AUTH_NOT_VALID); + } + } +} + +void hostapd_macaddr_acl_deny_sta(struct hostapd_data *hapd) +{ + struct sta_info *sta = NULL; + + if (hapd->conf->macaddr_acl != ACCEPT_UNLESS_DENIED) + return; + + for (sta = hapd->sta_list; sta; sta = sta->next) { + if (hostapd_maclist_found(hapd->conf->deny_mac, + hapd->conf->num_deny_mac, sta->addr, NULL)) { + hostapd_drv_sta_deauth(hapd, sta->addr, + WLAN_REASON_PREV_AUTH_NOT_VALID); + ap_sta_deauthenticate(hapd, sta, + WLAN_REASON_PREV_AUTH_NOT_VALID); + } + } +} + +int hostapd_macaddr_acl_command(struct hostapd_data *hapd, char *cmd) +{ + int ret = 0; + + if (os_strcasecmp(cmd, "accept") == 0) { + wpa_printf(MSG_DEBUG, "Changing to access control accept list"); + hapd->conf->macaddr_acl = DENY_UNLESS_ACCEPTED; + hostapd_macaddr_acl_accept_sta(hapd); + } else if (os_strcasecmp(cmd, "deny") == 0) { + wpa_printf(MSG_DEBUG, "Changing to accees control deny list"); + hapd->conf->macaddr_acl = ACCEPT_UNLESS_DENIED; + hostapd_macaddr_acl_deny_sta(hapd); + } else { + wpa_printf(MSG_ERROR, "Unknown acl command"); + ret = -1; + } + + return ret; +} diff --git a/src/ap/hostapd.h b/src/ap/hostapd.h index feea42d..6193200 100644 --- a/src/ap/hostapd.h +++ b/src/ap/hostapd.h @@ -276,6 +276,9 @@ void hostapd_new_assoc_sta(struct hostapd_data *hapd, struct sta_info *sta, struct hostapd_channel_data *hostapd_get_valid_channel(struct hostapd_data *hapd, int req_freq); +void hostapd_macaddr_acl_accept_sta(struct hostapd_data *hapd); +void hostapd_macaddr_acl_deny_sta(struct hostapd_data *hapd); +int hostapd_macaddr_acl_command(struct hostapd_data *hapd, char *cmd); /* utils.c */ int hostapd_register_probereq_cb(struct hostapd_data *hapd, -- cgit v1.1 From b1ce8a6945f52737f2c62ec6c3a5c54f87d16b3d Mon Sep 17 00:00:00 2001 From: Vishal Mahaveer Date: Fri, 9 Nov 2012 09:41:40 -0600 Subject: nl80211: add support for DRIVER COUNTRY command Add this for supporting country command coming as DRIVER command in Android. Signed-off-by: Vishal Mahaveer --- src/drivers/driver_nl80211.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index 7254ecc..b68dbd1 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -9788,6 +9788,8 @@ static int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf, } else if (os_strncasecmp(cmd, "SETBAND ", 8) == 0) { /* Do nothing: Handled by wpa_supplicant_driver_cmd */ return 0; + } else if(os_strncasecmp(cmd, "COUNTRY ", 8) == 0) { + return wpa_driver_nl80211_set_country(priv, cmd + 8); } else if (os_strcasecmp(cmd, "RXFILTER-START") == 0) { return nl80211_set_wowlan_triggers(bss, 1); } else if (os_strcasecmp(cmd, "RXFILTER-STOP") == 0) { -- cgit v1.1 From 8975c166e26ccda2b89eb8b7d3d796eb4ee0e186 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Mon, 12 Nov 2012 13:51:35 +0200 Subject: Avoid sched scan flood in case of mismatched security (UPSTREAM) Current sched scan in the kernel is limited to SSID matching. A rare corner case is when an AP with a matching SSID but unmatching security to a saved profile is in the vicinity. In such a case sched scan results will immediately be returned after initiating sched scan however no match will be found due to the security mismatch. This goes on in a tight loop which is bad as it will effectively prevent the host from suspending and scan results will eventually contain the single AP matched by the sched scan due to expiration of other APs scanned in normal scans which are less frequent. Avoid this by stopping sched scan after detecting sched scan results were received but no matched network. Don't start another sched scan immediately but wait for the next normal scan without any results to restart it. This prevents the tight loop. Signed-off-by: Eyal Shapira --- wpa_supplicant/events.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index 7f46a4f..c735da3 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -1232,9 +1232,20 @@ static int _wpa_supplicant_event_scan_results(struct wpa_supplicant *wpa_s, return 0; } #endif /* CONFIG_P2P */ - if ((data && data->scan_info.is_sched_scan_res) || - !wpa_s->sched_scanning) + /* + * If sched scan results were received but we didn't + * connect then there's an AP with a matching SSID + * which may have mismatching security. Don't restart + * another sched scan immediately and wait for the next + * normal scan in scan_interval to trigger it in order + * to avoid a sched scan results storm. + * In any case if it's not started kick start it. + */ + if (!wpa_s->sched_scanning) wpa_supplicant_req_sched_scan(wpa_s); + else if (data && data->scan_info.is_sched_scan_res) + wpa_supplicant_cancel_sched_scan(wpa_s); + wpa_supplicant_req_new_scan(wpa_s, timeout_sec, timeout_usec); } -- cgit v1.1 From 865eb5dc1f399c493a002a0f221f23c96799ed65 Mon Sep 17 00:00:00 2001 From: Victor Goldenshtein Date: Mon, 12 Nov 2012 17:32:11 +0200 Subject: wpa_s: restart sched scan on channel list change The channel list can be changed as a result of arriving beacon hints during normal scan or as a result of local Reg-Domain change, some passive channels can become active and shall be reconfigured accordingly for the scheduled scan. This fixes the connection to hidden SSIDs on 5Ghz band during default Reg-Domain 00 (world roaming). Signed-off-by: Victor Goldenshtein --- wpa_supplicant/events.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index c735da3..e97939e 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -2847,6 +2847,13 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, #ifdef CONFIG_P2P wpas_p2p_update_channel_list(wpa_s); #endif /* CONFIG_P2P */ + + /* Restart the sched scan with updated channel list */ + if (wpa_s->sched_scanning) { + wpa_dbg(wpa_s, MSG_DEBUG, "Channel list changed restart" + " sched scan."); + wpa_supplicant_req_sched_scan(wpa_s); + } break; case EVENT_INTERFACE_UNAVAILABLE: #ifdef CONFIG_P2P -- cgit v1.1 From f63238165abfda18b46bbc8c2a0e91aca853da64 Mon Sep 17 00:00:00 2001 From: Victor Goldenshtein Date: Tue, 13 Nov 2012 10:06:24 +0200 Subject: wpa_s: don't accumulate delayed sched scan requests (UPSTREAM) Clear any previous pending timeouts before scheduling a new delayed sched scan. Signed-off-by: Victor Goldenshtein --- wpa_supplicant/scan.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c index e50dcfc..887c747 100644 --- a/wpa_supplicant/scan.c +++ b/wpa_supplicant/scan.c @@ -799,6 +799,9 @@ int wpa_supplicant_delayed_sched_scan(struct wpa_supplicant *wpa_s, if (!wpa_s->sched_scan_supported) return -1; + eloop_cancel_timeout(wpa_supplicant_delayed_sched_scan_timeout, + wpa_s, NULL); + eloop_register_timeout(sec, usec, wpa_supplicant_delayed_sched_scan_timeout, wpa_s, NULL); -- cgit v1.1 From 4e1835b2ccb4698e8e7022522928317d219bca32 Mon Sep 17 00:00:00 2001 From: Eyal Shapira Date: Tue, 13 Nov 2012 03:00:21 +0200 Subject: P2P: Fix broken rx action frame handling (INTERNAL-SQUASH) Commit "P2P: Fix duplicate handling of rx action frames" went too far and dropped any rx action frames arriving on the GO interface. It assumed that any action frames were duplicated and received on both GO interface and P2P device interface. This is wrong as some actions frames like P2P presence request are sent to the GO interface address and won't be duplicated. The root cause of the duplication lies within the Rx path in mac80211 in Johannes` patch "mac80211: accept public action frames with mismatched BSSID". When wpa_s works with a separate group interface this creates a duplicated Rx on both the P2P dev interface and the GO interface. Fix the issue by canceling the duplication in wpa_s and discarding public action frames with unmatching bssid arriving on a dedicated GO interface (This should be squashed with "P2P: Fix duplicate handling of rx action frames") Signed-off-by: Eyal Shapira --- src/p2p/p2p.h | 5 +++++ src/p2p/p2p_i.h | 1 - wpa_supplicant/p2p_supplicant.c | 16 +++++++++++++--- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 3c439f3..a60974f 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -1726,4 +1726,9 @@ int p2p_prepare_channel(struct p2p_data *p2p, unsigned int force_freq); void p2p_set_config_timeout(struct p2p_data *p2p, u8 go_timeout, u8 client_timeout); +/** + * p2p_group_get_interface_addr - Get the interface address of a P2P group + * @group: P2P group context from p2p_group_init() + */ +const u8 *p2p_group_get_interface_addr(struct p2p_group *group); #endif /* P2P_H */ diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index d254818..9e3fd6f 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -557,7 +557,6 @@ struct p2p_noa_desc { }; /* p2p_group.c */ -const u8 * p2p_group_get_interface_addr(struct p2p_group *group); u8 p2p_group_presence_req(struct p2p_group *group, const u8 *client_interface_addr, const u8 *noa, size_t noa_len); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index d8d72da..42c062f 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -4137,9 +4137,19 @@ void wpas_p2p_rx_action(struct wpa_supplicant *wpa_s, const u8 *da, if (wpa_s->global->p2p == NULL) return; - if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) { - wpa_printf(MSG_DEBUG, "Discard RX action event on P2P " - "GO/CLI iface. P2P Device interface will handle it"); + /* + * Discard an Rx duplication created by mac80211 rx path + * when receiving public action frames with mismatched BSSID + * In case of separate GO interface such public action frames (prov disc + * dev disc, invites) these should be handled by the P2P dev interface + */ + if (wpa_s->p2p_group_interface == P2P_GROUP_INTERFACE_GO && + category == WLAN_ACTION_PUBLIC && + wpa_s->p2p_group && + os_memcmp(bssid, p2p_group_get_interface_addr(wpa_s->p2p_group), + ETH_ALEN)) { + wpa_printf(MSG_DEBUG, "Discard duplicate RX action event on" + " P2P GO interface"); return; } -- cgit v1.1