binder: Implement network addition/removal
Implement the |IIface.AddNetwork| & |IIface.RemoveNetwork| binder calls.
Also hookup the network addition notifications to BinderManager for
creating corresponding network binder objects. The network binder
objects are keyed using |ifname|_|network_id|.
BUG: 30015382
Change-Id: I0842563e74ff8b120d34f63fa28965bf264bb55f
TEST: Ran the integration tests under |wificond|.
Signed-off-by: Roshan Pius <rpius@google.com>
diff --git a/wpa_supplicant/binder/iface.cpp b/wpa_supplicant/binder/iface.cpp
index 6a3e223..267b90b 100644
--- a/wpa_supplicant/binder/iface.cpp
+++ b/wpa_supplicant/binder/iface.cpp
@@ -7,6 +7,7 @@
* See README for more details.
*/
+#include "binder_manager.h"
#include "iface.h"
namespace wpa_supplicant_binder {
@@ -34,11 +35,88 @@
android::binder::Status Iface::AddNetwork(
android::sp<fi::w1::wpa_supplicant::INetwork> *network_object_out)
{
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ if (!wpa_s) {
+ return android::binder::Status::fromServiceSpecificError(
+ ERROR_IFACE_INVALID,
+ "wpa_supplicant does not control this interface.");
+ }
+
+ struct wpa_ssid *ssid = wpa_config_add_network(wpa_s->conf);
+ if (!ssid) {
+ return android::binder::Status::fromServiceSpecificError(
+ ERROR_GENERIC, "wpa_supplicant couldn't add this network.");
+ }
+
+ // This sequence of steps after network addition is following what is
+ // currently being done in |ctrl_iface.c| & |dbus_new_handlers|.
+ // Notify the control interfaces about the network addition.
+ wpas_notify_network_added(wpa_s, ssid);
+ // Set the new network to be disabled.
+ ssid->disabled = 1;
+ // Set defaults for the new network.
+ wpa_config_set_network_defaults(ssid);
+
+ BinderManager *binder_manager = BinderManager::getInstance();
+ if (!binder_manager ||
+ binder_manager->getNetworkBinderObjectByIfnameAndNetworkId(
+ wpa_s->ifname, ssid->id, network_object_out)) {
+ return android::binder::Status::fromServiceSpecificError(
+ ERROR_GENERIC,
+ "wpa_supplicant encountered a binder error.");
+ }
return android::binder::Status::ok();
}
android::binder::Status Iface::RemoveNetwork(int network_id)
{
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ if (!wpa_s) {
+ return android::binder::Status::fromServiceSpecificError(
+ ERROR_IFACE_INVALID,
+ "wpa_supplicant does not control this interface.");
+ }
+
+ struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, network_id);
+ if (!ssid) {
+ return android::binder::Status::fromServiceSpecificError(
+ ERROR_NETWORK_UNKNOWN,
+ "wpa_supplicant does not control this network.");
+ }
+ if (wpa_config_remove_network(wpa_s->conf, network_id)) {
+ return android::binder::Status::fromServiceSpecificError(
+ ERROR_GENERIC,
+ "wpa_supplicant couldn't remove this network.");
+ }
+ return android::binder::Status::ok();
+}
+
+android::binder::Status Iface::GetNetwork(
+ int network_id,
+ android::sp<fi::w1::wpa_supplicant::INetwork> *network_object_out)
+{
+ struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+ if (!wpa_s) {
+ return android::binder::Status::fromServiceSpecificError(
+ ERROR_IFACE_INVALID,
+ "wpa_supplicant does not control this interface.");
+ }
+
+ struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, network_id);
+ if (!ssid) {
+ return android::binder::Status::fromServiceSpecificError(
+ ERROR_NETWORK_UNKNOWN,
+ "wpa_supplicant does not control this network.");
+ }
+
+ BinderManager *binder_manager = BinderManager::getInstance();
+ if (!binder_manager ||
+ binder_manager->getNetworkBinderObjectByIfnameAndNetworkId(
+ wpa_s->ifname, ssid->id, network_object_out)) {
+ return android::binder::Status::fromServiceSpecificError(
+ ERROR_GENERIC,
+ "wpa_supplicant encountered a binder error.");
+ }
return android::binder::Status::ok();
}