sta_iface.cpp revision 57ffbcfc79cd9f7a8389bfcbabea0bced5ed4dba
1e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt/* 257ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius * hidl interface for wpa_supplicant daemon 3e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi> 4e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com> 5e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt * 6e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt * This software may be distributed under the terms of the BSD license. 7e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt * See README for more details. 8e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt */ 9e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt 1057ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius#include "hidl_manager.h" 11e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt#include "iface.h" 12e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt 1357ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Piusnamespace wpa_supplicant_hidl { 14e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt 1532f9f5f37d24ed0346da2d320afa4fbea5713f00Roshan Pius#define RETURN_IF_IFACE_INVALID(wpa_s) \ 1632f9f5f37d24ed0346da2d320afa4fbea5713f00Roshan Pius { \ 1732f9f5f37d24ed0346da2d320afa4fbea5713f00Roshan Pius if (!wpa_s) { \ 1857ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status:: \ 1932f9f5f37d24ed0346da2d320afa4fbea5713f00Roshan Pius fromServiceSpecificError( \ 2032f9f5f37d24ed0346da2d320afa4fbea5713f00Roshan Pius ERROR_IFACE_INVALID, \ 2132f9f5f37d24ed0346da2d320afa4fbea5713f00Roshan Pius "wpa_supplicant does not control this " \ 2232f9f5f37d24ed0346da2d320afa4fbea5713f00Roshan Pius "interface."); \ 2332f9f5f37d24ed0346da2d320afa4fbea5713f00Roshan Pius } \ 2432f9f5f37d24ed0346da2d320afa4fbea5713f00Roshan Pius } // #define RETURN_IF_IFACE_INVALID(wpa_s) 258702ba9091ab6dd6702afedb7021c1caa277f8d4Roshan Pius 2654e763ada0bed9bf2c48415e82c5f04db23a3330Roshan PiusIface::Iface(struct wpa_global *wpa_global, const char ifname[]) 2754e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius : wpa_global_(wpa_global), ifname_(ifname) 2854e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius{ 2954e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius} 30e4663044d3a689fb5458247e9bc0f8b58cf72fcaDmitry Shmidt 3157ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Piusandroid::hidl::Status Iface::GetName(std::string *iface_name_out) 3254e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius{ 3354e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius // We could directly return the name we hold, but let's verify 3454e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius // if the underlying iface still exists. 358702ba9091ab6dd6702afedb7021c1caa277f8d4Roshan Pius RETURN_IF_IFACE_INVALID(retrieveIfacePtr()); 3654e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius *iface_name_out = ifname_; 3757ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::ok(); 3854e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius} 3954e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius 4057ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Piusandroid::hidl::Status Iface::AddNetwork( 41d6e375115b04e4ce30144a6a21ef4b1f8d3a0071Roshan Pius android::sp<fi::w1::wpa_supplicant::INetwork> *network_object_out) 42d6e375115b04e4ce30144a6a21ef4b1f8d3a0071Roshan Pius{ 43d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 448702ba9091ab6dd6702afedb7021c1caa277f8d4Roshan Pius RETURN_IF_IFACE_INVALID(wpa_s); 45d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius 46f745df8121ceec43d19edba801ab7b3d1c689a2aRoshan Pius struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s); 47d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius if (!ssid) { 4857ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 49d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius ERROR_GENERIC, "wpa_supplicant couldn't add this network."); 50d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius } 51d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius 5257ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius HidlManager *hidl_manager = HidlManager::getInstance(); 5357ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius if (!hidl_manager || 5457ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius hidl_manager->getNetworkHidlObjectByIfnameAndNetworkId( 55d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius wpa_s->ifname, ssid->id, network_object_out)) { 5657ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 57d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius ERROR_GENERIC, 5857ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius "wpa_supplicant encountered a hidl error."); 59d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius } 6057ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::ok(); 61d6e375115b04e4ce30144a6a21ef4b1f8d3a0071Roshan Pius} 62d6e375115b04e4ce30144a6a21ef4b1f8d3a0071Roshan Pius 6357ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Piusandroid::hidl::Status Iface::RemoveNetwork(int network_id) 64d6e375115b04e4ce30144a6a21ef4b1f8d3a0071Roshan Pius{ 65d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 668702ba9091ab6dd6702afedb7021c1caa277f8d4Roshan Pius RETURN_IF_IFACE_INVALID(wpa_s); 67d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius 68f745df8121ceec43d19edba801ab7b3d1c689a2aRoshan Pius int result = wpa_supplicant_remove_network(wpa_s, network_id); 69f745df8121ceec43d19edba801ab7b3d1c689a2aRoshan Pius if (result == -1) { 7057ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 71d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius ERROR_NETWORK_UNKNOWN, 72d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius "wpa_supplicant does not control this network."); 73d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius } 74f745df8121ceec43d19edba801ab7b3d1c689a2aRoshan Pius 75f745df8121ceec43d19edba801ab7b3d1c689a2aRoshan Pius if (result == -2) { 7657ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 77d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius ERROR_GENERIC, 78d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius "wpa_supplicant couldn't remove this network."); 79d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius } 8057ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::ok(); 81d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius} 82d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius 8357ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Piusandroid::hidl::Status Iface::GetNetwork( 84d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius int network_id, 85d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius android::sp<fi::w1::wpa_supplicant::INetwork> *network_object_out) 86d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius{ 87d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 888702ba9091ab6dd6702afedb7021c1caa277f8d4Roshan Pius RETURN_IF_IFACE_INVALID(wpa_s); 89d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius 90d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, network_id); 91d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius if (!ssid) { 9257ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 93d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius ERROR_NETWORK_UNKNOWN, 94d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius "wpa_supplicant does not control this network."); 95d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius } 96d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius 9757ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius HidlManager *hidl_manager = HidlManager::getInstance(); 9857ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius if (!hidl_manager || 9957ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius hidl_manager->getNetworkHidlObjectByIfnameAndNetworkId( 100d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius wpa_s->ifname, ssid->id, network_object_out)) { 10157ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 102d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius ERROR_GENERIC, 10357ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius "wpa_supplicant encountered a hidl error."); 104d385445171074ae070c5ddce94344ec0f06d15b4Roshan Pius } 10557ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::ok(); 106d6e375115b04e4ce30144a6a21ef4b1f8d3a0071Roshan Pius} 107d6e375115b04e4ce30144a6a21ef4b1f8d3a0071Roshan Pius 10857ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Piusandroid::hidl::Status Iface::RegisterCallback( 1090470cc8ceeb1a152594d90ce65cb13b6b907751bRoshan Pius const android::sp<fi::w1::wpa_supplicant::IIfaceCallback> &callback) 1100470cc8ceeb1a152594d90ce65cb13b6b907751bRoshan Pius{ 1110470cc8ceeb1a152594d90ce65cb13b6b907751bRoshan Pius struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 1128702ba9091ab6dd6702afedb7021c1caa277f8d4Roshan Pius RETURN_IF_IFACE_INVALID(wpa_s); 1138702ba9091ab6dd6702afedb7021c1caa277f8d4Roshan Pius 11457ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius HidlManager *hidl_manager = HidlManager::getInstance(); 11557ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius if (!hidl_manager || 11657ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius hidl_manager->addIfaceCallbackHidlObject(ifname_, callback)) { 11757ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 1180470cc8ceeb1a152594d90ce65cb13b6b907751bRoshan Pius ERROR_GENERIC, 11957ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius "wpa_supplicant encountered a hidl error."); 1200470cc8ceeb1a152594d90ce65cb13b6b907751bRoshan Pius } 12157ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::ok(); 1220470cc8ceeb1a152594d90ce65cb13b6b907751bRoshan Pius} 1230470cc8ceeb1a152594d90ce65cb13b6b907751bRoshan Pius 12457ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Piusandroid::hidl::Status Iface::Reassociate() 125f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius{ 126f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 127f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius RETURN_IF_IFACE_INVALID(wpa_s); 128f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius 129f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 13057ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 131f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius ERROR_IFACE_DISABLED); 132f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius } 133f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius wpas_request_connection(wpa_s); 13457ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::ok(); 135f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius} 136f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius 13757ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Piusandroid::hidl::Status Iface::Reconnect() 138f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius{ 139f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 140f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius RETURN_IF_IFACE_INVALID(wpa_s); 141f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius 142f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 14357ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 144f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius ERROR_IFACE_DISABLED); 145f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius } 146f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius if (!wpa_s->disconnected) { 14757ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 148f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius ERROR_IFACE_NOT_DISCONNECTED); 149f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius } 150f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius wpas_request_connection(wpa_s); 15157ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::ok(); 152f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius} 153f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius 15457ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Piusandroid::hidl::Status Iface::Disconnect() 155f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius{ 156f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 157f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius RETURN_IF_IFACE_INVALID(wpa_s); 158f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius 159f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) { 16057ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 161f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius ERROR_IFACE_DISABLED); 162f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius } 163f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius wpas_request_disconnection(wpa_s); 16457ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::ok(); 165f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius} 166f4e46cf18fbc77404ba7148a5de7334b602f6e55Roshan Pius 16757ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Piusandroid::hidl::Status Iface::SetPowerSave(bool enable) 168390ba2881ef621db480848b7e50b93d61542206aRoshan Pius{ 169390ba2881ef621db480848b7e50b93d61542206aRoshan Pius struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 170390ba2881ef621db480848b7e50b93d61542206aRoshan Pius RETURN_IF_IFACE_INVALID(wpa_s); 171390ba2881ef621db480848b7e50b93d61542206aRoshan Pius if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) { 172390ba2881ef621db480848b7e50b93d61542206aRoshan Pius const std::string error_msg = "Failed setting power save mode" + 173390ba2881ef621db480848b7e50b93d61542206aRoshan Pius std::to_string(enable) + "."; 17457ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 175390ba2881ef621db480848b7e50b93d61542206aRoshan Pius ERROR_GENERIC, error_msg.c_str()); 176390ba2881ef621db480848b7e50b93d61542206aRoshan Pius } 17757ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::ok(); 178390ba2881ef621db480848b7e50b93d61542206aRoshan Pius} 179390ba2881ef621db480848b7e50b93d61542206aRoshan Pius 18057ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Piusandroid::hidl::Status Iface::InitiateTDLSDiscover( 181390ba2881ef621db480848b7e50b93d61542206aRoshan Pius const std::vector<uint8_t> &mac_address) 182390ba2881ef621db480848b7e50b93d61542206aRoshan Pius{ 183390ba2881ef621db480848b7e50b93d61542206aRoshan Pius struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 184390ba2881ef621db480848b7e50b93d61542206aRoshan Pius RETURN_IF_IFACE_INVALID(wpa_s); 185390ba2881ef621db480848b7e50b93d61542206aRoshan Pius 186390ba2881ef621db480848b7e50b93d61542206aRoshan Pius if (mac_address.size() != MAC_ADDRESS_LEN) { 187390ba2881ef621db480848b7e50b93d61542206aRoshan Pius const std::string error_msg = 188390ba2881ef621db480848b7e50b93d61542206aRoshan Pius "Invalid MAC address value length: " + 189390ba2881ef621db480848b7e50b93d61542206aRoshan Pius std::to_string(mac_address.size()) + "."; 19057ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromExceptionCode( 19157ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius android::hidl::Status::EX_ILLEGAL_ARGUMENT, 192390ba2881ef621db480848b7e50b93d61542206aRoshan Pius error_msg.c_str()); 193390ba2881ef621db480848b7e50b93d61542206aRoshan Pius } 194390ba2881ef621db480848b7e50b93d61542206aRoshan Pius int ret; 195390ba2881ef621db480848b7e50b93d61542206aRoshan Pius const u8 *peer = mac_address.data(); 196390ba2881ef621db480848b7e50b93d61542206aRoshan Pius if (wpa_tdls_is_external_setup(wpa_s->wpa)) { 197390ba2881ef621db480848b7e50b93d61542206aRoshan Pius ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer); 198390ba2881ef621db480848b7e50b93d61542206aRoshan Pius } else { 199390ba2881ef621db480848b7e50b93d61542206aRoshan Pius ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer); 200390ba2881ef621db480848b7e50b93d61542206aRoshan Pius } 201390ba2881ef621db480848b7e50b93d61542206aRoshan Pius if (ret) { 20257ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 203390ba2881ef621db480848b7e50b93d61542206aRoshan Pius ERROR_GENERIC, "Failed to initiate TDLS Discover."); 204390ba2881ef621db480848b7e50b93d61542206aRoshan Pius } 20557ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::ok(); 206390ba2881ef621db480848b7e50b93d61542206aRoshan Pius} 207390ba2881ef621db480848b7e50b93d61542206aRoshan Pius 20857ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Piusandroid::hidl::Status Iface::InitiateTDLSSetup( 209390ba2881ef621db480848b7e50b93d61542206aRoshan Pius const std::vector<uint8_t> &mac_address) 210390ba2881ef621db480848b7e50b93d61542206aRoshan Pius{ 211390ba2881ef621db480848b7e50b93d61542206aRoshan Pius struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 212390ba2881ef621db480848b7e50b93d61542206aRoshan Pius RETURN_IF_IFACE_INVALID(wpa_s); 213390ba2881ef621db480848b7e50b93d61542206aRoshan Pius 214390ba2881ef621db480848b7e50b93d61542206aRoshan Pius if (mac_address.size() != MAC_ADDRESS_LEN) { 215390ba2881ef621db480848b7e50b93d61542206aRoshan Pius const std::string error_msg = 216390ba2881ef621db480848b7e50b93d61542206aRoshan Pius "Invalid MAC address value length: " + 217390ba2881ef621db480848b7e50b93d61542206aRoshan Pius std::to_string(mac_address.size()) + "."; 21857ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromExceptionCode( 21957ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius android::hidl::Status::EX_ILLEGAL_ARGUMENT, 220390ba2881ef621db480848b7e50b93d61542206aRoshan Pius error_msg.c_str()); 221390ba2881ef621db480848b7e50b93d61542206aRoshan Pius } 222390ba2881ef621db480848b7e50b93d61542206aRoshan Pius int ret; 223390ba2881ef621db480848b7e50b93d61542206aRoshan Pius const u8 *peer = mac_address.data(); 224390ba2881ef621db480848b7e50b93d61542206aRoshan Pius if (wpa_tdls_is_external_setup(wpa_s->wpa) && 225390ba2881ef621db480848b7e50b93d61542206aRoshan Pius !(wpa_s->conf->tdls_external_control)) { 226390ba2881ef621db480848b7e50b93d61542206aRoshan Pius wpa_tdls_remove(wpa_s->wpa, peer); 227390ba2881ef621db480848b7e50b93d61542206aRoshan Pius ret = wpa_tdls_start(wpa_s->wpa, peer); 228390ba2881ef621db480848b7e50b93d61542206aRoshan Pius } else { 229390ba2881ef621db480848b7e50b93d61542206aRoshan Pius ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer); 230390ba2881ef621db480848b7e50b93d61542206aRoshan Pius } 231390ba2881ef621db480848b7e50b93d61542206aRoshan Pius if (ret) { 23257ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 233390ba2881ef621db480848b7e50b93d61542206aRoshan Pius ERROR_GENERIC, "Failed to initiate TDLS Setup."); 234390ba2881ef621db480848b7e50b93d61542206aRoshan Pius } 23557ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::ok(); 236390ba2881ef621db480848b7e50b93d61542206aRoshan Pius} 237390ba2881ef621db480848b7e50b93d61542206aRoshan Pius 23857ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Piusandroid::hidl::Status Iface::InitiateTDLSTeardown( 239390ba2881ef621db480848b7e50b93d61542206aRoshan Pius const std::vector<uint8_t> &mac_address) 240390ba2881ef621db480848b7e50b93d61542206aRoshan Pius{ 241390ba2881ef621db480848b7e50b93d61542206aRoshan Pius struct wpa_supplicant *wpa_s = retrieveIfacePtr(); 242390ba2881ef621db480848b7e50b93d61542206aRoshan Pius RETURN_IF_IFACE_INVALID(wpa_s); 243390ba2881ef621db480848b7e50b93d61542206aRoshan Pius 244390ba2881ef621db480848b7e50b93d61542206aRoshan Pius if (mac_address.size() != MAC_ADDRESS_LEN) { 245390ba2881ef621db480848b7e50b93d61542206aRoshan Pius const std::string error_msg = 246390ba2881ef621db480848b7e50b93d61542206aRoshan Pius "Invalid MAC address value length: " + 247390ba2881ef621db480848b7e50b93d61542206aRoshan Pius std::to_string(mac_address.size()) + "."; 24857ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromExceptionCode( 24957ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius android::hidl::Status::EX_ILLEGAL_ARGUMENT, 250390ba2881ef621db480848b7e50b93d61542206aRoshan Pius error_msg.c_str()); 251390ba2881ef621db480848b7e50b93d61542206aRoshan Pius } 252390ba2881ef621db480848b7e50b93d61542206aRoshan Pius int ret; 253390ba2881ef621db480848b7e50b93d61542206aRoshan Pius const u8 *peer = mac_address.data(); 254390ba2881ef621db480848b7e50b93d61542206aRoshan Pius if (wpa_tdls_is_external_setup(wpa_s->wpa) && 255390ba2881ef621db480848b7e50b93d61542206aRoshan Pius !(wpa_s->conf->tdls_external_control)) { 256390ba2881ef621db480848b7e50b93d61542206aRoshan Pius ret = wpa_tdls_teardown_link( 257390ba2881ef621db480848b7e50b93d61542206aRoshan Pius wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED); 258390ba2881ef621db480848b7e50b93d61542206aRoshan Pius } else { 259390ba2881ef621db480848b7e50b93d61542206aRoshan Pius ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer); 260390ba2881ef621db480848b7e50b93d61542206aRoshan Pius } 261390ba2881ef621db480848b7e50b93d61542206aRoshan Pius if (ret) { 26257ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::fromServiceSpecificError( 263390ba2881ef621db480848b7e50b93d61542206aRoshan Pius ERROR_GENERIC, "Failed to initiate TDLS Teardown."); 264390ba2881ef621db480848b7e50b93d61542206aRoshan Pius } 26557ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius return android::hidl::Status::ok(); 266390ba2881ef621db480848b7e50b93d61542206aRoshan Pius} 267390ba2881ef621db480848b7e50b93d61542206aRoshan Pius 26854e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius/** 26954e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius * Retrieve the underlying |wpa_supplicant| struct pointer for 27054e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius * this iface. 27154e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius * If the underlying iface is removed, then all RPC method calls 27254e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius * on this object will return failure. 27354e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius */ 27454e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Piuswpa_supplicant *Iface::retrieveIfacePtr() 27554e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius{ 27654e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius return wpa_supplicant_get_iface( 27754e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius (struct wpa_global *)wpa_global_, ifname_.c_str()); 27854e763ada0bed9bf2c48415e82c5f04db23a3330Roshan Pius} 27957ffbcfc79cd9f7a8389bfcbabea0bced5ed4dbaRoshan Pius} // namespace wpa_supplicant_hidl 280