wpa_supplicant: Basic support for PBSS/PCP

PBSS (Personal Basic Service Set) is a new BSS type for DMG
networks. It is similar to infrastructure BSS, having an AP-like
entity called PCP (PBSS Control Point), but it has few differences.
PBSS support is mandatory for IEEE 802.11ad devices.

Add a new "pbss" argument to network block. The argument is used
in the following scenarios:
1. When network has mode=2 (AP), when pbss flag is set will start
as a PCP instead of an AP.
2. When network has mode=0 (station), when pbss flag is set will
connect to PCP instead of AP.

The function wpa_scan_res_match() was modified to match BSS according to
the pbss flag in the network block (wpa_ssid structure). When pbss flag
is set it will match only PCPs, and when it is clear it will match only
APs.

Signed-off-by: Lior David <qca_liord@qca.qualcomm.com>
This commit is contained in:
Lior David 2016-02-08 12:30:04 +02:00 committed by Jouni Malinen
parent 86b5c400a0
commit b907491281
13 changed files with 55 additions and 3 deletions

View file

@ -570,6 +570,8 @@ struct hostapd_bss_config {
char *no_probe_resp_if_seen_on; char *no_probe_resp_if_seen_on;
char *no_auth_if_seen_on; char *no_auth_if_seen_on;
int pbss;
}; };

View file

@ -1217,6 +1217,7 @@ int ieee802_11_build_ap_params(struct hostapd_data *hapd,
params->osen = 1; params->osen = 1;
} }
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
params->pbss = hapd->conf->pbss;
return 0; return 0;
} }

View file

@ -453,6 +453,8 @@ no_wps:
wpabuf_dup(wpa_s->conf->ap_vendor_elements); wpabuf_dup(wpa_s->conf->ap_vendor_elements);
} }
bss->pbss = ssid->pbss;
return 0; return 0;
} }

View file

@ -148,6 +148,17 @@ static inline int bss_is_dmg(const struct wpa_bss *bss)
return bss->freq > 45000; return bss->freq > 45000;
} }
/**
* Test whether a BSS is a PBSS.
* This checks whether a BSS is a DMG-band PBSS. PBSS is used for P2P DMG
* network.
*/
static inline int bss_is_pbss(struct wpa_bss *bss)
{
return bss_is_dmg(bss) &&
(bss->caps & IEEE80211_CAP_DMG_MASK) == IEEE80211_CAP_DMG_PBSS;
}
static inline void wpa_bss_update_level(struct wpa_bss *bss, int new_level) static inline void wpa_bss_update_level(struct wpa_bss *bss, int new_level)
{ {
if (bss != NULL && new_level < 0) if (bss != NULL && new_level < 0)

View file

@ -1980,6 +1980,7 @@ static const struct parse_data ssid_fields[] = {
{ INT(update_identifier) }, { INT(update_identifier) },
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
{ INT_RANGE(mac_addr, 0, 2) }, { INT_RANGE(mac_addr, 0, 2) },
{ INT_RANGE(pbss, 0, 1) },
}; };
#undef OFFSET #undef OFFSET

View file

@ -755,6 +755,7 @@ static void wpa_config_write_network(FILE *f, struct wpa_ssid *ssid)
INT(peerkey); INT(peerkey);
INT(mixed_cell); INT(mixed_cell);
INT(max_oper_chwidth); INT(max_oper_chwidth);
INT(pbss);
#ifdef CONFIG_IEEE80211W #ifdef CONFIG_IEEE80211W
write_int(f, "ieee80211w", ssid->ieee80211w, write_int(f, "ieee80211w", ssid->ieee80211w,
MGMT_FRAME_PROTECTION_DEFAULT); MGMT_FRAME_PROTECTION_DEFAULT);

View file

@ -359,6 +359,15 @@ struct wpa_ssid {
WPAS_MODE_MESH = 5, WPAS_MODE_MESH = 5,
} mode; } mode;
/**
* pbss - Whether to use PBSS. Relevant to DMG networks only.
* Used together with mode configuration. When mode is AP, it
* means to start a PCP instead of a regular AP. When mode is INFRA it
* means connect to a PCP instead of AP. P2P_GO and P2P_GROUP_FORMATION
* modes must use PBSS in DMG network.
*/
int pbss;
/** /**
* disabled - Whether this network is currently disabled * disabled - Whether this network is currently disabled
* *

View file

@ -988,8 +988,14 @@ static struct wpa_ssid * wpa_scan_res_match(struct wpa_supplicant *wpa_s,
continue; continue;
} }
if (!bss_is_ess(bss)) { if (!bss_is_ess(bss) && !bss_is_pbss(bss)) {
wpa_dbg(wpa_s, MSG_DEBUG, " skip - not ESS network"); wpa_dbg(wpa_s, MSG_DEBUG, " skip - neither ESS nor PBSS network");
continue;
}
if (ssid->pbss != bss_is_pbss(bss)) {
wpa_dbg(wpa_s, MSG_DEBUG, " skip - PBSS mismatch (ssid %d bss %d)",
ssid->pbss, bss_is_pbss(bss));
continue; continue;
} }

View file

@ -1898,6 +1898,8 @@ static void wpas_start_wps_go(struct wpa_supplicant *wpa_s,
*/ */
ssid->pairwise_cipher = WPA_CIPHER_GCMP; ssid->pairwise_cipher = WPA_CIPHER_GCMP;
ssid->group_cipher = WPA_CIPHER_GCMP; ssid->group_cipher = WPA_CIPHER_GCMP;
/* P2P GO in 60 GHz is always a PCP (PBSS) */
ssid->pbss = 1;
} }
if (os_strlen(params->passphrase) > 0) { if (os_strlen(params->passphrase) > 0) {
ssid->passphrase = os_strdup(params->passphrase); ssid->passphrase = os_strdup(params->passphrase);

View file

@ -1612,7 +1612,7 @@ static const char *network_fields[] = {
#ifdef CONFIG_HS20 #ifdef CONFIG_HS20
"update_identifier", "update_identifier",
#endif /* CONFIG_HS20 */ #endif /* CONFIG_HS20 */
"mac_addr" "mac_addr", "pbss"
}; };

View file

@ -2345,9 +2345,11 @@ static void wpas_start_assoc_cb(struct wpa_radio_work *work, int deinit)
} }
params.bssid_hint = bss->bssid; params.bssid_hint = bss->bssid;
params.freq_hint = bss->freq; params.freq_hint = bss->freq;
params.pbss = bss_is_pbss(bss);
} else { } else {
params.ssid = ssid->ssid; params.ssid = ssid->ssid;
params.ssid_len = ssid->ssid_len; params.ssid_len = ssid->ssid_len;
params.pbss = ssid->pbss;
} }
if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set && if (ssid->mode == WPAS_MODE_IBSS && ssid->bssid_set &&

View file

@ -702,6 +702,13 @@ fast_reauth=1
# an IBSS network with the configured SSID is already present, the frequency of # an IBSS network with the configured SSID is already present, the frequency of
# the network will be used instead of this configured value. # the network will be used instead of this configured value.
# #
# pbss: Whether to use PBSS. Relevant to IEEE 802.11ad networks only.
# Used together with mode configuration. When mode is AP, it means to start a
# PCP instead of a regular AP. When mode is infrastructure it means connect
# to a PCP instead of AP. P2P_GO and P2P_GROUP_FORMATION modes must use PBSS
# in IEEE 802.11ad network.
# For more details, see IEEE Std 802.11ad-2012.
#
# scan_freq: List of frequencies to scan # scan_freq: List of frequencies to scan
# Space-separated list of frequencies in MHz to scan when searching for this # Space-separated list of frequencies in MHz to scan when searching for this
# BSS. If the subset of channels used by the network is known, this option can # BSS. If the subset of channels used by the network is known, this option can

View file

@ -1149,6 +1149,10 @@ int wpas_wps_start_pbc(struct wpa_supplicant *wpa_s, const u8 *bssid,
ssid->ssid_len = wpa_s->go_params->ssid_len; ssid->ssid_len = wpa_s->go_params->ssid_len;
os_memcpy(ssid->ssid, wpa_s->go_params->ssid, os_memcpy(ssid->ssid, wpa_s->go_params->ssid,
ssid->ssid_len); ssid->ssid_len);
if (wpa_s->go_params->freq > 56160) {
/* P2P in 60 GHz uses PBSS */
ssid->pbss = 1;
}
wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP " wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP "
"SSID", ssid->ssid, ssid->ssid_len); "SSID", ssid->ssid, ssid->ssid_len);
} }
@ -1216,6 +1220,10 @@ static int wpas_wps_start_dev_pw(struct wpa_supplicant *wpa_s,
ssid->ssid_len = wpa_s->go_params->ssid_len; ssid->ssid_len = wpa_s->go_params->ssid_len;
os_memcpy(ssid->ssid, wpa_s->go_params->ssid, os_memcpy(ssid->ssid, wpa_s->go_params->ssid,
ssid->ssid_len); ssid->ssid_len);
if (wpa_s->go_params->freq > 56160) {
/* P2P in 60 GHz uses PBSS */
ssid->pbss = 1;
}
wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP " wpa_hexdump_ascii(MSG_DEBUG, "WPS: Use specific AP "
"SSID", ssid->ssid, ssid->ssid_len); "SSID", ssid->ssid, ssid->ssid_len);
} }