From 989a796c078f377f1640e42e6c7957effc3c24e2 Mon Sep 17 00:00:00 2001 From: Rajkumar Manoharan Date: Wed, 15 Aug 2012 22:53:01 +0300 Subject: P2P: Enable 40 MHz support for autonomous P2P group addition Add optional "ht40" argument for p2p_group_add command to enable 40 MHz in 5GHz band. This configures the secondary channel, when HT support is enabled and if the HW supports 40 MHz channel width. Signed-hostap: Rajkumar Manoharan --- src/p2p/p2p.h | 2 ++ wpa_supplicant/ap.c | 12 +++++++++ wpa_supplicant/config_ssid.h | 2 ++ wpa_supplicant/ctrl_iface.c | 19 ++++++++----- wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 4 +-- wpa_supplicant/p2p_supplicant.c | 42 ++++++++++++++++++++++++----- wpa_supplicant/p2p_supplicant.h | 6 +++-- wpa_supplicant/wpa_cli.c | 2 +- 8 files changed, 70 insertions(+), 19 deletions(-) diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 70ea654..6c4b666 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 */ 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_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 7f81938..d59e6e0 100644 --- a/wpa_supplicant/ctrl_iface.c +++ b/wpa_supplicant/ctrl_iface.c @@ -3564,7 +3564,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; @@ -3578,26 +3578,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; + 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); @@ -4434,7 +4439,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..6599e8a 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: diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 72668f6..8f35aab 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); @@ -2055,7 +2056,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 +2123,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); } @@ -2344,6 +2345,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) { @@ -3413,13 +3440,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); @@ -3531,7 +3559,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; @@ -3595,7 +3623,7 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, return -1; } - if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq)) + if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40)) return -1; if (params.freq && !p2p_supported_freq(wpa_s->global->p2p, params.freq)) { @@ -3662,7 +3690,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; @@ -3688,7 +3716,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, ¶ms, freq)) + if (wpas_p2p_init_go_params(wpa_s, ¶ms, freq, ht40)) return -1; params.role_go = 1; diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index c3f2dac..13d408c 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -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, @@ -146,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/wpa_cli.c b/wpa_supplicant/wpa_cli.c index ab700da..b9164e7 100644 --- a/wpa_supplicant/wpa_cli.c +++ b/wpa_supplicant/wpa_cli.c @@ -3276,7 +3276,7 @@ static struct wpa_cli_cmd wpa_cli_commands[] = { { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none, " = 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, " = request provisioning discovery" }, { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, -- cgit v1.1