Home | History | Annotate | Download | only in 1.0
      1 /*
      2  * hidl interface for wpa_supplicant daemon
      3  * Copyright (c) 2004-2016, Jouni Malinen <j (at) w1.fi>
      4  * Copyright (c) 2004-2016, Roshan Pius <rpius (at) google.com>
      5  *
      6  * This software may be distributed under the terms of the BSD license.
      7  * See README for more details.
      8  */
      9 
     10 #include "hidl_manager.h"
     11 #include "hidl_return_util.h"
     12 #include "iface_config_utils.h"
     13 #include "misc_utils.h"
     14 #include "sta_iface.h"
     15 
     16 extern "C" {
     17 #include "utils/eloop.h"
     18 #include "gas_query.h"
     19 #include "interworking.h"
     20 #include "hs20_supplicant.h"
     21 #include "wps_supplicant.h"
     22 }
     23 
     24 namespace {
     25 using android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
     26 using android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
     27 using android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
     28 using android::hardware::wifi::supplicant::V1_0::implementation::HidlManager;
     29 
     30 constexpr uint32_t kMaxAnqpElems = 100;
     31 constexpr char kGetMacAddress[] = "MACADDR";
     32 constexpr char kStartRxFilter[] = "RXFILTER-START";
     33 constexpr char kStopRxFilter[] = "RXFILTER-STOP";
     34 constexpr char kAddRxFilter[] = "RXFILTER-ADD";
     35 constexpr char kRemoveRxFilter[] = "RXFILTER-REMOVE";
     36 constexpr char kSetBtCoexistenceMode[] = "BTCOEXMODE";
     37 constexpr char kSetBtCoexistenceScanStart[] = "BTCOEXSCAN-START";
     38 constexpr char kSetBtCoexistenceScanStop[] = "BTCOEXSCAN-STOP";
     39 constexpr char kSetSupendModeEnabled[] = "SETSUSPENDMODE 1";
     40 constexpr char kSetSupendModeDisabled[] = "SETSUSPENDMODE 0";
     41 constexpr char kSetCountryCode[] = "COUNTRY";
     42 constexpr uint32_t kExtRadioWorkDefaultTimeoutInSec = static_cast<uint32_t>(
     43     ISupplicantStaIface::ExtRadioWorkDefaults::TIMEOUT_IN_SECS);
     44 constexpr char kExtRadioWorkNamePrefix[] = "ext:";
     45 
     46 uint8_t convertHidlRxFilterTypeToInternal(
     47     ISupplicantStaIface::RxFilterType type)
     48 {
     49 	switch (type) {
     50 	case ISupplicantStaIface::RxFilterType::V4_MULTICAST:
     51 		return 2;
     52 	case ISupplicantStaIface::RxFilterType::V6_MULTICAST:
     53 		return 3;
     54 	};
     55 	WPA_ASSERT(false);
     56 }
     57 
     58 uint8_t convertHidlBtCoexModeToInternal(
     59     ISupplicantStaIface::BtCoexistenceMode mode)
     60 {
     61 	switch (mode) {
     62 	case ISupplicantStaIface::BtCoexistenceMode::ENABLED:
     63 		return 0;
     64 	case ISupplicantStaIface::BtCoexistenceMode::DISABLED:
     65 		return 1;
     66 	case ISupplicantStaIface::BtCoexistenceMode::SENSE:
     67 		return 2;
     68 	};
     69 	WPA_ASSERT(false);
     70 }
     71 
     72 SupplicantStatus doZeroArgDriverCommand(
     73     struct wpa_supplicant *wpa_s, const char *cmd)
     74 {
     75 	std::vector<char> cmd_vec(cmd, cmd + strlen(cmd) + 1);
     76 	char driver_cmd_reply_buf[4096] = {};
     77 	if (wpa_drv_driver_cmd(
     78 		wpa_s, cmd_vec.data(), driver_cmd_reply_buf,
     79 		sizeof(driver_cmd_reply_buf))) {
     80 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
     81 	}
     82 	return {SupplicantStatusCode::SUCCESS, ""};
     83 }
     84 
     85 SupplicantStatus doOneArgDriverCommand(
     86     struct wpa_supplicant *wpa_s, const char *cmd, uint8_t arg)
     87 {
     88 	std::string cmd_str = std::string(cmd) + " " + std::to_string(arg);
     89 	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
     90 }
     91 
     92 SupplicantStatus doOneArgDriverCommand(
     93     struct wpa_supplicant *wpa_s, const char *cmd, const std::string &arg)
     94 {
     95 	std::string cmd_str = std::string(cmd) + " " + arg;
     96 	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
     97 }
     98 
     99 void endExtRadioWork(struct wpa_radio_work *work)
    100 {
    101 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
    102 	work->wpa_s->ext_work_in_progress = 0;
    103 	radio_work_done(work);
    104 	os_free(ework);
    105 }
    106 
    107 void extRadioWorkTimeoutCb(void *eloop_ctx, void *timeout_ctx)
    108 {
    109 	auto *work = static_cast<struct wpa_radio_work *>(eloop_ctx);
    110 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
    111 	wpa_dbg(
    112 	    work->wpa_s, MSG_DEBUG, "Timing out external radio work %u (%s)",
    113 	    ework->id, work->type);
    114 
    115 	HidlManager *hidl_manager = HidlManager::getInstance();
    116 	WPA_ASSERT(hidl_manager);
    117 	hidl_manager->notifyExtRadioWorkTimeout(work->wpa_s, ework->id);
    118 
    119 	endExtRadioWork(work);
    120 }
    121 
    122 void startExtRadioWork(struct wpa_radio_work *work)
    123 {
    124 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
    125 	work->wpa_s->ext_work_in_progress = 1;
    126 	if (!ework->timeout) {
    127 		ework->timeout = kExtRadioWorkDefaultTimeoutInSec;
    128 	}
    129 	eloop_register_timeout(
    130 	    ework->timeout, 0, extRadioWorkTimeoutCb, work, nullptr);
    131 }
    132 
    133 void extRadioWorkStartCb(struct wpa_radio_work *work, int deinit)
    134 {
    135 	// deinit==1 is invoked during interface removal. Since the HIDL
    136 	// interface does not support interface addition/removal, we don't
    137 	// need to handle this scenario.
    138 	WPA_ASSERT(!deinit);
    139 
    140 	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
    141 	wpa_dbg(
    142 	    work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)",
    143 	    ework->id, ework->type);
    144 
    145 	HidlManager *hidl_manager = HidlManager::getInstance();
    146 	WPA_ASSERT(hidl_manager);
    147 	hidl_manager->notifyExtRadioWorkStart(work->wpa_s, ework->id);
    148 
    149 	startExtRadioWork(work);
    150 }
    151 
    152 }  // namespace
    153 
    154 namespace android {
    155 namespace hardware {
    156 namespace wifi {
    157 namespace supplicant {
    158 namespace V1_0 {
    159 namespace implementation {
    160 using hidl_return_util::validateAndCall;
    161 
    162 StaIface::StaIface(struct wpa_global *wpa_global, const char ifname[])
    163     : wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
    164 {
    165 }
    166 
    167 void StaIface::invalidate() { is_valid_ = false; }
    168 bool StaIface::isValid()
    169 {
    170 	return (is_valid_ && (retrieveIfacePtr() != nullptr));
    171 }
    172 
    173 Return<void> StaIface::getName(getName_cb _hidl_cb)
    174 {
    175 	return validateAndCall(
    176 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    177 	    &StaIface::getNameInternal, _hidl_cb);
    178 }
    179 
    180 Return<void> StaIface::getType(getType_cb _hidl_cb)
    181 {
    182 	return validateAndCall(
    183 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    184 	    &StaIface::getTypeInternal, _hidl_cb);
    185 }
    186 
    187 Return<void> StaIface::addNetwork(addNetwork_cb _hidl_cb)
    188 {
    189 	return validateAndCall(
    190 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    191 	    &StaIface::addNetworkInternal, _hidl_cb);
    192 }
    193 
    194 Return<void> StaIface::removeNetwork(
    195     SupplicantNetworkId id, removeNetwork_cb _hidl_cb)
    196 {
    197 	return validateAndCall(
    198 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    199 	    &StaIface::removeNetworkInternal, _hidl_cb, id);
    200 }
    201 
    202 Return<void> StaIface::getNetwork(
    203     SupplicantNetworkId id, getNetwork_cb _hidl_cb)
    204 {
    205 	return validateAndCall(
    206 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    207 	    &StaIface::getNetworkInternal, _hidl_cb, id);
    208 }
    209 
    210 Return<void> StaIface::listNetworks(listNetworks_cb _hidl_cb)
    211 {
    212 	return validateAndCall(
    213 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    214 	    &StaIface::listNetworksInternal, _hidl_cb);
    215 }
    216 
    217 Return<void> StaIface::registerCallback(
    218     const sp<ISupplicantStaIfaceCallback> &callback,
    219     registerCallback_cb _hidl_cb)
    220 {
    221 	return validateAndCall(
    222 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    223 	    &StaIface::registerCallbackInternal, _hidl_cb, callback);
    224 }
    225 
    226 Return<void> StaIface::reassociate(reassociate_cb _hidl_cb)
    227 {
    228 	return validateAndCall(
    229 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    230 	    &StaIface::reassociateInternal, _hidl_cb);
    231 }
    232 
    233 Return<void> StaIface::reconnect(reconnect_cb _hidl_cb)
    234 {
    235 	return validateAndCall(
    236 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    237 	    &StaIface::reconnectInternal, _hidl_cb);
    238 }
    239 
    240 Return<void> StaIface::disconnect(disconnect_cb _hidl_cb)
    241 {
    242 	return validateAndCall(
    243 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    244 	    &StaIface::disconnectInternal, _hidl_cb);
    245 }
    246 
    247 Return<void> StaIface::setPowerSave(bool enable, setPowerSave_cb _hidl_cb)
    248 {
    249 	return validateAndCall(
    250 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    251 	    &StaIface::setPowerSaveInternal, _hidl_cb, enable);
    252 }
    253 
    254 Return<void> StaIface::initiateTdlsDiscover(
    255     const hidl_array<uint8_t, 6> &mac_address, initiateTdlsDiscover_cb _hidl_cb)
    256 {
    257 	return validateAndCall(
    258 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    259 	    &StaIface::initiateTdlsDiscoverInternal, _hidl_cb, mac_address);
    260 }
    261 
    262 Return<void> StaIface::initiateTdlsSetup(
    263     const hidl_array<uint8_t, 6> &mac_address, initiateTdlsSetup_cb _hidl_cb)
    264 {
    265 	return validateAndCall(
    266 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    267 	    &StaIface::initiateTdlsSetupInternal, _hidl_cb, mac_address);
    268 }
    269 
    270 Return<void> StaIface::initiateTdlsTeardown(
    271     const hidl_array<uint8_t, 6> &mac_address, initiateTdlsTeardown_cb _hidl_cb)
    272 {
    273 	return validateAndCall(
    274 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    275 	    &StaIface::initiateTdlsTeardownInternal, _hidl_cb, mac_address);
    276 }
    277 Return<void> StaIface::initiateAnqpQuery(
    278     const hidl_array<uint8_t, 6> &mac_address,
    279     const hidl_vec<ISupplicantStaIface::AnqpInfoId> &info_elements,
    280     const hidl_vec<ISupplicantStaIface::Hs20AnqpSubtypes> &sub_types,
    281     initiateAnqpQuery_cb _hidl_cb)
    282 {
    283 	return validateAndCall(
    284 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    285 	    &StaIface::initiateAnqpQueryInternal, _hidl_cb, mac_address,
    286 	    info_elements, sub_types);
    287 }
    288 
    289 Return<void> StaIface::initiateHs20IconQuery(
    290     const hidl_array<uint8_t, 6> &mac_address, const hidl_string &file_name,
    291     initiateHs20IconQuery_cb _hidl_cb)
    292 {
    293 	return validateAndCall(
    294 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    295 	    &StaIface::initiateHs20IconQueryInternal, _hidl_cb, mac_address,
    296 	    file_name);
    297 }
    298 
    299 Return<void> StaIface::getMacAddress(getMacAddress_cb _hidl_cb)
    300 {
    301 	return validateAndCall(
    302 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    303 	    &StaIface::getMacAddressInternal, _hidl_cb);
    304 }
    305 
    306 Return<void> StaIface::startRxFilter(startRxFilter_cb _hidl_cb)
    307 {
    308 	return validateAndCall(
    309 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    310 	    &StaIface::startRxFilterInternal, _hidl_cb);
    311 }
    312 
    313 Return<void> StaIface::stopRxFilter(stopRxFilter_cb _hidl_cb)
    314 {
    315 	return validateAndCall(
    316 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    317 	    &StaIface::stopRxFilterInternal, _hidl_cb);
    318 }
    319 
    320 Return<void> StaIface::addRxFilter(
    321     ISupplicantStaIface::RxFilterType type, addRxFilter_cb _hidl_cb)
    322 {
    323 	return validateAndCall(
    324 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    325 	    &StaIface::addRxFilterInternal, _hidl_cb, type);
    326 }
    327 
    328 Return<void> StaIface::removeRxFilter(
    329     ISupplicantStaIface::RxFilterType type, removeRxFilter_cb _hidl_cb)
    330 {
    331 	return validateAndCall(
    332 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    333 	    &StaIface::removeRxFilterInternal, _hidl_cb, type);
    334 }
    335 
    336 Return<void> StaIface::setBtCoexistenceMode(
    337     ISupplicantStaIface::BtCoexistenceMode mode,
    338     setBtCoexistenceMode_cb _hidl_cb)
    339 {
    340 	return validateAndCall(
    341 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    342 	    &StaIface::setBtCoexistenceModeInternal, _hidl_cb, mode);
    343 }
    344 
    345 Return<void> StaIface::setBtCoexistenceScanModeEnabled(
    346     bool enable, setBtCoexistenceScanModeEnabled_cb _hidl_cb)
    347 {
    348 	return validateAndCall(
    349 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    350 	    &StaIface::setBtCoexistenceScanModeEnabledInternal, _hidl_cb,
    351 	    enable);
    352 }
    353 
    354 Return<void> StaIface::setSuspendModeEnabled(
    355     bool enable, setSuspendModeEnabled_cb _hidl_cb)
    356 {
    357 	return validateAndCall(
    358 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    359 	    &StaIface::setSuspendModeEnabledInternal, _hidl_cb, enable);
    360 }
    361 
    362 Return<void> StaIface::setCountryCode(
    363     const hidl_array<int8_t, 2> &code, setCountryCode_cb _hidl_cb)
    364 {
    365 	return validateAndCall(
    366 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    367 	    &StaIface::setCountryCodeInternal, _hidl_cb, code);
    368 }
    369 
    370 Return<void> StaIface::startWpsRegistrar(
    371     const hidl_array<uint8_t, 6> &bssid, const hidl_string &pin,
    372     startWpsRegistrar_cb _hidl_cb)
    373 {
    374 	return validateAndCall(
    375 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    376 	    &StaIface::startWpsRegistrarInternal, _hidl_cb, bssid, pin);
    377 }
    378 
    379 Return<void> StaIface::startWpsPbc(
    380     const hidl_array<uint8_t, 6> &bssid, startWpsPbc_cb _hidl_cb)
    381 {
    382 	return validateAndCall(
    383 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    384 	    &StaIface::startWpsPbcInternal, _hidl_cb, bssid);
    385 }
    386 
    387 Return<void> StaIface::startWpsPinKeypad(
    388     const hidl_string &pin, startWpsPinKeypad_cb _hidl_cb)
    389 {
    390 	return validateAndCall(
    391 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    392 	    &StaIface::startWpsPinKeypadInternal, _hidl_cb, pin);
    393 }
    394 
    395 Return<void> StaIface::startWpsPinDisplay(
    396     const hidl_array<uint8_t, 6> &bssid, startWpsPinDisplay_cb _hidl_cb)
    397 {
    398 	return validateAndCall(
    399 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    400 	    &StaIface::startWpsPinDisplayInternal, _hidl_cb, bssid);
    401 }
    402 
    403 Return<void> StaIface::cancelWps(cancelWps_cb _hidl_cb)
    404 {
    405 	return validateAndCall(
    406 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    407 	    &StaIface::cancelWpsInternal, _hidl_cb);
    408 }
    409 
    410 Return<void> StaIface::setWpsDeviceName(
    411     const hidl_string &name, setWpsDeviceName_cb _hidl_cb)
    412 {
    413 	return validateAndCall(
    414 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    415 	    &StaIface::setWpsDeviceNameInternal, _hidl_cb, name);
    416 }
    417 
    418 Return<void> StaIface::setWpsDeviceType(
    419     const hidl_array<uint8_t, 8> &type, setWpsDeviceType_cb _hidl_cb)
    420 {
    421 	return validateAndCall(
    422 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    423 	    &StaIface::setWpsDeviceTypeInternal, _hidl_cb, type);
    424 }
    425 
    426 Return<void> StaIface::setWpsManufacturer(
    427     const hidl_string &manufacturer, setWpsManufacturer_cb _hidl_cb)
    428 {
    429 	return validateAndCall(
    430 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    431 	    &StaIface::setWpsManufacturerInternal, _hidl_cb, manufacturer);
    432 }
    433 
    434 Return<void> StaIface::setWpsModelName(
    435     const hidl_string &model_name, setWpsModelName_cb _hidl_cb)
    436 {
    437 	return validateAndCall(
    438 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    439 	    &StaIface::setWpsModelNameInternal, _hidl_cb, model_name);
    440 }
    441 
    442 Return<void> StaIface::setWpsModelNumber(
    443     const hidl_string &model_number, setWpsModelNumber_cb _hidl_cb)
    444 {
    445 	return validateAndCall(
    446 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    447 	    &StaIface::setWpsModelNumberInternal, _hidl_cb, model_number);
    448 }
    449 
    450 Return<void> StaIface::setWpsSerialNumber(
    451     const hidl_string &serial_number, setWpsSerialNumber_cb _hidl_cb)
    452 {
    453 	return validateAndCall(
    454 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    455 	    &StaIface::setWpsSerialNumberInternal, _hidl_cb, serial_number);
    456 }
    457 
    458 Return<void> StaIface::setWpsConfigMethods(
    459     uint16_t config_methods, setWpsConfigMethods_cb _hidl_cb)
    460 {
    461 	return validateAndCall(
    462 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    463 	    &StaIface::setWpsConfigMethodsInternal, _hidl_cb, config_methods);
    464 }
    465 
    466 Return<void> StaIface::setExternalSim(
    467     bool useExternalSim, setExternalSim_cb _hidl_cb)
    468 {
    469 	return validateAndCall(
    470 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    471 	    &StaIface::setExternalSimInternal, _hidl_cb, useExternalSim);
    472 }
    473 
    474 Return<void> StaIface::addExtRadioWork(
    475     const hidl_string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec,
    476     addExtRadioWork_cb _hidl_cb)
    477 {
    478 	return validateAndCall(
    479 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    480 	    &StaIface::addExtRadioWorkInternal, _hidl_cb, name, freq_in_mhz,
    481 	    timeout_in_sec);
    482 }
    483 
    484 Return<void> StaIface::removeExtRadioWork(
    485     uint32_t id, removeExtRadioWork_cb _hidl_cb)
    486 {
    487 	return validateAndCall(
    488 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    489 	    &StaIface::removeExtRadioWorkInternal, _hidl_cb, id);
    490 }
    491 
    492 Return<void> StaIface::enableAutoReconnect(
    493     bool enable, enableAutoReconnect_cb _hidl_cb)
    494 {
    495 	return validateAndCall(
    496 	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
    497 	    &StaIface::enableAutoReconnectInternal, _hidl_cb, enable);
    498 }
    499 
    500 std::pair<SupplicantStatus, std::string> StaIface::getNameInternal()
    501 {
    502 	return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
    503 }
    504 
    505 std::pair<SupplicantStatus, IfaceType> StaIface::getTypeInternal()
    506 {
    507 	return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::STA};
    508 }
    509 
    510 std::pair<SupplicantStatus, sp<ISupplicantNetwork>>
    511 StaIface::addNetworkInternal()
    512 {
    513 	android::sp<ISupplicantStaNetwork> network;
    514 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    515 	struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
    516 	if (!ssid) {
    517 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
    518 	}
    519 	HidlManager *hidl_manager = HidlManager::getInstance();
    520 	if (!hidl_manager ||
    521 	    hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId(
    522 		wpa_s->ifname, ssid->id, &network)) {
    523 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
    524 	}
    525 	return {{SupplicantStatusCode::SUCCESS, ""}, network};
    526 }
    527 
    528 SupplicantStatus StaIface::removeNetworkInternal(SupplicantNetworkId id)
    529 {
    530 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    531 	int result = wpa_supplicant_remove_network(wpa_s, id);
    532 	if (result == -1) {
    533 		return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""};
    534 	}
    535 	if (result != 0) {
    536 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    537 	}
    538 	return {SupplicantStatusCode::SUCCESS, ""};
    539 }
    540 
    541 std::pair<SupplicantStatus, sp<ISupplicantNetwork>>
    542 StaIface::getNetworkInternal(SupplicantNetworkId id)
    543 {
    544 	android::sp<ISupplicantStaNetwork> network;
    545 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    546 	struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id);
    547 	if (!ssid) {
    548 		return {{SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""},
    549 			network};
    550 	}
    551 	HidlManager *hidl_manager = HidlManager::getInstance();
    552 	if (!hidl_manager ||
    553 	    hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId(
    554 		wpa_s->ifname, ssid->id, &network)) {
    555 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
    556 	}
    557 	return {{SupplicantStatusCode::SUCCESS, ""}, network};
    558 }
    559 
    560 std::pair<SupplicantStatus, std::vector<SupplicantNetworkId>>
    561 StaIface::listNetworksInternal()
    562 {
    563 	std::vector<SupplicantNetworkId> network_ids;
    564 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    565 	for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
    566 	     wpa_ssid = wpa_ssid->next) {
    567 		network_ids.emplace_back(wpa_ssid->id);
    568 	}
    569 	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(network_ids)};
    570 }
    571 
    572 SupplicantStatus StaIface::registerCallbackInternal(
    573     const sp<ISupplicantStaIfaceCallback> &callback)
    574 {
    575 	HidlManager *hidl_manager = HidlManager::getInstance();
    576 	if (!hidl_manager ||
    577 	    hidl_manager->addStaIfaceCallbackHidlObject(ifname_, callback)) {
    578 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    579 	}
    580 	return {SupplicantStatusCode::SUCCESS, ""};
    581 }
    582 
    583 SupplicantStatus StaIface::reassociateInternal()
    584 {
    585 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    586 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
    587 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
    588 	}
    589 	wpas_request_connection(wpa_s);
    590 	return {SupplicantStatusCode::SUCCESS, ""};
    591 }
    592 
    593 SupplicantStatus StaIface::reconnectInternal()
    594 {
    595 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    596 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
    597 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
    598 	}
    599 	if (!wpa_s->disconnected) {
    600 		return {SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED,
    601 			""};
    602 	}
    603 	wpas_request_connection(wpa_s);
    604 	return {SupplicantStatusCode::SUCCESS, ""};
    605 }
    606 
    607 SupplicantStatus StaIface::disconnectInternal()
    608 {
    609 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    610 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
    611 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
    612 	}
    613 	wpas_request_disconnection(wpa_s);
    614 	return {SupplicantStatusCode::SUCCESS, ""};
    615 }
    616 
    617 SupplicantStatus StaIface::setPowerSaveInternal(bool enable)
    618 {
    619 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    620 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
    621 		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
    622 	}
    623 	if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) {
    624 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    625 	}
    626 	return {SupplicantStatusCode::SUCCESS, ""};
    627 }
    628 
    629 SupplicantStatus StaIface::initiateTdlsDiscoverInternal(
    630     const std::array<uint8_t, 6> &mac_address)
    631 {
    632 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    633 	int ret;
    634 	const u8 *peer = mac_address.data();
    635 	if (wpa_tdls_is_external_setup(wpa_s->wpa)) {
    636 		ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
    637 	} else {
    638 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
    639 	}
    640 	if (ret) {
    641 		wpa_printf(MSG_INFO, "StaIface: TDLS discover failed: %d", ret);
    642 	}
    643 	return {SupplicantStatusCode::SUCCESS, ""};
    644 }
    645 
    646 SupplicantStatus StaIface::initiateTdlsSetupInternal(
    647     const std::array<uint8_t, 6> &mac_address)
    648 {
    649 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    650 	int ret;
    651 	const u8 *peer = mac_address.data();
    652 	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
    653 	    !(wpa_s->conf->tdls_external_control)) {
    654 		wpa_tdls_remove(wpa_s->wpa, peer);
    655 		ret = wpa_tdls_start(wpa_s->wpa, peer);
    656 	} else {
    657 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
    658 	}
    659 	if (ret) {
    660 		wpa_printf(MSG_INFO, "StaIface: TDLS setup failed: %d", ret);
    661 	}
    662 	return {SupplicantStatusCode::SUCCESS, ""};
    663 }
    664 
    665 SupplicantStatus StaIface::initiateTdlsTeardownInternal(
    666     const std::array<uint8_t, 6> &mac_address)
    667 {
    668 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    669 	int ret;
    670 	const u8 *peer = mac_address.data();
    671 	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
    672 	    !(wpa_s->conf->tdls_external_control)) {
    673 		ret = wpa_tdls_teardown_link(
    674 		    wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
    675 	} else {
    676 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
    677 	}
    678 	if (ret) {
    679 		wpa_printf(MSG_INFO, "StaIface: TDLS teardown failed: %d", ret);
    680 	}
    681 	return {SupplicantStatusCode::SUCCESS, ""};
    682 }
    683 
    684 SupplicantStatus StaIface::initiateAnqpQueryInternal(
    685     const std::array<uint8_t, 6> &mac_address,
    686     const std::vector<ISupplicantStaIface::AnqpInfoId> &info_elements,
    687     const std::vector<ISupplicantStaIface::Hs20AnqpSubtypes> &sub_types)
    688 {
    689 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    690 	if (info_elements.size() > kMaxAnqpElems) {
    691 		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
    692 	}
    693 	uint16_t info_elems_buf[kMaxAnqpElems];
    694 	uint32_t num_info_elems = 0;
    695 	for (const auto &info_element : info_elements) {
    696 		info_elems_buf[num_info_elems++] =
    697 		    static_cast<std::underlying_type<
    698 			ISupplicantStaIface::AnqpInfoId>::type>(info_element);
    699 	}
    700 	uint32_t sub_types_bitmask = 0;
    701 	for (const auto &type : sub_types) {
    702 		sub_types_bitmask |= BIT(
    703 		    static_cast<std::underlying_type<
    704 			ISupplicantStaIface::Hs20AnqpSubtypes>::type>(type));
    705 	}
    706 	if (anqp_send_req(
    707 		wpa_s, mac_address.data(), info_elems_buf, num_info_elems,
    708 		sub_types_bitmask, false)) {
    709 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    710 	}
    711 	return {SupplicantStatusCode::SUCCESS, ""};
    712 }
    713 
    714 SupplicantStatus StaIface::initiateHs20IconQueryInternal(
    715     const std::array<uint8_t, 6> &mac_address, const std::string &file_name)
    716 {
    717 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    718 	wpa_s->fetch_osu_icon_in_progress = 0;
    719 	if (hs20_anqp_send_req(
    720 		wpa_s, mac_address.data(), BIT(HS20_STYPE_ICON_REQUEST),
    721 		reinterpret_cast<const uint8_t *>(file_name.c_str()),
    722 		file_name.size(), true)) {
    723 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    724 	}
    725 	return {SupplicantStatusCode::SUCCESS, ""};
    726 }
    727 
    728 std::pair<SupplicantStatus, std::array<uint8_t, 6>>
    729 StaIface::getMacAddressInternal()
    730 {
    731 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    732 	std::vector<char> cmd(
    733 	    kGetMacAddress, kGetMacAddress + sizeof(kGetMacAddress));
    734 	char driver_cmd_reply_buf[4096] = {};
    735 	int ret = wpa_drv_driver_cmd(
    736 	    wpa_s, cmd.data(), driver_cmd_reply_buf,
    737 	    sizeof(driver_cmd_reply_buf));
    738 	// Reply is of the format: "Macaddr = XX:XX:XX:XX:XX:XX"
    739 	std::string reply_str = driver_cmd_reply_buf;
    740 	if (ret < 0 || reply_str.empty() ||
    741 	    reply_str.find("=") == std::string::npos) {
    742 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
    743 	}
    744 	// Remove all whitespace first and then split using the delimiter "=".
    745 	reply_str.erase(
    746 	    remove_if(reply_str.begin(), reply_str.end(), isspace),
    747 	    reply_str.end());
    748 	std::string mac_addr_str =
    749 	    reply_str.substr(reply_str.find("=") + 1, reply_str.size());
    750 	std::array<uint8_t, 6> mac_addr;
    751 	if (hwaddr_aton(mac_addr_str.c_str(), mac_addr.data())) {
    752 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
    753 	}
    754 	return {{SupplicantStatusCode::SUCCESS, ""}, mac_addr};
    755 }
    756 
    757 SupplicantStatus StaIface::startRxFilterInternal()
    758 {
    759 	return doZeroArgDriverCommand(retrieveIfacePtr(), kStartRxFilter);
    760 }
    761 
    762 SupplicantStatus StaIface::stopRxFilterInternal()
    763 {
    764 	return doZeroArgDriverCommand(retrieveIfacePtr(), kStopRxFilter);
    765 }
    766 
    767 SupplicantStatus StaIface::addRxFilterInternal(
    768     ISupplicantStaIface::RxFilterType type)
    769 {
    770 	return doOneArgDriverCommand(
    771 	    retrieveIfacePtr(), kAddRxFilter,
    772 	    convertHidlRxFilterTypeToInternal(type));
    773 }
    774 
    775 SupplicantStatus StaIface::removeRxFilterInternal(
    776     ISupplicantStaIface::RxFilterType type)
    777 {
    778 	return doOneArgDriverCommand(
    779 	    retrieveIfacePtr(), kRemoveRxFilter,
    780 	    convertHidlRxFilterTypeToInternal(type));
    781 }
    782 
    783 SupplicantStatus StaIface::setBtCoexistenceModeInternal(
    784     ISupplicantStaIface::BtCoexistenceMode mode)
    785 {
    786 	return doOneArgDriverCommand(
    787 	    retrieveIfacePtr(), kSetBtCoexistenceMode,
    788 	    convertHidlBtCoexModeToInternal(mode));
    789 }
    790 
    791 SupplicantStatus StaIface::setBtCoexistenceScanModeEnabledInternal(bool enable)
    792 {
    793 	const char *cmd;
    794 	if (enable) {
    795 		cmd = kSetBtCoexistenceScanStart;
    796 	} else {
    797 		cmd = kSetBtCoexistenceScanStop;
    798 	}
    799 	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
    800 }
    801 
    802 SupplicantStatus StaIface::setSuspendModeEnabledInternal(bool enable)
    803 {
    804 	const char *cmd;
    805 	if (enable) {
    806 		cmd = kSetSupendModeEnabled;
    807 	} else {
    808 		cmd = kSetSupendModeDisabled;
    809 	}
    810 	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
    811 }
    812 
    813 SupplicantStatus StaIface::setCountryCodeInternal(
    814     const std::array<int8_t, 2> &code)
    815 {
    816 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    817 	SupplicantStatus status = doOneArgDriverCommand(
    818 	    wpa_s, kSetCountryCode,
    819 	    std::string(std::begin(code), std::end(code)));
    820 	if (status.code != SupplicantStatusCode::SUCCESS) {
    821 		return status;
    822 	}
    823 	struct p2p_data *p2p = wpa_s->global->p2p;
    824 	if (p2p) {
    825 		char country[3];
    826 		country[0] = code[0];
    827 		country[1] = code[1];
    828 		country[2] = 0x04;
    829 		p2p_set_country(p2p, country);
    830 	}
    831 	return {SupplicantStatusCode::SUCCESS, ""};
    832 }
    833 
    834 SupplicantStatus StaIface::startWpsRegistrarInternal(
    835     const std::array<uint8_t, 6> &bssid, const std::string &pin)
    836 {
    837 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    838 	if (wpas_wps_start_reg(wpa_s, bssid.data(), pin.c_str(), nullptr)) {
    839 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    840 	}
    841 	return {SupplicantStatusCode::SUCCESS, ""};
    842 }
    843 
    844 SupplicantStatus StaIface::startWpsPbcInternal(
    845     const std::array<uint8_t, 6> &bssid)
    846 {
    847 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    848 	const uint8_t *bssid_addr =
    849 	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
    850 	if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0)) {
    851 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    852 	}
    853 	return {SupplicantStatusCode::SUCCESS, ""};
    854 }
    855 
    856 SupplicantStatus StaIface::startWpsPinKeypadInternal(const std::string &pin)
    857 {
    858 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    859 	if (wpas_wps_start_pin(
    860 		wpa_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
    861 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    862 	}
    863 	return {SupplicantStatusCode::SUCCESS, ""};
    864 }
    865 
    866 std::pair<SupplicantStatus, std::string> StaIface::startWpsPinDisplayInternal(
    867     const std::array<uint8_t, 6> &bssid)
    868 {
    869 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    870 	const uint8_t *bssid_addr =
    871 	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
    872 	int pin =
    873 	    wpas_wps_start_pin(wpa_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
    874 	if (pin < 0) {
    875 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, ""};
    876 	}
    877 	return {{SupplicantStatusCode::SUCCESS, ""},
    878 		misc_utils::convertWpsPinToString(pin)};
    879 }
    880 
    881 SupplicantStatus StaIface::cancelWpsInternal()
    882 {
    883 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    884 	if (wpas_wps_cancel(wpa_s)) {
    885 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    886 	}
    887 	return {SupplicantStatusCode::SUCCESS, ""};
    888 }
    889 
    890 SupplicantStatus StaIface::setWpsDeviceNameInternal(const std::string &name)
    891 {
    892 	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
    893 }
    894 
    895 SupplicantStatus StaIface::setWpsDeviceTypeInternal(
    896     const std::array<uint8_t, 8> &type)
    897 {
    898 	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type);
    899 }
    900 
    901 SupplicantStatus StaIface::setWpsManufacturerInternal(
    902     const std::string &manufacturer)
    903 {
    904 	return iface_config_utils::setWpsManufacturer(
    905 	    retrieveIfacePtr(), manufacturer);
    906 }
    907 
    908 SupplicantStatus StaIface::setWpsModelNameInternal(
    909     const std::string &model_name)
    910 {
    911 	return iface_config_utils::setWpsModelName(
    912 	    retrieveIfacePtr(), model_name);
    913 }
    914 
    915 SupplicantStatus StaIface::setWpsModelNumberInternal(
    916     const std::string &model_number)
    917 {
    918 	return iface_config_utils::setWpsModelNumber(
    919 	    retrieveIfacePtr(), model_number);
    920 }
    921 
    922 SupplicantStatus StaIface::setWpsSerialNumberInternal(
    923     const std::string &serial_number)
    924 {
    925 	return iface_config_utils::setWpsSerialNumber(
    926 	    retrieveIfacePtr(), serial_number);
    927 }
    928 
    929 SupplicantStatus StaIface::setWpsConfigMethodsInternal(uint16_t config_methods)
    930 {
    931 	return iface_config_utils::setWpsConfigMethods(
    932 	    retrieveIfacePtr(), config_methods);
    933 }
    934 
    935 SupplicantStatus StaIface::setExternalSimInternal(bool useExternalSim)
    936 {
    937 	return iface_config_utils::setExternalSim(
    938 	    retrieveIfacePtr(), useExternalSim);
    939 }
    940 
    941 std::pair<SupplicantStatus, uint32_t> StaIface::addExtRadioWorkInternal(
    942     const std::string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec)
    943 {
    944 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    945 	auto *ework = static_cast<struct wpa_external_work *>(
    946 	    os_zalloc(sizeof(struct wpa_external_work)));
    947 	if (!ework) {
    948 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""},
    949 			UINT32_MAX};
    950 	}
    951 
    952 	std::string radio_work_name = kExtRadioWorkNamePrefix + name;
    953 	os_strlcpy(ework->type, radio_work_name.c_str(), sizeof(ework->type));
    954 	ework->timeout = timeout_in_sec;
    955 	wpa_s->ext_work_id++;
    956 	if (wpa_s->ext_work_id == 0) {
    957 		wpa_s->ext_work_id++;
    958 	}
    959 	ework->id = wpa_s->ext_work_id;
    960 
    961 	if (radio_add_work(
    962 		wpa_s, freq_in_mhz, ework->type, 0, extRadioWorkStartCb,
    963 		ework)) {
    964 		os_free(ework);
    965 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""},
    966 			UINT32_MAX};
    967 	}
    968 	return {SupplicantStatus{SupplicantStatusCode::SUCCESS, ""}, ework->id};
    969 }
    970 
    971 SupplicantStatus StaIface::removeExtRadioWorkInternal(uint32_t id)
    972 {
    973 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    974 	struct wpa_radio_work *work;
    975 	dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list)
    976 	{
    977 		if (os_strncmp(
    978 			work->type, kExtRadioWorkNamePrefix,
    979 			sizeof(kExtRadioWorkNamePrefix)) != 0)
    980 			continue;
    981 
    982 		auto *ework =
    983 		    static_cast<struct wpa_external_work *>(work->ctx);
    984 		if (ework->id != id)
    985 			continue;
    986 
    987 		wpa_dbg(
    988 		    wpa_s, MSG_DEBUG, "Completed external radio work %u (%s)",
    989 		    ework->id, ework->type);
    990 		eloop_cancel_timeout(extRadioWorkTimeoutCb, work, NULL);
    991 		endExtRadioWork(work);
    992 
    993 		return {SupplicantStatusCode::SUCCESS, ""};
    994 	}
    995 	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    996 }
    997 
    998 SupplicantStatus StaIface::enableAutoReconnectInternal(bool enable)
    999 {
   1000 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
   1001 	wpa_s->auto_reconnect_disabled = enable ? 0 : 1;
   1002 	return {SupplicantStatusCode::SUCCESS, ""};
   1003 }
   1004 
   1005 /**
   1006  * Retrieve the underlying |wpa_supplicant| struct
   1007  * pointer for this iface.
   1008  * If the underlying iface is removed, then all RPC method calls on this object
   1009  * will return failure.
   1010  */
   1011 wpa_supplicant *StaIface::retrieveIfacePtr()
   1012 {
   1013 	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
   1014 }
   1015 }  // namespace implementation
   1016 }  // namespace V1_0
   1017 }  // namespace wifi
   1018 }  // namespace supplicant
   1019 }  // namespace hardware
   1020 }  // namespace android
   1021