binder: Notify iface add/remove to binder
Notify |BinderManager| about any new iface addition/removal from
|wpa_supplicant| core.
|Iface| objects are stateless in the sense that they only
hold the name of the iface it controls. Every RPC call through the iface object
will first invoke |wpa_supplicant_get_iface| to ensure that the iface still
exists in the wpa_supplicant core.
While there,
1. Add some debug logs in binder.cpp.
2. Change C style comments to c++ style.
3. Add @utf8incpp annotation at the interface level in all the aidl files.
BUG: 29998764
TEST: Tested using the |gTest| integration tests. Will upload these under
|wificond|
Change-Id: If69bfaece7a6f69640fe8cbf90d1006a88aef8af
Signed-off-by: Roshan Pius <rpius@google.com>
diff --git a/wpa_supplicant/binder/binder.cpp b/wpa_supplicant/binder/binder.cpp
index 750e878..eb6006c 100644
--- a/wpa_supplicant/binder/binder.cpp
+++ b/wpa_supplicant/binder/binder.cpp
@@ -41,12 +41,16 @@
return NULL;
priv->global = global;
+ wpa_printf(MSG_DEBUG, "Initing binder control");
+
android::ProcessState::self()->setThreadPoolMaxThreadCount(0);
android::IPCThreadState::self()->disableBackgroundScheduling(true);
android::IPCThreadState::self()->setupPolling(&priv->binder_fd);
- wpa_printf(MSG_INFO, "Process binder events on FD %d", priv->binder_fd);
if (priv->binder_fd < 0)
goto err;
+
+ wpa_printf(
+ MSG_INFO, "Processing binder events on FD %d", priv->binder_fd);
/* Look for read events from the binder socket in the eloop. */
if (eloop_register_read_sock(
priv->binder_fd, wpas_binder_sock_handler, global, priv) < 0)
@@ -72,6 +76,8 @@
if (!priv)
return;
+ wpa_printf(MSG_DEBUG, "Deiniting binder control");
+
wpa_supplicant_binder::BinderManager::destroyInstance();
eloop_unregister_read_sock(priv->binder_fd);
android::IPCThreadState::shutdown();
@@ -82,6 +88,10 @@
if (!wpa_s->global->binder)
return 1;
+ wpa_printf(
+ MSG_DEBUG, "Registering interface to binder control: %s",
+ wpa_s->ifname);
+
wpa_supplicant_binder::BinderManager *binder_manager =
wpa_supplicant_binder::BinderManager::getInstance();
if (!binder_manager)
@@ -95,6 +105,10 @@
if (!wpa_s->global->binder)
return 1;
+ wpa_printf(
+ MSG_DEBUG, "Deregistering interface from binder control: %s",
+ wpa_s->ifname);
+
wpa_supplicant_binder::BinderManager *binder_manager =
wpa_supplicant_binder::BinderManager::getInstance();
if (!binder_manager)
diff --git a/wpa_supplicant/binder/binder_manager.cpp b/wpa_supplicant/binder/binder_manager.cpp
index 27e8ded..6551b50 100644
--- a/wpa_supplicant/binder/binder_manager.cpp
+++ b/wpa_supplicant/binder/binder_manager.cpp
@@ -59,7 +59,7 @@
if (iface_object_map_.find(iface_key) != iface_object_map_.end())
return 1;
- iface_object_map_[iface_key] = new Iface(wpa_s);
+ iface_object_map_[iface_key] = new Iface(wpa_s->global, wpa_s->ifname);
if (!iface_object_map_[iface_key].get())
return 1;
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
index ea11d42..fb77ffa 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
@@ -12,5 +12,17 @@
/**
* Interface exposed by wpa_supplicant for each network interface it controls.
*/
+@utf8InCpp
interface IIface {
+ /* Error values returned by the service to RPC method calls. */
+ const int ERROR_INVALID_ARGS = 1;
+ const int ERROR_UNKNOWN = 2;
+ const int ERROR_IFACE_UNKNOWN = 3;
+
+ /**
+ * Retrieves the name of the iface this object controls.
+ *
+ * @return Name of the network interface, e.g., wlan0
+ */
+ String GetName();
}
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
index 1cbee20..a52f857 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
@@ -16,6 +16,7 @@
* Interface exposed by the wpa_supplicant binder service registered
* with the service manager with name: fi.w1.wpa_supplicant.
*/
+@utf8InCpp
interface ISupplicant {
/* Error values returned by the service to RPC method calls. */
const int ERROR_INVALID_ARGS = 1;
@@ -45,7 +46,7 @@
*
* @param ifname Name of the network interface, e.g., wlan0
*/
- void RemoveInterface(in @utf8InCpp String ifname);
+ void RemoveInterface(in String ifname);
/**
* Gets a binder object for the interface corresponding to ifname
@@ -55,5 +56,5 @@
*
* @return Binder object representing the interface.
*/
- IIface GetInterface(in @utf8InCpp String ifname);
+ IIface GetInterface(in String ifname);
}
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
index d624d91..02261c7 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
@@ -16,5 +16,6 @@
* to host an instance of this binder object and pass a reference of the object
* to wpa_supplicant via the registerCallbacksObject method.
*/
+@utf8InCpp
interface ISupplicantCallbacks {
}
diff --git a/wpa_supplicant/binder/iface.cpp b/wpa_supplicant/binder/iface.cpp
index c61b3b0..4faa147 100644
--- a/wpa_supplicant/binder/iface.cpp
+++ b/wpa_supplicant/binder/iface.cpp
@@ -11,6 +11,36 @@
namespace wpa_supplicant_binder {
-Iface::Iface(struct wpa_supplicant *wpa_s) : wpa_s_(wpa_s) {}
+Iface::Iface(struct wpa_global *wpa_global, const char ifname[])
+ : wpa_global_(wpa_global), ifname_(ifname)
+{
+}
-} /* namespace wpa_supplicant_binder */
+android::binder::Status Iface::GetName(std::string *iface_name_out)
+{
+ // We could directly return the name we hold, but let's verify
+ // if the underlying iface still exists.
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ if (!wpa_s) {
+ return android::binder::Status::fromServiceSpecificError(
+ ERROR_IFACE_UNKNOWN,
+ "wpa_supplicant does not control this interface.");
+ }
+
+ *iface_name_out = ifname_;
+ return android::binder::Status::ok();
+}
+
+/**
+ * Retrieve the underlying |wpa_supplicant| struct pointer for
+ * this iface.
+ * If the underlying iface is removed, then all RPC method calls
+ * on this object will return failure.
+ */
+wpa_supplicant *Iface::retrieveIfacePtr()
+{
+ return wpa_supplicant_get_iface(
+ (struct wpa_global *)wpa_global_, ifname_.c_str());
+}
+
+} // namespace wpa_supplicant_binder
diff --git a/wpa_supplicant/binder/iface.h b/wpa_supplicant/binder/iface.h
index c0ee12c..f87f19f 100644
--- a/wpa_supplicant/binder/iface.h
+++ b/wpa_supplicant/binder/iface.h
@@ -28,15 +28,22 @@
class Iface : public fi::w1::wpa_supplicant::BnIface
{
public:
- Iface(struct wpa_supplicant *wpa_s);
+ Iface(struct wpa_global *wpa_global, const char ifname[]);
virtual ~Iface() = default;
+ // Binder methods exposed in aidl.
+ android::binder::Status GetName(std::string *iface_name_out) override;
+
private:
- /* Raw pointer to the structure maintained by the core for this
- * interface. */
- struct wpa_supplicant *wpa_s_;
+ // Reference to the global wpa_struct. This is assumed to be valid for
+ // the lifetime of the process.
+ const struct wpa_global *wpa_global_;
+ // Name of the iface this binder object controls
+ const std::string ifname_;
+
+ struct wpa_supplicant *retrieveIfacePtr();
};
-} /* namespace wpa_supplicant_binder */
+} // namespace wpa_supplicant_binder
-#endif /* WPA_SUPPLICANT_BINDER_IFACE_H */
+#endif // WPA_SUPPLICANT_BINDER_IFACE_H
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 67e36ae..536f3e6 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -70,6 +70,9 @@
if (wpas_dbus_register_interface(wpa_s))
return -1;
+ if (wpas_binder_register_interface(wpa_s))
+ return -1;
+
return 0;
}
@@ -84,6 +87,8 @@
/* unregister interface in new DBus ctrl iface */
wpas_dbus_unregister_interface(wpa_s);
+
+ wpas_binder_unregister_interface(wpa_s);
}