aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hostapd/Android.mk6
-rw-r--r--hostapd/hostapd.android.rc1
-rw-r--r--wpa_supplicant/hidl/1.0/hidl_manager.cpp4
-rw-r--r--wpa_supplicant/hidl/1.0/supplicant.cpp122
-rw-r--r--wpa_supplicant/hidl/1.0/supplicant.h1
-rw-r--r--wpa_supplicant/hidl/1.1/sta_network.cpp3
6 files changed, 134 insertions, 3 deletions
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index b4b0fea2..54d12f6c 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -46,11 +46,11 @@ L_CFLAGS += -DANDROID_LIB_STUB
endif
# Use Android specific directory for control interface sockets
-L_CFLAGS += -DCONFIG_CTRL_IFACE_CLIENT_DIR=\"/data/misc/wifi/sockets\"
-L_CFLAGS += -DCONFIG_CTRL_IFACE_DIR=\"/data/system/hostapd\"
+L_CFLAGS += -DCONFIG_CTRL_IFACE_CLIENT_DIR=\"/data/vendor/wifi/hostapd/sockets\"
+L_CFLAGS += -DCONFIG_CTRL_IFACE_DIR=\"/data/vendor/wifi/hostapd/ctrl\"
# Use Android specific directory for hostapd_cli command completion history
-L_CFLAGS += -DCONFIG_HOSTAPD_CLI_HISTORY_DIR=\"/data/misc/wifi\"
+L_CFLAGS += -DCONFIG_HOSTAPD_CLI_HISTORY_DIR=\"/data/vendor/wifi/hostapd\"
# To force sizeof(enum) = 4
ifeq ($(TARGET_ARCH),arm)
diff --git a/hostapd/hostapd.android.rc b/hostapd/hostapd.android.rc
index 70158c6f..37a95c22 100644
--- a/hostapd/hostapd.android.rc
+++ b/hostapd/hostapd.android.rc
@@ -9,6 +9,7 @@
on post-fs-data
mkdir /data/vendor/wifi 0770 wifi wifi
mkdir /data/vendor/wifi/hostapd 0770 wifi wifi
+ mkdir /data/vendor/wifi/hostapd/sockets 0770 wifi wifi
service hostapd /vendor/bin/hw/hostapd
interface android.hardware.wifi.hostapd@1.0::IHostapd default
diff --git a/wpa_supplicant/hidl/1.0/hidl_manager.cpp b/wpa_supplicant/hidl/1.0/hidl_manager.cpp
index 152203c9..4655da2c 100644
--- a/wpa_supplicant/hidl/1.0/hidl_manager.cpp
+++ b/wpa_supplicant/hidl/1.0/hidl_manager.cpp
@@ -395,6 +395,10 @@ int HidlManager::registerHidlService(struct wpa_global *global)
if (supplicant_object_->registerAsService() != android::NO_ERROR) {
return 1;
}
+ if (!supplicant_object_->ensureConfigFileExists()) {
+ // If config file does not exist, we cannot start supplicant.
+ return 1;
+ }
return 0;
}
diff --git a/wpa_supplicant/hidl/1.0/supplicant.cpp b/wpa_supplicant/hidl/1.0/supplicant.cpp
index a3815116..bf009b52 100644
--- a/wpa_supplicant/hidl/1.0/supplicant.cpp
+++ b/wpa_supplicant/hidl/1.0/supplicant.cpp
@@ -11,6 +11,110 @@
#include "hidl_return_util.h"
#include "supplicant.h"
+#include <android-base/file.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+namespace {
+constexpr char kStaIfaceConfPath[] =
+ "/data/misc/wifi/wpa_supplicant.conf";
+constexpr char kP2pIfaceConfPath[] =
+ "/data/misc/wifi/p2p_supplicant.conf";
+// Migrate conf files for existing devices.
+constexpr char kTemplateConfPath[] =
+ "/vendor/etc/wifi/wpa_supplicant.conf";
+constexpr mode_t kConfigFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
+
+int copyFile(
+ const std::string& src_file_path, const std::string& dest_file_path)
+{
+ std::string file_contents;
+ if (!android::base::ReadFileToString(src_file_path, &file_contents)) {
+ wpa_printf(
+ MSG_ERROR, "Failed to read from %s. Errno: %s",
+ src_file_path.c_str(), strerror(errno));
+ return -1;
+ }
+ if (!android::base::WriteStringToFile(
+ file_contents, dest_file_path, kConfigFileMode, getuid(),
+ getgid())) {
+ wpa_printf(
+ MSG_ERROR, "Failed to write to %s. Errno: %s",
+ dest_file_path.c_str(), strerror(errno));
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * Copy |src_file_path| to |dest_file_path| if it exists.
+ *
+ * Returns 1 if |src_file_path| does not exists,
+ * Returns -1 if the copy fails.
+ * Returns 0 if the copy succeeds.
+ */
+int copyFileIfItExists(
+ const std::string& src_file_path, const std::string& dest_file_path)
+{
+ int ret = access(src_file_path.c_str(), R_OK);
+ if ((ret != 0) && (errno == ENOENT)) {
+ return 1;
+ }
+ ret = copyFile(src_file_path, dest_file_path);
+ if (ret != 0) {
+ wpa_printf(
+ MSG_ERROR, "Failed copying %s to %s.",
+ src_file_path.c_str(), dest_file_path.c_str());
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * Ensure that the specified config file pointed by |config_file_path| exists.
+ * a) If the |config_file_path| exists with the correct permissions, return.
+ * b) If the |config_file_path| does not exists, copy over the contents of
+ * |template_config_file_path|.
+ */
+int copyTemplateConfigFileIfNotExists(
+ const std::string& config_file_path,
+ const std::string& template_config_file_path)
+{
+ int ret = access(config_file_path.c_str(), R_OK | W_OK);
+ if (ret == 0) {
+ return 0;
+ }
+ if (errno == EACCES) {
+ ret = chmod(config_file_path.c_str(), kConfigFileMode);
+ if (ret == 0) {
+ return 0;
+ } else {
+ wpa_printf(
+ MSG_ERROR, "Cannot set RW to %s. Errno: %s",
+ config_file_path.c_str(), strerror(errno));
+ return -1;
+ }
+ } else if (errno != ENOENT) {
+ wpa_printf(
+ MSG_ERROR, "Cannot acces %s. Errno: %s",
+ config_file_path.c_str(), strerror(errno));
+ return -1;
+ }
+ ret = copyFileIfItExists(template_config_file_path, config_file_path);
+ if (ret == 0) {
+ wpa_printf(
+ MSG_INFO, "Copied template conf file from %s to %s",
+ template_config_file_path.c_str(), config_file_path.c_str());
+ return 0;
+ } else if (ret == -1) {
+ unlink(config_file_path.c_str());
+ return -1;
+ }
+ // Did not create the conf file.
+ return -1;
+}
+} // namespace
+
namespace android {
namespace hardware {
namespace wifi {
@@ -31,6 +135,24 @@ bool Supplicant::isValid()
return true;
}
+bool Supplicant::ensureConfigFileExists()
+{
+ // To support Android P Wifi framework, make sure the config file exists.
+ if (copyTemplateConfigFileIfNotExists(
+ kStaIfaceConfPath, kTemplateConfPath) != 0) {
+ wpa_printf(MSG_ERROR, "Conf file does not exists: %s",
+ kStaIfaceConfPath);
+ return false;
+ }
+ // P2P configuration file is not madatory but required for some devices.
+ if (copyTemplateConfigFileIfNotExists(
+ kP2pIfaceConfPath, kTemplateConfPath) != 0) {
+ wpa_printf(MSG_INFO, "Conf file does not exists: %s",
+ kP2pIfaceConfPath);
+ }
+ return true;
+}
+
Return<void> Supplicant::getInterface(
const IfaceInfo& iface_info, getInterface_cb _hidl_cb)
{
diff --git a/wpa_supplicant/hidl/1.0/supplicant.h b/wpa_supplicant/hidl/1.0/supplicant.h
index 1ad84024..04d1ae17 100644
--- a/wpa_supplicant/hidl/1.0/supplicant.h
+++ b/wpa_supplicant/hidl/1.0/supplicant.h
@@ -40,6 +40,7 @@ public:
Supplicant(struct wpa_global* global);
~Supplicant() override = default;
bool isValid();
+ bool ensureConfigFileExists();
// Hidl methods exposed.
Return<void> getInterface(
diff --git a/wpa_supplicant/hidl/1.1/sta_network.cpp b/wpa_supplicant/hidl/1.1/sta_network.cpp
index e50927fd..9d4cc913 100644
--- a/wpa_supplicant/hidl/1.1/sta_network.cpp
+++ b/wpa_supplicant/hidl/1.1/sta_network.cpp
@@ -1528,6 +1528,9 @@ SupplicantStatus StaNetwork::selectInternal()
struct wpa_supplicant *wpa_s = retrieveIfacePtr();
wpa_s->scan_min_time.sec = 0;
wpa_s->scan_min_time.usec = 0;
+ // Make sure that the supplicant is updated to the latest
+ // MAC address, which might have changed due to MAC randomization.
+ wpa_supplicant_update_mac_addr(wpa_s);
wpa_supplicant_select_network(wpa_s, wpa_ssid);
return {SupplicantStatusCode::SUCCESS, ""};
}