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 "p2p_network.h"
     13 
     14 extern "C" {
     15 #include "config_ssid.h"
     16 }
     17 
     18 namespace android {
     19 namespace hardware {
     20 namespace wifi {
     21 namespace supplicant {
     22 namespace V1_0 {
     23 namespace implementation {
     24 using hidl_return_util::validateAndCall;
     25 
     26 P2pNetwork::P2pNetwork(
     27     struct wpa_global *wpa_global, const char ifname[], int network_id)
     28     : wpa_global_(wpa_global),
     29       ifname_(ifname),
     30       network_id_(network_id),
     31       is_valid_(true)
     32 {
     33 }
     34 
     35 void P2pNetwork::invalidate() { is_valid_ = false; }
     36 bool P2pNetwork::isValid()
     37 {
     38 	return (is_valid_ && (retrieveNetworkPtr() != nullptr));
     39 }
     40 
     41 Return<void> P2pNetwork::getId(getId_cb _hidl_cb)
     42 {
     43 	return validateAndCall(
     44 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
     45 	    &P2pNetwork::getIdInternal, _hidl_cb);
     46 }
     47 
     48 Return<void> P2pNetwork::getInterfaceName(getInterfaceName_cb _hidl_cb)
     49 {
     50 	return validateAndCall(
     51 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
     52 	    &P2pNetwork::getInterfaceNameInternal, _hidl_cb);
     53 }
     54 
     55 Return<void> P2pNetwork::getType(getType_cb _hidl_cb)
     56 {
     57 	return validateAndCall(
     58 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
     59 	    &P2pNetwork::getTypeInternal, _hidl_cb);
     60 }
     61 
     62 Return<void> P2pNetwork::registerCallback(
     63     const sp<ISupplicantP2pNetworkCallback> &callback,
     64     registerCallback_cb _hidl_cb)
     65 {
     66 	return validateAndCall(
     67 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
     68 	    &P2pNetwork::registerCallbackInternal, _hidl_cb, callback);
     69 }
     70 
     71 Return<void> P2pNetwork::getSsid(getSsid_cb _hidl_cb)
     72 {
     73 	return validateAndCall(
     74 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
     75 	    &P2pNetwork::getSsidInternal, _hidl_cb);
     76 }
     77 
     78 Return<void> P2pNetwork::getBssid(getBssid_cb _hidl_cb)
     79 {
     80 	return validateAndCall(
     81 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
     82 	    &P2pNetwork::getBssidInternal, _hidl_cb);
     83 }
     84 
     85 Return<void> P2pNetwork::isCurrent(isCurrent_cb _hidl_cb)
     86 {
     87 	return validateAndCall(
     88 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
     89 	    &P2pNetwork::isCurrentInternal, _hidl_cb);
     90 }
     91 
     92 Return<void> P2pNetwork::isPersistent(isPersistent_cb _hidl_cb)
     93 {
     94 	return validateAndCall(
     95 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
     96 	    &P2pNetwork::isPersistentInternal, _hidl_cb);
     97 }
     98 
     99 Return<void> P2pNetwork::isGo(isGo_cb _hidl_cb)
    100 {
    101 	return validateAndCall(
    102 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
    103 	    &P2pNetwork::isGoInternal, _hidl_cb);
    104 }
    105 
    106 Return<void> P2pNetwork::setClientList(
    107     const hidl_vec<hidl_array<uint8_t, 6>> &clients, setClientList_cb _hidl_cb)
    108 {
    109 	return validateAndCall(
    110 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
    111 	    &P2pNetwork::setClientListInternal, _hidl_cb, clients);
    112 }
    113 
    114 Return<void> P2pNetwork::getClientList(getClientList_cb _hidl_cb)
    115 {
    116 	return validateAndCall(
    117 	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
    118 	    &P2pNetwork::getClientListInternal, _hidl_cb);
    119 }
    120 
    121 std::pair<SupplicantStatus, uint32_t> P2pNetwork::getIdInternal()
    122 {
    123 	return {{SupplicantStatusCode::SUCCESS, ""}, network_id_};
    124 }
    125 
    126 std::pair<SupplicantStatus, std::string> P2pNetwork::getInterfaceNameInternal()
    127 {
    128 	return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
    129 }
    130 
    131 std::pair<SupplicantStatus, IfaceType> P2pNetwork::getTypeInternal()
    132 {
    133 	return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::P2P};
    134 }
    135 
    136 SupplicantStatus P2pNetwork::registerCallbackInternal(
    137     const sp<ISupplicantP2pNetworkCallback> &callback)
    138 {
    139 	HidlManager *hidl_manager = HidlManager::getInstance();
    140 	if (!hidl_manager ||
    141 	    hidl_manager->addP2pNetworkCallbackHidlObject(
    142 		ifname_, network_id_, callback)) {
    143 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    144 	}
    145 	return {SupplicantStatusCode::SUCCESS, ""};
    146 }
    147 
    148 std::pair<SupplicantStatus, std::vector<uint8_t>> P2pNetwork::getSsidInternal()
    149 {
    150 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
    151 	return {{SupplicantStatusCode::SUCCESS, ""},
    152 		{wpa_ssid->ssid, wpa_ssid->ssid + wpa_ssid->ssid_len}};
    153 }
    154 
    155 std::pair<SupplicantStatus, std::array<uint8_t, 6>>
    156 P2pNetwork::getBssidInternal()
    157 {
    158 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
    159 	std::array<uint8_t, 6> bssid{};
    160 	if (wpa_ssid->bssid_set) {
    161 		os_memcpy(bssid.data(), wpa_ssid->bssid, ETH_ALEN);
    162 	}
    163 	return {{SupplicantStatusCode::SUCCESS, ""}, bssid};
    164 }
    165 
    166 std::pair<SupplicantStatus, bool> P2pNetwork::isCurrentInternal()
    167 {
    168 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
    169 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
    170 	return {{SupplicantStatusCode::SUCCESS, ""},
    171 		(wpa_s->current_ssid == wpa_ssid)};
    172 }
    173 
    174 std::pair<SupplicantStatus, bool> P2pNetwork::isPersistentInternal()
    175 {
    176 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
    177 	return {{SupplicantStatusCode::SUCCESS, ""}, (wpa_ssid->disabled == 2)};
    178 }
    179 
    180 std::pair<SupplicantStatus, bool> P2pNetwork::isGoInternal()
    181 {
    182 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
    183 	return {{SupplicantStatusCode::SUCCESS, ""},
    184 		(wpa_ssid->mode == wpa_ssid::wpas_mode::WPAS_MODE_P2P_GO)};
    185 }
    186 
    187 SupplicantStatus P2pNetwork::setClientListInternal(
    188     const std::vector<hidl_array<uint8_t, 6>> &clients)
    189 {
    190 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
    191 	os_free(wpa_ssid->p2p_client_list);
    192 	// Internal representation uses a generic MAC addr/mask storage format
    193 	// (even though the mask is always 0xFF'ed for p2p_client_list). So, the
    194 	// first 6 bytes holds the client MAC address and the next 6 bytes are
    195 	// OxFF'ed.
    196 	wpa_ssid->p2p_client_list =
    197 	    (u8 *)os_malloc(ETH_ALEN * 2 * clients.size());
    198 	if (!wpa_ssid->p2p_client_list) {
    199 		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
    200 	}
    201 	u8 *list = wpa_ssid->p2p_client_list;
    202 	for (const auto &client : clients) {
    203 		os_memcpy(list, client.data(), ETH_ALEN);
    204 		list += ETH_ALEN;
    205 		os_memset(list, 0xFF, ETH_ALEN);
    206 		list += ETH_ALEN;
    207 	}
    208 	wpa_ssid->num_p2p_clients = clients.size();
    209 	return {SupplicantStatusCode::SUCCESS, ""};
    210 }
    211 
    212 std::pair<SupplicantStatus, std::vector<hidl_array<uint8_t, 6>>>
    213 P2pNetwork::getClientListInternal()
    214 {
    215 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
    216 	if (!wpa_ssid->p2p_client_list) {
    217 		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
    218 	}
    219 	std::vector<hidl_array<uint8_t, 6>> clients;
    220 	u8 *list = wpa_ssid->p2p_client_list;
    221 	for (size_t i = 0; i < wpa_ssid->num_p2p_clients; i++) {
    222 		clients.emplace_back(list);
    223 		list += 2 * ETH_ALEN;
    224 	}
    225 	return {{SupplicantStatusCode::SUCCESS, ""}, clients};
    226 }
    227 
    228 /**
    229  * Retrieve the underlying |wpa_ssid| struct pointer for
    230  * this network.
    231  * If the underlying network is removed or the interface
    232  * this network belong to is removed, all RPC method calls
    233  * on this object will return failure.
    234  */
    235 struct wpa_ssid *P2pNetwork::retrieveNetworkPtr()
    236 {
    237 	wpa_supplicant *wpa_s = retrieveIfacePtr();
    238 	if (!wpa_s)
    239 		return nullptr;
    240 	return wpa_config_get_network(wpa_s->conf, network_id_);
    241 }
    242 
    243 /**
    244  * Retrieve the underlying |wpa_supplicant| struct
    245  * pointer for this network.
    246  */
    247 struct wpa_supplicant *P2pNetwork::retrieveIfacePtr()
    248 {
    249 	return wpa_supplicant_get_iface(
    250 	    (struct wpa_global *)wpa_global_, ifname_.c_str());
    251 }
    252 }  // namespace implementation
    253 }  // namespace V1_0
    254 }  // namespace wifi
    255 }  // namespace supplicant
    256 }  // namespace hardware
    257 }  // namespace android
    258