aboutsummaryrefslogtreecommitdiff
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJustin Yun <justinyun@google.com>2018-04-03 18:16:11 +0900
committerJustin Yun <justinyun@google.com>2018-04-04 08:33:01 +0900
commit03dbff0b876bf0a54d08e17e14625edff0678154 (patch)
tree2b1b9c9315ca55b23b1c6de401219120e611482c /wpa_supplicant
parenteb93ab81f4753a0fcc8f2e5c12d12c27ffde7f2a (diff)
downloadwpa_supplicant_8-03dbff0b876bf0a54d08e17e14625edff0678154.tar.gz
Ensure config file for wpa_supplicant exists
Add ensuring the configuration file for wpa_supplicant hidl 1.0. When initializing hidl service, supplicant will copy the template configuration file if the configuration file is not exist. Bug: 74504608 Test: Wi-Fi is successfully turned on. Change-Id: I1c62ecf898445d2ddfb1efd26b2b0862e5ff87ff Merged-In: I1c62ecf898445d2ddfb1efd26b2b0862e5ff87ff (cherry picked from commit f5ff1e139e718d9c76edc2d8a11807936778ad97)
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/Android.mk3
-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
4 files changed, 129 insertions, 1 deletions
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 2d87f750..df278351 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -1723,7 +1723,7 @@ LOCAL_SHARED_LIBRARIES += libdbus
endif
ifeq ($(WPA_SUPPLICANT_USE_HIDL), y)
LOCAL_SHARED_LIBRARIES += android.hardware.wifi.supplicant@1.0
-LOCAL_SHARED_LIBRARIES += libhidlbase libhidltransport libhwbinder libutils
+LOCAL_SHARED_LIBRARIES += libhidlbase libhidltransport libhwbinder libutils libbase
LOCAL_STATIC_LIBRARIES += libwpa_hidl
endif
include $(BUILD_EXECUTABLE)
@@ -1785,6 +1785,7 @@ LOCAL_SRC_FILES := \
hidl/$(HIDL_INTERFACE_VERSION)/supplicant.cpp
LOCAL_SHARED_LIBRARIES := \
android.hardware.wifi.supplicant@$(HIDL_INTERFACE_VERSION) \
+ libbase \
libhidlbase \
libhidltransport \
libhwbinder \
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(