diff options
-rw-r--r-- | hostapd/Android.mk | 6 | ||||
-rw-r--r-- | hostapd/hostapd.android.rc | 1 | ||||
-rw-r--r-- | wpa_supplicant/hidl/1.0/hidl_manager.cpp | 4 | ||||
-rw-r--r-- | wpa_supplicant/hidl/1.0/supplicant.cpp | 122 | ||||
-rw-r--r-- | wpa_supplicant/hidl/1.0/supplicant.h | 1 | ||||
-rw-r--r-- | wpa_supplicant/hidl/1.1/sta_network.cpp | 3 |
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, ""}; } |