Merge "Enable scan mac randomization only if driver supports"
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
index d269ac7..d4146db 100644
--- a/wpa_supplicant/android.config
+++ b/wpa_supplicant/android.config
@@ -551,4 +551,7 @@
# WPA3-Personal (SAE)
CONFIG_SAE=y
+# WPA3-Enterprise (SuiteB-192)
+CONFIG_SUITEB192=y
+
include $(wildcard $(LOCAL_PATH)/android_config_*.inc)
diff --git a/wpa_supplicant/config.c b/wpa_supplicant/config.c
index dd7f603..a8987a6 100644
--- a/wpa_supplicant/config.c
+++ b/wpa_supplicant/config.c
@@ -2637,6 +2637,7 @@
#ifdef CONFIG_MBO
os_free(config->non_pref_chan);
#endif /* CONFIG_MBO */
+ os_free(config->p2p_device_persistent_mac_addr);
os_free(config);
}
@@ -4753,6 +4754,9 @@
{ INT(gas_rand_addr_lifetime), 0 },
{ INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
{ INT_RANGE(dpp_config_processing, 0, 2), 0 },
+ { INT(p2p_device_random_mac_addr), 0 },
+ { STR(p2p_device_persistent_mac_addr), 0 },
+ { INT(p2p_interface_random_mac_addr), 0 },
};
#undef FUNC
diff --git a/wpa_supplicant/config.h b/wpa_supplicant/config.h
index ad4dd88..ee20a93 100644
--- a/wpa_supplicant/config.h
+++ b/wpa_supplicant/config.h
@@ -1469,6 +1469,36 @@
* profile automatically
*/
int dpp_config_processing;
+
+ /**
+ * p2p_device_random_mac_addr - P2P Device MAC address policy default
+ *
+ * 0 = use permanent MAC address
+ * 1 = use random MAC address on creating the interface if there is no persistent groups.
+ *
+ * By default, permanent MAC address is used.
+ */
+ int p2p_device_random_mac_addr;
+
+ /**
+ * p2p_device_persistent_mac_addr - Record last used MAC address
+ *
+ * If there are saved persistent groups, P2P cannot generate another random MAC address,
+ * and need to restore to last used MAC address.
+ * format: aa:bb:cc:dd:ee:ff
+ */
+ char *p2p_device_persistent_mac_addr;
+
+ /**
+ * p2p_interface_random_mac_addr - P2P Interface MAC address policy default
+ *
+ * 0 = use permanent MAC address
+ * 1 = use random MAC address on creating the interface.
+ *
+ * By default, permanent MAC address is used.
+ */
+ int p2p_interface_random_mac_addr;
+
};
diff --git a/wpa_supplicant/config_file.c b/wpa_supplicant/config_file.c
index aa73f9d..3a6dae5 100644
--- a/wpa_supplicant/config_file.c
+++ b/wpa_supplicant/config_file.c
@@ -1511,6 +1511,15 @@
if (config->dpp_config_processing)
fprintf(f, "dpp_config_processing=%d\n",
config->dpp_config_processing);
+ if (config->p2p_device_random_mac_addr)
+ fprintf(f, "p2p_device_random_mac_addr=%d\n",
+ config->p2p_device_random_mac_addr);
+ if (config->p2p_device_persistent_mac_addr)
+ fprintf(f, "p2p_device_persistent_mac_addr=%s\n",
+ config->p2p_device_persistent_mac_addr);
+ if (config->p2p_interface_random_mac_addr)
+ fprintf(f, "p2p_interface_random_mac_addr=%d\n",
+ config->p2p_interface_random_mac_addr);
}
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index e775422..152e257 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -469,7 +469,7 @@
wpa_printf(MSG_INFO,
"DPP: No response received from responder - stopping initiation attempt");
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
- wpas_notify_dpp_timeout(wpa_s->ifname);
+ wpas_notify_dpp_timeout(wpa_s);
offchannel_send_action_done(wpa_s);
wpas_dpp_listen_stop(wpa_s);
dpp_auth_deinit(auth);
@@ -731,6 +731,7 @@
wpa_printf(MSG_INFO,
"DPP: No response received from responder - stopping initiation attempt");
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_INIT_FAILED);
+ wpas_notify_dpp_timeout(wpa_s);
eloop_cancel_timeout(wpas_dpp_reply_wait_timeout,
wpa_s, NULL);
offchannel_send_action_done(wpa_s);
@@ -1141,7 +1142,7 @@
peer_bi, own_bi, freq, hdr, buf, len);
if (!wpa_s->dpp_auth) {
wpa_printf(MSG_DEBUG, "DPP: No response generated");
- wpas_notify_dpp_auth_failure(wpa_s->ifname);
+ wpas_notify_dpp_auth_failure(wpa_s);
return;
}
wpas_dpp_set_testing_options(wpa_s, wpa_s->dpp_auth);
@@ -1264,7 +1265,7 @@
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_NETWORK_ID "%d", ssid->id);
- wpas_notify_dpp_config_received(wpa_s->ifname, ssid);
+ wpas_notify_dpp_config_received(wpa_s, ssid);
if (wpa_s->conf->dpp_config_processing < 2) {
return;
@@ -1389,7 +1390,7 @@
fail:
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
- wpas_notify_dpp_configuration_failure(wpa_s->ifname);
+ wpas_notify_dpp_configuration_failure(wpa_s);
dpp_auth_deinit(wpa_s->dpp_auth);
wpa_s->dpp_auth = NULL;
}
@@ -1467,7 +1468,7 @@
{
wpa_printf(MSG_DEBUG, "DPP: Authentication succeeded");
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_AUTH_SUCCESS "init=%d", initiator);
- wpas_notify_dpp_auth_success(wpa_s->ifname);
+ wpas_notify_dpp_auth_success(wpa_s);
#ifdef CONFIG_TESTING_OPTIONS
if (dpp_test == DPP_TEST_STOP_AT_AUTH_CONF) {
wpa_printf(MSG_INFO,
@@ -1524,13 +1525,13 @@
if (auth->auth_resp_status == DPP_STATUS_RESPONSE_PENDING) {
wpa_printf(MSG_DEBUG,
"DPP: Start wait for full response");
- wpas_notify_dpp_resp_pending(wpa_s->ifname);
+ wpas_notify_dpp_resp_pending(wpa_s);
offchannel_send_action_done(wpa_s);
wpas_dpp_listen_start(wpa_s, auth->curr_freq);
return;
}
wpa_printf(MSG_DEBUG, "DPP: No confirm generated");
- wpas_notify_dpp_auth_failure(wpa_s->ifname);
+ wpas_notify_dpp_auth_failure(wpa_s);
return;
}
os_memcpy(auth->peer_mac_addr, src, ETH_ALEN);
@@ -1568,7 +1569,7 @@
if (dpp_auth_conf_rx(auth, hdr, buf, len) < 0) {
wpa_printf(MSG_DEBUG, "DPP: Authentication failed");
- wpas_notify_dpp_auth_failure(wpa_s->ifname);
+ wpas_notify_dpp_auth_failure(wpa_s);
return;
}
@@ -2161,7 +2162,7 @@
resp = dpp_conf_req_rx(auth, query, query_len);
if (!resp) {
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
- wpas_notify_dpp_configuration_failure(wpa_s->ifname);
+ wpas_notify_dpp_configuration_failure(wpa_s);
}
auth->conf_resp = resp;
return resp;
@@ -2194,11 +2195,11 @@
wpas_dpp_listen_stop(wpa_s);
if (ok) {
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_SENT);
- wpas_notify_dpp_config_sent(wpa_s->ifname);
+ wpas_notify_dpp_config_sent(wpa_s);
}
else {
wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_CONF_FAILED);
- wpas_notify_dpp_configuration_failure(wpa_s->ifname);
+ wpas_notify_dpp_configuration_failure(wpa_s);
}
dpp_auth_deinit(wpa_s->dpp_auth);
wpa_s->dpp_auth = NULL;
diff --git a/wpa_supplicant/hidl/1.2/hidl.cpp b/wpa_supplicant/hidl/1.2/hidl.cpp
index 60ee85f..d8fa82f 100644
--- a/wpa_supplicant/hidl/1.2/hidl.cpp
+++ b/wpa_supplicant/hidl/1.2/hidl.cpp
@@ -27,9 +27,9 @@
using android::hardware::wifi::supplicant::V1_2::implementation::HidlManager;
using namespace android::hardware::wifi::supplicant::V1_2;
-static void wpas_hidl_notify_dpp_success(const char *ifname, DppSuccessCode code);
-static void wpas_hidl_notify_dpp_failure(const char *ifname, DppFailureCode code);
-static void wpas_hidl_notify_dpp_progress(const char *ifname, DppProgressCode code);
+static void wpas_hidl_notify_dpp_success(struct wpa_supplicant *wpa_s, DppSuccessCode code);
+static void wpas_hidl_notify_dpp_failure(struct wpa_supplicant *wpa_s, DppFailureCode code);
+static void wpas_hidl_notify_dpp_progress(struct wpa_supplicant *wpa_s, DppProgressCode code);
void wpas_hidl_sock_handler(
int sock, void * /* eloop_ctx */, void * /* sock_ctx */)
@@ -648,10 +648,10 @@
hidl_manager->notifyEapError(wpa_s, error_code);
}
-void wpas_hidl_notify_dpp_config_received(const char *ifname,
+void wpas_hidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid)
{
- if (!ifname || !ssid)
+ if (!wpa_s || !ssid)
return;
wpa_printf(
@@ -662,85 +662,85 @@
if (!hidl_manager)
return;
- hidl_manager->notifyDppConfigReceived(ifname, ssid);
+ hidl_manager->notifyDppConfigReceived(wpa_s, ssid);
}
-void wpas_hidl_notify_dpp_config_sent(const char *ifname)
+void wpas_hidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s)
{
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_success(ifname, DppSuccessCode::CONFIGURATION_SENT);
+ wpas_hidl_notify_dpp_success(wpa_s, DppSuccessCode::CONFIGURATION_SENT);
}
/* DPP Progress notifications */
-void wpas_hidl_notify_dpp_auth_success(const char *ifname)
+void wpas_hidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
{
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_progress(ifname, DppProgressCode::AUTHENTICATION_SUCCESS);
+ wpas_hidl_notify_dpp_progress(wpa_s, DppProgressCode::AUTHENTICATION_SUCCESS);
}
-void wpas_hidl_notify_dpp_resp_pending(const char *ifname)
+void wpas_hidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s)
{
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_progress(ifname, DppProgressCode::RESPONSE_PENDING);
+ wpas_hidl_notify_dpp_progress(wpa_s, DppProgressCode::RESPONSE_PENDING);
}
/* DPP Failure notifications */
-void wpas_hidl_notify_dpp_not_compatible(const char *ifname)
+void wpas_hidl_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s)
{
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_failure(ifname, DppFailureCode::NOT_COMPATIBLE);
+ wpas_hidl_notify_dpp_failure(wpa_s, DppFailureCode::NOT_COMPATIBLE);
}
-void wpas_hidl_notify_dpp_missing_auth(const char *ifname)
+void wpas_hidl_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s)
{
- if (!ifname)
+ if (!wpa_s)
return;
}
-void wpas_hidl_notify_dpp_configuration_failure(const char *ifname)
+void wpas_hidl_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s)
{
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_failure(ifname, DppFailureCode::CONFIGURATION);
+ wpas_hidl_notify_dpp_failure(wpa_s, DppFailureCode::CONFIGURATION);
}
-void wpas_hidl_notify_dpp_timeout(const char *ifname)
+void wpas_hidl_notify_dpp_timeout(struct wpa_supplicant *wpa_s)
{
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_failure(ifname, DppFailureCode::TIMEOUT);
+ wpas_hidl_notify_dpp_failure(wpa_s, DppFailureCode::TIMEOUT);
}
-void wpas_hidl_notify_dpp_auth_failure(const char *ifname)
+void wpas_hidl_notify_dpp_auth_failure(struct wpa_supplicant *wpa_s)
{
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_failure(ifname, DppFailureCode::AUTHENTICATION);
+ wpas_hidl_notify_dpp_failure(wpa_s, DppFailureCode::AUTHENTICATION);
}
-void wpas_hidl_notify_dpp_fail(const char *ifname)
+void wpas_hidl_notify_dpp_fail(struct wpa_supplicant *wpa_s)
{
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_failure(ifname, DppFailureCode::FAILURE);
+ wpas_hidl_notify_dpp_failure(wpa_s, DppFailureCode::FAILURE);
}
/* DPP notification helper functions */
-static void wpas_hidl_notify_dpp_success(const char *ifname, DppSuccessCode code)
+static void wpas_hidl_notify_dpp_success(struct wpa_supplicant *wpa_s, DppSuccessCode code)
{
- if (!ifname)
+ if (!wpa_s)
return;
wpa_printf(
@@ -751,12 +751,12 @@
if (!hidl_manager)
return;
- hidl_manager->notifyDppSuccess(ifname, code);
+ hidl_manager->notifyDppSuccess(wpa_s, code);
}
-static void wpas_hidl_notify_dpp_failure(const char *ifname, DppFailureCode code)
+static void wpas_hidl_notify_dpp_failure(struct wpa_supplicant *wpa_s, DppFailureCode code)
{
- if (!ifname)
+ if (!wpa_s)
return;
wpa_printf(
@@ -767,12 +767,12 @@
if (!hidl_manager)
return;
- hidl_manager->notifyDppFailure(ifname, code);
+ hidl_manager->notifyDppFailure(wpa_s, code);
}
-static void wpas_hidl_notify_dpp_progress(const char *ifname, DppProgressCode code)
+static void wpas_hidl_notify_dpp_progress(struct wpa_supplicant *wpa_s, DppProgressCode code)
{
- if (!ifname)
+ if (!wpa_s)
return;
wpa_printf(
@@ -783,5 +783,5 @@
if (!hidl_manager)
return;
- hidl_manager->notifyDppProgress(ifname, code);
+ hidl_manager->notifyDppProgress(wpa_s, code);
}
diff --git a/wpa_supplicant/hidl/1.2/hidl.h b/wpa_supplicant/hidl/1.2/hidl.h
index 914bc7b..a177f6e 100644
--- a/wpa_supplicant/hidl/1.2/hidl.h
+++ b/wpa_supplicant/hidl/1.2/hidl.h
@@ -99,18 +99,18 @@
const u8 *p2p_dev_addr);
void wpas_hidl_notify_eap_error(
struct wpa_supplicant *wpa_s, int error_code);
- void wpas_hidl_notify_dpp_config_received(const char *ifname,
+ void wpas_hidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
- void wpas_hidl_notify_dpp_config_sent(const char *ifname);
- void wpas_hidl_notify_dpp_auth_success(const char *ifname);
- void wpas_hidl_notify_dpp_resp_pending(const char *ifname);
- void wpas_hidl_notify_dpp_not_compatible(const char *ifname);
- void wpas_hidl_notify_dpp_missing_auth(const char *ifname);
- void wpas_hidl_notify_dpp_configuration_failure(const char *ifname);
- void wpas_hidl_notify_dpp_invalid_uri(const char *ifname);
- void wpas_hidl_notify_dpp_timeout(const char *ifname);
- void wpas_hidl_notify_dpp_auth_failure(const char *ifname);
- void wpas_hidl_notify_dpp_fail(const char *ifname);
+ void wpas_hidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s);
+ void wpas_hidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s);
+ void wpas_hidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s);
+ void wpas_hidl_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s);
+ void wpas_hidl_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s);
+ void wpas_hidl_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s);
+ void wpas_hidl_notify_dpp_invalid_uri(struct wpa_supplicant *wpa_s);
+ void wpas_hidl_notify_dpp_timeout(struct wpa_supplicant *wpa_s);
+ void wpas_hidl_notify_dpp_auth_failure(struct wpa_supplicant *wpa_s);
+ void wpas_hidl_notify_dpp_fail(struct wpa_supplicant *wpa_s);
#else // CONFIG_CTRL_IFACE_HIDL
static inline int wpas_hidl_register_interface(struct wpa_supplicant *wpa_s)
{
diff --git a/wpa_supplicant/hidl/1.2/hidl_manager.cpp b/wpa_supplicant/hidl/1.2/hidl_manager.cpp
index 1392159..c6fe92f 100644
--- a/wpa_supplicant/hidl/1.2/hidl_manager.cpp
+++ b/wpa_supplicant/hidl/1.2/hidl_manager.cpp
@@ -1491,20 +1491,23 @@
* @param ifname Interface name
* @param config Configuration object
*/
-void HidlManager::notifyDppConfigReceived(const char *ifname,
+void HidlManager::notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
struct wpa_ssid *config)
{
DppAkm securityAkm;
char *password;
- std::string hidl_ifname = ifname;
+ std::string hidl_ifname = wpa_s->ifname;
- if (config->key_mgmt & WPA_KEY_MGMT_SAE) {
+ if ((config->key_mgmt & WPA_KEY_MGMT_SAE) &&
+ (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) {
securityAkm = DppAkm::SAE;
} else if (config->key_mgmt & WPA_KEY_MGMT_PSK) {
securityAkm = DppAkm::PSK;
} else {
/* Unsupported AKM */
- notifyDppFailure(ifname, DppFailureCode::CONFIGURATION);
+ wpa_printf(MSG_ERROR, "DPP: Error: Unsupported AKM 0x%X",
+ config->key_mgmt);
+ notifyDppFailure(wpa_s, DppFailureCode::CONFIGURATION);
return;
}
@@ -1528,9 +1531,9 @@
* @param ifname Interface name
* @param code Status code
*/
-void HidlManager::notifyDppSuccess(const char *ifname, DppSuccessCode code)
+void HidlManager::notifyDppSuccess(struct wpa_supplicant *wpa_s, DppSuccessCode code)
{
- std::string hidl_ifname = ifname;
+ std::string hidl_ifname = wpa_s->ifname;
callWithEachStaIfaceCallback_1_2(hidl_ifname,
std::bind(&V1_2::ISupplicantStaIfaceCallback::onDppSuccess,
@@ -1543,9 +1546,9 @@
* @param ifname Interface name
* @param code Status code
*/
-void HidlManager::notifyDppFailure(const char *ifname, DppFailureCode code)
+void HidlManager::notifyDppFailure(struct wpa_supplicant *wpa_s, DppFailureCode code)
{
- std::string hidl_ifname = ifname;
+ std::string hidl_ifname = wpa_s->ifname;
callWithEachStaIfaceCallback_1_2(hidl_ifname,
std::bind(&V1_2::ISupplicantStaIfaceCallback::onDppFailure,
@@ -1558,9 +1561,9 @@
* @param ifname Interface name
* @param code Status code
*/
-void HidlManager::notifyDppProgress(const char *ifname, DppProgressCode code)
+void HidlManager::notifyDppProgress(struct wpa_supplicant *wpa_s, DppProgressCode code)
{
- std::string hidl_ifname = ifname;
+ std::string hidl_ifname = wpa_s->ifname;
callWithEachStaIfaceCallback_1_2(hidl_ifname,
std::bind(&V1_2::ISupplicantStaIfaceCallback::onDppProgress,
diff --git a/wpa_supplicant/hidl/1.2/hidl_manager.h b/wpa_supplicant/hidl/1.2/hidl_manager.h
index a7e2c86..7291347 100644
--- a/wpa_supplicant/hidl/1.2/hidl_manager.h
+++ b/wpa_supplicant/hidl/1.2/hidl_manager.h
@@ -128,11 +128,11 @@
struct wpa_supplicant *wpa_s, const u8 *sta,
const u8 *p2p_dev_addr);
void notifyEapError(struct wpa_supplicant *wpa_s, int error_code);
- void notifyDppConfigReceived(const char *ifname,
+ void notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
struct wpa_ssid *config);
- void notifyDppSuccess(const char *ifname, DppSuccessCode code);
- void notifyDppFailure(const char *ifname, DppFailureCode code);
- void notifyDppProgress(const char *ifname, DppProgressCode code);
+ void notifyDppSuccess(struct wpa_supplicant *wpa_s, DppSuccessCode code);
+ void notifyDppFailure(struct wpa_supplicant *wpa_s, DppFailureCode code);
+ void notifyDppProgress(struct wpa_supplicant *wpa_s, DppProgressCode code);
// Methods called from hidl objects.
void notifyExtRadioWorkStart(struct wpa_supplicant *wpa_s, uint32_t id);
@@ -357,6 +357,14 @@
WPA_KEY_MGMT_OWE,
"KeyMgmt value mismatch");
static_assert(
+ static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::WPA_PSK_SHA256) ==
+ WPA_KEY_MGMT_PSK_SHA256,
+ "KeyMgmt value mismatch");
+static_assert(
+ static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::WPA_EAP_SHA256) ==
+ WPA_KEY_MGMT_IEEE8021X_SHA256,
+ "KeyMgmt value mismatch");
+static_assert(
static_cast<uint32_t>(ISupplicantStaNetwork::ProtoMask::WPA) ==
WPA_PROTO_WPA,
"Proto value mismatch");
diff --git a/wpa_supplicant/hidl/1.2/p2p_iface.cpp b/wpa_supplicant/hidl/1.2/p2p_iface.cpp
index 80c0205..e528cb0 100644
--- a/wpa_supplicant/hidl/1.2/p2p_iface.cpp
+++ b/wpa_supplicant/hidl/1.2/p2p_iface.cpp
@@ -20,8 +20,13 @@
#include "ap.h"
#include "wps_supplicant.h"
#include "wifi_display.h"
+#include "utils/eloop.h"
+#include "wpa_supplicant_i.h"
+#include "driver_i.h"
}
+#define P2P_MAX_JOIN_SCAN_ATTEMPTS 10
+
namespace {
const char kConfigMethodStrPbc[] = "pbc";
const char kConfigMethodStrDisplay[] = "display";
@@ -30,6 +35,9 @@
constexpr uint8_t kWfdDeviceInfoSubelemId = 0;
constexpr char kWfdDeviceInfoSubelemLenHexStr[] = "0006";
+std::function<void()> pending_join_scan_callback = NULL;
+std::function<void()> pending_scan_res_join_callback = NULL;
+
using android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
using android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
uint8_t convertHidlMiracastModeToInternal(
@@ -82,6 +90,280 @@
}
return 1;
}
+
+void setBandScanFreqsList(
+ struct wpa_supplicant *wpa_s,
+ enum hostapd_hw_mode band,
+ struct wpa_driver_scan_params *params)
+{
+ /* Include only supported channels for the specified band */
+ struct hostapd_hw_modes *mode;
+ int count, i;
+
+ mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, band);
+ if (mode == NULL) {
+ /* No channels supported in this band. */
+ return;
+ }
+
+ params->freqs = (int *) os_calloc(mode->num_channels + 1, sizeof(int));
+ if (params->freqs == NULL)
+ return;
+ for (count = 0, i = 0; i < mode->num_channels; i++) {
+ if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED)
+ continue;
+ params->freqs[count++] = mode->channels[i].freq;
+ }
+}
+
+/**
+ * findBssBySsid - Fetch a BSS table entry based on SSID and optional BSSID.
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bssid: BSSID, zero addr matches any bssid
+ * @ssid: SSID
+ * @ssid_len: Length of @ssid
+ * Returns: Pointer to the BSS entry or %NULL if not found
+ */
+struct wpa_bss* findBssBySsid(
+ struct wpa_supplicant *wpa_s, const u8 *bssid,
+ const u8 *ssid, size_t ssid_len)
+{
+ struct wpa_bss *bss;
+ dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
+ if ((is_zero_ether_addr(bssid) ||
+ os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) &&
+ bss->ssid_len == ssid_len &&
+ os_memcmp(bss->ssid, ssid, ssid_len) == 0)
+ return bss;
+ }
+ return NULL;
+}
+
+struct wpa_ssid* addGroupClientNetwork(
+ struct wpa_supplicant* wpa_s,
+ uint8_t *group_owner_bssid,
+ const std::vector<uint8_t>& ssid,
+ const std::string& passphrase)
+{
+ struct wpa_ssid* wpa_network = wpa_config_add_network(wpa_s->conf);
+ if (!wpa_network) {
+ return NULL;
+ }
+ // set general network defaults
+ wpa_config_set_network_defaults(wpa_network);
+
+ // set P2p network defaults
+ wpa_network->p2p_group = 1;
+ wpa_network->mode = wpa_ssid::wpas_mode::WPAS_MODE_INFRA;
+
+ wpa_network->auth_alg = WPA_AUTH_ALG_OPEN;
+ wpa_network->key_mgmt = WPA_KEY_MGMT_PSK;
+ wpa_network->proto = WPA_PROTO_RSN;
+ wpa_network->pairwise_cipher = WPA_CIPHER_CCMP;
+ wpa_network->group_cipher = WPA_CIPHER_CCMP;
+ wpa_network->disabled = 2;
+
+ // set necessary fields
+ os_memcpy(wpa_network->bssid, group_owner_bssid, ETH_ALEN);
+ wpa_network->bssid_set = 1;
+
+ wpa_network->ssid = (uint8_t *)os_malloc(ssid.size());
+ if (wpa_network->ssid == NULL) {
+ wpa_config_remove_network(wpa_s->conf, wpa_network->id);
+ return NULL;
+ }
+ memcpy(wpa_network->ssid, ssid.data(), ssid.size());
+ wpa_network->ssid_len = ssid.size();
+
+ wpa_network->psk_set = 0;
+ wpa_network->passphrase = dup_binstr(passphrase.c_str(), passphrase.length());
+ if (wpa_network->passphrase == NULL) {
+ wpa_config_remove_network(wpa_s->conf, wpa_network->id);
+ return NULL;
+ }
+ wpa_config_update_psk(wpa_network);
+
+ return wpa_network;
+
+}
+
+void joinScanWrapper(void *eloop_ctx, void *timeout_ctx)
+{
+ struct wpa_supplicant *wpa_s = (struct wpa_supplicant *) eloop_ctx;
+
+ if (pending_join_scan_callback != NULL) {
+ pending_join_scan_callback();
+ }
+}
+
+void scanResJoinWrapper(
+ struct wpa_supplicant *wpa_s,
+ struct wpa_scan_results *scan_res)
+{
+ if (pending_scan_res_join_callback) {
+ pending_scan_res_join_callback();
+ }
+}
+
+int joinScanReq(
+ struct wpa_supplicant* wpa_s,
+ const std::vector<uint8_t>& ssid,
+ int freq)
+{
+ int ret;
+ struct wpa_driver_scan_params params;
+ struct wpabuf *ies;
+ size_t ielen;
+ unsigned int bands;
+
+ os_memset(¶ms, 0, sizeof(params));
+ if (ssid.size() > 0) {
+ params.ssids[0].ssid = ssid.data();
+ params.ssids[0].ssid_len = ssid.size();
+ } else {
+ params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID;
+ params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
+ }
+ wpa_printf(MSG_DEBUG, "Scan SSID %s for join with frequency %d (reinvoke)",
+ wpa_ssid_txt(params.ssids[0].ssid, params.ssids[0].ssid_len), freq);
+
+ if (freq > 0) {
+ if (freq == 2 || freq == 5) {
+ if (wpa_s->hw.modes != NULL) {
+ switch (freq) {
+ case 2:
+ setBandScanFreqsList(wpa_s,
+ HOSTAPD_MODE_IEEE80211G, ¶ms);
+ break;
+ case 5:
+ setBandScanFreqsList(wpa_s,
+ HOSTAPD_MODE_IEEE80211A, ¶ms);
+ break;
+ }
+ if (!params.freqs) {
+ wpa_printf(MSG_ERROR,
+ "P2P: No supported channels in %dG band.", freq);
+ return -1;
+ }
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "P2P: Unknown what %dG channels the driver supports.", freq);
+ }
+ } else {
+ if (0 == p2p_supported_freq_cli(wpa_s->global->p2p, freq)) {
+ wpa_printf(MSG_ERROR,
+ "P2P: freq %d is not supported for a client.", freq);
+ return -1;
+ }
+
+ params.freqs = (int *) os_malloc(sizeof(int) * 2);
+ if (params.freqs) {
+ params.freqs[0] = freq;
+ } else {
+ wpa_printf(MSG_ERROR,
+ "P2P: Cannot allocate memory for scan params.");
+ return -1;
+ }
+ }
+ }
+
+ ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
+ ies = wpabuf_alloc(ielen);
+ if (ies == NULL) {
+ if (params.freqs) {
+ os_free(params.freqs);
+ }
+ return -1;
+ }
+
+ bands = wpas_get_bands(wpa_s, params.freqs);
+ p2p_scan_ie(wpa_s->global->p2p, ies, NULL, bands);
+
+ params.p2p_probe = 1;
+ params.extra_ies = (u8 *) wpabuf_head(ies);
+ params.extra_ies_len = wpabuf_len(ies);
+ if (wpa_s->clear_driver_scan_cache) {
+ wpa_printf(MSG_DEBUG,
+ "Request driver to clear scan cache due to local BSS flush");
+ params.only_new_results = 1;
+ }
+
+ ret = wpa_drv_scan(wpa_s, ¶ms);
+ if (!ret) {
+ os_get_reltime(&wpa_s->scan_trigger_time);
+ wpa_s->scan_res_handler = scanResJoinWrapper;
+ wpa_s->own_scan_requested = 1;
+ wpa_s->clear_driver_scan_cache = 0;
+ }
+
+ if (params.freqs) {
+ os_free(params.freqs);
+ }
+
+ wpabuf_free(ies);
+
+ return ret;
+}
+
+int joinGroup(
+ struct wpa_supplicant* wpa_s,
+ uint8_t *group_owner_bssid,
+ const std::vector<uint8_t>& ssid,
+ const std::string& passphrase)
+{
+ int ret = 0;
+ int vht = wpa_s->conf->p2p_go_vht;
+ int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
+
+ // Construct a network for adding group.
+ // Group client follows the persistent attribute of Group Owner.
+ // If joined group is persistent, it adds a persistent network on GroupStarted.
+ struct wpa_ssid *wpa_network = addGroupClientNetwork(
+ wpa_s, group_owner_bssid, ssid, passphrase);
+ if (wpa_network == NULL) {
+ wpa_printf(MSG_ERROR, "P2P: Cannot construct a network for group join.");
+ return -1;
+ }
+
+ // this is temporary network only for establishing the connection.
+ wpa_network->temporary = 1;
+
+ if (wpas_p2p_group_add_persistent(
+ wpa_s, wpa_network, 0, 0, 0, 0, ht40, vht,
+ VHT_CHANWIDTH_USE_HT, NULL, 0, 1)) {
+ ret = -1;
+ }
+
+ // Always remove this temporary network at the end.
+ wpa_config_remove_network(wpa_s->conf, wpa_network->id);
+ return ret;
+}
+
+void notifyGroupJoinFailure(
+ struct wpa_supplicant* wpa_s)
+{
+ u8 zero_addr[ETH_ALEN] = {0};
+ std::vector<uint8_t> ssid = {'D', 'I', 'R', 'E','C', 'T', '-'};
+ std::string passphrase = "";
+ struct wpa_ssid *wpa_network = addGroupClientNetwork(
+ wpa_s, zero_addr, ssid, passphrase);
+ if (wpa_network) {
+ wpa_network->temporary = 1;
+ wpas_notify_p2p_group_formation_failure(wpa_s, "Failed to find the group.");
+ wpas_notify_p2p_group_removed(
+ wpa_s, wpa_network, "client");
+ wpa_config_remove_network(
+ wpa_s->conf, wpa_network->id);
+ } else {
+ wpa_printf(MSG_ERROR,
+ "P2P: Cannot construct a network.");
+ }
+}
+
+void scanResJoinIgnore(struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res) {
+ wpa_printf(MSG_DEBUG, "P2P: Ignore group join scan results.");
+}
+
} // namespace
namespace android {
@@ -706,6 +988,11 @@
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
}
+ if (wpa_s->scan_res_handler == scanResJoinWrapper) {
+ wpa_printf(MSG_DEBUG, "P2P: Stop pending group scan for stopping find).");
+ pending_scan_res_join_callback = NULL;
+ wpa_s->scan_res_handler = scanResJoinIgnore;
+ }
wpas_p2p_stop_find(wpa_s);
return {SupplicantStatusCode::SUCCESS, ""};
}
@@ -769,6 +1056,11 @@
SupplicantStatus P2pIface::cancelConnectInternal()
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+ if (wpa_s->scan_res_handler == scanResJoinWrapper) {
+ wpa_printf(MSG_DEBUG, "P2P: Stop pending group scan for canceling connect");
+ pending_scan_res_join_callback = NULL;
+ wpa_s->scan_res_handler = scanResJoinIgnore;
+ }
if (wpas_p2p_cancel(wpa_s)) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
@@ -1324,38 +1616,7 @@
return {SupplicantStatusCode::FAILURE_ARGS_INVALID, "passphrase is invalid."};
}
- if (joinExistingGroup) {
- struct wpa_bss *bss = findBssBySsid(
- wpa_s, peer_address.data(),
- ssid.data(), ssid.size());
- if (bss == NULL) {
- return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN,
- "No matched BSS found."};
- }
-
- // Construct a network for adding group.
- // Group client follows the persistent attribute of Group Owner.
- // If joined group is persistent, it adds a persistent network on GroupStarted.
- struct wpa_ssid *wpa_network = addGroupClientNetwork(
- wpa_s, bss->bssid, ssid, passphrase);
- if (wpa_network == NULL) {
- return {SupplicantStatusCode::FAILURE_UNKNOWN,
- "Cannot construct P2P network."};
- }
-
- // this is temporary network only for establishing the connection.
- wpa_network->temporary = 1;
-
- if (wpas_p2p_group_add_persistent(
- wpa_s, wpa_network, 0, 0, 0, 0, ht40, vht,
- VHT_CHANWIDTH_USE_HT, NULL, 0, 1)) {
- wpa_config_remove_network(wpa_s->conf, wpa_network->id);
- return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""};
- }
-
- // Always remove this temporary network at the end.
- wpa_config_remove_network(wpa_s->conf, wpa_network->id);
- } else {
+ if (!joinExistingGroup) {
if (wpa_s->global->p2p == NULL) {
return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
}
@@ -1370,10 +1631,94 @@
p2p->passphrase_set = 1;
if (wpas_p2p_group_add(
- wpa_s, persistent, freq, 0, ht40, vht,
- VHT_CHANWIDTH_USE_HT)) {
+ wpa_s, persistent, freq, 0, ht40, vht,
+ VHT_CHANWIDTH_USE_HT)) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
+ return {SupplicantStatusCode::SUCCESS, ""};
+ }
+
+ // The rest is for group join.
+ wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND before group join.");
+ wpas_p2p_stop_find(wpa_s);
+
+ struct wpa_bss *bss = findBssBySsid(
+ wpa_s, peer_address.data(),
+ ssid.data(), ssid.size());
+ if (bss != NULL) {
+ wpa_printf(MSG_DEBUG, "P2P: Join group with Group Owner " MACSTR,
+ MAC2STR(bss->bssid));
+ if (0 != joinGroup(wpa_s, bss->bssid, ssid, passphrase)) {
+ // no need to notify group join failure here,
+ // it will be handled by wpas_p2p_group_add_persistent
+ // called in joinGroup.
+ return {SupplicantStatusCode::FAILURE_UNKNOWN, "Failed to join a group."};
+ }
+ return {SupplicantStatusCode::SUCCESS, ""};
+ }
+
+ wpa_printf(MSG_INFO, "No matched BSS exists, try to find it by scan");
+
+ if (wpa_s->scan_res_handler) {
+ wpa_printf(MSG_WARNING, "There is on-going scanning, cannot start another scan.");
+ return {SupplicantStatusCode::FAILURE_UNKNOWN,
+ "Failed to start scan due to device busy."};
+ }
+
+ if (pending_scan_res_join_callback != NULL) {
+ wpa_printf(MSG_WARNING, "There is running group join scan.");
+ return {SupplicantStatusCode::FAILURE_UNKNOWN,
+ "Failed to start scan due to device busy."};
+ }
+
+ pending_join_scan_callback =
+ [wpa_s, ssid, freq]() {
+ if (0 != joinScanReq(wpa_s, ssid, freq)) {
+ notifyGroupJoinFailure(wpa_s);
+ pending_scan_res_join_callback = NULL;
+ }
+ };
+
+ pending_scan_res_join_callback = [wpa_s, ssid, passphrase, peer_address, this]() {
+ if (wpa_s->global->p2p_disabled) {
+ return;
+ }
+
+ wpa_printf(MSG_DEBUG, "P2P: Scan results received for join (reinvoke).");
+
+ struct wpa_bss *bss = findBssBySsid(
+ wpa_s, peer_address.data(), ssid.data(), ssid.size());
+ if (bss) {
+ if (0 != joinGroup(wpa_s, bss->bssid, ssid, passphrase)) {
+ wpa_printf(MSG_ERROR, "P2P: Failed to join a group.");
+ }
+ // no need to notify group join failure here,
+ // it will be handled by wpas_p2p_group_add_persistent
+ // called in joinGroup.
+ pending_scan_res_join_callback = NULL;
+ return;
+ }
+
+ wpa_s->p2p_join_scan_count++;
+ wpa_printf(MSG_DEBUG, "P2P: Join scan attempt %d.", wpa_s->p2p_join_scan_count);
+ eloop_cancel_timeout(joinScanWrapper, wpa_s, NULL);
+ if (wpa_s->p2p_join_scan_count <= P2P_MAX_JOIN_SCAN_ATTEMPTS) {
+ wpa_printf(MSG_DEBUG, "P2P: Try join again later.");
+ eloop_register_timeout(1, 0, joinScanWrapper, wpa_s, this);
+ return;
+ }
+
+ wpa_printf(MSG_ERROR, "P2P: Failed to find the group with "
+ "network name %s - stop join attempt",
+ ssid.data());
+ notifyGroupJoinFailure(wpa_s);
+ pending_scan_res_join_callback = NULL;
+ };
+
+ wpa_s->p2p_join_scan_count = 0;
+ if (0 != joinScanReq(wpa_s, ssid, freq)) {
+ pending_scan_res_join_callback = NULL;
+ return {SupplicantStatusCode::FAILURE_UNKNOWN, "Failed to start scan."};
}
return {SupplicantStatusCode::SUCCESS, ""};
}
@@ -1398,77 +1743,6 @@
return wpa_supplicant_get_iface(wpa_global_, group_ifname.c_str());
}
-struct wpa_ssid* P2pIface::addGroupClientNetwork(
- struct wpa_supplicant* wpa_s,
- uint8_t *group_owner_bssid,
- const std::vector<uint8_t>& ssid,
- const std::string& passphrase)
-{
- struct wpa_ssid* wpa_network = wpa_config_add_network(wpa_s->conf);
- if (!wpa_network) {
- return NULL;
- }
- // set general network defaults
- wpa_config_set_network_defaults(wpa_network);
-
- // set P2p network defaults
- wpa_network->p2p_group = 1;
- wpa_network->mode = wpa_ssid::wpas_mode::WPAS_MODE_INFRA;
-
- wpa_network->auth_alg = WPA_AUTH_ALG_OPEN;
- wpa_network->key_mgmt = WPA_KEY_MGMT_PSK;
- wpa_network->proto = WPA_PROTO_RSN;
- wpa_network->pairwise_cipher = WPA_CIPHER_CCMP;
- wpa_network->group_cipher = WPA_CIPHER_CCMP;
- wpa_network->disabled = 2;
-
- // set necessary fields
- os_memcpy(wpa_network->bssid, group_owner_bssid, ETH_ALEN);
- wpa_network->bssid_set = 1;
-
- wpa_network->ssid = (uint8_t *)os_malloc(ssid.size());
- if (wpa_network->ssid == NULL) {
- wpa_config_remove_network(wpa_s->conf, wpa_network->id);
- return NULL;
- }
- memcpy(wpa_network->ssid, ssid.data(), ssid.size());
- wpa_network->ssid_len = ssid.size();
-
- wpa_network->psk_set = 0;
- wpa_network->passphrase = dup_binstr(passphrase.c_str(), passphrase.length());
- if (wpa_network->passphrase == NULL) {
- wpa_config_remove_network(wpa_s->conf, wpa_network->id);
- return NULL;
- }
- wpa_config_update_psk(wpa_network);
-
- return wpa_network;
-
-}
-
-/**
- * findBssBySsid - Fetch a BSS table entry based on SSID and optional BSSID.
- * @wpa_s: Pointer to wpa_supplicant data
- * @bssid: BSSID, zero addr matches any bssid
- * @ssid: SSID
- * @ssid_len: Length of @ssid
- * Returns: Pointer to the BSS entry or %NULL if not found
- */
-struct wpa_bss* P2pIface::findBssBySsid(
- struct wpa_supplicant *wpa_s, const u8 *bssid,
- const u8 *ssid, size_t ssid_len)
-{
- struct wpa_bss *bss;
- dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
- if ((is_zero_ether_addr(bssid) ||
- os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) &&
- bss->ssid_len == ssid_len &&
- os_memcmp(bss->ssid, ssid, ssid_len) == 0)
- return bss;
- }
- return NULL;
-}
-
} // namespace implementation
} // namespace V1_2
} // namespace supplicant
diff --git a/wpa_supplicant/hidl/1.2/p2p_iface.h b/wpa_supplicant/hidl/1.2/p2p_iface.h
index a3ccdde..9b9da03 100644
--- a/wpa_supplicant/hidl/1.2/p2p_iface.h
+++ b/wpa_supplicant/hidl/1.2/p2p_iface.h
@@ -303,14 +303,6 @@
struct wpa_supplicant* retrieveIfacePtr();
struct wpa_supplicant* retrieveGroupIfacePtr(
const std::string& group_ifname);
- struct wpa_ssid* addGroupClientNetwork(
- struct wpa_supplicant* wpa_s,
- uint8_t *group_owner_bssid,
- const std::vector<uint8_t>& ssid,
- const std::string& passphrase);
- struct wpa_bss* findBssBySsid(
- struct wpa_supplicant *wpa_s, const u8 *bssid,
- const u8 *ssid, size_t ssid_len);
// Reference to the global wpa_struct. This is assumed to be valid for
// the lifetime of the process.
diff --git a/wpa_supplicant/hidl/1.2/sta_iface.cpp b/wpa_supplicant/hidl/1.2/sta_iface.cpp
index ae5fcbe..8c5178e 100644
--- a/wpa_supplicant/hidl/1.2/sta_iface.cpp
+++ b/wpa_supplicant/hidl/1.2/sta_iface.cpp
@@ -1187,6 +1187,14 @@
cmd += (own_bootstrap_id > 0) ?
" own=" + std::to_string(own_bootstrap_id) : "";
+ /* Check for supported AKMs */
+ if (security_akm != DppAkm::PSK && security_akm != DppAkm::SAE &&
+ security_akm != DppAkm::PSK_SAE) {
+ wpa_printf(MSG_ERROR, "DPP: Error: invalid AKM specified: %d",
+ security_akm);
+ return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
+ }
+
/* SAE AKM requires SSID and password to be initialized */
if ((security_akm == DppAkm::SAE ||
security_akm == DppAkm::PSK_SAE) &&
@@ -1204,9 +1212,6 @@
wpa_printf(MSG_ERROR, "DPP: Error: Password or PSK not specified");
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
- } else {
- wpa_printf(MSG_ERROR, "DPP: Error: invalid AKM specified");
- return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
cmd += " role=configurator";
diff --git a/wpa_supplicant/hidl/1.2/sta_network.cpp b/wpa_supplicant/hidl/1.2/sta_network.cpp
index 944c4a9..cf15909 100644
--- a/wpa_supplicant/hidl/1.2/sta_network.cpp
+++ b/wpa_supplicant/hidl/1.2/sta_network.cpp
@@ -34,7 +34,9 @@
static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::OSEN) |
static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::SAE) |
static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::SUITE_B_192) |
- static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::OWE));
+ static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::OWE) |
+ static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::WPA_PSK_SHA256) |
+ static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::WPA_EAP_SHA256));
constexpr uint32_t kAllowedProtoMask =
(static_cast<uint32_t>(ISupplicantStaNetwork::ProtoMask::WPA) |
static_cast<uint32_t>(ISupplicantStaNetwork::ProtoMask::RSN) |
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 37a4595..30bdb6d 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -1033,105 +1033,105 @@
/* DPP Success notifications */
-void wpas_notify_dpp_config_received(const char *ifname,
+void wpas_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid)
{
#ifdef CONFIG_DPP
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_config_received(ifname, ssid);
+ wpas_hidl_notify_dpp_config_received(wpa_s, ssid);
#endif /* CONFIG_DPP */
}
-void wpas_notify_dpp_config_sent(const char *ifname)
+void wpas_notify_dpp_config_sent(struct wpa_supplicant *wpa_s)
{
#ifdef CONFIG_DPP
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_config_sent(ifname);
+ wpas_hidl_notify_dpp_config_sent(wpa_s);
#endif /* CONFIG_DPP */
}
/* DPP Progress notifications */
-void wpas_notify_dpp_auth_success(const char *ifname)
+void wpas_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
{
#ifdef CONFIG_DPP
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_auth_success(ifname);
+ wpas_hidl_notify_dpp_auth_success(wpa_s);
#endif /* CONFIG_DPP */
}
-void wpas_notify_dpp_resp_pending(const char *ifname)
+void wpas_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s)
{
#ifdef CONFIG_DPP
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_resp_pending(ifname);
+ wpas_hidl_notify_dpp_resp_pending(wpa_s);
#endif /* CONFIG_DPP */
}
/* DPP Failure notifications */
-void wpas_notify_dpp_not_compatible(const char *ifname)
+void wpas_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s)
{
#ifdef CONFIG_DPP
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_not_compatible(ifname);
+ wpas_hidl_notify_dpp_not_compatible(wpa_s);
#endif /* CONFIG_DPP */
}
-void wpas_notify_dpp_missing_auth(const char *ifname)
+void wpas_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s)
{
#ifdef CONFIG_DPP
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_missing_auth(ifname);
+ wpas_hidl_notify_dpp_missing_auth(wpa_s);
#endif /* CONFIG_DPP */
}
-void wpas_notify_dpp_configuration_failure(const char *ifname)
+void wpas_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s)
{
#ifdef CONFIG_DPP
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_configuration_failure(ifname);
+ wpas_hidl_notify_dpp_configuration_failure(wpa_s);
#endif /* CONFIG_DPP */
}
-void wpas_notify_dpp_timeout(const char *ifname)
+void wpas_notify_dpp_timeout(struct wpa_supplicant *wpa_s)
{
#ifdef CONFIG_DPP
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_timeout(ifname);
+ wpas_hidl_notify_dpp_timeout(wpa_s);
#endif /* CONFIG_DPP */
}
-void wpas_notify_dpp_auth_failure(const char *ifname)
+void wpas_notify_dpp_auth_failure(struct wpa_supplicant *wpa_s)
{
#ifdef CONFIG_DPP
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_auth_failure(ifname);
+ wpas_hidl_notify_dpp_auth_failure(wpa_s);
#endif /* CONFIG_DPP */
}
-void wpas_notify_dpp_failure(const char *ifname)
+void wpas_notify_dpp_failure(struct wpa_supplicant *wpa_s)
{
#ifdef CONFIG_DPP
- if (!ifname)
+ if (!wpa_s)
return;
- wpas_hidl_notify_dpp_fail(ifname);
+ wpas_hidl_notify_dpp_fail(wpa_s);
#endif /* CONFIG_DPP */
}
diff --git a/wpa_supplicant/notify.h b/wpa_supplicant/notify.h
index b4cb476..703ef8f 100644
--- a/wpa_supplicant/notify.h
+++ b/wpa_supplicant/notify.h
@@ -167,16 +167,16 @@
void wpas_notify_hs20_rx_deauth_imminent_notice(struct wpa_supplicant *wpa_s,
u8 code, u16 reauth_delay,
const char *url);
-void wpas_notify_dpp_config_received(const char *ifname,
+void wpas_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
struct wpa_ssid *ssid);
-void wpas_notify_dpp_config_sent(const char *ifname);
-void wpas_notify_dpp_auth_success(const char *ifname);
-void wpas_notify_dpp_resp_pending(const char *ifname);
-void wpas_notify_dpp_not_compatible(const char *ifname);
-void wpas_notify_dpp_missing_auth(const char *ifname);
-void wpas_notify_dpp_configuration_failure(const char *ifname);
-void wpas_notify_dpp_timeout(const char *ifname);
-void wpas_notify_dpp_auth_failure(const char *ifname);
-void wpas_notify_dpp_failure(const char *ifname);
+void wpas_notify_dpp_config_sent(struct wpa_supplicant *wpa_s);
+void wpas_notify_dpp_auth_success(struct wpa_supplicant *wpa_s);
+void wpas_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s);
+void wpas_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s);
+void wpas_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s);
+void wpas_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s);
+void wpas_notify_dpp_timeout(struct wpa_supplicant *wpa_s);
+void wpas_notify_dpp_auth_failure(struct wpa_supplicant *wpa_s);
+void wpas_notify_dpp_failure(struct wpa_supplicant *wpa_s);
#endif /* NOTIFY_H */
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index b9b0bea..3d3296f 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -2075,6 +2075,17 @@
return -1;
}
+ if (wpa_s->conf->p2p_interface_random_mac_addr) {
+ if (random_mac_addr(wpa_s->pending_interface_addr) < 0) {
+ wpa_printf(MSG_ERROR, "P2P: Failed to generate random MAC address "
+ "for the group interface");
+ return -1;
+ }
+ wpa_printf(MSG_DEBUG, "P2P: Generate random MAC address " MACSTR " for the group",
+ MAC2STR(wpa_s->pending_interface_addr));
+ }
+
+
if (force_ifname[0]) {
wpa_printf(MSG_DEBUG, "P2P: Driver forced interface name %s",
force_ifname);
@@ -2153,6 +2164,25 @@
wpas_p2p_clone_config(group_wpa_s, wpa_s);
+ if (wpa_s->conf->p2p_interface_random_mac_addr) {
+ if (wpa_drv_set_mac_addr(group_wpa_s, wpa_s->pending_interface_addr) < 0) {
+ wpa_msg(group_wpa_s, MSG_INFO,
+ "Failed to set random MAC address");
+ wpa_supplicant_remove_iface(wpa_s->global, group_wpa_s, 0);
+ return NULL;
+ }
+
+ if (wpa_supplicant_update_mac_addr(group_wpa_s) < 0) {
+ wpa_msg(group_wpa_s, MSG_INFO,
+ "Could not update MAC address information");
+ wpa_supplicant_remove_iface(wpa_s->global, group_wpa_s, 0);
+ return NULL;
+ }
+
+ wpa_printf(MSG_DEBUG, "P2P: Using random MAC address " MACSTR " for the group",
+ MAC2STR(wpa_s->pending_interface_addr));
+ }
+
return group_wpa_s;
}
@@ -4314,6 +4344,57 @@
WPA_IF_P2P_CLIENT, len, freq_list);
}
+int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s)
+{
+ u8 addr[ETH_ALEN] = {0};
+
+ if (wpa_s->conf->p2p_device_random_mac_addr == 0)
+ return 0;
+
+ if (wpa_s->conf->ssid == NULL) {
+ if (random_mac_addr(addr) < 0) {
+ wpa_msg(wpa_s, MSG_INFO,
+ "Failed to generate random MAC address");
+ return -EINVAL;
+ }
+
+ // store generated MAC address.
+ if (wpa_s->conf->p2p_device_persistent_mac_addr)
+ os_free(wpa_s->conf->p2p_device_persistent_mac_addr);
+ size_t mac_addr_str_len = sizeof("00:00:00:00:00:00");
+ wpa_s->conf->p2p_device_persistent_mac_addr =
+ os_zalloc(mac_addr_str_len + 1);
+ os_snprintf(wpa_s->conf->p2p_device_persistent_mac_addr,
+ mac_addr_str_len, MACSTR, MAC2STR(addr));
+ } else {
+ // If there are existing saved groups, restore last MAC address.
+ // if there is no last used MAC address, the last one is factory MAC.
+ if (!wpa_s->conf->p2p_device_persistent_mac_addr)
+ return 0;
+
+ if (hwaddr_aton(wpa_s->conf->p2p_device_persistent_mac_addr, addr) < 0)
+ return -EINVAL;
+ wpa_msg(wpa_s, MSG_DEBUG, "Restore last used MAC address.");
+ }
+
+ if (wpa_drv_set_mac_addr(wpa_s, addr) < 0) {
+ wpa_msg(wpa_s, MSG_INFO,
+ "Failed to set random MAC address");
+ return -EINVAL;
+ }
+
+ if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
+ wpa_msg(wpa_s, MSG_INFO,
+ "Could not update MAC address information");
+ return -EINVAL;
+ }
+
+ wpa_msg(wpa_s, MSG_DEBUG, "Using random MAC address " MACSTR,
+ MAC2STR(addr));
+
+ return 0;
+}
+
/**
* wpas_p2p_init - Initialize P2P module for %wpa_supplicant
@@ -4335,6 +4416,12 @@
if (global->p2p)
return 0;
+ if (wpas_p2p_mac_setup(wpa_s) < 0) {
+ wpa_msg(wpa_s, MSG_ERROR,
+ "Failed to initialize P2P random MAC address.");
+ return -1;
+ }
+
os_memset(&p2p, 0, sizeof(p2p));
p2p.cb_ctx = wpa_s;
p2p.debug_print = wpas_p2p_debug_print;
diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h
index 63910d1..0a08a88 100644
--- a/wpa_supplicant/p2p_supplicant.h
+++ b/wpa_supplicant/p2p_supplicant.h
@@ -211,6 +211,7 @@
unsigned int period, unsigned int interval,
unsigned int count);
int wpas_p2p_lo_stop(struct wpa_supplicant *wpa_s);
+int wpas_p2p_mac_setup(struct wpa_supplicant *wpa_s);
#else /* CONFIG_P2P */