hostapd/wpa_supplicant/binder/supplicant.cpp
Roshan Pius f1a5a34d8e binder: Implement interface add/remove methods
This commit implements the methods defined in Supplicant service:
1. CreateInterface
2. RemoveInterface
3. GetInterface

The binder service returns the corresponding iface binder object
references which can be used by clients to control a specific
interface.

Signed-off-by: Roshan Pius <rpius@google.com>
2016-04-02 17:35:28 +03:00

125 lines
4.3 KiB
C++

/*
* binder interface for wpa_supplicant daemon
* Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
* Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "binder_manager.h"
#include "supplicant.h"
namespace wpa_supplicant_binder {
Supplicant::Supplicant(struct wpa_global *global)
: wpa_global_(global)
{
}
android::binder::Status Supplicant::CreateInterface(
const android::os::PersistableBundle &params,
android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
{
android::String16 driver, ifname, confname, bridge_ifname;
/* Check if required Ifname argument is missing */
if (!params.getString(android::String16("Ifname"), &ifname))
return android::binder::Status::fromServiceSpecificError(
ERROR_INVALID_ARGS,
android::String8("Ifname missing in params."));
/* Retrieve the remaining params from the dictionary */
params.getString(android::String16("Driver"), &driver);
params.getString(android::String16("ConfigFile"), &confname);
params.getString(android::String16("BridgeIfname"), &bridge_ifname);
/*
* Try to get the wpa_supplicant record for this iface, return
* an error if we already control it.
*/
if (wpa_supplicant_get_iface(wpa_global_,
android::String8(ifname).string()) != NULL)
return android::binder::Status::fromServiceSpecificError(
ERROR_IFACE_EXISTS,
android::String8("wpa_supplicant already controls this interface."));
android::binder::Status status;
struct wpa_supplicant *wpa_s = NULL;
struct wpa_interface iface;
os_memset(&iface, 0, sizeof(iface));
iface.driver = os_strdup(android::String8(driver).string());
iface.ifname = os_strdup(android::String8(ifname).string());
iface.confname = os_strdup(android::String8(confname).string());
iface.bridge_ifname = os_strdup(
android::String8(bridge_ifname).string());
/* Otherwise, have wpa_supplicant attach to it. */
wpa_s = wpa_supplicant_add_iface(wpa_global_, &iface, NULL);
/* The supplicant core creates a corresponding binder object via
* BinderManager when |wpa_supplicant_add_iface| is called. */
if (!wpa_s || !wpa_s->binder_object_key) {
status = android::binder::Status::fromServiceSpecificError(
ERROR_UNKNOWN,
android::String8("wpa_supplicant couldn't grab this interface."));
} else {
BinderManager *binder_manager = BinderManager::getInstance();
if (!binder_manager ||
binder_manager->getIfaceBinderObjectByKey(
wpa_s->binder_object_key, aidl_return))
status = android::binder::Status::fromServiceSpecificError(
ERROR_UNKNOWN,
android::String8("wpa_supplicant encountered a binder error."));
else
status = android::binder::Status::ok();
}
os_free((void *) iface.driver);
os_free((void *) iface.ifname);
os_free((void *) iface.confname);
os_free((void *) iface.bridge_ifname);
return status;
}
android::binder::Status Supplicant::RemoveInterface(const std::string &ifname)
{
struct wpa_supplicant *wpa_s;
wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
if (!wpa_s || !wpa_s->binder_object_key)
return android::binder::Status::fromServiceSpecificError(
ERROR_IFACE_UNKNOWN,
android::String8("wpa_supplicant does not control this interface."));
if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0))
return android::binder::Status::fromServiceSpecificError(
ERROR_UNKNOWN,
android::String8("wpa_supplicant couldn't remove this interface."));
return android::binder::Status::ok();
}
android::binder::Status Supplicant::GetInterface(
const std::string &ifname,
android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
{
struct wpa_supplicant *wpa_s;
wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
if (!wpa_s || !wpa_s->binder_object_key)
return android::binder::Status::fromServiceSpecificError(
ERROR_IFACE_UNKNOWN,
android::String8("wpa_supplicant does not control this interface."));
BinderManager *binder_manager = BinderManager::getInstance();
if (!binder_manager ||
binder_manager->getIfaceBinderObjectByKey(wpa_s->binder_object_key,
aidl_return))
return android::binder::Status::fromServiceSpecificError(
ERROR_UNKNOWN,
android::String8("wpa_supplicant encountered a binder error."));
return android::binder::Status::ok();
}
} /* namespace wpa_supplicant_binder */