hostapd(hidl): Add asynchronous failure callback
Changes in the CL:
a) Add a new callback registration mechanism for the hostapd HIDL interface.
b) Use the existing |setup_complete_cb| callback provided by the hostapd
core to trigger the new onFailure() HIDL callback.
Bug: 112705137
Test: Manual test. Simulated the issue reported in the bug and ensured
that UI toggled off.
Change-Id: I7211e313c107be3a4a7a52af69ffe1e565b5147b
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index ce4fc84..93c8d80 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -1136,6 +1136,7 @@
endif
ifeq ($(HOSTAPD_USE_HIDL), y)
LOCAL_SHARED_LIBRARIES += android.hardware.wifi.hostapd@1.0
+LOCAL_SHARED_LIBRARIES += android.hardware.wifi.hostapd@1.1
LOCAL_SHARED_LIBRARIES += libbase libhidlbase libhidltransport libhwbinder libutils
LOCAL_STATIC_LIBRARIES += libhostapd_hidl
endif
@@ -1178,12 +1179,13 @@
LOCAL_CPPFLAGS := $(L_CPPFLAGS)
LOCAL_CFLAGS := $(L_CFLAGS)
LOCAL_C_INCLUDES := $(INCLUDES)
-HIDL_INTERFACE_VERSION = 1.0
+HIDL_INTERFACE_VERSION = 1.1
LOCAL_SRC_FILES := \
hidl/$(HIDL_INTERFACE_VERSION)/hidl.cpp \
hidl/$(HIDL_INTERFACE_VERSION)/hostapd.cpp
LOCAL_SHARED_LIBRARIES := \
android.hardware.wifi.hostapd@1.0 \
+ android.hardware.wifi.hostapd@1.1 \
libbase \
libhidlbase \
libhidltransport \
diff --git a/hostapd/hidl/1.0/hidl.cpp b/hostapd/hidl/1.1/hidl.cpp
similarity index 93%
rename from hostapd/hidl/1.0/hidl.cpp
rename to hostapd/hidl/1.1/hidl.cpp
index a0dc50e..2051e7b 100644
--- a/hostapd/hidl/1.0/hidl.cpp
+++ b/hostapd/hidl/1.1/hidl.cpp
@@ -22,8 +22,8 @@
using android::hardware::configureRpcThreadpool;
using android::hardware::IPCThreadState;
-using android::hardware::wifi::hostapd::V1_0::IHostapd;
-using android::hardware::wifi::hostapd::V1_0::implementation::Hostapd;
+using android::hardware::wifi::hostapd::V1_1::IHostapd;
+using android::hardware::wifi::hostapd::V1_1::implementation::Hostapd;
// This file is a bridge between the hostapd code written in 'C' and the HIDL
// interface in C++. So, using "C" style static globals here!
diff --git a/hostapd/hidl/1.0/hidl.h b/hostapd/hidl/1.1/hidl.h
similarity index 100%
rename from hostapd/hidl/1.0/hidl.h
rename to hostapd/hidl/1.1/hidl.h
diff --git a/hostapd/hidl/1.0/hidl_return_util.h b/hostapd/hidl/1.1/hidl_return_util.h
similarity index 96%
rename from hostapd/hidl/1.0/hidl_return_util.h
rename to hostapd/hidl/1.1/hidl_return_util.h
index 1625dc2..d914ee2 100644
--- a/hostapd/hidl/1.0/hidl_return_util.h
+++ b/hostapd/hidl/1.1/hidl_return_util.h
@@ -16,7 +16,7 @@
namespace hardware {
namespace wifi {
namespace hostapd {
-namespace V1_0 {
+namespace V1_1 {
namespace implementation {
namespace hidl_return_util {
@@ -36,7 +36,7 @@
} // namespace hidl_return_util
} // namespace implementation
-} // namespace V1_0
+} // namespace V1_1
} // namespace hostapd
} // namespace wifi
} // namespace hardware
diff --git a/hostapd/hidl/1.0/hostapd.cpp b/hostapd/hidl/1.1/hostapd.cpp
similarity index 81%
rename from hostapd/hidl/1.0/hostapd.cpp
rename to hostapd/hidl/1.1/hostapd.cpp
index 3cd78b3..340b22c 100644
--- a/hostapd/hidl/1.0/hostapd.cpp
+++ b/hostapd/hidl/1.1/hostapd.cpp
@@ -33,7 +33,7 @@
using android::base::RemoveFileIfExists;
using android::base::StringPrintf;
using android::base::WriteStringToFile;
-using android::hardware::wifi::hostapd::V1_0::IHostapd;
+using android::hardware::wifi::hostapd::V1_1::IHostapd;
std::string WriteHostapdConfig(
const std::string& interface_name, const std::string& config)
@@ -187,15 +187,35 @@
hw_mode_as_string.c_str(), ht_cap_vht_oper_chwidth_as_string.c_str(),
nw_params.isHidden ? 1 : 0, encryption_config_as_string.c_str());
}
+
+// hostapd core functions accept "C" style function pointers, so use global
+// functions to pass to the hostapd core function and store the corresponding
+// std::function methods to be invoked.
+//
+// NOTE: Using the pattern from the vendor HAL (wifi_legacy_hal.cpp).
+//
+// Callback to be invoked once setup is complete
+std::function<void(struct hostapd_data*)> on_setup_complete_internal_callback;
+void onAsyncSetupCompleteCb(void* ctx)
+{
+ struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
+ if (on_setup_complete_internal_callback) {
+ on_setup_complete_internal_callback(iface_hapd);
+ // Invalidate this callback since we don't want this firing
+ // again.
+ on_setup_complete_internal_callback = nullptr;
+ }
+}
} // namespace
namespace android {
namespace hardware {
namespace wifi {
namespace hostapd {
-namespace V1_0 {
+namespace V1_1 {
namespace implementation {
using hidl_return_util::call;
+using namespace android::hardware::wifi::hostapd::V1_0;
Hostapd::Hostapd(struct hapd_interfaces* interfaces) : interfaces_(interfaces)
{}
@@ -216,12 +236,20 @@
this, &Hostapd::removeAccessPointInternal, _hidl_cb, iface_name);
}
-Return<void> Hostapd::terminate() {
+Return<void> Hostapd::terminate()
+{
wpa_printf(MSG_INFO, "Terminating...");
eloop_terminate();
return Void();
}
+Return<void> Hostapd::registerCallback(
+ const sp<IHostapdCallback>& callback, registerCallback_cb _hidl_cb)
+{
+ return call(
+ this, &Hostapd::registerCallbackInternal, _hidl_cb, callback);
+}
+
HostapdStatus Hostapd::addAccessPointInternal(
const IfaceParams& iface_params, const NetworkParams& nw_params)
{
@@ -256,6 +284,23 @@
struct hostapd_data* iface_hapd =
hostapd_get_iface(interfaces_, iface_params.ifaceName.c_str());
WPA_ASSERT(iface_hapd != nullptr && iface_hapd->iface != nullptr);
+ // Register the setup complete callbacks
+ on_setup_complete_internal_callback =
+ [this](struct hostapd_data* iface_hapd) {
+ wpa_printf(
+ MSG_DEBUG, "AP interface setup completed - state %s",
+ hostapd_state_text(iface_hapd->iface->state));
+ if (iface_hapd->iface->state == HAPD_IFACE_DISABLED) {
+ // Invoke the failure callback on all registered
+ // clients.
+ for (const auto& callback : callbacks_) {
+ callback->onFailure(
+ iface_hapd->conf->iface);
+ }
+ }
+ };
+ iface_hapd->setup_complete_cb = onAsyncSetupCompleteCb;
+ iface_hapd->setup_complete_cb_ctx = iface_hapd;
if (hostapd_enable_iface(iface_hapd->iface) < 0) {
wpa_printf(
MSG_ERROR, "Enabling interface %s failed",
@@ -278,8 +323,16 @@
}
return {HostapdStatusCode::SUCCESS, ""};
}
+
+HostapdStatus Hostapd::registerCallbackInternal(
+ const sp<IHostapdCallback>& callback)
+{
+ callbacks_.push_back(callback);
+ return {HostapdStatusCode::SUCCESS, ""};
+}
+
} // namespace implementation
-} // namespace V1_0
+} // namespace V1_1
} // namespace hostapd
} // namespace wifi
} // namespace hardware
diff --git a/hostapd/hidl/1.0/hostapd.h b/hostapd/hidl/1.1/hostapd.h
similarity index 76%
rename from hostapd/hidl/1.0/hostapd.h
rename to hostapd/hidl/1.1/hostapd.h
index 7985fd9..3438d8b 100644
--- a/hostapd/hidl/1.0/hostapd.h
+++ b/hostapd/hidl/1.1/hostapd.h
@@ -14,7 +14,8 @@
#include <android-base/macros.h>
-#include <android/hardware/wifi/hostapd/1.0/IHostapd.h>
+#include <android/hardware/wifi/hostapd/1.1/IHostapd.h>
+#include <android/hardware/wifi/hostapd/1.1/IHostapdCallback.h>
extern "C"
{
@@ -28,15 +29,16 @@
namespace hardware {
namespace wifi {
namespace hostapd {
-namespace V1_0 {
+namespace V1_1 {
namespace implementation {
+using namespace android::hardware::wifi::hostapd::V1_0;
/**
* Implementation of the hostapd hidl object. This hidl
* object is used core for global control operations on
* hostapd.
*/
-class Hostapd : public V1_0::IHostapd
+class Hostapd : public V1_1::IHostapd
{
public:
Hostapd(hapd_interfaces* interfaces);
@@ -50,20 +52,27 @@
const hidl_string& iface_name,
removeAccessPoint_cb _hidl_cb) override;
Return<void> terminate() override;
+ Return<void> registerCallback(
+ const sp<IHostapdCallback>& callback,
+ registerCallback_cb _hidl_cb) override;
private:
// Corresponding worker functions for the HIDL methods.
HostapdStatus addAccessPointInternal(
const IfaceParams& iface_params, const NetworkParams& nw_params);
HostapdStatus removeAccessPointInternal(const std::string& iface_name);
+ HostapdStatus registerCallbackInternal(
+ const sp<IHostapdCallback>& callback);
// Raw pointer to the global structure maintained by the core.
struct hapd_interfaces* interfaces_;
+ // Callbacks registered.
+ std::vector<sp<IHostapdCallback>> callbacks_;
DISALLOW_COPY_AND_ASSIGN(Hostapd);
};
} // namespace implementation
-} // namespace V1_0
+} // namespace V1_1
} // namespace hostapd
} // namespace wifi
} // namespace hardware
diff --git a/hostapd/hostapd.android.rc b/hostapd/hostapd.android.rc
index 37a95c2..c8792d6 100644
--- a/hostapd/hostapd.android.rc
+++ b/hostapd/hostapd.android.rc
@@ -13,6 +13,7 @@
service hostapd /vendor/bin/hw/hostapd
interface android.hardware.wifi.hostapd@1.0::IHostapd default
+ interface android.hardware.wifi.hostapd@1.1::IHostapd default
class main
capabilities NET_ADMIN NET_RAW
user wifi