blob: 8d9cfc61880b09bb95f246e5995e7cdf3913ed99 [file] [log] [blame]
Roshan Pius3c4e8a32016-10-03 14:53:58 -07001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Roshan Pius3c4e8a32016-10-03 14:53:58 -070017#include <android-base/logging.h>
Roshan Pius9377a0d2017-10-06 13:18:54 -070018#include <cutils/properties.h>
Roshan Pius3c4e8a32016-10-03 14:53:58 -070019
Roshan Pius3c868522016-10-27 12:43:49 -070020#include "hidl_return_util.h"
Roshan Piuse2d0ab52016-12-05 15:24:20 -080021#include "hidl_struct_util.h"
Roshan Pius3c868522016-10-27 12:43:49 -070022#include "wifi_chip.h"
Roshan Pius5c055462016-10-11 08:27:27 -070023#include "wifi_status_util.h"
Roshan Pius3c4e8a32016-10-03 14:53:58 -070024
Roshan Pius35d958c2016-10-06 16:47:38 -070025namespace {
Roshan Pius35d958c2016-10-06 16:47:38 -070026using android::hardware::hidl_string;
Roshan Piusabcf78f2017-10-06 16:30:38 -070027using android::hardware::hidl_vec;
Roshan Pius2c06a3f2016-12-15 17:51:40 -080028using android::hardware::wifi::V1_0::ChipModeId;
Roshan Pius52947fb2016-11-18 11:38:07 -080029using android::hardware::wifi::V1_0::IfaceType;
Roshan Pius675609b2017-10-31 14:24:58 -070030using android::hardware::wifi::V1_0::IWifiChip;
Roshan Piusabcf78f2017-10-06 16:30:38 -070031using android::sp;
Roshan Pius52947fb2016-11-18 11:38:07 -080032
Roshan Pius2c06a3f2016-12-15 17:51:40 -080033constexpr ChipModeId kInvalidModeId = UINT32_MAX;
Roshan Piuscc338202017-11-02 13:54:09 -070034// These mode ID's should be unique (even across combo versions). Refer to
35// handleChipConfiguration() for it's usage.
36// Mode ID's for V1
37constexpr ChipModeId kV1StaChipModeId = 0;
38constexpr ChipModeId kV1ApChipModeId = 1;
39// Mode ID for V2
40constexpr ChipModeId kV2ChipModeId = 2;
Roshan Pius35d958c2016-10-06 16:47:38 -070041
Roshan Pius35d958c2016-10-06 16:47:38 -070042template <typename Iface>
Roshan Pius675609b2017-10-31 14:24:58 -070043void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
44 iface->invalidate();
45 ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface),
46 ifaces.end());
47}
48
49template <typename Iface>
50void invalidateAndClearAll(std::vector<sp<Iface>>& ifaces) {
51 for (const auto& iface : ifaces) {
Roshan Piusabcf78f2017-10-06 16:30:38 -070052 iface->invalidate();
Roshan Piusabcf78f2017-10-06 16:30:38 -070053 }
Roshan Pius675609b2017-10-31 14:24:58 -070054 ifaces.clear();
55}
56
57template <typename Iface>
58std::vector<hidl_string> getNames(std::vector<sp<Iface>>& ifaces) {
59 std::vector<hidl_string> names;
60 for (const auto& iface : ifaces) {
61 names.emplace_back(iface->getName());
62 }
63 return names;
64}
65
66template <typename Iface>
67sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces,
68 const std::string& name) {
69 std::vector<hidl_string> names;
70 for (const auto& iface : ifaces) {
71 if (name == iface->getName()) {
72 return iface;
73 }
74 }
75 return nullptr;
Roshan Pius35d958c2016-10-06 16:47:38 -070076}
Roshan Pius9377a0d2017-10-06 13:18:54 -070077
78std::string getWlan0IfaceName() {
Roshan Piusabcf78f2017-10-06 16:30:38 -070079 std::array<char, PROPERTY_VALUE_MAX> buffer;
80 property_get("wifi.interface", buffer.data(), "wlan0");
81 return buffer.data();
Roshan Pius9377a0d2017-10-06 13:18:54 -070082}
83
Roshan Pius9377a0d2017-10-06 13:18:54 -070084std::string getWlan1IfaceName() {
Roshan Pius8e3c7ef2017-11-03 09:43:08 -070085 std::array<char, PROPERTY_VALUE_MAX> buffer;
86 property_get("wifi.concurrent.interface", buffer.data(), "wlan1");
87 return buffer.data();
Roshan Pius9377a0d2017-10-06 13:18:54 -070088}
Roshan Pius9377a0d2017-10-06 13:18:54 -070089
90std::string getP2pIfaceName() {
Roshan Piusabcf78f2017-10-06 16:30:38 -070091 std::array<char, PROPERTY_VALUE_MAX> buffer;
92 property_get("wifi.direct.interface", buffer.data(), "p2p0");
93 return buffer.data();
Roshan Pius9377a0d2017-10-06 13:18:54 -070094}
95
Roshan Piusabcf78f2017-10-06 16:30:38 -070096} // namespace
Roshan Pius35d958c2016-10-06 16:47:38 -070097
Roshan Pius3c4e8a32016-10-03 14:53:58 -070098namespace android {
99namespace hardware {
100namespace wifi {
Etan Cohen6ce50902017-09-14 07:30:57 -0700101namespace V1_2 {
Roshan Pius79a99752016-10-04 13:03:58 -0700102namespace implementation {
Roshan Pius3c868522016-10-27 12:43:49 -0700103using hidl_return_util::validateAndCall;
Roshan Piusba38d9c2017-12-08 07:32:08 -0800104using hidl_return_util::validateAndCallWithLock;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700105
Roshan Pius52947fb2016-11-18 11:38:07 -0800106WifiChip::WifiChip(
Roshan Piusabcf78f2017-10-06 16:30:38 -0700107 ChipId chip_id, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
Roshan Pius200a17d2017-11-01 13:03:35 -0700108 const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
109 const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags)
Roshan Pius52947fb2016-11-18 11:38:07 -0800110 : chip_id_(chip_id),
111 legacy_hal_(legacy_hal),
112 mode_controller_(mode_controller),
Roshan Pius200a17d2017-11-01 13:03:35 -0700113 feature_flags_(feature_flags),
Roshan Pius52947fb2016-11-18 11:38:07 -0800114 is_valid_(true),
Roshan Pius48185b22016-12-15 19:10:30 -0800115 current_mode_id_(kInvalidModeId),
Roshan Piuscc338202017-11-02 13:54:09 -0700116 debug_ring_buffer_cb_registered_(false) {
117 populateModes();
118}
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700119
Roshan Piusaabe5752016-09-29 09:03:59 -0700120void WifiChip::invalidate() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700121 invalidateAndRemoveAllIfaces();
122 legacy_hal_.reset();
123 event_cb_handler_.invalidate();
124 is_valid_ = false;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700125}
126
Roshan Piusabcf78f2017-10-06 16:30:38 -0700127bool WifiChip::isValid() { return is_valid_; }
Roshan Pius3c868522016-10-27 12:43:49 -0700128
Roshan Piusd37341f2017-01-31 13:13:28 -0800129std::set<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700130 return event_cb_handler_.getCallbacks();
Roshan Pius203cb032016-12-14 17:41:20 -0800131}
132
Roshan Pius5c055462016-10-11 08:27:27 -0700133Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700134 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
135 &WifiChip::getIdInternal, hidl_status_cb);
Roshan Piuscd566bd2016-10-10 08:03:42 -0700136}
137
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700138Return<void> WifiChip::registerEventCallback(
Roshan Pius5c055462016-10-11 08:27:27 -0700139 const sp<IWifiChipEventCallback>& event_callback,
140 registerEventCallback_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700141 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
142 &WifiChip::registerEventCallbackInternal,
143 hidl_status_cb, event_callback);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700144}
145
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700146Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700147 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
148 &WifiChip::getCapabilitiesInternal, hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700149}
150
Roshan Pius5c055462016-10-11 08:27:27 -0700151Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700152 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
153 &WifiChip::getAvailableModesInternal,
154 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700155}
156
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800157Return<void> WifiChip::configureChip(ChipModeId mode_id,
Roshan Pius5c055462016-10-11 08:27:27 -0700158 configureChip_cb hidl_status_cb) {
Roshan Piusba38d9c2017-12-08 07:32:08 -0800159 return validateAndCallWithLock(
160 this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
161 &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700162}
163
Roshan Pius5c055462016-10-11 08:27:27 -0700164Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700165 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
166 &WifiChip::getModeInternal, hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700167}
168
Roshan Pius5c055462016-10-11 08:27:27 -0700169Return<void> WifiChip::requestChipDebugInfo(
170 requestChipDebugInfo_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700171 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
172 &WifiChip::requestChipDebugInfoInternal,
173 hidl_status_cb);
Roshan Pius5c055462016-10-11 08:27:27 -0700174}
175
176Return<void> WifiChip::requestDriverDebugDump(
177 requestDriverDebugDump_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700178 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
179 &WifiChip::requestDriverDebugDumpInternal,
180 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700181}
182
Roshan Pius5c055462016-10-11 08:27:27 -0700183Return<void> WifiChip::requestFirmwareDebugDump(
184 requestFirmwareDebugDump_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700185 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
186 &WifiChip::requestFirmwareDebugDumpInternal,
187 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700188}
189
Roshan Pius5c055462016-10-11 08:27:27 -0700190Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700191 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
192 &WifiChip::createApIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700193}
194
Roshan Pius5c055462016-10-11 08:27:27 -0700195Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700196 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
197 &WifiChip::getApIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700198}
199
Roshan Pius5c055462016-10-11 08:27:27 -0700200Return<void> WifiChip::getApIface(const hidl_string& ifname,
201 getApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700202 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
203 &WifiChip::getApIfaceInternal, hidl_status_cb,
204 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700205}
206
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800207Return<void> WifiChip::removeApIface(const hidl_string& ifname,
208 removeApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700209 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
210 &WifiChip::removeApIfaceInternal, hidl_status_cb,
211 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800212}
213
Roshan Pius5c055462016-10-11 08:27:27 -0700214Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700215 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
216 &WifiChip::createNanIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700217}
218
Roshan Pius5c055462016-10-11 08:27:27 -0700219Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700220 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
221 &WifiChip::getNanIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700222}
223
224Return<void> WifiChip::getNanIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700225 getNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700226 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
227 &WifiChip::getNanIfaceInternal, hidl_status_cb,
228 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700229}
230
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800231Return<void> WifiChip::removeNanIface(const hidl_string& ifname,
232 removeNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700233 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
234 &WifiChip::removeNanIfaceInternal, hidl_status_cb,
235 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800236}
237
Roshan Pius5c055462016-10-11 08:27:27 -0700238Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700239 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
240 &WifiChip::createP2pIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700241}
242
Roshan Pius5c055462016-10-11 08:27:27 -0700243Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700244 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
245 &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700246}
247
248Return<void> WifiChip::getP2pIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700249 getP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700250 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
251 &WifiChip::getP2pIfaceInternal, hidl_status_cb,
252 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700253}
254
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800255Return<void> WifiChip::removeP2pIface(const hidl_string& ifname,
256 removeP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700257 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
258 &WifiChip::removeP2pIfaceInternal, hidl_status_cb,
259 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800260}
261
Roshan Pius5c055462016-10-11 08:27:27 -0700262Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700263 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
264 &WifiChip::createStaIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700265}
266
Roshan Pius5c055462016-10-11 08:27:27 -0700267Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700268 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
269 &WifiChip::getStaIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700270}
271
272Return<void> WifiChip::getStaIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700273 getStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700274 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
275 &WifiChip::getStaIfaceInternal, hidl_status_cb,
276 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700277}
278
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800279Return<void> WifiChip::removeStaIface(const hidl_string& ifname,
280 removeStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700281 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
282 &WifiChip::removeStaIfaceInternal, hidl_status_cb,
283 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800284}
285
Roshan Pius5c055462016-10-11 08:27:27 -0700286Return<void> WifiChip::createRttController(
287 const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700288 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
289 &WifiChip::createRttControllerInternal,
290 hidl_status_cb, bound_iface);
Roshan Pius59268282016-10-06 20:23:47 -0700291}
292
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700293Return<void> WifiChip::getDebugRingBuffersStatus(
294 getDebugRingBuffersStatus_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700295 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
296 &WifiChip::getDebugRingBuffersStatusInternal,
297 hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700298}
299
300Return<void> WifiChip::startLoggingToDebugRingBuffer(
Roshan Piusabcf78f2017-10-06 16:30:38 -0700301 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
302 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700303 startLoggingToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700304 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
305 &WifiChip::startLoggingToDebugRingBufferInternal,
306 hidl_status_cb, ring_name, verbose_level,
307 max_interval_in_sec, min_data_size_in_bytes);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700308}
309
310Return<void> WifiChip::forceDumpToDebugRingBuffer(
311 const hidl_string& ring_name,
312 forceDumpToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700313 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
314 &WifiChip::forceDumpToDebugRingBufferInternal,
315 hidl_status_cb, ring_name);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700316}
317
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800318Return<void> WifiChip::stopLoggingToDebugRingBuffer(
319 stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700320 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
321 &WifiChip::stopLoggingToDebugRingBufferInternal,
322 hidl_status_cb);
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800323}
324
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700325Return<void> WifiChip::getDebugHostWakeReasonStats(
326 getDebugHostWakeReasonStats_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700327 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
328 &WifiChip::getDebugHostWakeReasonStatsInternal,
329 hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700330}
331
Roshan Pius203cb032016-12-14 17:41:20 -0800332Return<void> WifiChip::enableDebugErrorAlerts(
333 bool enable, enableDebugErrorAlerts_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700334 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
335 &WifiChip::enableDebugErrorAlertsInternal,
336 hidl_status_cb, enable);
Roshan Pius203cb032016-12-14 17:41:20 -0800337}
338
Roshan Pius735ff432017-07-25 08:48:08 -0700339Return<void> WifiChip::selectTxPowerScenario(
340 TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700341 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
342 &WifiChip::selectTxPowerScenarioInternal,
343 hidl_status_cb, scenario);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700344}
345
Roshan Pius735ff432017-07-25 08:48:08 -0700346Return<void> WifiChip::resetTxPowerScenario(
347 resetTxPowerScenario_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700348 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
349 &WifiChip::resetTxPowerScenarioInternal,
350 hidl_status_cb);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700351}
352
Roshan Pius35d958c2016-10-06 16:47:38 -0700353void WifiChip::invalidateAndRemoveAllIfaces() {
Roshan Pius675609b2017-10-31 14:24:58 -0700354 invalidateAndClearAll(ap_ifaces_);
355 invalidateAndClearAll(nan_ifaces_);
356 invalidateAndClearAll(p2p_ifaces_);
357 invalidateAndClearAll(sta_ifaces_);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700358 // Since all the ifaces are invalid now, all RTT controller objects
359 // using those ifaces also need to be invalidated.
360 for (const auto& rtt : rtt_controllers_) {
361 rtt->invalidate();
362 }
363 rtt_controllers_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -0700364}
365
Roshan Pius3c868522016-10-27 12:43:49 -0700366std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700367 return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700368}
369
370WifiStatus WifiChip::registerEventCallbackInternal(
371 const sp<IWifiChipEventCallback>& event_callback) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700372 if (!event_cb_handler_.addCallback(event_callback)) {
373 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
374 }
375 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius3c868522016-10-27 12:43:49 -0700376}
377
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700378std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700379 legacy_hal::wifi_error legacy_status;
380 uint32_t legacy_feature_set;
381 uint32_t legacy_logger_feature_set;
382 std::tie(legacy_status, legacy_feature_set) =
383 legacy_hal_.lock()->getSupportedFeatureSet(getWlan0IfaceName());
384 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
385 return {createWifiStatusFromLegacyError(legacy_status), 0};
386 }
387 std::tie(legacy_status, legacy_logger_feature_set) =
388 legacy_hal_.lock()->getLoggerSupportedFeatureSet(getWlan0IfaceName());
389 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius876220f2017-12-28 16:19:06 -0800390 // some devices don't support querying logger feature set
391 legacy_logger_feature_set = 0;
Roshan Piusabcf78f2017-10-06 16:30:38 -0700392 }
393 uint32_t hidl_caps;
394 if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
395 legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
396 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
397 }
398 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700399}
400
Roshan Pius3c868522016-10-27 12:43:49 -0700401std::pair<WifiStatus, std::vector<IWifiChip::ChipMode>>
402WifiChip::getAvailableModesInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700403 return {createWifiStatus(WifiStatusCode::SUCCESS), modes_};
Roshan Pius3c868522016-10-27 12:43:49 -0700404}
405
Roshan Piusba38d9c2017-12-08 07:32:08 -0800406WifiStatus WifiChip::configureChipInternal(
407 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
408 ChipModeId mode_id) {
Roshan Piuscc338202017-11-02 13:54:09 -0700409 if (!isValidModeId(mode_id)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700410 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
411 }
412 if (mode_id == current_mode_id_) {
413 LOG(DEBUG) << "Already in the specified mode " << mode_id;
414 return createWifiStatus(WifiStatusCode::SUCCESS);
415 }
Roshan Piusba38d9c2017-12-08 07:32:08 -0800416 WifiStatus status = handleChipConfiguration(lock, mode_id);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700417 if (status.code != WifiStatusCode::SUCCESS) {
418 for (const auto& callback : event_cb_handler_.getCallbacks()) {
419 if (!callback->onChipReconfigureFailure(status).isOk()) {
420 LOG(ERROR)
421 << "Failed to invoke onChipReconfigureFailure callback";
422 }
423 }
424 return status;
425 }
Roshan Piusd37341f2017-01-31 13:13:28 -0800426 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700427 if (!callback->onChipReconfigured(mode_id).isOk()) {
428 LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
429 }
Roshan Pius52947fb2016-11-18 11:38:07 -0800430 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700431 current_mode_id_ = mode_id;
Roshan Piusba38d9c2017-12-08 07:32:08 -0800432 LOG(INFO) << "Configured chip in mode " << mode_id;
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800433 return status;
Roshan Pius3c868522016-10-27 12:43:49 -0700434}
435
436std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700437 if (!isValidModeId(current_mode_id_)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700438 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE),
439 current_mode_id_};
440 }
441 return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700442}
443
444std::pair<WifiStatus, IWifiChip::ChipDebugInfo>
445WifiChip::requestChipDebugInfoInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700446 IWifiChip::ChipDebugInfo result;
447 legacy_hal::wifi_error legacy_status;
448 std::string driver_desc;
449 std::tie(legacy_status, driver_desc) =
450 legacy_hal_.lock()->getDriverVersion(getWlan0IfaceName());
451 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
452 LOG(ERROR) << "Failed to get driver version: "
453 << legacyErrorToString(legacy_status);
454 WifiStatus status = createWifiStatusFromLegacyError(
455 legacy_status, "failed to get driver version");
456 return {status, result};
457 }
458 result.driverDescription = driver_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700459
Roshan Piusabcf78f2017-10-06 16:30:38 -0700460 std::string firmware_desc;
461 std::tie(legacy_status, firmware_desc) =
462 legacy_hal_.lock()->getFirmwareVersion(getWlan0IfaceName());
463 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
464 LOG(ERROR) << "Failed to get firmware version: "
465 << legacyErrorToString(legacy_status);
466 WifiStatus status = createWifiStatusFromLegacyError(
467 legacy_status, "failed to get firmware version");
468 return {status, result};
469 }
470 result.firmwareDescription = firmware_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700471
Roshan Piusabcf78f2017-10-06 16:30:38 -0700472 return {createWifiStatus(WifiStatusCode::SUCCESS), result};
Roshan Pius3c868522016-10-27 12:43:49 -0700473}
474
475std::pair<WifiStatus, std::vector<uint8_t>>
476WifiChip::requestDriverDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700477 legacy_hal::wifi_error legacy_status;
478 std::vector<uint8_t> driver_dump;
479 std::tie(legacy_status, driver_dump) =
480 legacy_hal_.lock()->requestDriverMemoryDump(getWlan0IfaceName());
481 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
482 LOG(ERROR) << "Failed to get driver debug dump: "
483 << legacyErrorToString(legacy_status);
484 return {createWifiStatusFromLegacyError(legacy_status),
485 std::vector<uint8_t>()};
486 }
487 return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
Roshan Pius3c868522016-10-27 12:43:49 -0700488}
489
490std::pair<WifiStatus, std::vector<uint8_t>>
491WifiChip::requestFirmwareDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700492 legacy_hal::wifi_error legacy_status;
493 std::vector<uint8_t> firmware_dump;
494 std::tie(legacy_status, firmware_dump) =
495 legacy_hal_.lock()->requestFirmwareMemoryDump(getWlan0IfaceName());
496 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
497 LOG(ERROR) << "Failed to get firmware debug dump: "
498 << legacyErrorToString(legacy_status);
499 return {createWifiStatusFromLegacyError(legacy_status), {}};
500 }
501 return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
Roshan Pius3c868522016-10-27 12:43:49 -0700502}
503
504std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700505 if (!canCurrentModeSupportIfaceOfType(IfaceType::AP)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700506 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -0800507 }
Roshan Pius8e3c7ef2017-11-03 09:43:08 -0700508 std::string ifname = allocateApOrStaIfaceName();
Roshan Pius675609b2017-10-31 14:24:58 -0700509 sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_);
510 ap_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700511 for (const auto& callback : event_cb_handler_.getCallbacks()) {
512 if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
513 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
514 }
515 }
Roshan Pius675609b2017-10-31 14:24:58 -0700516 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700517}
518
519std::pair<WifiStatus, std::vector<hidl_string>>
520WifiChip::getApIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700521 if (ap_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700522 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
523 }
Roshan Pius675609b2017-10-31 14:24:58 -0700524 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -0700525}
526
527std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::getApIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800528 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700529 const auto iface = findUsingName(ap_ifaces_, ifname);
530 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700531 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
532 }
Roshan Pius675609b2017-10-31 14:24:58 -0700533 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700534}
535
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800536WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700537 const auto iface = findUsingName(ap_ifaces_, ifname);
538 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700539 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800540 }
Roshan Pius675609b2017-10-31 14:24:58 -0700541 invalidateAndClear(ap_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700542 for (const auto& callback : event_cb_handler_.getCallbacks()) {
543 if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
544 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
545 }
546 }
547 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800548}
549
Roshan Pius3c868522016-10-27 12:43:49 -0700550std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700551 if (!canCurrentModeSupportIfaceOfType(IfaceType::NAN)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700552 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Etan Cohenc5700402017-03-08 16:43:38 -0800553 }
Roshan Pius8e3c7ef2017-11-03 09:43:08 -0700554 // These are still assumed to be based on wlan0.
Roshan Piuscc338202017-11-02 13:54:09 -0700555 std::string ifname = getWlan0IfaceName();
556 sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_);
557 nan_ifaces_.push_back(iface);
558 for (const auto& callback : event_cb_handler_.getCallbacks()) {
559 if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
560 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
561 }
562 }
563 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700564}
565
566std::pair<WifiStatus, std::vector<hidl_string>>
567WifiChip::getNanIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700568 if (nan_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700569 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
570 }
Roshan Pius675609b2017-10-31 14:24:58 -0700571 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -0700572}
573
574std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::getNanIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800575 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700576 const auto iface = findUsingName(nan_ifaces_, ifname);
577 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700578 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
579 }
Roshan Pius675609b2017-10-31 14:24:58 -0700580 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700581}
582
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800583WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700584 const auto iface = findUsingName(nan_ifaces_, ifname);
585 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700586 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800587 }
Roshan Pius675609b2017-10-31 14:24:58 -0700588 invalidateAndClear(nan_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700589 for (const auto& callback : event_cb_handler_.getCallbacks()) {
590 if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
591 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
592 }
593 }
594 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800595}
596
Roshan Pius3c868522016-10-27 12:43:49 -0700597std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700598 if (!canCurrentModeSupportIfaceOfType(IfaceType::P2P)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700599 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -0800600 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700601 std::string ifname = getP2pIfaceName();
Roshan Pius675609b2017-10-31 14:24:58 -0700602 sp<WifiP2pIface> iface = new WifiP2pIface(ifname, legacy_hal_);
603 p2p_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700604 for (const auto& callback : event_cb_handler_.getCallbacks()) {
605 if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
606 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
607 }
608 }
Roshan Pius675609b2017-10-31 14:24:58 -0700609 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700610}
611
612std::pair<WifiStatus, std::vector<hidl_string>>
613WifiChip::getP2pIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700614 if (p2p_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700615 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
616 }
Roshan Pius675609b2017-10-31 14:24:58 -0700617 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -0700618}
619
620std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800621 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700622 const auto iface = findUsingName(p2p_ifaces_, ifname);
623 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700624 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
625 }
Roshan Pius675609b2017-10-31 14:24:58 -0700626 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700627}
628
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800629WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700630 const auto iface = findUsingName(p2p_ifaces_, ifname);
631 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700632 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800633 }
Roshan Pius675609b2017-10-31 14:24:58 -0700634 invalidateAndClear(p2p_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700635 for (const auto& callback : event_cb_handler_.getCallbacks()) {
636 if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
637 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
638 }
639 }
640 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800641}
642
Roshan Pius3c868522016-10-27 12:43:49 -0700643std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700644 if (!canCurrentModeSupportIfaceOfType(IfaceType::STA)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700645 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -0800646 }
Roshan Pius8e3c7ef2017-11-03 09:43:08 -0700647 std::string ifname = allocateApOrStaIfaceName();
Roshan Pius675609b2017-10-31 14:24:58 -0700648 sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_);
649 sta_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700650 for (const auto& callback : event_cb_handler_.getCallbacks()) {
651 if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
652 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
653 }
654 }
Roshan Pius675609b2017-10-31 14:24:58 -0700655 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700656}
657
658std::pair<WifiStatus, std::vector<hidl_string>>
659WifiChip::getStaIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700660 if (sta_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700661 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
662 }
Roshan Pius675609b2017-10-31 14:24:58 -0700663 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -0700664}
665
666std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::getStaIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800667 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700668 const auto iface = findUsingName(sta_ifaces_, ifname);
669 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700670 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
671 }
Roshan Pius675609b2017-10-31 14:24:58 -0700672 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700673}
674
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800675WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700676 const auto iface = findUsingName(sta_ifaces_, ifname);
677 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700678 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800679 }
Roshan Pius675609b2017-10-31 14:24:58 -0700680 invalidateAndClear(sta_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700681 for (const auto& callback : event_cb_handler_.getCallbacks()) {
682 if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
683 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
684 }
685 }
686 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800687}
688
Roshan Pius3c868522016-10-27 12:43:49 -0700689std::pair<WifiStatus, sp<IWifiRttController>>
690WifiChip::createRttControllerInternal(const sp<IWifiIface>& bound_iface) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700691 sp<WifiRttController> rtt =
692 new WifiRttController(getWlan0IfaceName(), bound_iface, legacy_hal_);
693 rtt_controllers_.emplace_back(rtt);
694 return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
Roshan Pius3c868522016-10-27 12:43:49 -0700695}
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700696
697std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
698WifiChip::getDebugRingBuffersStatusInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700699 legacy_hal::wifi_error legacy_status;
700 std::vector<legacy_hal::wifi_ring_buffer_status>
701 legacy_ring_buffer_status_vec;
702 std::tie(legacy_status, legacy_ring_buffer_status_vec) =
703 legacy_hal_.lock()->getRingBuffersStatus(getWlan0IfaceName());
704 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
705 return {createWifiStatusFromLegacyError(legacy_status), {}};
706 }
707 std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
708 if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
709 legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
710 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
711 }
712 return {createWifiStatus(WifiStatusCode::SUCCESS),
713 hidl_ring_buffer_status_vec};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700714}
715
716WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
Roshan Piusabcf78f2017-10-06 16:30:38 -0700717 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
718 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
719 WifiStatus status = registerDebugRingBufferCallback();
720 if (status.code != WifiStatusCode::SUCCESS) {
721 return status;
722 }
723 legacy_hal::wifi_error legacy_status =
724 legacy_hal_.lock()->startRingBufferLogging(
725 getWlan0IfaceName(), ring_name,
726 static_cast<
727 std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
728 verbose_level),
729 max_interval_in_sec, min_data_size_in_bytes);
730 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700731}
732
733WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800734 const hidl_string& ring_name) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700735 WifiStatus status = registerDebugRingBufferCallback();
736 if (status.code != WifiStatusCode::SUCCESS) {
737 return status;
738 }
739 legacy_hal::wifi_error legacy_status =
740 legacy_hal_.lock()->getRingBufferData(getWlan0IfaceName(), ring_name);
741 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700742}
743
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800744WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700745 legacy_hal::wifi_error legacy_status =
746 legacy_hal_.lock()->deregisterRingBufferCallbackHandler(
747 getWlan0IfaceName());
748 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800749}
750
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700751std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
752WifiChip::getDebugHostWakeReasonStatsInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700753 legacy_hal::wifi_error legacy_status;
754 legacy_hal::WakeReasonStats legacy_stats;
755 std::tie(legacy_status, legacy_stats) =
756 legacy_hal_.lock()->getWakeReasonStats(getWlan0IfaceName());
757 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
758 return {createWifiStatusFromLegacyError(legacy_status), {}};
759 }
760 WifiDebugHostWakeReasonStats hidl_stats;
761 if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats,
762 &hidl_stats)) {
763 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
764 }
765 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700766}
767
Roshan Pius203cb032016-12-14 17:41:20 -0800768WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700769 legacy_hal::wifi_error legacy_status;
770 if (enable) {
771 android::wp<WifiChip> weak_ptr_this(this);
772 const auto& on_alert_callback = [weak_ptr_this](
773 int32_t error_code,
774 std::vector<uint8_t> debug_data) {
775 const auto shared_ptr_this = weak_ptr_this.promote();
776 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
777 LOG(ERROR) << "Callback invoked on an invalid object";
778 return;
779 }
780 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
781 if (!callback->onDebugErrorAlert(error_code, debug_data)
782 .isOk()) {
783 LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
784 }
785 }
786 };
787 legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
Roshan Piusacededb2017-10-06 14:59:26 -0700788 getWlan0IfaceName(), on_alert_callback);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700789 } else {
790 legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
Roshan Piusacededb2017-10-06 14:59:26 -0700791 getWlan0IfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -0700792 }
793 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius203cb032016-12-14 17:41:20 -0800794}
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800795
Roshan Pius735ff432017-07-25 08:48:08 -0700796WifiStatus WifiChip::selectTxPowerScenarioInternal(TxPowerScenario scenario) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700797 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
798 getWlan0IfaceName(),
799 hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
800 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700801}
802
Roshan Pius735ff432017-07-25 08:48:08 -0700803WifiStatus WifiChip::resetTxPowerScenarioInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700804 auto legacy_status =
805 legacy_hal_.lock()->resetTxPowerScenario(getWlan0IfaceName());
806 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700807}
808
Roshan Piusba38d9c2017-12-08 07:32:08 -0800809WifiStatus WifiChip::handleChipConfiguration(
810 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
811 ChipModeId mode_id) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700812 // If the chip is already configured in a different mode, stop
813 // the legacy HAL and then start it after firmware mode change.
Roshan Piuscc338202017-11-02 13:54:09 -0700814 if (isValidModeId(current_mode_id_)) {
Roshan Piusba38d9c2017-12-08 07:32:08 -0800815 LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_
816 << " to mode " << mode_id;
817 invalidateAndRemoveAllIfaces();
818 legacy_hal::wifi_error legacy_status =
819 legacy_hal_.lock()->stop(lock, []() {});
820 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
821 LOG(ERROR) << "Failed to stop legacy HAL: "
822 << legacyErrorToString(legacy_status);
823 return createWifiStatusFromLegacyError(legacy_status);
824 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700825 }
Roshan Piuscc338202017-11-02 13:54:09 -0700826 // Firmware mode change not needed for V2 devices.
827 bool success = true;
828 if (mode_id == kV1StaChipModeId) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700829 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
Roshan Piuscc338202017-11-02 13:54:09 -0700830 } else if (mode_id == kV1ApChipModeId) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700831 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
832 }
833 if (!success) {
834 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
835 }
836 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
837 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
838 LOG(ERROR) << "Failed to start legacy HAL: "
839 << legacyErrorToString(legacy_status);
840 return createWifiStatusFromLegacyError(legacy_status);
841 }
842 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800843}
Roshan Pius48185b22016-12-15 19:10:30 -0800844
845WifiStatus WifiChip::registerDebugRingBufferCallback() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700846 if (debug_ring_buffer_cb_registered_) {
847 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius48185b22016-12-15 19:10:30 -0800848 }
Roshan Pius3797e182017-03-30 18:01:54 -0700849
Roshan Piusabcf78f2017-10-06 16:30:38 -0700850 android::wp<WifiChip> weak_ptr_this(this);
851 const auto& on_ring_buffer_data_callback =
852 [weak_ptr_this](const std::string& /* name */,
853 const std::vector<uint8_t>& data,
854 const legacy_hal::wifi_ring_buffer_status& status) {
855 const auto shared_ptr_this = weak_ptr_this.promote();
856 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
857 LOG(ERROR) << "Callback invoked on an invalid object";
858 return;
859 }
860 WifiDebugRingBufferStatus hidl_status;
861 if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(
862 status, &hidl_status)) {
863 LOG(ERROR) << "Error converting ring buffer status";
864 return;
865 }
866 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
867 if (!callback->onDebugRingBufferDataAvailable(hidl_status, data)
868 .isOk()) {
869 LOG(ERROR)
870 << "Failed to invoke onDebugRingBufferDataAvailable"
871 << " callback on: " << toString(callback);
872 }
873 }
874 };
875 legacy_hal::wifi_error legacy_status =
876 legacy_hal_.lock()->registerRingBufferCallbackHandler(
877 getWlan0IfaceName(), on_ring_buffer_data_callback);
Roshan Pius48185b22016-12-15 19:10:30 -0800878
Roshan Piusabcf78f2017-10-06 16:30:38 -0700879 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
880 debug_ring_buffer_cb_registered_ = true;
881 }
882 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius48185b22016-12-15 19:10:30 -0800883}
884
Roshan Piuscc338202017-11-02 13:54:09 -0700885void WifiChip::populateModes() {
886 // The chip combination supported for current devices is fixed.
887 // They can be one of the following based on device features:
888 // a) 2 separate modes of operation with 1 interface combination each:
889 // Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN(optional)
890 // concurrent iface operations.
891 // Mode 2 (AP mode): Will support 1 AP iface operation.
892 //
893 // b) 1 mode of operation with 2 interface combinations
894 // (conditional on isDualInterfaceSupported()):
895 // Interface Combination 1: Will support 1 STA and 1 P2P or NAN(optional)
896 // concurrent iface operations.
897 // Interface Combination 2: Will support 1 STA and 1 STA or AP concurrent
898 // iface operations.
899 // If Aware is enabled (conditional on isAwareSupported()), the iface
900 // combination will be modified to support either P2P or NAN in place of
901 // just P2P.
902 if (feature_flags_.lock()->isDualInterfaceSupported()) {
903 // V2 Iface combinations for Mode Id = 2.
904 const IWifiChip::ChipIfaceCombinationLimit
905 chip_iface_combination_limit_1 = {{IfaceType::STA}, 1};
906 const IWifiChip::ChipIfaceCombinationLimit
907 chip_iface_combination_limit_2 = {{IfaceType::STA, IfaceType::AP},
908 1};
909 IWifiChip::ChipIfaceCombinationLimit chip_iface_combination_limit_3;
910 if (feature_flags_.lock()->isAwareSupported()) {
911 chip_iface_combination_limit_3 = {{IfaceType::P2P, IfaceType::NAN},
912 1};
913 } else {
914 chip_iface_combination_limit_3 = {{IfaceType::P2P}, 1};
915 }
916 const IWifiChip::ChipIfaceCombination chip_iface_combination_1 = {
917 {chip_iface_combination_limit_1, chip_iface_combination_limit_2}};
918 const IWifiChip::ChipIfaceCombination chip_iface_combination_2 = {
919 {chip_iface_combination_limit_1, chip_iface_combination_limit_3}};
920 const IWifiChip::ChipMode chip_mode = {
921 kV2ChipModeId,
922 {chip_iface_combination_1, chip_iface_combination_2}};
923 modes_ = {chip_mode};
924 } else {
925 // V1 Iface combinations for Mode Id = 0. (STA Mode)
926 const IWifiChip::ChipIfaceCombinationLimit
927 sta_chip_iface_combination_limit_1 = {{IfaceType::STA}, 1};
928 IWifiChip::ChipIfaceCombinationLimit sta_chip_iface_combination_limit_2;
929 if (feature_flags_.lock()->isAwareSupported()) {
930 sta_chip_iface_combination_limit_2 = {
931 {IfaceType::P2P, IfaceType::NAN}, 1};
932 } else {
933 sta_chip_iface_combination_limit_2 = {{IfaceType::P2P}, 1};
934 }
935 const IWifiChip::ChipIfaceCombination sta_chip_iface_combination = {
936 {sta_chip_iface_combination_limit_1,
937 sta_chip_iface_combination_limit_2}};
938 const IWifiChip::ChipMode sta_chip_mode = {
939 kV1StaChipModeId, {sta_chip_iface_combination}};
940 // Iface combinations for Mode Id = 1. (AP Mode)
941 const IWifiChip::ChipIfaceCombinationLimit
942 ap_chip_iface_combination_limit = {{IfaceType::AP}, 1};
943 const IWifiChip::ChipIfaceCombination ap_chip_iface_combination = {
944 {ap_chip_iface_combination_limit}};
945 const IWifiChip::ChipMode ap_chip_mode = {kV1ApChipModeId,
946 {ap_chip_iface_combination}};
947 modes_ = {sta_chip_mode, ap_chip_mode};
948 }
949}
950
951std::vector<IWifiChip::ChipIfaceCombination>
952WifiChip::getCurrentModeIfaceCombinations() {
953 if (!isValidModeId(current_mode_id_)) {
954 LOG(ERROR) << "Chip not configured in a mode yet";
955 return {};
956 }
957 for (const auto& mode : modes_) {
958 if (mode.id == current_mode_id_) {
959 return mode.availableCombinations;
960 }
961 }
962 CHECK(0) << "Expected to find iface combinations for current mode!";
963 return {};
964}
965
966// Returns a map indexed by IfaceType with the number of ifaces currently
967// created of the corresponding type.
968std::map<IfaceType, size_t> WifiChip::getCurrentIfaceCombination() {
969 std::map<IfaceType, size_t> iface_counts;
970 iface_counts[IfaceType::AP] = ap_ifaces_.size();
971 iface_counts[IfaceType::NAN] = nan_ifaces_.size();
972 iface_counts[IfaceType::P2P] = p2p_ifaces_.size();
973 iface_counts[IfaceType::STA] = sta_ifaces_.size();
974 return iface_counts;
975}
976
977// This expands the provided iface combinations to a more parseable
978// form. Returns a vector of available combinations possible with the number
979// of ifaces of each type in the combination.
980// This method is a port of HalDeviceManager.expandIfaceCombos() from framework.
981std::vector<std::map<IfaceType, size_t>> WifiChip::expandIfaceCombinations(
982 const IWifiChip::ChipIfaceCombination& combination) {
983 uint32_t num_expanded_combos = 1;
984 for (const auto& limit : combination.limits) {
985 for (uint32_t i = 0; i < limit.maxIfaces; i++) {
986 num_expanded_combos *= limit.types.size();
987 }
988 }
989
990 // Allocate the vector of expanded combos and reset all iface counts to 0
991 // in each combo.
992 std::vector<std::map<IfaceType, size_t>> expanded_combos;
993 expanded_combos.resize(num_expanded_combos);
994 for (auto& expanded_combo : expanded_combos) {
995 for (const auto type :
996 {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
997 expanded_combo[type] = 0;
998 }
999 }
1000 uint32_t span = num_expanded_combos;
1001 for (const auto& limit : combination.limits) {
1002 for (uint32_t i = 0; i < limit.maxIfaces; i++) {
1003 span /= limit.types.size();
1004 for (uint32_t k = 0; k < num_expanded_combos; ++k) {
1005 const auto iface_type =
1006 limit.types[(k / span) % limit.types.size()];
1007 expanded_combos[k][iface_type]++;
1008 }
1009 }
1010 }
1011 return expanded_combos;
1012}
1013
1014bool WifiChip::canExpandedIfaceCombinationSupportIfaceOfType(
1015 const std::map<IfaceType, size_t>& combo, IfaceType requested_type) {
1016 const auto current_combo = getCurrentIfaceCombination();
1017
1018 // Check if we have space for 1 more iface of |type| in this combo
1019 for (const auto type :
1020 {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
1021 size_t num_ifaces_needed = current_combo.at(type);
1022 if (type == requested_type) {
1023 num_ifaces_needed++;
1024 }
1025 size_t num_ifaces_allowed = combo.at(type);
1026 if (num_ifaces_needed > num_ifaces_allowed) {
1027 return false;
1028 }
1029 }
1030 return true;
1031}
1032
1033// This method does the following:
1034// a) Enumerate all possible iface combos by expanding the current
1035// ChipIfaceCombination.
1036// b) Check if the requested iface type can be added to the current mode.
1037bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType type) {
1038 if (!isValidModeId(current_mode_id_)) {
1039 LOG(ERROR) << "Chip not configured in a mode yet";
1040 return false;
1041 }
1042 const auto combinations = getCurrentModeIfaceCombinations();
1043 for (const auto& combination : combinations) {
1044 const auto expanded_combos = expandIfaceCombinations(combination);
1045 for (const auto& expanded_combo : expanded_combos) {
1046 if (canExpandedIfaceCombinationSupportIfaceOfType(expanded_combo,
1047 type)) {
1048 return true;
1049 }
1050 }
1051 }
1052 return false;
1053}
1054
1055bool WifiChip::isValidModeId(ChipModeId mode_id) {
1056 for (const auto& mode : modes_) {
1057 if (mode.id == mode_id) {
1058 return true;
1059 }
1060 }
1061 return false;
1062}
1063
Roshan Pius8e3c7ef2017-11-03 09:43:08 -07001064// Return "wlan0", if "wlan0" is not already in use, else return "wlan1".
1065// This is based on the assumption that we'll have a max of 2 concurrent
1066// AP/STA ifaces.
1067std::string WifiChip::allocateApOrStaIfaceName() {
1068 auto ap_iface = findUsingName(ap_ifaces_, getWlan0IfaceName());
1069 auto sta_iface = findUsingName(sta_ifaces_, getWlan0IfaceName());
1070 if (!ap_iface.get() && !sta_iface.get()) {
1071 return getWlan0IfaceName();
1072 }
1073 ap_iface = findUsingName(ap_ifaces_, getWlan1IfaceName());
1074 sta_iface = findUsingName(sta_ifaces_, getWlan1IfaceName());
1075 if (!ap_iface.get() && !sta_iface.get()) {
1076 return getWlan1IfaceName();
1077 }
1078 // This should never happen. We screwed up somewhere if it did.
1079 CHECK(0) << "wlan0 and wlan1 in use already!";
1080 return {};
1081}
1082
Roshan Pius79a99752016-10-04 13:03:58 -07001083} // namespace implementation
Etan Cohen6ce50902017-09-14 07:30:57 -07001084} // namespace V1_2
Roshan Pius3c4e8a32016-10-03 14:53:58 -07001085} // namespace wifi
1086} // namespace hardware
1087} // namespace android