Files
android_external_wpa_suppli…/wpa_supplicant/aidl/p2p_iface.cpp
Sunil Ravi 68c25c259b IP Address Allocation in EAPOL-Key Frames
Implementation of Wi-Fi P2P Technical Specification v1.7 - Section  4.2.8
"IP Address Allocation in EAPOL-Key Frames (4-Way Handshake)".

Changes includes,
1. Configure the IP addresses in supplicant for P2P GO to provide the IP address to
client in EAPOL handshake.
2. Send the received IP address information to framework.

Bug: 170056953
Test: Manual - Establish P2P connection & confirmed from sniffer logs
      and logcat logs that IP addresse is allocated via EAPOL exchange.
      Ping works after connection.
Change-Id: I5978708b098e57e48db52dae14f9bbba28199f2d
2023-02-10 22:07:36 +00:00

1879 lines
58 KiB
C++

/*
* WPA Supplicant - P2P Iface Aidl interface
* Copyright (c) 2021, Google Inc. All rights reserved.
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include "aidl_manager.h"
#include "aidl_return_util.h"
#include "iface_config_utils.h"
#include "misc_utils.h"
#include "p2p_iface.h"
#include "sta_network.h"
extern "C"
{
#include "ap.h"
#include "wps_supplicant.h"
#include "wifi_display.h"
#include "utils/eloop.h"
#include "wpa_supplicant_i.h"
#include "driver_i.h"
}
#define P2P_JOIN_LIMIT 3
namespace {
const char kConfigMethodStrPbc[] = "pbc";
const char kConfigMethodStrDisplay[] = "display";
const char kConfigMethodStrKeypad[] = "keypad";
constexpr char kSetMiracastMode[] = "MIRACAST ";
constexpr uint8_t kWfdDeviceInfoSubelemId = 0;
constexpr uint8_t kWfdR2DeviceInfoSubelemId = 11;
constexpr char kWfdDeviceInfoSubelemLenHexStr[] = "0006";
std::function<void()> pending_join_scan_callback = NULL;
std::function<void()> pending_scan_res_join_callback = NULL;
using aidl::android::hardware::wifi::supplicant::ISupplicantP2pIface;
using aidl::android::hardware::wifi::supplicant::ISupplicantStaNetwork;
using aidl::android::hardware::wifi::supplicant::MiracastMode;
using aidl::android::hardware::wifi::supplicant::P2pFrameTypeMask;
uint8_t convertAidlMiracastModeToInternal(
MiracastMode mode)
{
switch (mode) {
case MiracastMode::DISABLED:
return 0;
case MiracastMode::SOURCE:
return 1;
case MiracastMode::SINK:
return 2;
};
WPA_ASSERT(false);
}
/**
* Check if the provided ssid is valid or not.
*
* Returns 1 if valid, 0 otherwise.
*/
int isSsidValid(const std::vector<uint8_t>& ssid)
{
if (ssid.size() == 0 ||
ssid.size() >
static_cast<uint32_t>(ISupplicantStaNetwork::
SSID_MAX_LEN_IN_BYTES)) {
return 0;
}
return 1;
}
/**
* Check if the provided psk passhrase is valid or not.
*
* Returns 1 if valid, 0 otherwise.
*/
int isPskPassphraseValid(const std::string &psk)
{
if (psk.size() <
static_cast<uint32_t>(ISupplicantStaNetwork::
PSK_PASSPHRASE_MIN_LEN_IN_BYTES) ||
psk.size() >
static_cast<uint32_t>(ISupplicantStaNetwork::
PSK_PASSPHRASE_MAX_LEN_IN_BYTES)) {
return 0;
}
if (has_ctrl_char((u8 *)psk.c_str(), psk.size())) {
return 0;
}
return 1;
}
/*
* isAnyEtherAddr - match any ether address
*
*/
int isAnyEtherAddr(const u8 *a)
{
// 02:00:00:00:00:00
return (a[0] == 2) && !(a[1] | a[2] | a[3] | a[4] | a[5]);
}
struct wpa_ssid* addGroupClientNetwork(
struct wpa_supplicant* wpa_s,
const uint8_t *group_owner_bssid,
const std::vector<uint8_t>& ssid,
const std::string& passphrase)
{
struct wpa_ssid* wpa_network = wpa_config_add_network(wpa_s->conf);
if (!wpa_network) {
return NULL;
}
// set general network defaults
wpa_config_set_network_defaults(wpa_network);
// set P2p network defaults
wpa_network->p2p_group = 1;
wpa_network->mode = wpas_mode::WPAS_MODE_INFRA;
wpa_network->disabled = 2;
// set necessary fields
if (!isAnyEtherAddr(group_owner_bssid)) {
os_memcpy(wpa_network->bssid, group_owner_bssid, ETH_ALEN);
wpa_network->bssid_set = 1;
}
wpa_network->ssid = (uint8_t *)os_malloc(ssid.size());
if (wpa_network->ssid == NULL) {
wpa_config_remove_network(wpa_s->conf, wpa_network->id);
return NULL;
}
memcpy(wpa_network->ssid, ssid.data(), ssid.size());
wpa_network->ssid_len = ssid.size();
wpa_network->psk_set = 0;
wpa_network->passphrase = dup_binstr(passphrase.c_str(), passphrase.length());
if (wpa_network->passphrase == NULL) {
wpa_config_remove_network(wpa_s->conf, wpa_network->id);
return NULL;
}
wpa_config_update_psk(wpa_network);
return wpa_network;
}
void scanResJoinWrapper(
struct wpa_supplicant *wpa_s,
struct wpa_scan_results *scan_res)
{
if (wpa_s->p2p_scan_work) {
struct wpa_radio_work *work = wpa_s->p2p_scan_work;
wpa_s->p2p_scan_work = NULL;
radio_work_done(work);
}
if (pending_scan_res_join_callback) {
pending_scan_res_join_callback();
}
}
static bool is6GhzAllowed(struct wpa_supplicant *wpa_s) {
if (!wpa_s->global->p2p) return false;
return wpa_s->global->p2p->allow_6ghz;
}
int joinGroup(
struct wpa_supplicant* wpa_s,
const uint8_t *group_owner_bssid,
const std::vector<uint8_t>& ssid,
const std::string& passphrase,
uint32_t freq)
{
int ret = 0;
int he = wpa_s->conf->p2p_go_he;
int vht = wpa_s->conf->p2p_go_vht;
int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
// Construct a network for adding group.
// Group client follows the persistent attribute of Group Owner.
// If joined group is persistent, it adds a persistent network on GroupStarted.
struct wpa_ssid *wpa_network = addGroupClientNetwork(
wpa_s, group_owner_bssid, ssid, passphrase);
if (wpa_network == NULL) {
wpa_printf(MSG_ERROR, "P2P: Cannot construct a network for group join.");
return -1;
}
// this is temporary network only for establishing the connection.
wpa_network->temporary = 1;
if (wpas_p2p_group_add_persistent(
wpa_s, wpa_network, 0, 0, freq, 0, ht40, vht,
CONF_OPER_CHWIDTH_USE_HT, he, 0, NULL, 0, 0, is6GhzAllowed(wpa_s), P2P_JOIN_LIMIT, true)) {
ret = -1;
}
// Always remove this temporary network at the end.
wpa_config_remove_network(wpa_s->conf, wpa_network->id);
return ret;
}
void scanResJoinIgnore(struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res) {
wpa_printf(MSG_DEBUG, "P2P: Ignore group join scan results.");
if (wpa_s->p2p_scan_work) {
struct wpa_radio_work *work = wpa_s->p2p_scan_work;
wpa_s->p2p_scan_work = NULL;
radio_work_done(work);
}
}
static void updateP2pVendorElem(struct wpa_supplicant* wpa_s, enum wpa_vendor_elem_frame frameType,
const std::vector<uint8_t>& vendorElemBytes) {
wpa_printf(MSG_INFO, "Set vendor elements to frames %d", frameType);
struct wpa_supplicant* vendor_elem_wpa_s = wpas_vendor_elem(wpa_s, frameType);
if (vendor_elem_wpa_s->vendor_elem[frameType]) {
wpabuf_free(vendor_elem_wpa_s->vendor_elem[frameType]);
vendor_elem_wpa_s->vendor_elem[frameType] = NULL;
}
if (vendorElemBytes.size() > 0) {
vendor_elem_wpa_s->vendor_elem[frameType] =
wpabuf_alloc_copy(vendorElemBytes.data(), vendorElemBytes.size());
}
wpas_vendor_elem_update(vendor_elem_wpa_s);
}
uint32_t convertWpaP2pFrameTypeToHalP2pFrameTypeBit(int frameType) {
switch (frameType) {
case VENDOR_ELEM_PROBE_REQ_P2P:
return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_PROBE_REQ_P2P);
case VENDOR_ELEM_PROBE_RESP_P2P:
return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_PROBE_RESP_P2P);
case VENDOR_ELEM_PROBE_RESP_P2P_GO:
return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_PROBE_RESP_P2P_GO);
case VENDOR_ELEM_BEACON_P2P_GO:
return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_BEACON_P2P_GO);
case VENDOR_ELEM_P2P_PD_REQ:
return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_PD_REQ);
case VENDOR_ELEM_P2P_PD_RESP:
return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_PD_RESP);
case VENDOR_ELEM_P2P_GO_NEG_REQ:
return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_GO_NEG_REQ);
case VENDOR_ELEM_P2P_GO_NEG_RESP:
return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_GO_NEG_RESP);
case VENDOR_ELEM_P2P_GO_NEG_CONF:
return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_GO_NEG_CONF);
case VENDOR_ELEM_P2P_INV_REQ:
return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_INV_REQ);
case VENDOR_ELEM_P2P_INV_RESP:
return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_INV_RESP);
case VENDOR_ELEM_P2P_ASSOC_REQ:
return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_ASSOC_REQ);
case VENDOR_ELEM_P2P_ASSOC_RESP:
return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_ASSOC_RESP);
}
return 0;
}
} // namespace
namespace aidl {
namespace android {
namespace hardware {
namespace wifi {
namespace supplicant {
using aidl_return_util::validateAndCall;
using misc_utils::createStatus;
using misc_utils::createStatusWithMsg;
P2pIface::P2pIface(struct wpa_global* wpa_global, const char ifname[])
: wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
{}
void P2pIface::invalidate() { is_valid_ = false; }
bool P2pIface::isValid()
{
return (is_valid_ && (retrieveIfacePtr() != nullptr));
}
::ndk::ScopedAStatus P2pIface::getName(
std::string* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::getNameInternal, _aidl_return);
}
::ndk::ScopedAStatus P2pIface::getType(
IfaceType* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::getTypeInternal, _aidl_return);
}
::ndk::ScopedAStatus P2pIface::addNetwork(
std::shared_ptr<ISupplicantP2pNetwork>* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::addNetworkInternal, _aidl_return);
}
::ndk::ScopedAStatus P2pIface::removeNetwork(
int32_t in_id)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::removeNetworkInternal, in_id);
}
::ndk::ScopedAStatus P2pIface::getNetwork(
int32_t in_id, std::shared_ptr<ISupplicantP2pNetwork>* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::getNetworkInternal, _aidl_return, in_id);
}
::ndk::ScopedAStatus P2pIface::listNetworks(
std::vector<int32_t>* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::listNetworksInternal, _aidl_return);
}
::ndk::ScopedAStatus P2pIface::registerCallback(
const std::shared_ptr<ISupplicantP2pIfaceCallback>& in_callback)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::registerCallbackInternal, in_callback);
}
::ndk::ScopedAStatus P2pIface::getDeviceAddress(
std::vector<uint8_t>* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::getDeviceAddressInternal, _aidl_return);
}
::ndk::ScopedAStatus P2pIface::setSsidPostfix(
const std::vector<uint8_t>& in_postfix)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setSsidPostfixInternal, in_postfix);
}
::ndk::ScopedAStatus P2pIface::setGroupIdle(
const std::string& in_groupIfName, int32_t in_timeoutInSec)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setGroupIdleInternal, in_groupIfName,
in_timeoutInSec);
}
::ndk::ScopedAStatus P2pIface::setPowerSave(
const std::string& in_groupIfName, bool in_enable)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setPowerSaveInternal, in_groupIfName, in_enable);
}
::ndk::ScopedAStatus P2pIface::find(
int32_t in_timeoutInSec)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::findInternal, in_timeoutInSec);
}
::ndk::ScopedAStatus P2pIface::stopFind()
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::stopFindInternal);
}
::ndk::ScopedAStatus P2pIface::flush()
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::flushInternal);
}
::ndk::ScopedAStatus P2pIface::connect(
const std::vector<uint8_t>& in_peerAddress,
WpsProvisionMethod in_provisionMethod,
const std::string& in_preSelectedPin, bool in_joinExistingGroup,
bool in_persistent, int32_t in_goIntent, std::string* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::connectInternal, _aidl_return, in_peerAddress,
in_provisionMethod, in_preSelectedPin, in_joinExistingGroup,
in_persistent, in_goIntent);
}
::ndk::ScopedAStatus P2pIface::cancelConnect()
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::cancelConnectInternal);
}
::ndk::ScopedAStatus P2pIface::provisionDiscovery(
const std::vector<uint8_t>& in_peerAddress,
WpsProvisionMethod in_provisionMethod)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::provisionDiscoveryInternal, in_peerAddress,
in_provisionMethod);
}
ndk::ScopedAStatus P2pIface::addGroup(
bool in_persistent, int32_t in_persistentNetworkId)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::addGroupInternal, in_persistent,
in_persistentNetworkId);
}
::ndk::ScopedAStatus P2pIface::addGroupWithConfig(
const std::vector<uint8_t>& in_ssid,
const std::string& in_pskPassphrase, bool in_persistent,
int32_t in_freq, const std::vector<uint8_t>& in_peerAddress,
bool in_joinExistingGroup)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::addGroupWithConfigInternal, in_ssid,
in_pskPassphrase, in_persistent, in_freq,
in_peerAddress, in_joinExistingGroup);
}
::ndk::ScopedAStatus P2pIface::removeGroup(
const std::string& in_groupIfName)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::removeGroupInternal, in_groupIfName);
}
::ndk::ScopedAStatus P2pIface::reject(
const std::vector<uint8_t>& in_peerAddress)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::rejectInternal, in_peerAddress);
}
::ndk::ScopedAStatus P2pIface::invite(
const std::string& in_groupIfName,
const std::vector<uint8_t>& in_goDeviceAddress,
const std::vector<uint8_t>& in_peerAddress)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::inviteInternal, in_groupIfName,
in_goDeviceAddress, in_peerAddress);
}
::ndk::ScopedAStatus P2pIface::reinvoke(
int32_t in_persistentNetworkId,
const std::vector<uint8_t>& in_peerAddress)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::reinvokeInternal, in_persistentNetworkId,
in_peerAddress);
}
::ndk::ScopedAStatus P2pIface::configureExtListen(
int32_t in_periodInMillis, int32_t in_intervalInMillis)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::configureExtListenInternal, in_periodInMillis,
in_intervalInMillis);
}
::ndk::ScopedAStatus P2pIface::setListenChannel(
int32_t in_channel, int32_t in_operatingClass)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setListenChannelInternal, in_channel,
in_operatingClass);
}
::ndk::ScopedAStatus P2pIface::setDisallowedFrequencies(
const std::vector<FreqRange>& in_ranges)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setDisallowedFrequenciesInternal, in_ranges);
}
::ndk::ScopedAStatus P2pIface::getSsid(
const std::vector<uint8_t>& in_peerAddress,
std::vector<uint8_t>* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::getSsidInternal, _aidl_return, in_peerAddress);
}
::ndk::ScopedAStatus P2pIface::getGroupCapability(
const std::vector<uint8_t>& in_peerAddress,
P2pGroupCapabilityMask* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::getGroupCapabilityInternal, _aidl_return, in_peerAddress);
}
::ndk::ScopedAStatus P2pIface::addBonjourService(
const std::vector<uint8_t>& in_query,
const std::vector<uint8_t>& in_response)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::addBonjourServiceInternal, in_query, in_response);
}
::ndk::ScopedAStatus P2pIface::removeBonjourService(
const std::vector<uint8_t>& in_query)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::removeBonjourServiceInternal, in_query);
}
::ndk::ScopedAStatus P2pIface::addUpnpService(
int32_t in_version, const std::string& in_serviceName)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::addUpnpServiceInternal, in_version, in_serviceName);
}
::ndk::ScopedAStatus P2pIface::removeUpnpService(
int32_t in_version, const std::string& in_serviceName)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::removeUpnpServiceInternal, in_version,
in_serviceName);
}
::ndk::ScopedAStatus P2pIface::flushServices()
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::flushServicesInternal);
}
::ndk::ScopedAStatus P2pIface::requestServiceDiscovery(
const std::vector<uint8_t>& in_peerAddress,
const std::vector<uint8_t>& in_query,
int64_t* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::requestServiceDiscoveryInternal, _aidl_return,
in_peerAddress, in_query);
}
::ndk::ScopedAStatus P2pIface::cancelServiceDiscovery(
int64_t in_identifier)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::cancelServiceDiscoveryInternal, in_identifier);
}
::ndk::ScopedAStatus P2pIface::setMiracastMode(
MiracastMode in_mode)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setMiracastModeInternal, in_mode);
}
::ndk::ScopedAStatus P2pIface::startWpsPbc(
const std::string& in_groupIfName,
const std::vector<uint8_t>& in_bssid)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::startWpsPbcInternal, in_groupIfName, in_bssid);
}
::ndk::ScopedAStatus P2pIface::startWpsPinKeypad(
const std::string& in_groupIfName,
const std::string& in_pin)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::startWpsPinKeypadInternal, in_groupIfName, in_pin);
}
::ndk::ScopedAStatus P2pIface::startWpsPinDisplay(
const std::string& in_groupIfName,
const std::vector<uint8_t>& in_bssid,
std::string* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::startWpsPinDisplayInternal, _aidl_return,
in_groupIfName, in_bssid);
}
::ndk::ScopedAStatus P2pIface::cancelWps(
const std::string& in_groupIfName)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::cancelWpsInternal, in_groupIfName);
}
::ndk::ScopedAStatus P2pIface::setWpsDeviceName(
const std::string& in_name)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setWpsDeviceNameInternal, in_name);
}
::ndk::ScopedAStatus P2pIface::setWpsDeviceType(
const std::vector<uint8_t>& in_type)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setWpsDeviceTypeInternal, in_type);
}
::ndk::ScopedAStatus P2pIface::setWpsManufacturer(
const std::string& in_manufacturer)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setWpsManufacturerInternal, in_manufacturer);
}
::ndk::ScopedAStatus P2pIface::setWpsModelName(
const std::string& in_modelName)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setWpsModelNameInternal, in_modelName);
}
::ndk::ScopedAStatus P2pIface::setWpsModelNumber(
const std::string& in_modelNumber)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setWpsModelNumberInternal, in_modelNumber);
}
::ndk::ScopedAStatus P2pIface::setWpsSerialNumber(
const std::string& in_serialNumber)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setWpsSerialNumberInternal, in_serialNumber);
}
::ndk::ScopedAStatus P2pIface::setWpsConfigMethods(
WpsConfigMethods in_configMethods)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setWpsConfigMethodsInternal, in_configMethods);
}
::ndk::ScopedAStatus P2pIface::enableWfd(
bool in_enable)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::enableWfdInternal, in_enable);
}
::ndk::ScopedAStatus P2pIface::setWfdDeviceInfo(
const std::vector<uint8_t>& in_info)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setWfdDeviceInfoInternal, in_info);
}
::ndk::ScopedAStatus P2pIface::createNfcHandoverRequestMessage(
std::vector<uint8_t>* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::createNfcHandoverRequestMessageInternal, _aidl_return);
}
::ndk::ScopedAStatus P2pIface::createNfcHandoverSelectMessage(
std::vector<uint8_t>* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::createNfcHandoverSelectMessageInternal, _aidl_return);
}
::ndk::ScopedAStatus P2pIface::reportNfcHandoverResponse(
const std::vector<uint8_t>& in_request)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::reportNfcHandoverResponseInternal, in_request);
}
::ndk::ScopedAStatus P2pIface::reportNfcHandoverInitiation(
const std::vector<uint8_t>& in_select)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::reportNfcHandoverInitiationInternal, in_select);
}
::ndk::ScopedAStatus P2pIface::saveConfig()
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::saveConfigInternal);
}
::ndk::ScopedAStatus P2pIface::setMacRandomization(
bool in_enable)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setMacRandomizationInternal, in_enable);
}
::ndk::ScopedAStatus P2pIface::setEdmg(
bool in_enable)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
&P2pIface::setEdmgInternal, in_enable);
}
::ndk::ScopedAStatus P2pIface::getEdmg(
bool* _aidl_return)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
&P2pIface::getEdmgInternal, _aidl_return);
}
::ndk::ScopedAStatus P2pIface::setWfdR2DeviceInfo(
const std::vector<uint8_t>& in_info)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setWfdR2DeviceInfoInternal, in_info);
}
::ndk::ScopedAStatus P2pIface::removeClient(
const std::vector<uint8_t>& peer_address, bool isLegacyClient)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::removeClientInternal, peer_address, isLegacyClient);
}
::ndk::ScopedAStatus P2pIface::findOnSocialChannels(
int32_t in_timeoutInSec)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::findOnSocialChannelsInternal, in_timeoutInSec);
}
::ndk::ScopedAStatus P2pIface::findOnSpecificFrequency(
int32_t in_freq,
int32_t in_timeoutInSec)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::findOnSpecificFrequencyInternal,
in_freq, in_timeoutInSec);
}
::ndk::ScopedAStatus P2pIface::setVendorElements(
P2pFrameTypeMask in_frameTypeMask,
const std::vector<uint8_t>& in_vendorElemBytes)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::setVendorElementsInternal, in_frameTypeMask, in_vendorElemBytes);
}
::ndk::ScopedAStatus P2pIface::configureEapolIpAddressAllocationParams(
int32_t in_ipAddressGo, int32_t in_ipAddressMask,
int32_t in_ipAddressStart, int32_t in_ipAddressEnd)
{
return validateAndCall(
this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
&P2pIface::configureEapolIpAddressAllocationParamsInternal,
in_ipAddressGo, in_ipAddressMask, in_ipAddressStart, in_ipAddressEnd);
}
std::pair<std::string, ndk::ScopedAStatus> P2pIface::getNameInternal()
{
return {ifname_, ndk::ScopedAStatus::ok()};
}
std::pair<IfaceType, ndk::ScopedAStatus> P2pIface::getTypeInternal()
{
return {IfaceType::P2P, ndk::ScopedAStatus::ok()};
}
std::pair<std::shared_ptr<ISupplicantP2pNetwork>, ndk::ScopedAStatus>
P2pIface::addNetworkInternal()
{
std::shared_ptr<ISupplicantP2pNetwork> network;
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
struct wpa_ssid* ssid = wpa_supplicant_add_network(wpa_s);
if (!ssid) {
return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
AidlManager* aidl_manager = AidlManager::getInstance();
if (!aidl_manager ||
aidl_manager->getP2pNetworkAidlObjectByIfnameAndNetworkId(
wpa_s->ifname, ssid->id, &network)) {
return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
return {network, ndk::ScopedAStatus::ok()};
}
ndk::ScopedAStatus P2pIface::removeNetworkInternal(int32_t id)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
int result = wpa_supplicant_remove_network(wpa_s, id);
if (result == -1) {
return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
} else if (result != 0) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
std::pair<std::shared_ptr<ISupplicantP2pNetwork>, ndk::ScopedAStatus>
P2pIface::getNetworkInternal(int32_t id)
{
std::shared_ptr<ISupplicantP2pNetwork> network;
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
struct wpa_ssid* ssid = wpa_config_get_network(wpa_s->conf, id);
if (!ssid) {
return {network, createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN)};
}
AidlManager* aidl_manager = AidlManager::getInstance();
if (!aidl_manager ||
aidl_manager->getP2pNetworkAidlObjectByIfnameAndNetworkId(
wpa_s->ifname, ssid->id, &network)) {
return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
return {network, ndk::ScopedAStatus::ok()};
}
std::pair<std::vector<int32_t>, ndk::ScopedAStatus>
P2pIface::listNetworksInternal()
{
std::vector<int32_t> network_ids;
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
for (struct wpa_ssid* wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
wpa_ssid = wpa_ssid->next) {
network_ids.emplace_back(wpa_ssid->id);
}
return {std::move(network_ids), ndk::ScopedAStatus::ok()};
}
ndk::ScopedAStatus P2pIface::registerCallbackInternal(
const std::shared_ptr<ISupplicantP2pIfaceCallback>& callback)
{
AidlManager* aidl_manager = AidlManager::getInstance();
if (!aidl_manager ||
aidl_manager->addP2pIfaceCallbackAidlObject(ifname_, callback)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
P2pIface::getDeviceAddressInternal()
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
std::vector<uint8_t> addr(
wpa_s->global->p2p_dev_addr,
wpa_s->global->p2p_dev_addr + ETH_ALEN);
return {addr, ndk::ScopedAStatus::ok()};
}
ndk::ScopedAStatus P2pIface::setSsidPostfixInternal(
const std::vector<uint8_t>& postfix)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (p2p_set_ssid_postfix(
wpa_s->global->p2p, postfix.data(), postfix.size())) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::setGroupIdleInternal(
const std::string& group_ifname, uint32_t timeout_in_sec)
{
struct wpa_supplicant* wpa_group_s =
retrieveGroupIfacePtr(group_ifname);
if (!wpa_group_s) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
}
wpa_group_s->conf->p2p_group_idle = timeout_in_sec;
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::setPowerSaveInternal(
const std::string& group_ifname, bool enable)
{
struct wpa_supplicant* wpa_group_s =
retrieveGroupIfacePtr(group_ifname);
if (!wpa_group_s) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
}
if (wpa_drv_set_p2p_powersave(wpa_group_s, enable, -1, -1)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::findInternal(uint32_t timeout_in_sec)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
}
uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
if (wpas_p2p_find(
wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
nullptr, search_delay, 0, nullptr, 0, is6GhzAllowed(wpa_s))) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::stopFindInternal()
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
}
if (wpa_s->scan_res_handler == scanResJoinWrapper) {
wpa_printf(MSG_DEBUG, "P2P: Stop pending group scan for stopping find).");
pending_scan_res_join_callback = NULL;
wpa_s->scan_res_handler = scanResJoinIgnore;
}
wpas_p2p_stop_find(wpa_s);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::flushInternal()
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
wpa_s->force_long_sd = 0;
wpas_p2p_stop_find(wpa_s);
wpa_s->parent->p2ps_method_config_any = 0;
wpa_bss_flush(wpa_s);
if (wpa_s->global->p2p)
p2p_flush(wpa_s->global->p2p);
return ndk::ScopedAStatus::ok();
}
// This method only implements support for subset (needed by Android framework)
// of parameters that can be specified for connect.
std::pair<std::string, ndk::ScopedAStatus> P2pIface::connectInternal(
const std::vector<uint8_t>& peer_address,
WpsProvisionMethod provision_method,
const std::string& pre_selected_pin, bool join_existing_group,
bool persistent, uint32_t go_intent)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (go_intent > 15) {
return {"", createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
}
if (peer_address.size() != ETH_ALEN) {
return {"", createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
}
int go_intent_signed = join_existing_group ? -1 : go_intent;
p2p_wps_method wps_method = {};
switch (provision_method) {
case WpsProvisionMethod::PBC:
wps_method = WPS_PBC;
break;
case WpsProvisionMethod::DISPLAY:
wps_method = WPS_PIN_DISPLAY;
break;
case WpsProvisionMethod::KEYPAD:
wps_method = WPS_PIN_KEYPAD;
break;
}
int he = wpa_s->conf->p2p_go_he;
int vht = wpa_s->conf->p2p_go_vht;
int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
int edmg = wpa_s->conf->p2p_go_edmg;
const char* pin =
pre_selected_pin.length() > 0 ? pre_selected_pin.data() : nullptr;
int new_pin = wpas_p2p_connect(
wpa_s, peer_address.data(), pin, wps_method, persistent, false,
join_existing_group, false, go_intent_signed, 0, 0, -1, false, ht40,
vht, CONF_OPER_CHWIDTH_USE_HT, he, edmg, nullptr, 0, is6GhzAllowed(wpa_s));
if (new_pin < 0) {
return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
std::string pin_ret;
if (provision_method == WpsProvisionMethod::DISPLAY &&
pre_selected_pin.empty()) {
pin_ret = misc_utils::convertWpsPinToString(new_pin);
}
return {pin_ret, ndk::ScopedAStatus::ok()};
}
ndk::ScopedAStatus P2pIface::cancelConnectInternal()
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (wpa_s->scan_res_handler == scanResJoinWrapper) {
wpa_printf(MSG_DEBUG, "P2P: Stop pending group scan for canceling connect");
pending_scan_res_join_callback = NULL;
wpa_s->scan_res_handler = scanResJoinIgnore;
}
if (wpas_p2p_cancel(wpa_s)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::provisionDiscoveryInternal(
const std::vector<uint8_t>& peer_address,
WpsProvisionMethod provision_method)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
p2ps_provision* prov_param;
const char* config_method_str = nullptr;
if (peer_address.size() != ETH_ALEN) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
switch (provision_method) {
case WpsProvisionMethod::PBC:
config_method_str = kConfigMethodStrPbc;
break;
case WpsProvisionMethod::DISPLAY:
config_method_str = kConfigMethodStrDisplay;
break;
case WpsProvisionMethod::KEYPAD:
config_method_str = kConfigMethodStrKeypad;
break;
}
if (wpas_p2p_prov_disc(
wpa_s, peer_address.data(), config_method_str,
WPAS_P2P_PD_FOR_GO_NEG, nullptr)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::removeGroupInternal(const std::string& group_ifname)
{
struct wpa_supplicant* wpa_group_s =
retrieveGroupIfacePtr(group_ifname);
if (!wpa_group_s) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
}
if (wpas_p2p_group_remove(wpa_group_s, group_ifname.c_str())) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::rejectInternal(
const std::vector<uint8_t>& peer_address)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
}
if (peer_address.size() != ETH_ALEN) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
if (wpas_p2p_reject(wpa_s, peer_address.data())) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::inviteInternal(
const std::string& group_ifname,
const std::vector<uint8_t>& go_device_address,
const std::vector<uint8_t>& peer_address)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (peer_address.size() != ETH_ALEN) {
return {createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
if (wpas_p2p_invite_group(
wpa_s, group_ifname.c_str(), peer_address.data(),
go_device_address.data(), is6GhzAllowed(wpa_s))) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::reinvokeInternal(
int32_t persistent_network_id,
const std::vector<uint8_t>& peer_address)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
int he = wpa_s->conf->p2p_go_he;
int vht = wpa_s->conf->p2p_go_vht;
int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
int edmg = wpa_s->conf->p2p_go_edmg;
struct wpa_ssid* ssid =
wpa_config_get_network(wpa_s->conf, persistent_network_id);
if (ssid == NULL || ssid->disabled != 2) {
return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
}
if (peer_address.size() != ETH_ALEN) {
return {createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
if (wpas_p2p_invite(
wpa_s, peer_address.data(), ssid, NULL, 0, 0, ht40, vht,
CONF_OPER_CHWIDTH_USE_HT, 0, he, edmg, is6GhzAllowed(wpa_s))) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::configureExtListenInternal(
uint32_t period_in_millis, uint32_t interval_in_millis)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (wpas_p2p_ext_listen(wpa_s, period_in_millis, interval_in_millis)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::setListenChannelInternal(
uint32_t channel, uint32_t operating_class)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (p2p_set_listen_channel(
wpa_s->global->p2p, operating_class, channel, 1)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::setDisallowedFrequenciesInternal(
const std::vector<FreqRange>& ranges)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
using DestT = struct wpa_freq_range_list::wpa_freq_range;
DestT* freq_ranges = nullptr;
// Empty ranges is used to enable all frequencies.
if (ranges.size() != 0) {
freq_ranges = static_cast<DestT*>(
os_malloc(sizeof(DestT) * ranges.size()));
if (!freq_ranges) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
uint32_t i = 0;
for (const auto& range : ranges) {
freq_ranges[i].min = range.min;
freq_ranges[i].max = range.max;
i++;
}
}
os_free(wpa_s->global->p2p_disallow_freq.range);
wpa_s->global->p2p_disallow_freq.range = freq_ranges;
wpa_s->global->p2p_disallow_freq.num = ranges.size();
wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_DISALLOW);
return ndk::ScopedAStatus::ok();
}
std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> P2pIface::getSsidInternal(
const std::vector<uint8_t>& peer_address)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (peer_address.size() != ETH_ALEN) {
return {std::vector<uint8_t>(),
createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
const struct p2p_peer_info* info =
p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
if (!info) {
return {std::vector<uint8_t>(),
createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
const struct p2p_device* dev =
reinterpret_cast<const struct p2p_device*>(
(reinterpret_cast<const uint8_t*>(info)) -
offsetof(struct p2p_device, info));
std::vector<uint8_t> ssid;
if (dev && dev->oper_ssid_len) {
ssid.assign(
dev->oper_ssid, dev->oper_ssid + dev->oper_ssid_len);
}
return {ssid, ndk::ScopedAStatus::ok()};
}
std::pair<P2pGroupCapabilityMask, ndk::ScopedAStatus> P2pIface::getGroupCapabilityInternal(
const std::vector<uint8_t>& peer_address)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (peer_address.size() != ETH_ALEN) {
return {static_cast<P2pGroupCapabilityMask>(0),
createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
const struct p2p_peer_info* info =
p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
if (!info) {
return {static_cast<P2pGroupCapabilityMask>(0),
createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
return {static_cast<P2pGroupCapabilityMask>(info->group_capab),
ndk::ScopedAStatus::ok()};
}
ndk::ScopedAStatus P2pIface::addBonjourServiceInternal(
const std::vector<uint8_t>& query, const std::vector<uint8_t>& response)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
auto query_buf = misc_utils::convertVectorToWpaBuf(query);
auto response_buf = misc_utils::convertVectorToWpaBuf(response);
if (!query_buf || !response_buf) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
if (wpas_p2p_service_add_bonjour(
wpa_s, query_buf.get(), response_buf.get())) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
// If successful, the wpabuf is referenced internally and hence should
// not be freed.
query_buf.release();
response_buf.release();
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::removeBonjourServiceInternal(
const std::vector<uint8_t>& query)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
auto query_buf = misc_utils::convertVectorToWpaBuf(query);
if (!query_buf) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
if (wpas_p2p_service_del_bonjour(wpa_s, query_buf.get())) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::addUpnpServiceInternal(
uint32_t version, const std::string& service_name)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (wpas_p2p_service_add_upnp(wpa_s, version, service_name.c_str())) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::removeUpnpServiceInternal(
uint32_t version, const std::string& service_name)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (wpas_p2p_service_del_upnp(wpa_s, version, service_name.c_str())) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::flushServicesInternal()
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
wpas_p2p_service_flush(wpa_s);
return ndk::ScopedAStatus::ok();
}
std::pair<uint64_t, ndk::ScopedAStatus> P2pIface::requestServiceDiscoveryInternal(
const std::vector<uint8_t>& peer_address,
const std::vector<uint8_t>& query)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
auto query_buf = misc_utils::convertVectorToWpaBuf(query);
if (!query_buf) {
return {0, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
if (peer_address.size() != ETH_ALEN) {
return {0, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
const uint8_t* dst_addr = is_zero_ether_addr(peer_address.data())
? nullptr
: peer_address.data();
uint64_t identifier =
wpas_p2p_sd_request(wpa_s, dst_addr, query_buf.get());
if (identifier == 0) {
return {0, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
return {identifier, ndk::ScopedAStatus::ok()};
}
ndk::ScopedAStatus P2pIface::cancelServiceDiscoveryInternal(uint64_t identifier)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (wpas_p2p_sd_cancel_request(wpa_s, identifier)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::setMiracastModeInternal(
MiracastMode mode)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
uint8_t mode_internal = convertAidlMiracastModeToInternal(mode);
const std::string cmd_str =
kSetMiracastMode + std::to_string(mode_internal);
std::vector<char> cmd(
cmd_str.c_str(), cmd_str.c_str() + cmd_str.size() + 1);
char driver_cmd_reply_buf[4096] = {};
if (wpa_drv_driver_cmd(
wpa_s, cmd.data(), driver_cmd_reply_buf,
sizeof(driver_cmd_reply_buf))) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::startWpsPbcInternal(
const std::string& group_ifname, const std::vector<uint8_t>& bssid)
{
struct wpa_supplicant* wpa_group_s =
retrieveGroupIfacePtr(group_ifname);
if (!wpa_group_s) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
}
if (bssid.size() != ETH_ALEN) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
const uint8_t* bssid_addr =
is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
#ifdef CONFIG_AP
if (wpa_group_s->ap_iface) {
if (wpa_supplicant_ap_wps_pbc(wpa_group_s, bssid_addr, NULL)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
#endif /* CONFIG_AP */
if (wpas_wps_start_pbc(wpa_group_s, bssid_addr, 0, 0)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::startWpsPinKeypadInternal(
const std::string& group_ifname, const std::string& pin)
{
struct wpa_supplicant* wpa_group_s =
retrieveGroupIfacePtr(group_ifname);
if (!wpa_group_s) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
}
#ifdef CONFIG_AP
if (wpa_group_s->ap_iface) {
if (wpa_supplicant_ap_wps_pin(
wpa_group_s, nullptr, pin.c_str(), nullptr, 0, 0) < 0) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
#endif /* CONFIG_AP */
if (wpas_wps_start_pin(
wpa_group_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
std::pair<std::string, ndk::ScopedAStatus> P2pIface::startWpsPinDisplayInternal(
const std::string& group_ifname, const std::vector<uint8_t>& bssid)
{
struct wpa_supplicant* wpa_group_s =
retrieveGroupIfacePtr(group_ifname);
if (!wpa_group_s) {
return {"", createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN)};
}
if (bssid.size() != ETH_ALEN) {
return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
const uint8_t* bssid_addr =
is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
int pin = wpas_wps_start_pin(
wpa_group_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
if (pin < 0) {
return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
return {misc_utils::convertWpsPinToString(pin), ndk::ScopedAStatus::ok()};
}
ndk::ScopedAStatus P2pIface::cancelWpsInternal(const std::string& group_ifname)
{
struct wpa_supplicant* wpa_group_s =
retrieveGroupIfacePtr(group_ifname);
if (!wpa_group_s) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
}
if (wpas_wps_cancel(wpa_group_s)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::setWpsDeviceNameInternal(const std::string& name)
{
return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
}
ndk::ScopedAStatus P2pIface::setWpsDeviceTypeInternal(
const std::vector<uint8_t>& type)
{
std::array<uint8_t, 8> type_arr;
if (type.size() != 8) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
std::copy_n(type.begin(), 8, type_arr.begin());
return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type_arr);
}
ndk::ScopedAStatus P2pIface::setWpsManufacturerInternal(
const std::string& manufacturer)
{
return iface_config_utils::setWpsManufacturer(
retrieveIfacePtr(), manufacturer);
}
ndk::ScopedAStatus P2pIface::setWpsModelNameInternal(
const std::string& model_name)
{
return iface_config_utils::setWpsModelName(
retrieveIfacePtr(), model_name);
}
ndk::ScopedAStatus P2pIface::setWpsModelNumberInternal(
const std::string& model_number)
{
return iface_config_utils::setWpsModelNumber(
retrieveIfacePtr(), model_number);
}
ndk::ScopedAStatus P2pIface::setWpsSerialNumberInternal(
const std::string& serial_number)
{
return iface_config_utils::setWpsSerialNumber(
retrieveIfacePtr(), serial_number);
}
ndk::ScopedAStatus P2pIface::setWpsConfigMethodsInternal(WpsConfigMethods config_methods)
{
return iface_config_utils::setWpsConfigMethods(
retrieveIfacePtr(), static_cast<uint16_t>(config_methods));
}
ndk::ScopedAStatus P2pIface::enableWfdInternal(bool enable)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
wifi_display_enable(wpa_s->global, enable);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::setWfdDeviceInfoInternal(
const std::vector<uint8_t>& info)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
std::vector<char> wfd_device_info_hex(info.size() * 2 + 1);
wpa_snprintf_hex(
wfd_device_info_hex.data(), wfd_device_info_hex.size(), info.data(),
info.size());
// |wifi_display_subelem_set| expects the first 2 bytes
// to hold the lenght of the subelement. In this case it's
// fixed to 6, so prepend that.
std::string wfd_device_info_set_cmd_str =
std::to_string(kWfdDeviceInfoSubelemId) + " " +
kWfdDeviceInfoSubelemLenHexStr + wfd_device_info_hex.data();
std::vector<char> wfd_device_info_set_cmd(
wfd_device_info_set_cmd_str.c_str(),
wfd_device_info_set_cmd_str.c_str() +
wfd_device_info_set_cmd_str.size() + 1);
if (wifi_display_subelem_set(
wpa_s->global, wfd_device_info_set_cmd.data())) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
P2pIface::createNfcHandoverRequestMessageInternal()
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
auto buf = misc_utils::createWpaBufUniquePtr(
wpas_p2p_nfc_handover_req(wpa_s, 1));
if (!buf) {
return {std::vector<uint8_t>(),
createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
return {misc_utils::convertWpaBufToVector(buf.get()),
ndk::ScopedAStatus::ok()};
}
std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
P2pIface::createNfcHandoverSelectMessageInternal()
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
auto buf = misc_utils::createWpaBufUniquePtr(
wpas_p2p_nfc_handover_sel(wpa_s, 1, 0));
if (!buf) {
return {std::vector<uint8_t>(),
createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
}
return {misc_utils::convertWpaBufToVector(buf.get()),
ndk::ScopedAStatus::ok()};
}
ndk::ScopedAStatus P2pIface::reportNfcHandoverResponseInternal(
const std::vector<uint8_t>& request)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
auto req = misc_utils::convertVectorToWpaBuf(request);
auto sel = misc_utils::convertVectorToWpaBuf(std::vector<uint8_t>{0});
if (!req || !sel) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
if (wpas_p2p_nfc_report_handover(wpa_s, 0, req.get(), sel.get(), 0)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::reportNfcHandoverInitiationInternal(
const std::vector<uint8_t>& select)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
auto req = misc_utils::convertVectorToWpaBuf(std::vector<uint8_t>{0});
auto sel = misc_utils::convertVectorToWpaBuf(select);
if (!req || !sel) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
if (wpas_p2p_nfc_report_handover(wpa_s, 1, req.get(), sel.get(), 0)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::saveConfigInternal()
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (!wpa_s->conf->update_config) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
if (wpa_config_write(wpa_s->confname, wpa_s->conf)) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::addGroupInternal(
bool persistent, int32_t persistent_network_id)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
int he = wpa_s->conf->p2p_go_he;
int vht = wpa_s->conf->p2p_go_vht;
int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
int edmg = wpa_s->conf->p2p_go_edmg;
struct wpa_ssid* ssid =
wpa_config_get_network(wpa_s->conf, persistent_network_id);
if (ssid == NULL) {
if (wpas_p2p_group_add(
wpa_s, persistent, 0, 0, ht40, vht,
CONF_OPER_CHWIDTH_USE_HT, he, edmg, is6GhzAllowed(wpa_s))) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
} else {
return ndk::ScopedAStatus::ok();
}
} else if (ssid->disabled == 2) {
if (wpas_p2p_group_add_persistent(
wpa_s, ssid, 0, 0, 0, 0, ht40, vht,
CONF_OPER_CHWIDTH_USE_HT, he, edmg, NULL, 0, 0, is6GhzAllowed(wpa_s), 0, false)) {
return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
} else {
return ndk::ScopedAStatus::ok();
}
}
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
ndk::ScopedAStatus P2pIface::addGroupWithConfigInternal(
const std::vector<uint8_t>& ssid, const std::string& passphrase,
bool persistent, uint32_t freq, const std::vector<uint8_t>& peer_address,
bool joinExistingGroup)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
int he = wpa_s->conf->p2p_go_he;
int vht = wpa_s->conf->p2p_go_vht;
int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
int edmg = wpa_s->conf->p2p_go_edmg;
if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
}
if (!isSsidValid(ssid)) {
return createStatusWithMsg(SupplicantStatusCode::FAILURE_ARGS_INVALID,
"SSID is invalid.");
}
if (!isPskPassphraseValid(passphrase)) {
return createStatusWithMsg(SupplicantStatusCode::FAILURE_ARGS_INVALID,
"Passphrase is invalid.");
}
if (!joinExistingGroup) {
struct p2p_data *p2p = wpa_s->global->p2p;
os_memcpy(p2p->ssid, ssid.data(), ssid.size());
p2p->ssid_len = ssid.size();
p2p->ssid_set = 1;
os_memset(p2p->passphrase, 0, sizeof(p2p->passphrase));
os_memcpy(p2p->passphrase, passphrase.c_str(), passphrase.length());
p2p->passphrase_set = 1;
if (wpas_p2p_group_add(
wpa_s, persistent, freq, 0, ht40, vht,
CONF_OPER_CHWIDTH_USE_HT, he, edmg, is6GhzAllowed(wpa_s))) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
// The rest is for group join.
wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND before group join.");
wpas_p2p_stop_find(wpa_s);
if (peer_address.size() != ETH_ALEN) {
return createStatusWithMsg(SupplicantStatusCode::FAILURE_ARGS_INVALID,
"Peer address is invalid.");
}
if (joinGroup(wpa_s, peer_address.data(), ssid, passphrase, freq)) {
return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
"Failed to start scan.");
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::setMacRandomizationInternal(bool enable)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
bool currentEnabledState = !!wpa_s->conf->p2p_device_random_mac_addr;
u8 *addr = NULL;
// The same state, no change is needed.
if (currentEnabledState == enable) {
wpa_printf(MSG_DEBUG, "The random MAC is %s already.",
(enable) ? "enabled" : "disabled");
return ndk::ScopedAStatus::ok();
}
if (enable) {
wpa_s->conf->p2p_device_random_mac_addr = 1;
wpa_s->conf->p2p_interface_random_mac_addr = 1;
int status = wpas_p2p_mac_setup(wpa_s);
// restore config if it failed to set up MAC address.
if (status < 0) {
wpa_s->conf->p2p_device_random_mac_addr = 0;
wpa_s->conf->p2p_interface_random_mac_addr = 0;
if (status == -ENOTSUP) {
return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNSUPPORTED,
"Failed to set up MAC address, feature not supported.");
}
return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
"Failed to set up MAC address.");
}
} else {
// disable random MAC will use original MAC address
// regardless of any saved persistent groups.
if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
wpa_printf(MSG_ERROR, "Failed to restore MAC address");
return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
"Failed to restore MAC address.");
}
if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
wpa_printf(MSG_INFO, "Could not update MAC address information");
return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
"Failed to update MAC address.");
}
wpa_s->conf->p2p_device_random_mac_addr = 0;
wpa_s->conf->p2p_interface_random_mac_addr = 0;
}
// update internal data to send out correct device address in action frame.
os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
os_memcpy(wpa_s->global->p2p->cfg->dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::setEdmgInternal(bool enable)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
wpa_printf(MSG_DEBUG, "set p2p_go_edmg to %d", enable);
wpa_s->conf->p2p_go_edmg = enable ? 1 : 0;
wpa_s->p2p_go_edmg = enable ? 1 : 0;
return ndk::ScopedAStatus::ok();
}
std::pair<bool, ndk::ScopedAStatus> P2pIface::getEdmgInternal()
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
return {(wpa_s->p2p_go_edmg == 1), ndk::ScopedAStatus::ok()};
}
ndk::ScopedAStatus P2pIface::setWfdR2DeviceInfoInternal(
const std::vector<uint8_t>& info)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
uint32_t wfd_r2_device_info_hex_len = info.size() * 2 + 1;
std::vector<char> wfd_r2_device_info_hex(wfd_r2_device_info_hex_len);
wpa_snprintf_hex(
wfd_r2_device_info_hex.data(), wfd_r2_device_info_hex.size(),
info.data(),info.size());
std::string wfd_r2_device_info_set_cmd_str =
std::to_string(kWfdR2DeviceInfoSubelemId) + " " +
wfd_r2_device_info_hex.data();
std::vector<char> wfd_r2_device_info_set_cmd(
wfd_r2_device_info_set_cmd_str.c_str(),
wfd_r2_device_info_set_cmd_str.c_str() +
wfd_r2_device_info_set_cmd_str.size() + 1);
if (wifi_display_subelem_set(
wpa_s->global, wfd_r2_device_info_set_cmd.data())) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::removeClientInternal(
const std::vector<uint8_t>& peer_address, bool isLegacyClient)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (peer_address.size() != ETH_ALEN) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
wpas_p2p_remove_client(wpa_s, peer_address.data(), isLegacyClient? 1 : 0);
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::findOnSocialChannelsInternal(uint32_t timeout_in_sec)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
}
uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
if (wpas_p2p_find(
wpa_s, timeout_in_sec, P2P_FIND_ONLY_SOCIAL, 0, nullptr,
nullptr, search_delay, 0, nullptr, 0, is6GhzAllowed(wpa_s))) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::findOnSpecificFrequencyInternal(
uint32_t freq, uint32_t timeout_in_sec)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
}
uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
if (wpas_p2p_find(
wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
nullptr, search_delay, 0, nullptr, freq, is6GhzAllowed(wpa_s))) {
return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::setVendorElementsInternal(
P2pFrameTypeMask frameTypeMask,
const std::vector<uint8_t>& vendorElemBytes)
{
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
for (int i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
uint32_t bit = convertWpaP2pFrameTypeToHalP2pFrameTypeBit(i);
if (0 == bit) continue;
if (static_cast<uint32_t>(frameTypeMask) & bit) {
updateP2pVendorElem(wpa_s, (enum wpa_vendor_elem_frame) i, vendorElemBytes);
}
}
return ndk::ScopedAStatus::ok();
}
ndk::ScopedAStatus P2pIface::configureEapolIpAddressAllocationParamsInternal(
uint32_t ipAddressGo, uint32_t ipAddressMask,
uint32_t ipAddressStart, uint32_t ipAddressEnd)
{
wpa_printf(MSG_DEBUG, "P2P: Configure IP addresses for IP allocation in EAPOL"
" ipAddressGo: 0x%x mask: 0x%x Range - Start: 0x%x End: 0x%x",
ipAddressGo, ipAddressMask, ipAddressStart, ipAddressEnd);
struct wpa_supplicant* wpa_s = retrieveIfacePtr();
os_memcpy(wpa_s->conf->ip_addr_go, &ipAddressGo, 4);
os_memcpy(wpa_s->conf->ip_addr_mask, &ipAddressMask, 4);
os_memcpy(wpa_s->conf->ip_addr_start, &ipAddressStart, 4);
os_memcpy(wpa_s->conf->ip_addr_end, &ipAddressEnd, 4);
return ndk::ScopedAStatus::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* P2pIface::retrieveIfacePtr()
{
return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
}
/**
* Retrieve the underlying |wpa_supplicant| struct
* pointer for this group iface.
*/
wpa_supplicant* P2pIface::retrieveGroupIfacePtr(const std::string& group_ifname)
{
return wpa_supplicant_get_iface(wpa_global_, group_ifname.c_str());
}
} // namespace supplicant
} // namespace wifi
} // namespace hardware
} // namespace android
} // namespace aidl