blob: 788f99ceedae21b532f70725152aeb4cb47944aa [file] [log] [blame]
/*
* hidl 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 "hidl_manager.h"
#include "hidl_return_util.h"
#include "p2p_network.h"
extern "C" {
#include "config_ssid.h"
}
namespace android {
namespace hardware {
namespace wifi {
namespace supplicant {
namespace V1_0 {
namespace implementation {
using hidl_return_util::validateAndCall;
P2pNetwork::P2pNetwork(
struct wpa_global *wpa_global, const char ifname[], int network_id)
: wpa_global_(wpa_global),
ifname_(ifname),
network_id_(network_id),
is_valid_(true)
{
}
void P2pNetwork::invalidate() { is_valid_ = false; }
bool P2pNetwork::isValid()
{
return (is_valid_ && (retrieveNetworkPtr() != nullptr));
}
Return<void> P2pNetwork::getId(getId_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
&P2pNetwork::getIdInternal, _hidl_cb);
}
Return<void> P2pNetwork::getInterfaceName(getInterfaceName_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
&P2pNetwork::getInterfaceNameInternal, _hidl_cb);
}
Return<void> P2pNetwork::getType(getType_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
&P2pNetwork::getTypeInternal, _hidl_cb);
}
Return<void> P2pNetwork::registerCallback(
const sp<ISupplicantP2pNetworkCallback> &callback,
registerCallback_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
&P2pNetwork::registerCallbackInternal, _hidl_cb, callback);
}
Return<void> P2pNetwork::getSsid(getSsid_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
&P2pNetwork::getSsidInternal, _hidl_cb);
}
Return<void> P2pNetwork::getBssid(getBssid_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
&P2pNetwork::getBssidInternal, _hidl_cb);
}
Return<void> P2pNetwork::isCurrent(isCurrent_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
&P2pNetwork::isCurrentInternal, _hidl_cb);
}
Return<void> P2pNetwork::isPersistent(isPersistent_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
&P2pNetwork::isPersistentInternal, _hidl_cb);
}
Return<void> P2pNetwork::isGo(isGo_cb _hidl_cb)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
&P2pNetwork::isGoInternal, _hidl_cb);
}
std::pair<SupplicantStatus, uint32_t> P2pNetwork::getIdInternal()
{
return {{SupplicantStatusCode::SUCCESS, ""}, network_id_};
}
std::pair<SupplicantStatus, std::string> P2pNetwork::getInterfaceNameInternal()
{
return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
}
std::pair<SupplicantStatus, IfaceType> P2pNetwork::getTypeInternal()
{
return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::P2P};
}
SupplicantStatus P2pNetwork::registerCallbackInternal(
const sp<ISupplicantP2pNetworkCallback> &callback)
{
HidlManager *hidl_manager = HidlManager::getInstance();
if (!hidl_manager ||
hidl_manager->addP2pNetworkCallbackHidlObject(
ifname_, network_id_, callback)) {
return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
}
return {SupplicantStatusCode::SUCCESS, ""};
}
std::pair<SupplicantStatus, std::vector<uint8_t>> P2pNetwork::getSsidInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
return {{SupplicantStatusCode::SUCCESS, ""},
{wpa_ssid->ssid, wpa_ssid->ssid + wpa_ssid->ssid_len}};
}
std::pair<SupplicantStatus, std::array<uint8_t, 6>>
P2pNetwork::getBssidInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
std::array<uint8_t, 6> bssid{};
if (wpa_ssid->bssid_set) {
os_memcpy(bssid.data(), wpa_ssid->bssid, ETH_ALEN);
}
return {{SupplicantStatusCode::SUCCESS, ""}, bssid};
}
std::pair<SupplicantStatus, bool> P2pNetwork::isCurrentInternal()
{
struct wpa_supplicant *wpa_s = retrieveIfacePtr();
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
return {{SupplicantStatusCode::SUCCESS, ""},
(wpa_s->current_ssid == wpa_ssid)};
}
std::pair<SupplicantStatus, bool> P2pNetwork::isPersistentInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
return {{SupplicantStatusCode::SUCCESS, ""}, (wpa_ssid->disabled == 2)};
}
std::pair<SupplicantStatus, bool> P2pNetwork::isGoInternal()
{
struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
return {{SupplicantStatusCode::SUCCESS, ""},
(wpa_ssid->mode == wpa_ssid::wpas_mode::WPAS_MODE_P2P_GO)};
}
/**
* Retrieve the underlying |wpa_ssid| struct pointer for
* this network.
* If the underlying network is removed or the interface
* this network belong to is removed, all RPC method calls
* on this object will return failure.
*/
struct wpa_ssid *P2pNetwork::retrieveNetworkPtr()
{
wpa_supplicant *wpa_s = retrieveIfacePtr();
if (!wpa_s)
return nullptr;
return wpa_config_get_network(wpa_s->conf, network_id_);
}
/**
* Retrieve the underlying |wpa_supplicant| struct
* pointer for this network.
*/
struct wpa_supplicant *P2pNetwork::retrieveIfacePtr()
{
return wpa_supplicant_get_iface(
(struct wpa_global *)wpa_global_, ifname_.c_str());
}
} // namespace implementation
} // namespace V1_0
} // namespace wifi
} // namespace supplicant
} // namespace hardware
} // namespace android