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 <rmanohar@qca.qualcomm.com>
This commit is contained in:
Rajkumar Manoharan 2012-08-15 22:53:01 +03:00 committed by Jouni Malinen
parent 931228aa10
commit 7aeac98509
8 changed files with 70 additions and 19 deletions

View file

@ -75,6 +75,8 @@ struct p2p_go_neg_results {
*/ */
int freq; int freq;
int ht40;
/** /**
* ssid - SSID of the group * ssid - SSID of the group
*/ */

View file

@ -99,6 +99,18 @@ static int wpa_supplicant_conf_ap(struct wpa_supplicant *wpa_s,
if (!no_ht && mode && mode->ht_capab) { if (!no_ht && mode && mode->ht_capab) {
conf->ieee80211n = 1; 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 * white-list capabilities that won't cause issues

View file

@ -364,6 +364,8 @@ struct wpa_ssid {
*/ */
int frequency; int frequency;
int ht40;
/** /**
* wpa_ptk_rekey - Maximum lifetime for PTK in seconds * wpa_ptk_rekey - Maximum lifetime for PTK in seconds
* *

View file

@ -3482,7 +3482,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, static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
char *cmd, int freq) char *cmd, int freq, int ht40)
{ {
int id; int id;
struct wpa_ssid *ssid; struct wpa_ssid *ssid;
@ -3496,26 +3496,31 @@ static int p2p_ctrl_group_add_persistent(struct wpa_supplicant *wpa_s,
return -1; 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) static int p2p_ctrl_group_add(struct wpa_supplicant *wpa_s, char *cmd)
{ {
int freq = 0; int freq = 0, ht40;
char *pos; char *pos;
pos = os_strstr(cmd, "freq="); pos = os_strstr(cmd, "freq=");
if (pos) if (pos)
freq = atoi(pos + 5); freq = atoi(pos + 5);
ht40 = os_strstr(cmd, "ht40") != NULL;
if (os_strncmp(cmd, "persistent=", 11) == 0) 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 || if (os_strcmp(cmd, "persistent") == 0 ||
os_strncmp(cmd, "persistent ", 11) == 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) 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'", wpa_printf(MSG_DEBUG, "CTRL: Invalid P2P_GROUP_ADD parameters '%s'",
cmd); cmd);
@ -4313,7 +4318,7 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
if (wpas_p2p_group_remove(wpa_s, buf + 17)) if (wpas_p2p_group_remove(wpa_s, buf + 17))
reply_len = -1; reply_len = -1;
} else if (os_strcmp(buf, "P2P_GROUP_ADD") == 0) { } 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; reply_len = -1;
} else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) { } else if (os_strncmp(buf, "P2P_GROUP_ADD ", 14) == 0) {
if (p2p_ctrl_group_add(wpa_s, buf + 14)) if (p2p_ctrl_group_add(wpa_s, buf + 14))

View file

@ -346,13 +346,13 @@ DBusMessage * wpas_dbus_handler_p2p_group_add(DBusMessage *message,
if (ssid == NULL || ssid->disabled != 2) if (ssid == NULL || ssid->disabled != 2)
goto inv_args; 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( reply = wpas_dbus_error_unknown_error(
message, message,
"Failed to reinvoke a persistent group"); "Failed to reinvoke a persistent group");
goto out; 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; goto inv_args;
out: out:

View file

@ -819,6 +819,7 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s,
ssid->mode = group_formation ? WPAS_MODE_P2P_GROUP_FORMATION : ssid->mode = group_formation ? WPAS_MODE_P2P_GROUP_FORMATION :
WPAS_MODE_P2P_GO; WPAS_MODE_P2P_GO;
ssid->frequency = params->freq; ssid->frequency = params->freq;
ssid->ht40 = params->ht40;
ssid->ssid = os_zalloc(params->ssid_len + 1); ssid->ssid = os_zalloc(params->ssid_len + 1);
if (ssid->ssid) { if (ssid->ssid) {
os_memcpy(ssid->ssid, params->ssid, params->ssid_len); os_memcpy(ssid->ssid, params->ssid, params->ssid_len);
@ -2042,7 +2043,7 @@ static void wpas_invitation_received(void *ctx, const u8 *sa, const u8 *bssid,
MAC2STR(sa), op_freq); MAC2STR(sa), op_freq);
if (s) { if (s) {
wpas_p2p_group_add_persistent( 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) { } else if (bssid) {
wpas_p2p_join(wpa_s, bssid, go_dev_addr, wpas_p2p_join(wpa_s, bssid, go_dev_addr,
wpa_s->p2p_wps_method, 0); wpa_s->p2p_wps_method, 0);
@ -2109,7 +2110,7 @@ static void wpas_invitation_result(void *ctx, int status, const u8 *bssid)
} }
wpas_p2p_group_add_persistent(wpa_s, ssid, 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,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, static int wpas_get_noa(void *ctx, const u8 *interface_addr, u8 *buf,
size_t buf_len) size_t buf_len)
{ {
@ -3400,13 +3427,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, static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
struct p2p_go_neg_results *params, struct p2p_go_neg_results *params,
int freq) int freq, int ht40)
{ {
u8 bssid[ETH_ALEN]; u8 bssid[ETH_ALEN];
int res; int res;
os_memset(params, 0, sizeof(*params)); os_memset(params, 0, sizeof(*params));
params->role_go = 1; params->role_go = 1;
params->ht40 = ht40;
if (freq) { if (freq) {
wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on forced " wpa_printf(MSG_DEBUG, "P2P: Set GO freq based on forced "
"frequency %d MHz", freq); "frequency %d MHz", freq);
@ -3518,7 +3546,7 @@ wpas_p2p_get_group_iface(struct wpa_supplicant *wpa_s, int addr_allocated,
* i.e., without using Group Owner Negotiation. * i.e., without using Group Owner Negotiation.
*/ */
int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group, 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; struct p2p_go_neg_results params;
unsigned int r; unsigned int r;
@ -3576,7 +3604,7 @@ int wpas_p2p_group_add(struct wpa_supplicant *wpa_s, int persistent_group,
return -1; 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; return -1;
if (params.freq && if (params.freq &&
!p2p_supported_freq(wpa_s->global->p2p, params.freq)) { !p2p_supported_freq(wpa_s->global->p2p, params.freq)) {
@ -3643,7 +3671,7 @@ static int wpas_start_p2p_client(struct wpa_supplicant *wpa_s,
int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s, int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid, int addr_allocated, struct wpa_ssid *ssid, int addr_allocated,
int freq) int freq, int ht40)
{ {
struct p2p_go_neg_results params; struct p2p_go_neg_results params;
int go = 0; int go = 0;
@ -3669,7 +3697,7 @@ int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
if (ssid->mode != WPAS_MODE_P2P_GO) if (ssid->mode != WPAS_MODE_P2P_GO)
return -1; 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; return -1;
params.role_go = 1; params.role_go = 1;

View file

@ -28,10 +28,10 @@ void wpas_p2p_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
unsigned int freq); unsigned int freq);
int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname); 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 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, int wpas_p2p_group_add_persistent(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid, int addr_allocated, 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 p2p_group * wpas_p2p_group_init(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid); struct wpa_ssid *ssid);
void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr, void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
@ -141,5 +141,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, void wpas_p2p_notify_ap_sta_authorized(struct wpa_supplicant *wpa_s,
const u8 *addr); const u8 *addr);
int wpas_p2p_scan_no_go_seen(struct wpa_supplicant *wpa_s); 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 */ #endif /* P2P_SUPPLICANT_H */

View file

@ -2368,7 +2368,7 @@ static struct wpa_cli_cmd wpa_cli_commands[] = {
{ "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none, { "p2p_group_remove", wpa_cli_cmd_p2p_group_remove, cli_cmd_flag_none,
"<ifname> = remove P2P group interface (terminate group if GO)" }, "<ifname> = remove P2P group interface (terminate group if GO)" },
{ "p2p_group_add", wpa_cli_cmd_p2p_group_add, cli_cmd_flag_none, { "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, { "p2p_prov_disc", wpa_cli_cmd_p2p_prov_disc, cli_cmd_flag_none,
"<addr> <method> = request provisioning discovery" }, "<addr> <method> = request provisioning discovery" },
{ "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase, { "p2p_get_passphrase", wpa_cli_cmd_p2p_get_passphrase,