[PATCH v2 1/2] P2P: Enable 40MHz support for p2p group addition
Rajkumar Manoharan
rmanohar
Thu Jul 12 01:44:45 PDT 2012
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 | 11 ++++++
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 | 52 +++++++++++++++++++++++++----
wpa_supplicant/p2p_supplicant.h | 7 ++--
wpa_supplicant/wpa_cli.c | 19 +++++------
7 files changed, 83 insertions(+), 28 deletions(-)
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index f9e0045..a40b637 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -99,6 +99,17 @@ 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_select_ht40_sec_channel(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..10d4777 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);
+ if (os_strncmp(cmd, "ht40", 4) == 0)
+ ht40 = 1;
+
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..4d7641f 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);
}
@@ -2331,6 +2332,42 @@ static int wpas_go_connected(void *ctx, const u8 *dev_addr)
return 0;
}
+int wpas_p2p_select_ht40_sec_channel(struct wpa_supplicant *wpa_s,
+ struct hostapd_hw_modes *mode,
+ u8 channel)
+{
+ int op;
+ struct p2p_oper_class_map op_class[] = {
+ { 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 }
+ };
+
+ 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) {
+ int flag;
+ if (ch != channel)
+ continue;
+ 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)))
+ return 0;
+ if (o->bw == BW40PLUS &&
+ (!(flag & HOSTAPD_CHAN_HT40PLUS) ||
+ !has_channel(wpa_s->global, mode, ch + 4, NULL)))
+ return 0;
+ return (o->bw == BW40MINUS) ? -1 : 1;
+ }
+ }
+ return 0;
+}
/**
* wpas_p2p_init - Initialize P2P module for %wpa_supplicant
@@ -3364,13 +3401,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;
+ wpa_s->conf->p2p_go_ht40 = ht40;
if (freq) {
wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on forced "
"frequency %d MHz", freq);
@@ -3482,7 +3520,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;
@@ -3540,7 +3578,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)) {
@@ -3607,7 +3645,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;
@@ -3633,7 +3671,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 e2fe259..af2b0bf 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -28,14 +28,17 @@ 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 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,
int registrar);
+int wpas_p2p_select_ht40_sec_channel(struct wpa_supplicant *wpa_s,
+ struct hostapd_hw_modes *mode,
+ u8 channel);
enum wpas_p2p_prov_disc_use {
WPAS_P2P_PD_FOR_GO_NEG,
WPAS_P2P_PD_FOR_JOIN,
diff --git a/wpa_supplicant/wpa_cli.c b/wpa_supplicant/wpa_cli.c
index b159ad3..cbfe742 100644
--- a/wpa_supplicant/wpa_cli.c
+++ b/wpa_supplicant/wpa_cli.c
@@ -2231,17 +2231,14 @@ static int wpa_cli_cmd_p2p_group_add(struct wpa_ctrl *ctrl, int argc,
char *argv[])
{
char cmd[128];
- int res;
-
- if (argc == 0)
- return wpa_ctrl_command(ctrl, "P2P_GROUP_ADD");
+ int res = 0, i = 0;
- if (argc > 1)
- res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s %s",
- argv[0], argv[1]);
- else
- res = os_snprintf(cmd, sizeof(cmd), "P2P_GROUP_ADD %s",
- argv[0]);
+ res = os_snprintf(cmd + res, sizeof(cmd) - res, "P2P_GROUP_ADD");
+ while (i < argc) {
+ res += os_snprintf(cmd + res, sizeof(cmd) - res, " %s",
+ argv[i]);
+ i++;
+ }
if (res < 0 || (size_t) res >= sizeof(cmd))
return -1;
cmd[sizeof(cmd) - 1] = '\0';
@@ -3221,7 +3218,7 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
{ "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,
--
1.7.11.1
More information about the Hostap
mailing list