[PATCH v3 1/2] P2P: Enable 40MHz support for p2p group addition
Arik Nemtsov
arik
Wed Jul 18 12:37:14 PDT 2012
On Tue, Jul 17, 2012 at 1:09 PM, Rajkumar Manoharan
<rmanohar at qca.qualcomm.com> wrote:
> Add optional "ht40" argument for p2p_group_add command to enable 40MHz
> in 5GHz band. This could configure secondary channel, when 11n support
> was enabled and if the HW supports 40MHz channel width.
>
> Signed-hostap: Rajkumar Manoharan <rmanohar at qca.qualcomm.com>
> ---
> wpa_supplicant/ap.c | 12 ++++
> wpa_supplicant/config.h | 1 +
> wpa_supplicant/ctrl_iface.c | 19 ++++--
> wpa_supplicant/dbus/dbus_new_handlers_p2p.c | 2 +-
> wpa_supplicant/p2p_supplicant.c | 101 +++++++++++++++++++---------
> wpa_supplicant/p2p_supplicant.h | 6 +-
> wpa_supplicant/wpa_cli.c | 19 +++---
> 7 files changed, 107 insertions(+), 53 deletions(-)
>
> diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
> index f9e0045..87765da 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) &&
> + wpa_s->conf->p2p_go_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
>
> /*
> * white-list capabilities that won't cause issues
> diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
> index 46c4da2..b9317e4 100644
> --- a/wpa_supplicant/config.h
> +++ b/wpa_supplicant/config.h
> @@ -510,6 +510,7 @@ struct wpa_config {
> int p2p_oper_reg_class;
> int p2p_oper_channel;
> int p2p_go_intent;
> + int p2p_go_ht40;
> char *p2p_ssid_postfix;
> int persistent_reconnect;
> int p2p_intra_bss;
> diff --git a/wpa_supplicant/ctrl_iface.c b/wpa_supplicant/ctrl_iface.c
> index cb3e523..1a63902 100644
> --- a/wpa_supplicant/ctrl_iface.c
> +++ b/wpa_supplicant/ctrl_iface.c
> @@ -3429,7 +3429,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;
> @@ -3443,26 +3443,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 = 0;
> 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);
> @@ -4257,7 +4262,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..f784e85 100644
> --- a/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
> +++ b/wpa_supplicant/dbus/dbus_new_handlers_p2p.c
> @@ -346,7 +346,7 @@ 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");
> diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
> index 218ed2f..1539f76 100644
> --- a/wpa_supplicant/p2p_supplicant.c
> +++ b/wpa_supplicant/p2p_supplicant.c
> @@ -841,6 +841,7 @@ static void wpas_p2p_clone_config(struct wpa_supplicant *dst,
> sizeof(d->sec_device_type));
> d->num_sec_device_types = s->num_sec_device_types;
>
> + d->p2p_go_ht40 = s->p2p_go_ht40;
> d->p2p_group_idle = s->p2p_group_idle;
> d->p2p_intra_bss = s->p2p_intra_bss;
> d->persistent_reconnect = s->persistent_reconnect;
> @@ -2019,7 +2020,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);
> @@ -2086,7 +2087,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);
> }
>
>
> @@ -2223,26 +2224,46 @@ 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 "
> @@ -2262,16 +2283,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 +2343,30 @@ static int wpas_go_connected(void *ctx, const u8 *dev_addr)
> return 0;
> }
>
> +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) ||
The HOSTAPD_MODE_IEEE80211A checks seem a bit redundant, but the
patches look good overall.
Arik
More information about the Hostap
mailing list