diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index b9ca5bd02..6e4a850b5 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -77,6 +77,8 @@ struct p2p_go_neg_results { int ht40; + int vht; + /** * ssid - SSID of the group */ diff --git a/wpa_supplicant/README-P2P b/wpa_supplicant/README-P2P index 76f82191a..ffc2baf06 100644 --- a/wpa_supplicant/README-P2P +++ b/wpa_supplicant/README-P2P @@ -125,7 +125,7 @@ join-a-group style PD instead of GO Negotiation style PD. p2p_connect [display|keypad] [persistent|persistent=] [join|auth] - [go_intent=<0..15>] [freq=] [ht40] [provdisc] + [go_intent=<0..15>] [freq=] [ht40] [vht] [provdisc] Start P2P group formation with a discovered P2P peer. This includes optional group owner negotiation, group interface setup, provisioning, @@ -166,7 +166,8 @@ used prior to starting GO Negotiation as a workaround with some deployed P2P implementations that require this to allow the user to accept the connection. -p2p_group_add [persistent|persistent=] [freq=] [ht40] +p2p_group_add [persistent|persistent=] [freq=] + [ht40] [vht] Set up a P2P group owner manually (i.e., without group owner negotiation with a specific peer). This is also known as autonomous @@ -373,7 +374,8 @@ Remove all local services from internal SD query processing. Invitation p2p_invite [persistent=|group=] [peer=address] - [go_dev_addr=address] [freq=] [ht40] [pref=] + [go_dev_addr=address] [freq=] [ht40] [vht] + [pref=] Invite a peer to join a group (e.g., group=wlan1) or to reinvoke a persistent group (e.g., persistent=4). If the peer device is the GO of diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c index 0c9e8f043..08d2ecdd9 100644 --- a/wpa_supplicant/config.c +++ b/wpa_supplicant/config.c @@ -3253,6 +3253,7 @@ static const struct global_parse_data global_fields[] = { { FUNC(p2p_no_go_freq), CFG_CHANGED_P2P_PREF_CHAN }, { INT_RANGE(p2p_add_cli_chan, 0, 1), 0 }, { INT(p2p_go_ht40), 0 }, + { INT(p2p_go_vht), 0 }, { INT(p2p_disabled), 0 }, { INT(p2p_no_group_iface), 0 }, { INT_RANGE(p2p_ignore_shared_freq, 0, 1), 0 }, diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h index 340088880..8cbeb6286 100644 --- a/wpa_supplicant/config.h +++ b/wpa_supplicant/config.h @@ -827,6 +827,16 @@ struct wpa_config { */ int p2p_go_ht40; + /** + * p2p_go_vht - Default mode for VHT enable when operating as GO + * + * This will take effect for p2p_group_add, p2p_connect, and p2p_invite. + * 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_vht; + /** * p2p_disabled - Whether P2P operations are disabled for this interface */ diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c index 27d48467e..cb2dde8e2 100644 --- a/wpa_supplicant/config_file.c +++ b/wpa_supplicant/config_file.c @@ -952,6 +952,8 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config) fprintf(f, "p2p_add_cli_chan=%d\n", config->p2p_add_cli_chan); if (config->p2p_go_ht40) fprintf(f, "p2p_go_ht40=%u\n", config->p2p_go_ht40); + if (config->p2p_go_vht) + fprintf(f, "p2p_go_vht=%u\n", config->p2p_go_vht); if (config->p2p_disabled) fprintf(f, "p2p_disabled=%u\n", config->p2p_disabled); if (config->p2p_no_group_iface) diff --git a/wpa_supplicant/config_ssid.h b/wpa_supplicant/config_ssid.h index 3a4427239..2a8be6bd4 100644 --- a/wpa_supplicant/config_ssid.h +++ b/wpa_supplicant/config_ssid.h @@ -394,6 +394,8 @@ struct wpa_ssid { int ht40; + int vht; + /** * wpa_ptk_rekey - Maximum lifetime for PTK in seconds * diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c index 86e7ece88..809ae0c2e 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -3688,12 +3688,12 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, int go_intent = -1; int freq = 0; int pd; - int ht40; + int ht40, vht; /* <"pbc" | "pin" | PIN> [label|display|keypad] * [persistent|persistent=] * [join] [auth] [go_intent=<0..15>] [freq=] [provdisc] - * [ht40] */ + * [ht40] [vht] */ if (hwaddr_aton(cmd, addr)) return -1; @@ -3721,7 +3721,9 @@ 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; + vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht; + ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 || + vht; pos2 = os_strstr(pos, " go_intent="); if (pos2) { @@ -3762,7 +3764,7 @@ static int p2p_ctrl_connect(struct wpa_supplicant *wpa_s, char *cmd, new_pin = wpas_p2p_connect(wpa_s, addr, pin, wps_method, persistent_group, automatic, join, auth, go_intent, freq, persistent_id, pd, - ht40); + ht40, vht); if (new_pin == -2) { os_memcpy(buf, "FAIL-CHANNEL-UNAVAILABLE\n", 25); return 25; @@ -4126,7 +4128,7 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) struct wpa_ssid *ssid; u8 *_peer = NULL, peer[ETH_ALEN]; int freq = 0, pref_freq = 0; - int ht40; + int ht40, vht; id = atoi(cmd); pos = os_strstr(cmd, " peer="); @@ -4160,9 +4162,12 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd) return -1; } - ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40; + vht = (os_strstr(cmd, " vht") != NULL) || wpa_s->conf->p2p_go_vht; + ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40 || + vht; - return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40, pref_freq); + return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40, vht, + pref_freq); } @@ -4209,7 +4214,8 @@ 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, int ht40) + char *cmd, int freq, int ht40, + int vht) { int id; struct wpa_ssid *ssid; @@ -4223,32 +4229,34 @@ 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, ht40, NULL, - 0); + return wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, ht40, vht, + NULL, 0); } static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd) { - int freq = 0, ht40; + int freq = 0, ht40, vht; 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; + vht = (os_strstr(cmd, "vht") != NULL) || wpa_s->conf->p2p_go_vht; + ht40 = (os_strstr(cmd, "ht40") != NULL) || wpa_s->conf->p2p_go_ht40 || + vht; if (os_strncmp(cmd, "persistent=", 11) == 0) return p2p_ctrl_group_add_persistent(wpa_s, cmd + 11, freq, - ht40); + ht40, vht); if (os_strcmp(cmd, "persistent") == 0 || os_strncmp(cmd, "persistent ", 11) == 0) - return wpas_p2p_group_add(wpa_s, 1, freq, ht40); + return wpas_p2p_group_add(wpa_s, 1, freq, ht40, vht); if (os_strncmp(cmd, "freq=", 5) == 0) - return wpas_p2p_group_add(wpa_s, 0, freq, ht40); + return wpas_p2p_group_add(wpa_s, 0, freq, ht40, vht); if (ht40) - return wpas_p2p_group_add(wpa_s, 0, freq, ht40); + return wpas_p2p_group_add(wpa_s, 0, freq, ht40, vht); wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'", cmd); @@ -5410,7 +5418,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, 0)) + if (wpas_p2p_group_add(wpa_s, 0, 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 52b36b4a9..5150a76bd 100644 --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c @@ -346,14 +346,14 @@ 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, 0, + if (wpas_p2p_group_add_persistent(wpa_s, ssid, 0, freq, 0, 0, NULL, 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, 0)) + } else if (wpas_p2p_group_add(wpa_s, persistent_group, freq, 0, 0)) goto inv_args; out: @@ -505,7 +505,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, 0); + go_intent, freq, -1, 0, 0, 0); if (new_pin >= 0) { char npin[9]; @@ -631,8 +631,8 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message, if (ssid == NULL || ssid->disabled != 2) goto err; - if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0, 0) < 0) - { + if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0, 0, 0) < + 0) { reply = wpas_dbus_error_unknown_error( message, "Failed to reinvoke a persistent group"); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 422de4d2b..c22113a04 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -1088,6 +1088,7 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s, WPAS_MODE_P2P_GO; ssid->frequency = params->freq; ssid->ht40 = params->ht40; + ssid->vht = params->vht; ssid->ssid = os_zalloc(params->ssid_len + 1); if (ssid->ssid) { os_memcpy(ssid->ssid, params->ssid, params->ssid_len); @@ -1347,6 +1348,8 @@ void wpas_go_neg_completed(void *ctx, struct p2p_go_neg_results *res) if (wpa_s->p2p_go_ht40) res->ht40 = 1; + if (wpa_s->p2p_go_vht) + res->vht = 1; wpa_msg_global(wpa_s, MSG_INFO, P2P_EVENT_GO_NEG_SUCCESS "role=%s " "freq=%d ht40=%d peer_dev=" MACSTR " peer_iface=" MACSTR @@ -2727,7 +2730,7 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid, if (s) { int go = s->mode == WPAS_MODE_P2P_GO; wpas_p2p_group_add_persistent( - wpa_s, s, go, go ? op_freq : 0, 0, NULL, + wpa_s, s, go, go ? op_freq : 0, 0, 0, NULL, go ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0); } else if (bssid) { wpa_s->user_initiated_pd = 0; @@ -2897,7 +2900,8 @@ 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, wpa_s->p2p_persistent_go_freq, - wpa_s->p2p_go_ht40, channels, + wpa_s->p2p_go_ht40, wpa_s->p2p_go_vht, + channels, ssid->mode == WPAS_MODE_P2P_GO ? P2P_MAX_INITIAL_CONN_WAIT_GO_REINVOKE : 0); @@ -3735,7 +3739,8 @@ static void wpas_p2p_scan_res_join(struct wpa_supplicant *wpa_s, wpa_s->p2p_connect_freq, wpa_s->p2p_persistent_id, wpa_s->p2p_pd_before_go_neg, - wpa_s->p2p_go_ht40); + wpa_s->p2p_go_ht40, + wpa_s->p2p_go_vht); return; } @@ -4105,6 +4110,7 @@ exit_free: * @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 + * @vht: Start GO with VHT support * 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 @@ -4113,7 +4119,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 ht40) + int ht40, int vht) { int force_freq = 0, pref_freq = 0; int ret = 0, res; @@ -4148,6 +4154,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, wpa_s->p2p_fallback_to_go_neg = 0; wpa_s->p2p_pd_before_go_neg = !!pd; wpa_s->p2p_go_ht40 = !!ht40; + wpa_s->p2p_go_vht = !!vht; if (pin) os_strlcpy(wpa_s->p2p_pin, pin, sizeof(wpa_s->p2p_pin)); @@ -4402,7 +4409,7 @@ static int wpas_p2p_select_go_freq(struct wpa_supplicant *wpa_s, int freq) static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s, struct p2p_go_neg_results *params, - int freq, int ht40, + int freq, int ht40, int vht, const struct p2p_channels *channels) { int res, *freqs; @@ -4412,6 +4419,7 @@ static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s, os_memset(params, 0, sizeof(*params)); params->role_go = 1; params->ht40 = ht40; + params->vht = vht; if (freq) { if (!freq_included(channels, freq)) { wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not " @@ -4578,13 +4586,15 @@ wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated, * @wpa_s: Pointer to wpa_supplicant data from wpa_supplicant_add_iface() * @persistent_group: Whether to create a persistent group * @freq: Frequency for the group or 0 to indicate no hardcoding + * @ht40: Start GO with 40 MHz channel width + * @vht: Start GO with VHT support * Returns: 0 on success, -1 on failure * * This function creates a new P2P group with the local end as the Group Owner, * i.e., without using Group Owner Negotiation. */ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, - int freq, int ht40) + int freq, int ht40, int vht) { struct p2p_go_neg_results params; @@ -4602,7 +4612,7 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, if (freq < 0) return -1; - if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, NULL)) + if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, vht, NULL)) return -1; if (params.freq && !p2p_supported_freq_go(wpa_s->global->p2p, params.freq)) { @@ -4670,7 +4680,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 ht40, + int freq, int ht40, int vht, const struct p2p_channels *channels, int connection_timeout) { @@ -4705,7 +4715,7 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, if (freq < 0) return -1; - if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, channels)) + if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40, vht, channels)) return -1; params.role_go = 1; @@ -5166,7 +5176,7 @@ int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr) /* Invite to reinvoke a persistent group */ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq, - int ht40, int pref_freq) + int ht40, int vht, int pref_freq) { enum p2p_invite_role role; u8 *bssid = NULL; @@ -5238,6 +5248,7 @@ int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname, wpa_s->p2p_persistent_go_freq = 0; wpa_s->p2p_go_ht40 = 0; + wpa_s->p2p_go_vht = 0; for (wpa_s = global->ifaces; wpa_s; wpa_s = wpa_s->next) { if (os_strcmp(wpa_s->ifname, ifname) == 0) @@ -6116,7 +6127,8 @@ static void wpas_p2p_fallback_to_go_neg(struct wpa_supplicant *wpa_s, 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_go_ht40); + wpa_s->p2p_go_ht40, + wpa_s->p2p_go_vht); } diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index b4cb0f5b4..c0ad29eae 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -24,17 +24,17 @@ 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 ht40); + int pd, int ht40, int vht); 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, unsigned int freq); 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 ht40); + int freq, int ht40, int vht); int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int addr_allocated, - int freq, int ht40, + int freq, int ht40, int vht, const struct p2p_channels *channels, int connection_timeout); struct p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s, @@ -111,7 +111,7 @@ int wpas_p2p_service_del_upnp(struct wpa_supplicant *wpa_s, u8 version, int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr); int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq, - int ht40, int pref_freq); + int ht40, int vht, int pref_freq); int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname, const u8 *peer_addr, const u8 *go_dev_addr); void wpas_p2p_completed(struct wpa_supplicant *wpa_s); diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c index 9268446fa..3519616d4 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -617,6 +617,7 @@ static char ** wpa_cli_complete_set(const char *str, int pos) "p2p_intra_bss", "p2p_group_idle", "p2p_pref_chan", "p2p_no_go_freq", "p2p_go_ht40", "p2p_disabled", "p2p_no_group_iface", + "p2p_go_vht", "p2p_ignore_shared_freq", "country", "bss_max_count", "bss_expiration_age", "bss_expiration_scan_count", "filter_ssids", "filter_rssi", "max_num_sta", diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index eea7be9ab..da536cb20 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/wpa_supplicant/wpa_supplicant_i.h @@ -639,6 +639,7 @@ struct wpa_supplicant { unsigned int p2p_fallback_to_go_neg:1; unsigned int p2p_pd_before_go_neg:1; unsigned int p2p_go_ht40:1; + unsigned int p2p_go_vht:1; unsigned int user_initiated_pd:1; unsigned int p2p_go_group_formation_completed:1; int p2p_first_connection_timeout;