Add initial implementation for the mainline
supplicant service.
This provides the initialization and teardown
logic, as well as an implementation of the
current AIDL interface.
Bug: 365585450
Test: Manual test - Retrieve service in the
framework and call the terminate method.
Change-Id: I30e5e4dbaf9cd5c13955045d3dc73fad4f0e3c1b
diff --git a/wpa_supplicant/aidl/mainline/mainline_supplicant.cpp b/wpa_supplicant/aidl/mainline/mainline_supplicant.cpp
new file mode 100644
index 0000000..97ad056
--- /dev/null
+++ b/wpa_supplicant/aidl/mainline/mainline_supplicant.cpp
@@ -0,0 +1,21 @@
+/*
+ * WPA Supplicant - Mainline supplicant AIDL implementation
+ * Copyright (c) 2024, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "mainline_supplicant.h"
+
+using ::ndk::ScopedAStatus;
+
+MainlineSupplicant::MainlineSupplicant(struct wpa_global* global) {
+ wpa_global_ = global;
+}
+
+ndk::ScopedAStatus MainlineSupplicant::terminate() {
+ wpa_printf(MSG_INFO, "Terminating...");
+ wpa_supplicant_terminate_proc(wpa_global_);
+ return ndk::ScopedAStatus::ok();
+}
diff --git a/wpa_supplicant/aidl/mainline/mainline_supplicant.h b/wpa_supplicant/aidl/mainline/mainline_supplicant.h
new file mode 100644
index 0000000..4cdc9c8
--- /dev/null
+++ b/wpa_supplicant/aidl/mainline/mainline_supplicant.h
@@ -0,0 +1,34 @@
+/*
+ * WPA Supplicant - Mainline supplicant AIDL implementation
+ * Copyright (c) 2024, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef MAINLINE_SUPPLICANT_IMPL_H
+#define MAINLINE_SUPPLICANT_IMPL_H
+
+#include <aidl/android/system/wifi/mainline_supplicant/BnMainlineSupplicant.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "utils/wpa_debug.h"
+#include "wpa_supplicant_i.h"
+}
+
+using ::aidl::android::system::wifi::mainline_supplicant::BnMainlineSupplicant;
+
+class MainlineSupplicant : public BnMainlineSupplicant {
+ public:
+ MainlineSupplicant(struct wpa_global* global);
+ ndk::ScopedAStatus terminate();
+
+ private:
+ // Raw pointer to the global structure maintained by the core
+ struct wpa_global* wpa_global_;
+};
+
+#endif // MAINLINE_SUPPLICANT_IMPL_H
diff --git a/wpa_supplicant/aidl/mainline/service.cpp b/wpa_supplicant/aidl/mainline/service.cpp
new file mode 100644
index 0000000..da343ea
--- /dev/null
+++ b/wpa_supplicant/aidl/mainline/service.cpp
@@ -0,0 +1,91 @@
+/*
+ * WPA Supplicant - Mainline supplicant service
+ * Copyright (c) 2024, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include <android/binder_manager.h>
+#include <android/binder_process.h>
+
+#include "mainline_supplicant.h"
+
+extern "C"
+{
+#include "aidl_i.h"
+#include "service.h"
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "utils/includes.h"
+#include "utils/wpa_debug.h"
+}
+
+using ::ndk::SharedRefBase;
+
+/* Handler for requests to the service */
+void aidl_sock_handler(int /* sock */, void * /* eloop_ctx */, void * /* sock_ctx */) {
+ // Suppress warning, since this service is only available after Android V
+ if (__builtin_available(android __ANDROID_API_V__, *)) {
+ ABinderProcess_handlePolledCommands();
+ }
+}
+
+bool register_service(struct wpa_global *global) {
+ wpa_printf(MSG_INFO, "Registering as a lazy service");
+ std::string service_name = "wifi_mainline_supplicant";
+ std::shared_ptr<MainlineSupplicant> service = SharedRefBase::make<MainlineSupplicant>(global);
+
+ // Suppress warning, since this service is only available after Android V
+ if (__builtin_available(android __ANDROID_API_V__, *)) {
+ int status =
+ AServiceManager_registerLazyService(service->asBinder().get(), service_name.c_str());
+ if (status != EX_NONE) {
+ wpa_printf(MSG_ERROR, "Registration failed with status %d", status);
+ }
+ return status == EX_NONE;
+ }
+ return false;
+}
+
+struct wpas_aidl_priv *mainline_aidl_init(struct wpa_global *global) {
+ wpa_printf(MSG_INFO, "Initializing the mainline supplicant service");
+ struct wpas_aidl_priv *priv = (wpas_aidl_priv *)os_zalloc(sizeof(*priv));
+ if (!priv) {
+ wpa_printf(MSG_ERROR, "Unable to allocate the global AIDL object");
+ return NULL;
+ }
+ priv->global = global;
+
+ // Suppress warning, since this service is only available after Android V
+ if (__builtin_available(android __ANDROID_API_V__, *)) {
+ ABinderProcess_setupPolling(&priv->aidl_fd);
+ }
+ if (priv->aidl_fd < 0) {
+ wpa_printf(MSG_ERROR, "Unable to set up polling");
+ mainline_aidl_deinit(priv);
+ return NULL;
+ }
+
+ if (eloop_register_read_sock(priv->aidl_fd, aidl_sock_handler, global, priv) < 0) {
+ wpa_printf(MSG_ERROR, "Unable to register eloop read socket");
+ mainline_aidl_deinit(priv);
+ return NULL;
+ }
+
+ if (!register_service(global)) {
+ wpa_printf(MSG_ERROR, "Unable to register service");
+ mainline_aidl_deinit(priv);
+ return NULL;
+ }
+
+ wpa_printf(MSG_INFO, "AIDL setup is complete");
+ return priv;
+}
+
+void mainline_aidl_deinit(struct wpas_aidl_priv *priv) {
+ if (!priv) return;
+ wpa_printf(MSG_INFO, "Deiniting the mainline supplicant service");
+ eloop_unregister_read_sock(priv->aidl_fd);
+ os_free(priv);
+}
diff --git a/wpa_supplicant/aidl/mainline/service.h b/wpa_supplicant/aidl/mainline/service.h
new file mode 100644
index 0000000..6d213e7
--- /dev/null
+++ b/wpa_supplicant/aidl/mainline/service.h
@@ -0,0 +1,27 @@
+/*
+ * WPA Supplicant - Mainline supplicant service
+ * Copyright (c) 2024, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef MAINLINE_SUPPLICANT_SERVICE_H
+#define MAINLINE_SUPPLICANT_SERVICE_H
+
+#ifdef _cplusplus
+extern "C"
+{
+#endif // _cplusplus
+
+struct wpas_aidl_priv;
+struct wpa_global;
+
+struct wpas_aidl_priv *mainline_aidl_init(struct wpa_global *global);
+void mainline_aidl_deinit(struct wpas_aidl_priv *priv);
+
+#ifdef _cplusplus
+}
+#endif // _cplusplus
+
+#endif // MAINLINE_SUPPLICANT_SERVICE_H
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index c1258a8..1fb2628 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -28,6 +28,10 @@
#include "notify.h"
#include "aidl/vendor/aidl.h"
+#ifdef MAINLINE_SUPPLICANT
+#include "aidl/mainline/service.h"
+#endif
+
int wpas_notify_supplicant_initialized(struct wpa_global *global)
{
#ifdef CONFIG_CTRL_IFACE_DBUS_NEW
@@ -48,6 +52,12 @@
}
#endif /* CONFIG_AIDL */
+#ifdef MAINLINE_SUPPLICANT
+ global->aidl = mainline_aidl_init(global);
+ if (!global->aidl)
+ return -1;
+#endif /* MAINLINE_SUPPLICANT */
+
return 0;
}
@@ -63,6 +73,12 @@
if (global->aidl)
wpas_aidl_deinit(global->aidl);
#endif /* CONFIG_AIDL */
+
+#ifdef MAINLINE_SUPPLICANT
+ if (global->aidl)
+ mainline_aidl_deinit(global->aidl);
+#endif /* MAINLINE_SUPPLICANT */
+
}