diff options
-rw-r--r-- | src/drivers/driver_nl80211.c | 3 | ||||
-rw-r--r-- | src/p2p/p2p_go_neg.c | 3 | ||||
-rw-r--r-- | wpa_supplicant/config.c | 1 | ||||
-rw-r--r-- | wpa_supplicant/config.h | 8 | ||||
-rw-r--r-- | wpa_supplicant/config_file.c | 2 | ||||
-rw-r--r-- | wpa_supplicant/ctrl_iface.c | 3 | ||||
-rw-r--r-- | wpa_supplicant/p2p_supplicant.c | 68 | ||||
-rw-r--r-- | wpa_supplicant/wpa_supplicant_template.conf | 2 |
8 files changed, 82 insertions, 8 deletions
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c index a1a09a5..7254ecc 100644 --- a/src/drivers/driver_nl80211.c +++ b/src/drivers/driver_nl80211.c @@ -9785,6 +9785,9 @@ static int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf, if(i < 0) return i; return nl80211_toggle_wowlan_trigger(bss, i, 0); + } else if (os_strncasecmp(cmd, "SETBAND ", 8) == 0) { + /* Do nothing: Handled by wpa_supplicant_driver_cmd */ + return 0; } else if (os_strcasecmp(cmd, "RXFILTER-START") == 0) { return nl80211_set_wowlan_triggers(bss, 1); } else if (os_strcasecmp(cmd, "RXFILTER-STOP") == 0) { diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c index 8c2ad3a..2d31f4b 100644 --- a/src/p2p/p2p_go_neg.c +++ b/src/p2p/p2p_go_neg.c @@ -1043,7 +1043,8 @@ void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa, wpa_hexdump(MSG_DEBUG, "P2P: channels", c->channel, c->channels); } - if (!p2p_channels_includes(&intersection, p2p->op_reg_class, + if (!p2p->cfg->cfg_op_channel || + !p2p_channels_includes(&intersection, p2p->op_reg_class, p2p->op_channel)) p2p_reselect_channel(p2p, &intersection); diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 8bae7b7..69eb7d0 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -2995,6 +2995,7 @@ static const struct global_parse_data global_fields[] = { { BIN(wps_nfc_dev_pw), 0 }, { INT(p2p_go_max_inactivity), 0 }, { INT(p2p_go_ht40), 0 }, + { INT(p2p_multi_chan), 0 }, { INT_RANGE(sched_scan_num_short_intervals, 0, MAX_NUM_SCHED_SCAN_SHORT_INTERVALS), 0 }, { INT_RANGE(sched_scan_short_interval, 1, MAX_SCHED_SCAN_INTERVAL), 0 }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 568af0d..eb7dbf0 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -702,6 +702,14 @@ struct wpa_config { int p2p_go_ht40; /** + * p2p_multi_chan - Default to multi-channel operation when operating + * as p2p. We will try to optimize throughput instead of trying to make + * sure P2P starts on the same channel as another interface that's + * currently connected. + */ + int p2p_multi_chan; + + /** * sched_scan_short_interval - Initial interval for sched scan in secs * sched scan will start with this interval for num_short_intervals * intervals and then switch to a longer interval defined by diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 32c6990..cbece8e 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -898,6 +898,8 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) config->p2p_go_max_inactivity); if (config->p2p_go_ht40) fprintf(f, "p2p_go_ht40=%u\n", config->p2p_go_ht40); + if (config->p2p_multi_chan) + fprintf(f, "p2p_multi_chan=%u\n", config->p2p_multi_chan); if (config->sched_scan_num_short_intervals != DEFAULT_SCHED_SCAN_NUM_SHORT_INTERVALS) fprintf(f, "sched_scan_num_short_intervals=%u\n", diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 2fdd535..8aad951 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -2974,6 +2974,9 @@ int p2p_handle_concurrency_conflicts(struct wpa_supplicant *wpa_s, int *go_inten struct wpa_supplicant *iface = NULL; struct p2p_data *p2p = wpa_s->global->p2p; + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) + return 0; + wpa_printf(MSG_INFO, "p2p: handling concurrency conflicts"); /* we only fear frequency conflicts */ diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 89bd5ae..b0eb594 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -3264,13 +3264,17 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, return ret; } - if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid) == 0 && - wpa_s->assoc_freq) - oper_freq = wpa_s->assoc_freq; - else { - oper_freq = wpa_drv_shared_freq(wpa_s); - if (oper_freq < 0) - oper_freq = 0; + if (!(wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) || + !wpa_s->conf->p2p_multi_chan) { + if (wpa_s->current_ssid && + wpa_drv_get_bssid(wpa_s, bssid) == 0 && + wpa_s->assoc_freq) + oper_freq = wpa_s->assoc_freq; + else { + oper_freq = wpa_drv_shared_freq(wpa_s); + if (oper_freq < 0) + oper_freq = 0; + } } if (freq > 0) { @@ -3965,6 +3969,18 @@ static void wpas_p2p_clear_pending_action_tx(struct wpa_supplicant *wpa_s) wpa_s->pending_action_tx = NULL; } +static int wpas_p2p_connected(struct wpa_supplicant *wpa_s) +{ + struct wpa_supplicant *iface; + + for (iface = wpa_s->global->ifaces; iface; iface = iface->next) { + if (iface->p2p_group_interface == P2P_GROUP_INTERFACE_GO || + iface->p2p_group_interface == P2P_GROUP_INTERFACE_CLIENT) + return 1; + } + + return 0; +} int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout, enum p2p_discovery_type type, @@ -3981,6 +3997,14 @@ int wpas_p2p_find(struct wpa_supplicant *wpa_s, unsigned int timeout, wpa_s->p2p_in_provisioning) return -1; + + if (!(wpa_s->drv_flags & + WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT) && + wpas_p2p_connected(wpa_s)) { + wpa_printf(MSG_DEBUG, "P2P: find blocked due to active GO/CLI"); + return -1; + } + wpa_supplicant_cancel_sched_scan(wpa_s); return p2p_find(wpa_s->global->p2p, timeout, type, @@ -4892,6 +4916,24 @@ int wpas_p2p_unauthorize(struct wpa_supplicant *wpa_s, const char *addr) return p2p_unauthorize(p2p, peer); } +int wpas_is_p2p_iface(struct wpa_supplicant *wpa_s) +{ + struct wpa_ssid *ssid; + + if (wpa_s->p2p_group_interface != NOT_P2P_GROUP_INTERFACE) + return 1; + + /* P2P GO in case no group iface */ + if (wpa_s->p2p_group) + return 1; + + /* P2P CLI in case no group iface */ + ssid = wpa_s->current_ssid; + if (ssid && ssid->p2p_group) + return 1; + + return 0; +} /** * wpas_p2p_disconnect - Disconnect from a P2P Group @@ -4910,6 +4952,12 @@ int wpas_p2p_disconnect(struct wpa_supplicant *wpa_s) if (wpa_s == NULL) return -1; + if (!wpas_is_p2p_iface(wpa_s)) { + wpa_printf(MSG_DEBUG, "P2P: No group to disconnect on %s", + wpa_s->ifname); + return -1; + } + wpa_s->removal_reason = P2P_GROUP_REMOVAL_REQUESTED; wpas_p2p_group_delete(wpa_s, 0); @@ -5032,6 +5080,12 @@ int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s, int freq) iface->current_ssid->frequency = freq; continue; } + + /* some drivers can handle this on their own */ + if (wpa_s->driver->hapd_channel_switch) { + wpa_printf(MSG_INFO, "P2P: GO Ch. switch will be initiated by the driver"); + continue; + } } /* diff --git a/wpa_supplicant/wpa_supplicant_template.conf b/wpa_supplicant/wpa_supplicant_template.conf index b9f902b..901209a 100644 --- a/wpa_supplicant/wpa_supplicant_template.conf +++ b/wpa_supplicant/wpa_supplicant_template.conf @@ -7,3 +7,5 @@ fast_reauth=1 p2p_conc_mode=2 p2p_go_max_inactivity=30 p2p_go_ht40=1 +p2p_multi_chan=1 +disassoc_low_ack=1 |