Merge "hostapd: support for 60GHz SoftAP"
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index 3590b09..91cdefe 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -69,6 +69,10 @@
endif
endif
+ifdef CONFIG_TESTING_OPTIONS
+L_CFLAGS += -DCONFIG_TESTING_OPTIONS
+CONFIG_WPS_TESTING=y
+endif
ifndef CONFIG_OS
ifdef CONFIG_NATIVE_WINDOWS
diff --git a/hostapd/android.config b/hostapd/android.config
index f791daa..fd3c1a1 100644
--- a/hostapd/android.config
+++ b/hostapd/android.config
@@ -244,3 +244,11 @@
# This can be used to enable functionality to improve interworking with
# external networks.
CONFIG_INTERWORKING=y
+
+# Testing options
+# This can be used to enable some testing options (see also the example
+# configuration file) that are useful for testing clients that
+# connect to this hostapd. These options allow, for example, to drop a
+# certain percentage of probe requests or auth/(re)assoc frames.
+# Each test case requires a flag set in hostapd.conf or through hostapd_cli
+#CONFIG_TESTING_OPTIONS=y
diff --git a/hostapd/config_file.c b/hostapd/config_file.c
index ce32f3c..efbfd80 100644
--- a/hostapd/config_file.c
+++ b/hostapd/config_file.c
@@ -4184,6 +4184,10 @@
bss->oci_freq_override_fils_assoc = atoi(pos);
} else if (os_strcmp(buf, "oci_freq_override_wnm_sleep") == 0) {
bss->oci_freq_override_wnm_sleep = atoi(pos);
+ } else if (os_strcmp(buf, "skip_send_eapol") == 0) {
+ conf->skip_send_eapol = atoi(pos);
+ } else if (os_strcmp(buf, "enable_eapol_large_timeout") == 0) {
+ conf->enable_eapol_large_timeout = atoi(pos);
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_SAE
} else if (os_strcmp(buf, "sae_password") == 0) {
diff --git a/hostapd/ctrl_iface.c b/hostapd/ctrl_iface.c
index 30fa47f..02b41fd 100644
--- a/hostapd/ctrl_iface.c
+++ b/hostapd/ctrl_iface.c
@@ -1504,6 +1504,10 @@
wpa_auth_set_ocv_override_freq(
hapd->wpa_auth,
WPA_AUTH_OCV_OVERRIDE_FILS_ASSOC, atoi(value));
+ else if (os_strcasecmp(cmd, "skip_send_eapol") == 0)
+ wpa_auth_set_skip_send_eapol(hapd->wpa_auth, atoi(value));
+ else if (os_strcasecmp(cmd, "enable_eapol_large_timeout") == 0)
+ wpa_auth_set_enable_eapol_large_timeout(hapd->wpa_auth, atoi(value));
#endif /* CONFIG_TESTING_OPTIONS */
}
diff --git a/hostapd/hidl/1.3/hostapd.cpp b/hostapd/hidl/1.3/hostapd.cpp
index 41ac89c..1a342e5 100644
--- a/hostapd/hidl/1.3/hostapd.cpp
+++ b/hostapd/hidl/1.3/hostapd.cpp
@@ -588,6 +588,23 @@
}
}
+bool forceStaDisconnection(struct hostapd_data* hapd,
+ const std::array<uint8_t, 6>& client_address,
+ const uint16_t reason_code) {
+ struct sta_info *sta;
+ for (sta = hapd->sta_list; sta; sta = sta->next) {
+ int res;
+ res = memcmp(sta->addr, client_address.data(), ETH_ALEN);
+ if (res == 0) {
+ wpa_printf(MSG_INFO, "Force client:" MACSTR " disconnect with reason: %d",
+ MAC2STR(client_address.data()), reason_code);
+ ap_sta_disconnect(hapd, sta, sta->addr, reason_code);
+ return true;
+ }
+ }
+ return false;
+}
+
// hostapd core functions accept "C" style function pointers, so use global
// functions to pass to the hostapd core function and store the corresponding
// std::function methods to be invoked.
@@ -884,7 +901,9 @@
enum wpa_msg_type type, const char *txt,
size_t len) {
wpa_printf(MSG_DEBUG, "Receive wpa msg : %s", txt);
- if (os_strncmp(txt, WPA_EVENT_CHANNEL_SWITCH,
+ if (os_strncmp(txt, AP_EVENT_ENABLED,
+ strlen(AP_EVENT_ENABLED)) == 0 ||
+ os_strncmp(txt, WPA_EVENT_CHANNEL_SWITCH,
strlen(WPA_EVENT_CHANNEL_SWITCH)) == 0) {
for (const auto &callback : callbacks_) {
callback->onApInstanceInfoChanged(
@@ -952,20 +971,29 @@
const std::array<uint8_t, 6>& client_address, V1_2::Ieee80211ReasonCode reason_code)
{
struct hostapd_data *hapd = hostapd_get_iface(interfaces_, iface_name.c_str());
- struct sta_info *sta;
+ bool result;
+ if (!hapd) {
+ for (auto const& iface : br_interfaces_) {
+ if (iface.first == iface_name) {
+ for (auto const& instance : iface.second) {
+ hapd = hostapd_get_iface(interfaces_, instance.c_str());
+ if (hapd) {
+ result = forceStaDisconnection(hapd, client_address,
+ (uint16_t) reason_code);
+ if (result) break;
+ }
+ }
+ }
+ }
+ } else {
+ result = forceStaDisconnection(hapd, client_address, (uint16_t) reason_code);
+ }
if (!hapd) {
wpa_printf(MSG_ERROR, "Interface %s doesn't exist", iface_name.c_str());
return {V1_2::HostapdStatusCode::FAILURE_IFACE_UNKNOWN, ""};
}
- for (sta = hapd->sta_list; sta; sta = sta->next) {
- int res;
- res = memcmp(sta->addr, client_address.data(), ETH_ALEN);
- if (res == 0) {
- wpa_printf(MSG_INFO, "Force client:" MACSTR " disconnect with reason: %d",
- MAC2STR(client_address.data()), (uint16_t) reason_code);
- ap_sta_disconnect(hapd, sta, sta->addr, (uint16_t) reason_code);
- return {V1_2::HostapdStatusCode::SUCCESS, ""};
- }
+ if (result) {
+ return {V1_2::HostapdStatusCode::SUCCESS, ""};
}
return {V1_2::HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, ""};
}
diff --git a/src/ap/ap_config.c b/src/ap/ap_config.c
index 04535a1..f0e4236 100644
--- a/src/ap/ap_config.c
+++ b/src/ap/ap_config.c
@@ -252,6 +252,8 @@
conf->ignore_reassoc_probability = 0.0;
conf->corrupt_gtk_rekey_mic_probability = 0.0;
conf->ecsa_ie_only = 0;
+ conf->skip_send_eapol = 0;
+ conf->enable_eapol_large_timeout = 0;
#endif /* CONFIG_TESTING_OPTIONS */
conf->acs = 0;
diff --git a/src/ap/ap_config.h b/src/ap/ap_config.h
index bada04c..0cb4b52 100644
--- a/src/ap/ap_config.h
+++ b/src/ap/ap_config.h
@@ -1005,6 +1005,8 @@
double ignore_reassoc_probability;
double corrupt_gtk_rekey_mic_probability;
int ecsa_ie_only;
+ unsigned int skip_send_eapol;
+ unsigned int enable_eapol_large_timeout;
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_ACS
diff --git a/src/ap/wpa_auth.c b/src/ap/wpa_auth.c
index 9d74bfc..e48894f 100644
--- a/src/ap/wpa_auth.c
+++ b/src/ap/wpa_auth.c
@@ -188,6 +188,10 @@
{
if (!wpa_auth->cb->send_eapol)
return -1;
+#ifdef CONFIG_TESTING_OPTIONS
+ if (wpa_auth->conf.skip_send_eapol)
+ return 0;
+#endif
return wpa_auth->cb->send_eapol(wpa_auth->cb_ctx, addr, data, data_len,
encrypt);
}
@@ -1663,7 +1667,7 @@
wpa_auth_set_eapol(wpa_auth, sm->addr, WPA_EAPOL_inc_EapolFramesTx, 1);
wpa_auth_send_eapol(wpa_auth, sm->addr, (u8 *) hdr, len,
- sm->pairwise_set);
+ sm->pairwise_set);
os_free(hdr);
}
@@ -1698,6 +1702,11 @@
#ifdef TEST_FUZZ
timeout_ms = 1;
#endif /* TEST_FUZZ */
+#ifdef CONFIG_TESTING_OPTIONS
+ if(wpa_auth->conf.enable_eapol_large_timeout) {
+ timeout_ms = 50 * 1000;
+ }
+#endif
wpa_printf(MSG_DEBUG,
"WPA: Use EAPOL-Key timeout of %u ms (retry counter %u)",
timeout_ms, ctr);
@@ -5612,4 +5621,19 @@
}
}
+void wpa_auth_set_skip_send_eapol(struct wpa_authenticator *wpa_auth,
+ u8 val)
+{
+ if (wpa_auth)
+ wpa_auth->conf.skip_send_eapol = val;
+}
+
+void wpa_auth_set_enable_eapol_large_timeout(struct wpa_authenticator *wpa_auth,
+ u8 val)
+{
+ if (wpa_auth)
+ wpa_auth->conf.enable_eapol_large_timeout = val;
+}
+
+
#endif /* CONFIG_TESTING_OPTIONS */
diff --git a/src/ap/wpa_auth.h b/src/ap/wpa_auth.h
index 5f9df9c..ff90464 100644
--- a/src/ap/wpa_auth.h
+++ b/src/ap/wpa_auth.h
@@ -240,6 +240,8 @@
unsigned int gtk_rsc_override_set:1;
unsigned int igtk_rsc_override_set:1;
int ft_rsnxe_used;
+ unsigned int skip_send_eapol:1;
+ unsigned int enable_eapol_large_timeout:1;
#endif /* CONFIG_TESTING_OPTIONS */
unsigned int oci_freq_override_eapol_m3;
unsigned int oci_freq_override_eapol_g1;
@@ -542,5 +544,9 @@
void wpa_auth_set_ocv_override_freq(struct wpa_authenticator *wpa_auth,
enum wpa_auth_ocv_override_frame frame,
unsigned int freq);
+void wpa_auth_set_skip_send_eapol(struct wpa_authenticator *wpa_auth,
+ u8 val);
+void wpa_auth_set_enable_eapol_large_timeout(struct wpa_authenticator *wpa_auth,
+ u8 val);
#endif /* WPA_AUTH_H */
diff --git a/src/ap/wpa_auth_glue.c b/src/ap/wpa_auth_glue.c
index c01654f..bb44c7a 100644
--- a/src/ap/wpa_auth_glue.c
+++ b/src/ap/wpa_auth_glue.c
@@ -180,6 +180,8 @@
wconf->oci_freq_override_ft_assoc = conf->oci_freq_override_ft_assoc;
wconf->oci_freq_override_fils_assoc =
conf->oci_freq_override_fils_assoc;
+ wconf->skip_send_eapol = iconf->skip_send_eapol;
+ wconf->enable_eapol_large_timeout = iconf->enable_eapol_large_timeout;
#endif /* CONFIG_TESTING_OPTIONS */
#ifdef CONFIG_P2P
os_memcpy(wconf->ip_addr_go, conf->ip_addr_go, 4);
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
index b11e371..3c0431b 100644
--- a/wpa_supplicant/android.config
+++ b/wpa_supplicant/android.config
@@ -533,8 +533,9 @@
# Opportunistic Wireless Encryption (OWE)
CONFIG_OWE=y
-# Easy Connect (Device Provisioning Protocol - DPP R1)
+# Easy Connect (Device Provisioning Protocol - DPP R1 & R2)
CONFIG_DPP=y
+CONFIG_DPP2=y
# WPA3-Personal (SAE)
CONFIG_SAE=y
diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c
index a4892e7..ac88a7d 100644
--- a/wpa_supplicant/ap.c
+++ b/wpa_supplicant/ap.c
@@ -44,6 +44,27 @@
#endif /* CONFIG_WPS */
+static bool is_chanwidth160_supported(struct hostapd_hw_modes *mode,
+ struct hostapd_config *conf)
+{
+#ifdef CONFIG_IEEE80211AX
+ if (conf->ieee80211ax) {
+ struct he_capabilities *he_cap;
+
+ he_cap = &mode->he_capab[IEEE80211_MODE_AP];
+ if (he_cap->phy_cap[HE_PHYCAP_CHANNEL_WIDTH_SET_IDX] &
+ (HE_PHYCAP_CHANNEL_WIDTH_SET_80PLUS80MHZ_IN_5G |
+ HE_PHYCAP_CHANNEL_WIDTH_SET_160MHZ_IN_5G))
+ return true;
+ }
+#endif /* CONFIG_IEEE80211AX */
+ if (mode->vht_capab & (VHT_CAP_SUPP_CHAN_WIDTH_160MHZ |
+ VHT_CAP_SUPP_CHAN_WIDTH_160_80PLUS80MHZ))
+ return true;
+ return false;
+}
+
+
static void wpas_conf_ap_vht(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid,
struct hostapd_config *conf,
@@ -105,7 +126,7 @@
*/
hostapd_set_oper_chwidth(conf, CHANWIDTH_160MHZ);
center_chan = wpas_p2p_get_vht160_center(wpa_s, mode, channel);
- if (center_chan) {
+ if (center_chan && is_chanwidth160_supported(mode, conf)) {
wpa_printf(MSG_DEBUG,
"VHT center channel %u for auto-selected 160 MHz bandwidth",
center_chan);
diff --git a/wpa_supplicant/hidl/1.4/sta_iface.cpp b/wpa_supplicant/hidl/1.4/sta_iface.cpp
index 7aa5ebf..731808d 100644
--- a/wpa_supplicant/hidl/1.4/sta_iface.cpp
+++ b/wpa_supplicant/hidl/1.4/sta_iface.cpp
@@ -40,6 +40,8 @@
using android::hardware::wifi::supplicant::V1_4::ConnectionCapabilities;
using android::hardware::wifi::supplicant::V1_4::LegacyMode;
using android::hardware::wifi::supplicant::V1_4::implementation::HidlManager;
+using android::hardware::wifi::supplicant::V1_4::DppResponderBootstrapInfo;
+using android::hardware::wifi::supplicant::V1_4::DppCurve;
constexpr uint32_t kMaxAnqpElems = 100;
constexpr char kGetMacAddress[] = "MACADDR";
@@ -218,6 +220,65 @@
return mask;
}
+const std::string getDppListenChannel(struct wpa_supplicant *wpa_s, int32_t *listen_channel)
+{
+ struct hostapd_hw_modes *mode;
+ int chan44 = 0, chan149 = 0;
+ *listen_channel = 0;
+
+ /* Check if device support 2.4GHz band*/
+ mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
+ HOSTAPD_MODE_IEEE80211G, 0);
+ if (mode) {
+ *listen_channel = 6;
+ return "81/6";
+ }
+ /* Check if device support 5GHz band */
+ mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
+ HOSTAPD_MODE_IEEE80211A, 0);
+ if (mode) {
+ for (int i = 0; i < mode->num_channels; i++) {
+ struct hostapd_channel_data *chan = &mode->channels[i];
+
+ if (chan->flag & (HOSTAPD_CHAN_DISABLED |
+ HOSTAPD_CHAN_RADAR))
+ continue;
+ if (chan->freq == 5220)
+ chan44 = 1;
+ if (chan->freq == 5745)
+ chan149 = 1;
+ }
+ if (chan149) {
+ *listen_channel = 149;
+ return "124/149";
+ } else if (chan44) {
+ *listen_channel = 44;
+ return "115/44";
+ }
+ }
+
+ return "";
+}
+
+const std::string convertCurveTypeToName(DppCurve curve)
+{
+ switch (curve) {
+ case DppCurve::PRIME256V1:
+ return "prime256v1";
+ case DppCurve::SECP384R1:
+ return "secp384r1";
+ case DppCurve::SECP521R1:
+ return "secp521r1";
+ case DppCurve::BRAINPOOLP256R1:
+ return "brainpoolP256r1";
+ case DppCurve::BRAINPOOLP384R1:
+ return "brainpoolP384r1";
+ case DppCurve::BRAINPOOLP512R1:
+ return "brainpoolP512r1";
+ }
+ WPA_ASSERT(false);
+}
+
} // namespace
namespace android {
@@ -684,6 +745,31 @@
&StaIface::stopDppInitiatorInternal, _hidl_cb);
}
+Return<void> StaIface::generateDppBootstrapInfoForResponder(
+ const hidl_array<uint8_t, 6> &mac_address, const hidl_string& device_info,
+ DppCurve curve, generateDppBootstrapInfoForResponder_cb _hidl_cb)
+{
+ return validateAndCall(
+ this, V1_4::SupplicantStatusCode::FAILURE_IFACE_INVALID,
+ &StaIface::generateDppBootstrapInfoForResponderInternal, _hidl_cb, mac_address,
+ device_info, curve);
+}
+
+Return<void> StaIface::startDppEnrolleeResponder(
+ uint32_t listen_channel, startDppEnrolleeResponder_cb _hidl_cb)
+{
+ return validateAndCall(
+ this, V1_4::SupplicantStatusCode::FAILURE_IFACE_INVALID,
+ &StaIface::startDppEnrolleeResponderInternal, _hidl_cb, listen_channel);
+}
+
+Return<void> StaIface::stopDppResponder(uint32_t own_bootstrap_id, stopDppResponder_cb _hidl_cb)
+{
+ return validateAndCall(
+ this, V1_4::SupplicantStatusCode::FAILURE_IFACE_INVALID,
+ &StaIface::stopDppResponderInternal, _hidl_cb, own_bootstrap_id);
+}
+
Return<void> StaIface::getWpaDriverCapabilities(
getWpaDriverCapabilities_cb _hidl_cb)
{
@@ -1478,6 +1564,111 @@
#endif
}
+std::pair<V1_4::SupplicantStatus, DppResponderBootstrapInfo>
+StaIface::generateDppBootstrapInfoForResponderInternal(const std::array<uint8_t, 6> &mac_address,
+ const std::string& device_info, DppCurve curve)
+{
+#ifdef CONFIG_DPP
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ std::string cmd = "type=qrcode";
+ int32_t id;
+ int32_t listen_channel = 0;
+ struct DppResponderBootstrapInfo bootstrap_info;
+ const char *uri;
+ std::string listen_channel_str;
+ std::string mac_addr_str;
+ char buf[3] = {0};
+
+ cmd += (device_info.empty()) ? "" : " info=" + device_info;
+
+ listen_channel_str = getDppListenChannel(wpa_s, &listen_channel);
+ if (listen_channel == 0) {
+ wpa_printf(MSG_ERROR, "StaIface: Failed to derive DPP listen channel");
+ return {{V1_4::SupplicantStatusCode::FAILURE_UNKNOWN, ""}, bootstrap_info};
+ }
+ cmd += " chan=" + listen_channel_str;
+
+ cmd += " mac=";
+ for (int i = 0;i < 6;i++) {
+ snprintf(buf, sizeof(buf), "%02x", mac_address[i]);
+ mac_addr_str.append(buf);
+ }
+ cmd += mac_addr_str;
+
+ cmd += " curve=" + convertCurveTypeToName(curve);
+
+ id = dpp_bootstrap_gen(wpa_s->dpp, cmd.c_str());
+ wpa_printf(MSG_DEBUG,
+ "DPP generate bootstrap QR code command: %s id: %d", cmd.c_str(), id);
+ if (id > 0) {
+ uri = dpp_bootstrap_get_uri(wpa_s->dpp, id);
+ if (uri) {
+ wpa_printf(MSG_DEBUG, "DPP Bootstrap info: id: %d "
+ "listen_channel: %d uri: %s", id, listen_channel, uri);
+ bootstrap_info.bootstrapId = id;
+ bootstrap_info.listenChannel = listen_channel;
+ bootstrap_info.uri = uri;
+ return {{V1_4::SupplicantStatusCode::SUCCESS, ""}, bootstrap_info};
+ }
+ }
+ return {{V1_4::SupplicantStatusCode::FAILURE_UNKNOWN, ""}, bootstrap_info};
+#else
+ return {{V1_4::SupplicantStatusCode::FAILURE_UNSUPPORTED, ""}, bootstrap_info};
+#endif
+}
+
+V1_4::SupplicantStatus StaIface::startDppEnrolleeResponderInternal(uint32_t listen_channel)
+{
+#ifdef CONFIG_DPP
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ std::string cmd = "";
+ uint32_t freq = (listen_channel <= 14 ? 2407 : 5000) + listen_channel * 5;
+
+ /* Report received configuration to HIDL and create an internal profile */
+ wpa_s->conf->dpp_config_processing = 1;
+
+ cmd += std::to_string(freq);
+ cmd += " role=enrollee netrole=sta";
+
+ wpa_printf(MSG_DEBUG,
+ "DPP Enrollee Responder command: %s", cmd.c_str());
+
+ if (wpas_dpp_listen(wpa_s, cmd.c_str()) == 0) {
+ return {V1_4::SupplicantStatusCode::SUCCESS, ""};
+ }
+ return {V1_4::SupplicantStatusCode::FAILURE_UNKNOWN, ""};
+#else
+ return {V1_4::SupplicantStatusCode::FAILURE_UNSUPPORTED, ""};
+#endif
+}
+
+V1_4::SupplicantStatus StaIface::stopDppResponderInternal(uint32_t own_bootstrap_id)
+{
+#ifdef CONFIG_DPP
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ std::string bootstrap_id_str;
+
+ if (own_bootstrap_id == 0) {
+ bootstrap_id_str = "*";
+ }
+ else {
+ bootstrap_id_str = std::to_string(own_bootstrap_id);
+ }
+
+ wpa_printf(MSG_DEBUG, "DPP Stop DPP Responder id: %d ", own_bootstrap_id);
+ wpas_dpp_stop(wpa_s);
+ wpas_dpp_listen_stop(wpa_s);
+
+ if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) < 0) {
+ wpa_printf(MSG_ERROR, "StaIface: dpp_bootstrap_remove failed");
+ }
+
+ return {V1_4::SupplicantStatusCode::SUCCESS, ""};
+#else
+ return {V1_4::SupplicantStatusCode::FAILURE_UNSUPPORTED, ""};
+#endif
+}
+
std::pair<SupplicantStatus, android::hardware::wifi::supplicant::V1_3::ConnectionCapabilities>
StaIface::getConnectionCapabilitiesInternal()
{
diff --git a/wpa_supplicant/hidl/1.4/sta_iface.h b/wpa_supplicant/hidl/1.4/sta_iface.h
index bb5344b..d49e469 100644
--- a/wpa_supplicant/hidl/1.4/sta_iface.h
+++ b/wpa_supplicant/hidl/1.4/sta_iface.h
@@ -205,6 +205,13 @@
getKeyMgmtCapabilities_1_3_cb _hidl_cb) override;
Return<void> getWpaDriverCapabilities_1_4(
getWpaDriverCapabilities_1_4_cb _hidl_cb) override;
+ Return<void> generateDppBootstrapInfoForResponder(const hidl_array<uint8_t, 6> &mac_address,
+ const hidl_string& device_info, DppCurve curve,
+ generateDppBootstrapInfoForResponder_cb _hidl_cb) override;
+ Return<void> startDppEnrolleeResponder(uint32_t listen_channel,
+ startDppEnrolleeResponder_cb _hidl_cb) override;
+ Return<void> stopDppResponder(uint32_t own_bootstrap_id,
+ stopDppResponder_cb _hidl_cb) override;
private:
// Corresponding worker functions for the HIDL methods.
@@ -303,6 +310,12 @@
SupplicantStatus setMboCellularDataStatusInternal(bool available);
std::pair<SupplicantStatus, uint32_t> getKeyMgmtCapabilitiesInternal_1_3();
std::pair<V1_4::SupplicantStatus, uint32_t> getWpaDriverCapabilitiesInternal_1_4();
+ std::pair<V1_4::SupplicantStatus, V1_4::DppResponderBootstrapInfo>
+ generateDppBootstrapInfoForResponderInternal(
+ const std::array<uint8_t, 6>& mac_address, const std::string& device_info,
+ DppCurve curve);
+ V1_4::SupplicantStatus startDppEnrolleeResponderInternal(uint32_t listen_channel);
+ V1_4::SupplicantStatus stopDppResponderInternal(uint32_t own_bootstrap_id);
struct wpa_supplicant* retrieveIfacePtr();
diff --git a/wpa_supplicant/hidl/1.4/sta_network.cpp b/wpa_supplicant/hidl/1.4/sta_network.cpp
index 6d53282..3e773de 100644
--- a/wpa_supplicant/hidl/1.4/sta_network.cpp
+++ b/wpa_supplicant/hidl/1.4/sta_network.cpp
@@ -2273,6 +2273,11 @@
return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
}
setFastTransitionKeyMgmt(key_mgmt_mask);
+
+ if (key_mgmt_mask & WPA_KEY_MGMT_OWE) {
+ // Do not allow to connect to Open network when OWE is selected
+ wpa_ssid->owe_only = 1;
+ }
wpa_ssid->key_mgmt = key_mgmt_mask;
wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", wpa_ssid->key_mgmt);
resetInternalStateAfterParamsUpdate();