wpa_supplicant(hidl): Support add/remove interfaces
Add HIDL API's for adding/removing interfaces dynamically.
These interface params are pixel specific, so other OEM's will need to
modify the params to suit their device configuration.
Bug: 65673678
Test: VTS tests
Change-Id: I41d3452652bb2e2139aad4670b71c07fab4c574d
diff --git a/wpa_supplicant/hidl/1.1/supplicant.cpp b/wpa_supplicant/hidl/1.1/supplicant.cpp
index 9d2dac7..950f0c7 100644
--- a/wpa_supplicant/hidl/1.1/supplicant.cpp
+++ b/wpa_supplicant/hidl/1.1/supplicant.cpp
@@ -11,6 +11,20 @@
#include "hidl_return_util.h"
#include "supplicant.h"
+namespace {
+// Pre-populated interface params for interfaces controlled by wpa_supplicant.
+// Note: This may differ for other OEM's. So, modify this accordingly.
+constexpr char kIfaceDriverName[] = "nl80211";
+constexpr char kStaIfaceConfPath[] =
+ "/data/misc/wifi/wpa_supplicant.conf";
+constexpr char kStaIfaceConfOverlayPath[] =
+ "/vendor/etc/wifi/wpa_supplicant_overlay.conf";
+constexpr char kP2pIfaceConfPath[] =
+ "/data/misc/wifi/p2p_supplicant.conf";
+constexpr char kP2pIfaceConfOverlayPath[] =
+ "/vendor/etc/wifi/p2p_supplicant_overlay.conf";
+} // namespace
+
namespace android {
namespace hardware {
namespace wifi {
@@ -19,11 +33,6 @@
namespace implementation {
using hidl_return_util::validateAndCall;
-// These are hardcoded for android.
-const char Supplicant::kDriverName[] = "nl80211";
-const char Supplicant::kConfigFilePath[] =
- "/data/misc/wifi/wpa_supplicant.conf";
-
Supplicant::Supplicant(struct wpa_global* global) : wpa_global_(global) {}
bool Supplicant::isValid()
{
@@ -31,6 +40,22 @@
return true;
}
+Return<void> Supplicant::addInterface(
+ const IfaceInfo& iface_info, addInterface_cb _hidl_cb)
+{
+ return validateAndCall(
+ this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+ &Supplicant::addInterfaceInternal, _hidl_cb, iface_info);
+}
+
+Return<void> Supplicant::removeInterface(
+ const IfaceInfo& iface_info, removeInterface_cb _hidl_cb)
+{
+ return validateAndCall(
+ this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+ &Supplicant::removeInterfaceInternal, _hidl_cb, iface_info);
+}
+
Return<void> Supplicant::getInterface(
const IfaceInfo& iface_info, getInterface_cb _hidl_cb)
{
@@ -94,6 +119,58 @@
}
std::pair<SupplicantStatus, sp<ISupplicantIface>>
+Supplicant::addInterfaceInternal(const IfaceInfo& iface_info)
+{
+ android::sp<ISupplicantIface> iface;
+
+ // Check if required |ifname| argument is empty.
+ if (iface_info.name.empty()) {
+ return {{SupplicantStatusCode::FAILURE_ARGS_INVALID, ""}, {}};
+ }
+ // Try to get the wpa_supplicant record for this iface, return
+ // the iface object with the appropriate status code if it exists.
+ SupplicantStatus status;
+ std::tie(status, iface) = getInterfaceInternal(iface_info);
+ if (status.code == SupplicantStatusCode::SUCCESS) {
+ return {{SupplicantStatusCode::FAILURE_IFACE_EXISTS, ""},
+ iface};
+ }
+
+ struct wpa_interface iface_params = {};
+ iface_params.driver = kIfaceDriverName;
+ if (iface_info.type == IfaceType::P2P) {
+ iface_params.confname = kP2pIfaceConfPath;
+ iface_params.confanother = kP2pIfaceConfOverlayPath;
+ } else {
+ iface_params.confname = kStaIfaceConfPath;
+ iface_params.confanother = kStaIfaceConfOverlayPath;
+ }
+ iface_params.ifname = iface_info.name.c_str();
+ struct wpa_supplicant* wpa_s =
+ wpa_supplicant_add_iface(wpa_global_, &iface_params, NULL);
+ if (!wpa_s) {
+ return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
+ }
+ // The supplicant core creates a corresponding hidl object via
+ // HidlManager when |wpa_supplicant_add_iface| is called.
+ return getInterfaceInternal(iface_info);
+}
+
+SupplicantStatus Supplicant::removeInterfaceInternal(
+ const IfaceInfo& iface_info)
+{
+ struct wpa_supplicant* wpa_s =
+ wpa_supplicant_get_iface(wpa_global_, iface_info.name.c_str());
+ if (!wpa_s) {
+ return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
+ }
+ if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0)) {
+ return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
+ }
+ return {SupplicantStatusCode::SUCCESS, ""};
+}
+
+std::pair<SupplicantStatus, sp<ISupplicantIface>>
Supplicant::getInterfaceInternal(const IfaceInfo& iface_info)
{
struct wpa_supplicant* wpa_s =
diff --git a/wpa_supplicant/hidl/1.1/supplicant.h b/wpa_supplicant/hidl/1.1/supplicant.h
index b14065f..75fb0db 100644
--- a/wpa_supplicant/hidl/1.1/supplicant.h
+++ b/wpa_supplicant/hidl/1.1/supplicant.h
@@ -44,6 +44,10 @@
bool isValid();
// Hidl methods exposed.
+ Return<void> addInterface(
+ const IfaceInfo& iface_info, addInterface_cb _hidl_cb) override;
+ Return<void> removeInterface(
+ const IfaceInfo& iface_info, removeInterface_cb _hidl_cb) override;
Return<void> getInterface(
const IfaceInfo& iface_info, getInterface_cb _hidl_cb) override;
Return<void> listInterfaces(listInterfaces_cb _hidl_cb) override;
@@ -63,6 +67,9 @@
// Corresponding worker functions for the HIDL methods.
std::pair<SupplicantStatus, sp<ISupplicantIface>> getInterfaceInternal(
const IfaceInfo& iface_info);
+ std::pair<SupplicantStatus, sp<ISupplicantIface>> addInterfaceInternal(
+ const IfaceInfo& iface_info);
+ SupplicantStatus removeInterfaceInternal(const IfaceInfo& iface_info);
std::pair<SupplicantStatus, std::vector<ISupplicant::IfaceInfo>>
listInterfacesInternal();
SupplicantStatus registerCallbackInternal(