1 /*
2 * WPA Supplicant - Mainline supplicant service
3 * Copyright (c) 2024, Google Inc. All rights reserved.
4 *
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
7 */
8
9 #include <android/binder_manager.h>
10 #include <android/binder_process.h>
11
12 #include "mainline_supplicant.h"
13
14 extern "C"
15 {
16 #include "aidl_i.h"
17 #include "service.h"
18 #include "utils/common.h"
19 #include "utils/eloop.h"
20 #include "utils/includes.h"
21 #include "utils/wpa_debug.h"
22 }
23
24 using ::ndk::SharedRefBase;
25
26 /* Handler for requests to the service */
aidl_sock_handler(int,void *,void *)27 void aidl_sock_handler(int /* sock */, void * /* eloop_ctx */, void * /* sock_ctx */) {
28 // Suppress warning, since this service is only available after Android V
29 if (__builtin_available(android __ANDROID_API_V__, *)) {
30 ABinderProcess_handlePolledCommands();
31 }
32 }
33
register_service(struct wpa_global * global)34 bool register_service(struct wpa_global *global) {
35 wpa_printf(MSG_INFO, "Registering as a lazy service");
36 std::string service_name = "wifi_mainline_supplicant";
37 std::shared_ptr<MainlineSupplicant> service = SharedRefBase::make<MainlineSupplicant>(global);
38
39 // Suppress warning, since this service is only available after Android V
40 if (__builtin_available(android __ANDROID_API_V__, *)) {
41 int status =
42 AServiceManager_registerLazyService(service->asBinder().get(), service_name.c_str());
43 if (status != EX_NONE) {
44 wpa_printf(MSG_ERROR, "Registration failed with status %d", status);
45 }
46 return status == EX_NONE;
47 }
48 return false;
49 }
50
mainline_aidl_init(struct wpa_global * global)51 struct wpas_aidl_priv *mainline_aidl_init(struct wpa_global *global) {
52 wpa_printf(MSG_INFO, "Initializing the mainline supplicant service");
53 struct wpas_aidl_priv *priv = (wpas_aidl_priv *)os_zalloc(sizeof(*priv));
54 if (!priv) {
55 wpa_printf(MSG_ERROR, "Unable to allocate the global AIDL object");
56 return NULL;
57 }
58 priv->global = global;
59
60 // Suppress warning, since this service is only available after Android V
61 if (__builtin_available(android __ANDROID_API_V__, *)) {
62 ABinderProcess_setupPolling(&priv->aidl_fd);
63 }
64 if (priv->aidl_fd < 0) {
65 wpa_printf(MSG_ERROR, "Unable to set up polling");
66 mainline_aidl_deinit(priv);
67 return NULL;
68 }
69
70 if (eloop_register_read_sock(priv->aidl_fd, aidl_sock_handler, global, priv) < 0) {
71 wpa_printf(MSG_ERROR, "Unable to register eloop read socket");
72 mainline_aidl_deinit(priv);
73 return NULL;
74 }
75
76 if (!register_service(global)) {
77 wpa_printf(MSG_ERROR, "Unable to register service");
78 mainline_aidl_deinit(priv);
79 return NULL;
80 }
81
82 wpa_printf(MSG_INFO, "AIDL setup is complete");
83 return priv;
84 }
85
mainline_aidl_deinit(struct wpas_aidl_priv * priv)86 void mainline_aidl_deinit(struct wpas_aidl_priv *priv) {
87 if (!priv) return;
88 wpa_printf(MSG_INFO, "Deiniting the mainline supplicant service");
89 eloop_unregister_read_sock(priv->aidl_fd);
90 os_free(priv);
91 }
92