aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVishal Mahaveer <vishalm@ti.com>2012-09-17 21:00:32 -0500
committerVishal Mahaveer <vishalm@ti.com>2012-09-17 21:00:32 -0500
commit38c89c99dd5b2d3e16b564c5437cc69ad021f91a (patch)
tree179d635a6de281483c5c71ec6469706722f47502
parentc74cce202a87e55ee7693a07bda6e417929bc2fc (diff)
parentc820dd239e664ab3403c9cd69b6ca51a21b09f8e (diff)
downloadexternal_wpa_supplicant_8_ti-38c89c99dd5b2d3e16b564c5437cc69ad021f91a.zip
external_wpa_supplicant_8_ti-38c89c99dd5b2d3e16b564c5437cc69ad021f91a.tar.gz
external_wpa_supplicant_8_ti-38c89c99dd5b2d3e16b564c5437cc69ad021f91a.tar.bz2
Merge commit 'ol_r8.a4.02' into d-jb-release
-rw-r--r--src/ap/ap_config.c4
-rw-r--r--src/ap/beacon.c2
-rw-r--r--src/ap/hw_features.c2
-rw-r--r--src/p2p/p2p.c24
-rw-r--r--src/p2p/p2p.h21
-rw-r--r--src/p2p/p2p_go_neg.c38
-rw-r--r--src/p2p/p2p_i.h3
-rw-r--r--src/p2p/p2p_invitation.c3
-rw-r--r--src/wps/wps_enrollee.c10
-rw-r--r--src/wps/wps_registrar.c14
-rw-r--r--wpa_supplicant/ap.c12
-rw-r--r--wpa_supplicant/config.c5
-rw-r--r--wpa_supplicant/config.h10
-rw-r--r--wpa_supplicant/config_file.c2
-rw-r--r--wpa_supplicant/config_ssid.h2
-rw-r--r--wpa_supplicant/ctrl_iface.c53
-rw-r--r--wpa_supplicant/dbus/dbus_new_handlers_p2p.c6
-rw-r--r--wpa_supplicant/p2p_supplicant.c133
-rw-r--r--wpa_supplicant/p2p_supplicant.h9
-rw-r--r--wpa_supplicant/scan.c18
-rw-r--r--wpa_supplicant/wpa_cli.c4
-rw-r--r--wpa_supplicant/wpa_supplicant.c10
-rw-r--r--wpa_supplicant/wpa_supplicant_i.h1
-rw-r--r--wpa_supplicant/wpa_supplicant_template.conf3
24 files changed, 292 insertions, 97 deletions
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index b9e1c5f..e7de744 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -104,9 +104,9 @@ struct hostapd_config * hostapd_config_defaults(void)
const struct wpa_wmm_ac_params ac_be =
{ aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
const struct wpa_wmm_ac_params ac_vi = /* video traffic */
- { aCWmin - 1, aCWmin, 2, 3000 / 32, 1 };
+ { aCWmin - 1, aCWmin, 2, 3000 / 32, 0 };
const struct wpa_wmm_ac_params ac_vo = /* voice traffic */
- { aCWmin - 2, aCWmin - 1, 2, 1500 / 32, 1 };
+ { aCWmin - 2, aCWmin - 1, 2, 1500 / 32, 0 };
const struct hostapd_tx_queue_params txq_bk =
{ 7, ecw2cw(aCWmin), ecw2cw(aCWmax), 0 };
const struct hostapd_tx_queue_params txq_be =
diff --git a/src/ap/beacon.c b/src/ap/beacon.c
index 0f29ccd..a1bb067 100644
--- a/src/ap/beacon.c
+++ b/src/ap/beacon.c
@@ -643,7 +643,7 @@ void ieee802_11_set_beacon(struct hostapd_data *hapd)
params.proberesp_len = resp_len;
params.dtim_period = hapd->conf->dtim_period;
params.beacon_int = hapd->iconf->beacon_int;
- params.basic_rates = hapd->iconf->basic_rates;
+ params.basic_rates = hapd->iface->basic_rates;
params.ssid = (u8 *) hapd->conf->ssid.ssid;
params.ssid_len = hapd->conf->ssid.ssid_len;
params.pairwise_ciphers = hapd->conf->rsn_pairwise ?
diff --git a/src/ap/hw_features.c b/src/ap/hw_features.c
index 76c4211..0900e78 100644
--- a/src/ap/hw_features.c
+++ b/src/ap/hw_features.c
@@ -129,6 +129,8 @@ int hostapd_prepare_rates(struct hostapd_iface *iface,
i = 0;
while (basic_rates[i] >= 0)
i++;
+ if (i)
+ i++; /* -1 termination */
os_free(iface->basic_rates);
iface->basic_rates = os_malloc(i * sizeof(int));
if (iface->basic_rates)
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 9a74450..e905e77 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -2382,6 +2382,9 @@ struct p2p_data * p2p_init(const struct p2p_config *cfg)
eloop_register_timeout(P2P_PEER_EXPIRATION_INTERVAL, 0,
p2p_expiration_timeout, p2p, NULL);
+ p2p->go_timeout = 100;
+ p2p->client_timeout = 20;
+
return p2p;
}
@@ -2864,7 +2867,7 @@ static void p2p_go_neg_req_cb(struct p2p_data *p2p, int success)
* channel.
*/
p2p_set_state(p2p, P2P_CONNECT);
- p2p_set_timeout(p2p, 0, 100000);
+ p2p_set_timeout(p2p, 0, success ? 200000 : 100000);
}
@@ -2880,7 +2883,7 @@ static void p2p_go_neg_resp_cb(struct p2p_data *p2p, int success)
return;
}
p2p_set_state(p2p, P2P_CONNECT);
- p2p_set_timeout(p2p, 0, 100000);
+ p2p_set_timeout(p2p, 0, 250000);
}
@@ -4098,3 +4101,20 @@ int p2p_in_progress(struct p2p_data *p2p)
return 0;
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)
+{
+ if (p2p) {
+ p2p->go_timeout = go_timeout;
+ p2p->client_timeout = client_timeout;
+ }
+}
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 9be5b84..3f796d0 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -75,6 +75,8 @@ struct p2p_go_neg_results {
*/
int freq;
+ int ht40;
+
/**
* ssid - SSID of the group
*/
@@ -1688,6 +1690,16 @@ 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
@@ -1715,4 +1727,13 @@ const char * p2p_wps_method_text(enum p2p_wps_method method);
int p2p_prepare_channel(struct p2p_data *p2p, unsigned int force_freq);
+/**
+ * p2p_set_config_timeout - Set local config timeouts
+ * @p2p: P2P module context from p2p_init()
+ * @go_timeout: Time in 10 ms units it takes to start the GO mode
+ * @client_timeout: Time in 10 ms units it takes to start the client mode
+ */
+void p2p_set_config_timeout(struct p2p_data *p2p, u8 go_timeout,
+ u8 client_timeout);
+
#endif /* P2P_H */
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index 51db6df..8c2ad3a 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -161,7 +161,7 @@ static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p,
p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) |
p2p->next_tie_breaker);
p2p->next_tie_breaker = !p2p->next_tie_breaker;
- p2p_buf_add_config_timeout(buf, 100, 20);
+ p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout);
p2p_buf_add_listen_channel(buf, p2p->cfg->country, p2p->cfg->reg_class,
p2p->cfg->channel);
if (p2p->ext_listen_interval)
@@ -274,7 +274,7 @@ static struct wpabuf * p2p_build_go_neg_resp(struct p2p_data *p2p,
~P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY,
group_capab);
p2p_buf_add_go_intent(buf, (p2p->go_intent << 1) | tie_breaker);
- p2p_buf_add_config_timeout(buf, 100, 20);
+ p2p_buf_add_config_timeout(buf, p2p->go_timeout, p2p->client_timeout);
if (peer && peer->go_state == REMOTE_GO) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Omit Operating "
"Channel attribute");
@@ -366,6 +366,35 @@ static void p2p_reselect_channel(struct p2p_data *p2p,
}
}
+ /* Try a channel where we might be able to use HT40 */
+ for (i = 0; i < intersection->reg_classes; i++) {
+ struct p2p_reg_class *c = &intersection->reg_class[i];
+ if (c->reg_class == 116 || c->reg_class == 117 ||
+ c->reg_class == 126 || c->reg_class == 127) {
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
+ "P2P: Pick possible HT40 channel (reg_class "
+ "%u channel %u) from intersection",
+ c->reg_class, c->channel[0]);
+ p2p->op_reg_class = c->reg_class;
+ p2p->op_channel = c->channel[0];
+ return;
+ }
+ }
+
+ /*
+ * Try to see if the original channel is in the intersection. If
+ * so, no need to change anything, as it already contains some
+ * randomness.
+ */
+ if (p2p_channels_includes(intersection, p2p->op_reg_class,
+ p2p->op_channel)) {
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
+ "P2P: Using original operating class and channel "
+ "(reg_class %u channel %u) from intersection",
+ p2p->op_reg_class, p2p->op_channel);
+ return;
+ }
+
/*
* Fall back to whatever is included in the channel intersection since
* no better options seems to be available.
@@ -623,7 +652,8 @@ void p2p_process_go_neg_req(struct p2p_data *p2p, const u8 *sa,
wpa_hexdump(MSG_DEBUG, "P2P: channels",
c->channel, c->channels);
}
- if (!p2p_channels_includes(&intersection,
+ if (!p2p->cfg->cfg_op_channel ||
+ !p2p_channels_includes(&intersection,
p2p->op_reg_class,
p2p->op_channel))
p2p_reselect_channel(p2p, &intersection);
@@ -700,7 +730,7 @@ fail:
P2P_PENDING_GO_NEG_RESPONSE_FAILURE;
if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
p2p->cfg->dev_addr,
- wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
+ wpabuf_head(resp), wpabuf_len(resp), 250) < 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Failed to send Action frame");
}
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index ca5fc3a..d254818 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -432,6 +432,9 @@ struct p2p_data {
* in IDLE state.
*/
int pd_retries;
+
+ u8 go_timeout;
+ u8 client_timeout;
};
/**
diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c
index 65c5477..c70fc7a 100644
--- a/src/p2p/p2p_invitation.c
+++ b/src/p2p/p2p_invitation.c
@@ -36,7 +36,8 @@ static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p,
if (p2p->inv_role == P2P_INVITE_ROLE_ACTIVE_GO || !p2p->inv_persistent)
p2p_buf_add_config_timeout(buf, 0, 0);
else
- p2p_buf_add_config_timeout(buf, 100, 20);
+ p2p_buf_add_config_timeout(buf, p2p->go_timeout,
+ p2p->client_timeout);
p2p_buf_add_invitation_flags(buf, p2p->inv_persistent ?
P2P_INVITATION_FLAGS_TYPE : 0);
p2p_buf_add_operating_channel(buf, p2p->cfg->country,
diff --git a/src/wps/wps_enrollee.c b/src/wps/wps_enrollee.c
index da0c101..389aa84 100644
--- a/src/wps/wps_enrollee.c
+++ b/src/wps/wps_enrollee.c
@@ -1150,7 +1150,7 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
return WPS_FAILURE;
if (attr.enrollee_nonce == NULL ||
- os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
+ os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
return WPS_FAILURE;
}
@@ -1242,14 +1242,14 @@ static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
}
if (attr.registrar_nonce == NULL ||
- os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
+ os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
{
wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
return WPS_FAILURE;
}
if (attr.enrollee_nonce == NULL ||
- os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
+ os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
return WPS_FAILURE;
}
@@ -1289,7 +1289,7 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
}
if (attr.registrar_nonce == NULL ||
- os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
+ os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
{
wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
wpa_hexdump(MSG_DEBUG, "WPS: Received Registrar Nonce",
@@ -1300,7 +1300,7 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
}
if (attr.enrollee_nonce == NULL ||
- os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
+ os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
wpa_hexdump(MSG_DEBUG, "WPS: Received Enrollee Nonce",
attr.enrollee_nonce, WPS_NONCE_LEN);
diff --git a/src/wps/wps_registrar.c b/src/wps/wps_registrar.c
index 44bb006..53684d6 100644
--- a/src/wps/wps_registrar.c
+++ b/src/wps/wps_registrar.c
@@ -2854,7 +2854,7 @@ static enum wps_process_res wps_process_wsc_msg(struct wps_data *wps,
if (*attr.msg_type != WPS_M1 &&
(attr.registrar_nonce == NULL ||
os_memcmp(wps->nonce_r, attr.registrar_nonce,
- WPS_NONCE_LEN != 0))) {
+ WPS_NONCE_LEN) != 0)) {
wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
return WPS_FAILURE;
}
@@ -2950,14 +2950,14 @@ static enum wps_process_res wps_process_wsc_ack(struct wps_data *wps,
#endif /* CONFIG_WPS_UPNP */
if (attr.registrar_nonce == NULL ||
- os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
+ os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
{
wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
return WPS_FAILURE;
}
if (attr.enrollee_nonce == NULL ||
- os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
+ os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
return WPS_FAILURE;
}
@@ -3019,14 +3019,14 @@ static enum wps_process_res wps_process_wsc_nack(struct wps_data *wps,
#endif /* CONFIG_WPS_UPNP */
if (attr.registrar_nonce == NULL ||
- os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
+ os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
{
wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
return WPS_FAILURE;
}
if (attr.enrollee_nonce == NULL ||
- os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
+ os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
return WPS_FAILURE;
}
@@ -3105,14 +3105,14 @@ static enum wps_process_res wps_process_wsc_done(struct wps_data *wps,
#endif /* CONFIG_WPS_UPNP */
if (attr.registrar_nonce == NULL ||
- os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN != 0))
+ os_memcmp(wps->nonce_r, attr.registrar_nonce, WPS_NONCE_LEN) != 0)
{
wpa_printf(MSG_DEBUG, "WPS: Mismatch in registrar nonce");
return WPS_FAILURE;
}
if (attr.enrollee_nonce == NULL ||
- os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN != 0)) {
+ os_memcmp(wps->nonce_e, attr.enrollee_nonce, WPS_NONCE_LEN) != 0) {
wpa_printf(MSG_DEBUG, "WPS: Mismatch in enrollee nonce");
return WPS_FAILURE;
}
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index db10544..e79f71f 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -99,6 +99,18 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
if (!no_ht && mode && mode->ht_capab) {
conf->ieee80211n = 1;
+#ifdef CONFIG_P2P
+ if (conf->hw_mode == HOSTAPD_MODE_IEEE80211A &&
+ (mode->ht_capab &
+ HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET) &&
+ ssid->ht40)
+ conf->secondary_channel =
+ wpas_p2p_get_ht40_mode(wpa_s, mode,
+ conf->channel);
+ if (conf->secondary_channel)
+ conf->ht_capab |=
+ HT_CAP_INFO_SUPP_CHANNEL_WIDTH_SET;
+#endif /* CONFIG_P2P */
/*
* white-list capabilities that won't cause issues
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index 886cff9..8bae7b7 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2542,9 +2542,9 @@ struct wpa_config * wpa_config_alloc_empty(const char *ctrl_interface,
const struct wpa_wmm_ac_params ac_be =
{ aCWmin, aCWmax, 3, 0, 0 }; /* best effort traffic */
const struct wpa_wmm_ac_params ac_vi = /* video traffic */
- { aCWmin - 1, aCWmin, 2, 3000 / 32, 1 };
+ { aCWmin - 1, aCWmin, 2, 3000 / 32, 0 };
const struct wpa_wmm_ac_params ac_vo = /* voice traffic */
- { aCWmin - 2, aCWmin - 1, 2, 1500 / 32, 1 };
+ { aCWmin - 2, aCWmin - 1, 2, 1500 / 32, 0 };
config = os_zalloc(sizeof(*config));
if (config == NULL)
@@ -2994,6 +2994,7 @@ static const struct global_parse_data global_fields[] = {
{ BIN(wps_nfc_dh_privkey), 0 },
{ BIN(wps_nfc_dev_pw), 0 },
{ INT(p2p_go_max_inactivity), 0 },
+ { INT(p2p_go_ht40), 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 fd9ba78..568af0d 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -692,6 +692,16 @@ struct wpa_config {
int p2p_go_max_inactivity;
/**
+ * p2p_go_ht40 - Default mode for HT40 enable when operating as GO.
+ *
+ * This will take effect for p2p_group_add and p2p_connect. Note that
+ * regulatory constraints and driver capabilities are consulted anyway,
+ * so setting it to 1 can't do real harm
+ * By default: 0 (disabled)
+ */
+ int p2p_go_ht40;
+
+ /**
* 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 b99517b..32c6990 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -896,6 +896,8 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
if (config->p2p_go_max_inactivity != DEFAULT_P2P_GO_MAX_INACTIVITY)
fprintf(f, "p2p_go_max_inactivity=%u\n",
config->p2p_go_max_inactivity);
+ if (config->p2p_go_ht40)
+ fprintf(f, "p2p_go_ht40=%u\n", config->p2p_go_ht40);
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/config_ssid.h b/wpa_supplicant/config_ssid.h
index 9baf405..f75241b 100644
--- a/wpa_supplicant/config_ssid.h
+++ b/wpa_supplicant/config_ssid.h
@@ -356,6 +356,8 @@ struct wpa_ssid {
*/
int frequency;
+ int ht40;
+
/**
* wpa_ptk_rekey - Maximum lifetime for PTK in seconds
*
diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
index 4c21833..2fdd535 100644
--- a/wpa_supplicant/ctrl_iface.c
+++ b/wpa_supplicant/ctrl_iface.c
@@ -3050,10 +3050,15 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
int go_intent = -1;
int freq = 0;
int pd;
+ int ht40;
+#ifdef ANDROID_P2P
+ int no_p2p_conc;
+#endif
/* <addr> <"pbc" | "pin" | PIN> [label|display|keypad]
* [persistent|persistent=<network id>]
- * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] [provdisc] */
+ * [join] [auth] [go_intent=<0..15>] [freq=<in MHz>] [provdisc]
+ * [ht40] */
if (hwaddr_aton(cmd, addr))
return -1;
@@ -3081,6 +3086,10 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
auth = os_strstr(pos, " auth") != NULL;
automatic = os_strstr(pos, " auto") != NULL;
pd = os_strstr(pos, " provdisc") != NULL;
+ ht40 = (os_strstr(cmd, "ht40") != NULL) || wpa_s->conf->p2p_go_ht40;
+#ifdef ANDROID_P2P
+ no_p2p_conc = os_strstr(pos, " no_p2p_conc") != NULL;
+#endif
pos2 = os_strstr(pos, " go_intent=");
if (pos2) {
@@ -3119,22 +3128,25 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd,
}
#ifdef ANDROID_P2P
- if (p2p_handle_concurrency_conflicts(wpa_s, &go_intent) != 0) {
- wpa_printf(MSG_INFO, "P2P: Canceling p2p connect due to "
- "single channel concurrency conflicts.");
- return -1;
- }
+ if (!no_p2p_conc) {
+ if (p2p_handle_concurrency_conflicts(wpa_s, &go_intent) != 0) {
+ wpa_printf(MSG_INFO, "P2P: Canceling p2p connect due "
+ "to single channel concurrency conflicts.");
+ return -1;
+ }
- if (join && go_intent == 15) {
- wpa_printf(MSG_INFO, "P2P: Canceling p2p join due to "
- "single channel concurrency conflicts.");
- return -1;
+ if (join && go_intent == 15) {
+ wpa_printf(MSG_INFO, "P2P: Canceling p2p join due to "
+ "single channel concurrency conflicts.");
+ return -1;
+ }
}
#endif
new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
persistent_group, automatic, join,
- auth, go_intent, freq, persistent_id, pd);
+ auth, go_intent, freq, persistent_id, pd,
+ ht40);
if (new_pin == -2) {
os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25);
return 25;
@@ -3556,7 +3568,7 @@ static int p2p_ctrl_invite(struct wpa_supplicant *wpa_s, char *cmd)
static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
- char *cmd, int freq)
+ char *cmd, int freq, int ht40)
{
int id;
struct wpa_ssid *ssid;
@@ -3570,26 +3582,31 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
return -1;
}
- return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq);
+ return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, ht40);
}
static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
{
- int freq = 0;
+ int freq = 0, ht40;
char *pos;
pos = os_strstr(cmd, "freq=");
if (pos)
freq = atoi(pos + 5);
+ ht40 = (os_strstr(cmd, "ht40") != NULL) || wpa_s->conf->p2p_go_ht40;
+
if (os_strncmp(cmd, "persistent=", 11) == 0)
- return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq);
+ return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq,
+ ht40);
if (os_strcmp(cmd, "persistent") == 0 ||
os_strncmp(cmd, "persistent ", 11) == 0)
- return wpas_p2p_group_add(wpa_s, 1, freq);
+ return wpas_p2p_group_add(wpa_s, 1, freq, ht40);
if (os_strncmp(cmd, "freq=", 5) == 0)
- return wpas_p2p_group_add(wpa_s, 0, freq);
+ return wpas_p2p_group_add(wpa_s, 0, freq, ht40);
+ if (ht40)
+ return wpas_p2p_group_add(wpa_s, 0, freq, ht40);
wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'",
cmd);
@@ -4426,7 +4443,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
if (wpas_p2p_group_remove(wpa_s, buf + 17))
reply_len = -1;
} else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) {
- if (wpas_p2p_group_add(wpa_s, 0, 0))
+ if (wpas_p2p_group_add(wpa_s, 0, 0, 0))
reply_len = -1;
} else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) {
if (p2p_ctrl_group_add(wpa_s, buf + 14))
diff --git a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
index f4541f7..241a2e8 100644
--- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
+++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
@@ -346,13 +346,13 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
if (ssid == NULL || ssid->disabled != 2)
goto inv_args;
- if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq)) {
+ if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0)) {
reply = wpas_dbus_error_unknown_error(
message,
"Failed to reinvoke a persistent group");
goto out;
}
- } else if (wpas_p2p_group_add(wpa_s, persistent_group, freq))
+ } else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, 0))
goto inv_args;
out:
@@ -504,7 +504,7 @@ DBusMessage * wpas_dbus_handler_p2p_connect(DBusMessage *message,
new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method,
persistent_group, 0, join, authorize_only,
- go_intent, freq, -1, 0);
+ go_intent, freq, -1, 0, 0);
if (new_pin >= 0) {
char npin[9];
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index cc83feb..89bd5ae 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -832,6 +832,7 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s,
ssid->mode = group_formation ? WPAS_MODE_P2P_GROUP_FORMATION :
WPAS_MODE_P2P_GO;
ssid->frequency = params->freq;
+ ssid->ht40 = params->ht40;
ssid->ssid = os_zalloc(params->ssid_len + 1);
if (ssid->ssid) {
os_memcpy(ssid->ssid, params->ssid, params->ssid_len);
@@ -1030,6 +1031,9 @@ void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res)
return;
}
+ if (wpa_s->p2p_go_ht40)
+ res->ht40 = 1;
+
wpa_msg(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_SUCCESS);
wpas_notify_p2p_go_neg_completed(wpa_s, res);
@@ -2055,7 +2059,7 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
MAC2STR(sa), op_freq);
if (s) {
wpas_p2p_group_add_persistent(
- wpa_s, s, s->mode == WPAS_MODE_P2P_GO, 0);
+ wpa_s, s, s->mode == WPAS_MODE_P2P_GO, 0, 0);
} else if (bssid) {
wpas_p2p_join(wpa_s, bssid, go_dev_addr,
wpa_s->p2p_wps_method, 0);
@@ -2122,7 +2126,7 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid)
}
wpas_p2p_group_add_persistent(wpa_s, ssid,
- ssid->mode == WPAS_MODE_P2P_GO, 0);
+ ssid->mode == WPAS_MODE_P2P_GO, 0, 0);
}
@@ -2259,26 +2263,48 @@ struct p2p_oper_class_map {
enum { BW20, BW40PLUS, BW40MINUS } bw;
};
+static struct p2p_oper_class_map op_class[] = {
+ { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20 },
+ { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20 },
+#if 0 /* Do not enable HT40 on 2 GHz for now */
+ { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS },
+ { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS },
+#endif
+ { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20 },
+ { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20 },
+ { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS },
+ { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS },
+ { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS },
+ { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS },
+ { -1, 0, 0, 0, 0, BW20 }
+};
+
+
+static int wpas_p2p_verify_channel(struct wpa_supplicant *wpa_s,
+ struct hostapd_hw_modes *mode,
+ u8 channel, u8 bw)
+{
+ int flag;
+
+ if (!has_channel(wpa_s->global, mode, channel, &flag))
+ return -1;
+ if (bw == BW40MINUS &&
+ (!(flag & HOSTAPD_CHAN_HT40MINUS) ||
+ !has_channel(wpa_s->global, mode, channel - 4, NULL)))
+ return 0;
+ if (bw == BW40PLUS &&
+ (!(flag & HOSTAPD_CHAN_HT40PLUS) ||
+ !has_channel(wpa_s->global, mode, channel + 4, NULL)))
+ return 0;
+ return 1;
+}
+
+
static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
struct p2p_channels *chan)
{
struct hostapd_hw_modes *mode;
int cla, op;
- struct p2p_oper_class_map op_class[] = {
- { HOSTAPD_MODE_IEEE80211G, 81, 1, 13, 1, BW20 },
- { HOSTAPD_MODE_IEEE80211G, 82, 14, 14, 1, BW20 },
-#if 0 /* Do not enable HT40 on 2 GHz for now */
- { HOSTAPD_MODE_IEEE80211G, 83, 1, 9, 1, BW40PLUS },
- { HOSTAPD_MODE_IEEE80211G, 84, 5, 13, 1, BW40MINUS },
-#endif
- { HOSTAPD_MODE_IEEE80211A, 115, 36, 48, 4, BW20 },
- { HOSTAPD_MODE_IEEE80211A, 124, 149, 161, 4, BW20 },
- { HOSTAPD_MODE_IEEE80211A, 116, 36, 44, 8, BW40PLUS },
- { HOSTAPD_MODE_IEEE80211A, 117, 40, 48, 8, BW40MINUS },
- { HOSTAPD_MODE_IEEE80211A, 126, 149, 157, 8, BW40PLUS },
- { HOSTAPD_MODE_IEEE80211A, 127, 153, 161, 8, BW40MINUS },
- { -1, 0, 0, 0, 0, BW20 }
- };
if (wpa_s->hw.modes == NULL) {
wpa_printf(MSG_DEBUG, "P2P: Driver did not support fetching "
@@ -2298,16 +2324,7 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
if (mode == NULL)
continue;
for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
- int flag;
- if (!has_channel(wpa_s->global, mode, ch, &flag))
- continue;
- if (o->bw == BW40MINUS &&
- (!(flag & HOSTAPD_CHAN_HT40MINUS) ||
- !has_channel(wpa_s->global, mode, ch - 4, NULL)))
- continue;
- if (o->bw == BW40PLUS &&
- (!(flag & HOSTAPD_CHAN_HT40PLUS) ||
- !has_channel(wpa_s->global, mode, ch + 4, NULL)))
+ if (wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw) < 1)
continue;
if (reg == NULL) {
wpa_printf(MSG_DEBUG, "P2P: Add operating "
@@ -2331,6 +2348,32 @@ static int wpas_p2p_setup_channels(struct wpa_supplicant *wpa_s,
}
+int wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s,
+ struct hostapd_hw_modes *mode, u8 channel)
+{
+ int op, ret;
+
+ for (op = 0; op_class[op].op_class; op++) {
+ struct p2p_oper_class_map *o = &op_class[op];
+ u8 ch;
+
+ for (ch = o->min_chan; ch <= o->max_chan; ch += o->inc) {
+ if (o->mode != HOSTAPD_MODE_IEEE80211A ||
+ o->bw == BW20 || ch != channel)
+ continue;
+ ret = wpas_p2p_verify_channel(wpa_s, mode, ch, o->bw);
+ if (ret < 0)
+ continue;
+ else if (ret > 0)
+ return (o->bw == BW40MINUS) ? -1 : 1;
+ else
+ return 0;
+ }
+ }
+ return 0;
+}
+
+
static int wpas_get_noa(void *ctx, const u8 *interface_addr, u8 *buf,
size_t buf_len)
{
@@ -2640,6 +2683,13 @@ static int wpas_p2p_start_go_neg(struct wpa_supplicant *wpa_s,
force_freq, persistent_group);
}
+ /*
+ * Increase GO config timeout if HT40 is used since it takes some time
+ * to scan channels for coex purposes before the BSS can be started.
+ */
+ p2p_set_config_timeout(wpa_s->global->p2p,
+ wpa_s->p2p_go_ht40 ? 255 : 100, 20);
+
return p2p_connect(wpa_s->global->p2p, peer_addr, wps_method,
go_intent, own_interface_addr, force_freq,
persistent_group, ssid ? ssid->ssid : NULL,
@@ -2844,7 +2894,8 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s,
wpa_s->p2p_go_intent,
wpa_s->p2p_connect_freq,
wpa_s->p2p_persistent_id,
- wpa_s->p2p_pd_before_go_neg);
+ wpa_s->p2p_pd_before_go_neg,
+ wpa_s->p2p_go_ht40);
return;
}
@@ -3130,6 +3181,7 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s)
* parameters or -1 to generate new values (SSID/passphrase)
* @pd: Whether to send Provision Discovery prior to GO Negotiation as an
* interoperability workaround when initiating group formation
+ * @ht40: Start GO with 40 MHz channel width
* Returns: 0 or new PIN (if pin was %NULL) on success, -1 on unspecified
* failure, -2 on failure due to channel not currently available,
* -3 if forced channel is not supported
@@ -3137,7 +3189,8 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s)
int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
const char *pin, enum p2p_wps_method wps_method,
int persistent_group, int auto_join, int join, int auth,
- int go_intent, int freq, int persistent_id, int pd)
+ int go_intent, int freq, int persistent_id, int pd,
+ int ht40)
{
int force_freq = 0, oper_freq = 0;
u8 bssid[ETH_ALEN];
@@ -3169,6 +3222,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
wpa_s->p2p_connect_freq = freq;
wpa_s->p2p_fallback_to_go_neg = 0;
wpa_s->p2p_pd_before_go_neg = !!pd;
+ wpa_s->p2p_go_ht40 = !!ht40;
if (pin)
os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin));
@@ -3400,13 +3454,14 @@ int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname)
static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
struct p2p_go_neg_results *params,
- int freq)
+ int freq, int ht40)
{
u8 bssid[ETH_ALEN];
int res;
os_memset(params, 0, sizeof(*params));
params->role_go = 1;
+ params->ht40 = ht40;
if (freq) {
wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on forced "
"frequency %d MHz", freq);
@@ -3518,7 +3573,7 @@ wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
* i.e., without using Group Owner Negotiation.
*/
int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
- int freq)
+ int freq, int ht40)
{
struct p2p_go_neg_results params;
unsigned int r;
@@ -3582,7 +3637,7 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
return -1;
}
- if (wpas_p2p_init_go_params(wpa_s, &params, freq))
+ if (wpas_p2p_init_go_params(wpa_s, &params, freq, ht40))
return -1;
if (params.freq &&
!p2p_supported_freq(wpa_s->global->p2p, params.freq)) {
@@ -3649,7 +3704,7 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid, int addr_allocated,
- int freq)
+ int freq, int ht40)
{
struct p2p_go_neg_results params;
int go = 0;
@@ -3675,7 +3730,7 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
if (ssid->mode != WPAS_MODE_P2P_GO)
return -1;
- if (wpas_p2p_init_go_params(wpa_s, &params, freq))
+ if (wpas_p2p_init_go_params(wpa_s, &params, freq, ht40))
return -1;
params.role_go = 1;
@@ -4870,6 +4925,13 @@ 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)
@@ -5016,7 +5078,8 @@ static void wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s,
wpa_s->p2p_wps_method, wpa_s->p2p_persistent_group, 0,
0, 0, wpa_s->p2p_go_intent, wpa_s->p2p_connect_freq,
wpa_s->p2p_persistent_id,
- wpa_s->p2p_pd_before_go_neg);
+ wpa_s->p2p_pd_before_go_neg,
+ wpa_s->p2p_go_ht40);
}
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 24fb81e..f24fb28 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -21,7 +21,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
const char *pin, enum p2p_wps_method wps_method,
int persistent_group, int auto_join, int join,
int auth, int go_intent, int freq, int persistent_id,
- int pd);
+ int pd, int ht40);
void wpas_p2p_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
unsigned int freq, unsigned int duration);
void wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
@@ -32,10 +32,10 @@ int wpas_p2p_handle_frequency_conflicts(struct wpa_supplicant *wpa_s,
#endif
int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname);
int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
- int freq);
+ int freq, int ht40);
int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid, int addr_allocated,
- int freq);
+ int freq, int ht40);
struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
@@ -137,6 +137,7 @@ 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,
@@ -145,5 +146,7 @@ struct wpa_ssid * wpas_p2p_get_persistent(struct wpa_supplicant *wpa_s,
void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
const u8 *addr);
int wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s);
+int wpas_p2p_get_ht40_mode(struct wpa_supplicant *wpa_s,
+ struct hostapd_hw_modes *mode, u8 channel);
#endif /* P2P_SUPPLICANT_H */
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index ca7af57..6b43968 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 (!wpa_s->global->p2p_disabled && wpa_s->global->p2p) {
+ if (wpas_p2p_non_idle(wpa_s)) {
wpa_s->wps->dev.p2p = 1;
if (!wps) {
wps = 1;
@@ -369,8 +369,7 @@ static void wpas_add_interworking_elements(struct wpa_supplicant *wpa_s,
static struct wpabuf *
-wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s,
- struct wpa_driver_scan_params *params)
+wpa_supplicant_extra_ies(struct wpa_supplicant *wpa_s)
{
struct wpabuf *extra_ie = NULL;
#ifdef CONFIG_WPS
@@ -690,7 +689,7 @@ static void wpa_supplicant_scan(void *eloop_ctx, void *timeout_ctx)
ssid_list_set:
wpa_supplicant_optimize_freqs(wpa_s, &params);
- extra_ie = wpa_supplicant_extra_ies(wpa_s, &params);
+ extra_ie = wpa_supplicant_extra_ies(wpa_s);
#ifdef CONFIG_HS20
if (wpa_s->conf->hs20 && wpabuf_resize(&extra_ie, 6) == 0)
@@ -828,7 +827,7 @@ int wpa_supplicant_req_sched_scan(struct wpa_supplicant *wpa_s)
struct wpa_driver_scan_params params;
struct wpa_driver_scan_params *scan_params;
struct wpa_ssid *ssid = NULL;
- struct wpabuf *wps_ie = NULL;
+ struct wpabuf *extra_ie = NULL;
int ret, prio = 0;
unsigned int max_sched_scan_ssids;
int wildcard = 0;
@@ -962,8 +961,11 @@ start_scan:
if (!params.num_ssids)
params.num_ssids++;
- if (wpa_s->wps)
- wps_ie = wpa_supplicant_extra_ies(wpa_s, &params);
+ extra_ie = wpa_supplicant_extra_ies(wpa_s);
+ if (extra_ie) {
+ params.extra_ies = wpabuf_head(extra_ie);
+ params.extra_ies_len = wpabuf_len(extra_ie);
+ }
scan_params = &params;
@@ -992,7 +994,7 @@ scan:
}
- wpabuf_free(wps_ie);
+ wpabuf_free(extra_ie);
if (params.filter_ssids)
os_free(params.filter_ssids);
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index ab700da..3f94854 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -3270,13 +3270,13 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
{ "p2p_stop_find", wpa_cli_cmd_p2p_stop_find, cli_cmd_flag_none,
"= stop P2P Devices search" },
{ "p2p_connect", wpa_cli_cmd_p2p_connect, cli_cmd_flag_none,
- "<addr> <\"pbc\"|PIN> = connect to a P2P Devices" },
+ "<addr> <\"pbc\"|PIN> [ht40] = connect to a P2P Device" },
{ "p2p_listen", wpa_cli_cmd_p2p_listen, cli_cmd_flag_none,
"[timeout] = listen for P2P Devices for up-to timeout seconds" },
{ "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
"<ifname> = remove P2P group interface (terminate group if GO)" },
{ "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none,
- "= add a new P2P group (local end as GO)" },
+ "[ht40] = add a new P2P group (local end as GO)" },
{ "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
"<addr> <method> = request provisioning discovery" },
{ "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 56a8fe1..73ffde8 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -555,10 +555,14 @@ void wpa_supplicant_start_bgscan(struct wpa_supplicant *wpa_s)
* affected.
*/
} else {
- struct wpa_scan_results *scan_res =
- wpa_supplicant_get_scan_results(wpa_s, NULL, 0);
+ struct wpa_scan_results *scan_res;
wpa_s->bgscan_ssid = wpa_s->current_ssid;
- bgscan_notify_scan(wpa_s, scan_res);
+ scan_res = wpa_supplicant_get_scan_results(wpa_s, NULL,
+ 0);
+ if (scan_res) {
+ bgscan_notify_scan(wpa_s, scan_res);
+ wpa_scan_results_free(scan_res);
+ }
}
} else
wpa_s->bgscan_ssid = NULL;
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 9968386..74faada 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -541,6 +541,7 @@ struct wpa_supplicant {
unsigned int p2p_persistent_group:1;
unsigned int p2p_fallback_to_go_neg:1;
unsigned int p2p_pd_before_go_neg:1;
+ unsigned int p2p_go_ht40:1;
int p2p_persistent_id;
int p2p_go_intent;
int p2p_connect_freq;
diff --git a/wpa_supplicant/wpa_supplicant_template.conf b/wpa_supplicant/wpa_supplicant_template.conf
index 8203295..917ade4 100644
--- a/wpa_supplicant/wpa_supplicant_template.conf
+++ b/wpa_supplicant/wpa_supplicant_template.conf
@@ -11,4 +11,5 @@ model_number=wl18xx
serial_number=12345
p2p_conc_mode=2
driver_param=use_p2p_group_interface=1
-p2p_go_max_inactivity=30 \ No newline at end of file
+p2p_go_max_inactivity=30
+p2p_go_ht40=1