blob: d7be38ffe1a5e694561eff1fc3ebf1b11c426d44 [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
84/** Not used yet.
85std::string getWlan1IfaceName() {
86 std::array<char, PROPERTY_VALUE_MAX> buffer;
87 property_get("wifi.concurrent.interface", buffer.data(), "wlan1");
88 return buffer.data();
89}
90*/
91
92std::string getP2pIfaceName() {
Roshan Piusabcf78f2017-10-06 16:30:38 -070093 std::array<char, PROPERTY_VALUE_MAX> buffer;
94 property_get("wifi.direct.interface", buffer.data(), "p2p0");
95 return buffer.data();
Roshan Pius9377a0d2017-10-06 13:18:54 -070096}
97
Roshan Piusabcf78f2017-10-06 16:30:38 -070098} // namespace
Roshan Pius35d958c2016-10-06 16:47:38 -070099
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700100namespace android {
101namespace hardware {
102namespace wifi {
Etan Cohen6ce50902017-09-14 07:30:57 -0700103namespace V1_2 {
Roshan Pius79a99752016-10-04 13:03:58 -0700104namespace implementation {
Roshan Pius3c868522016-10-27 12:43:49 -0700105using hidl_return_util::validateAndCall;
Roshan Piusba38d9c2017-12-08 07:32:08 -0800106using hidl_return_util::validateAndCallWithLock;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700107
Roshan Pius52947fb2016-11-18 11:38:07 -0800108WifiChip::WifiChip(
Roshan Piusabcf78f2017-10-06 16:30:38 -0700109 ChipId chip_id, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
Roshan Pius200a17d2017-11-01 13:03:35 -0700110 const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
111 const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags)
Roshan Pius52947fb2016-11-18 11:38:07 -0800112 : chip_id_(chip_id),
113 legacy_hal_(legacy_hal),
114 mode_controller_(mode_controller),
Roshan Pius200a17d2017-11-01 13:03:35 -0700115 feature_flags_(feature_flags),
Roshan Pius52947fb2016-11-18 11:38:07 -0800116 is_valid_(true),
Roshan Pius48185b22016-12-15 19:10:30 -0800117 current_mode_id_(kInvalidModeId),
Roshan Piuscc338202017-11-02 13:54:09 -0700118 debug_ring_buffer_cb_registered_(false) {
119 populateModes();
120}
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700121
Roshan Piusaabe5752016-09-29 09:03:59 -0700122void WifiChip::invalidate() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700123 invalidateAndRemoveAllIfaces();
124 legacy_hal_.reset();
125 event_cb_handler_.invalidate();
126 is_valid_ = false;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700127}
128
Roshan Piusabcf78f2017-10-06 16:30:38 -0700129bool WifiChip::isValid() { return is_valid_; }
Roshan Pius3c868522016-10-27 12:43:49 -0700130
Roshan Piusd37341f2017-01-31 13:13:28 -0800131std::set<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700132 return event_cb_handler_.getCallbacks();
Roshan Pius203cb032016-12-14 17:41:20 -0800133}
134
Roshan Pius5c055462016-10-11 08:27:27 -0700135Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700136 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
137 &WifiChip::getIdInternal, hidl_status_cb);
Roshan Piuscd566bd2016-10-10 08:03:42 -0700138}
139
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700140Return<void> WifiChip::registerEventCallback(
Roshan Pius5c055462016-10-11 08:27:27 -0700141 const sp<IWifiChipEventCallback>& event_callback,
142 registerEventCallback_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700143 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
144 &WifiChip::registerEventCallbackInternal,
145 hidl_status_cb, event_callback);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700146}
147
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700148Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700149 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
150 &WifiChip::getCapabilitiesInternal, hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700151}
152
Roshan Pius5c055462016-10-11 08:27:27 -0700153Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700154 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
155 &WifiChip::getAvailableModesInternal,
156 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700157}
158
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800159Return<void> WifiChip::configureChip(ChipModeId mode_id,
Roshan Pius5c055462016-10-11 08:27:27 -0700160 configureChip_cb hidl_status_cb) {
Roshan Piusba38d9c2017-12-08 07:32:08 -0800161 return validateAndCallWithLock(
162 this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
163 &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700164}
165
Roshan Pius5c055462016-10-11 08:27:27 -0700166Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700167 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
168 &WifiChip::getModeInternal, hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700169}
170
Roshan Pius5c055462016-10-11 08:27:27 -0700171Return<void> WifiChip::requestChipDebugInfo(
172 requestChipDebugInfo_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700173 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
174 &WifiChip::requestChipDebugInfoInternal,
175 hidl_status_cb);
Roshan Pius5c055462016-10-11 08:27:27 -0700176}
177
178Return<void> WifiChip::requestDriverDebugDump(
179 requestDriverDebugDump_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700180 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
181 &WifiChip::requestDriverDebugDumpInternal,
182 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700183}
184
Roshan Pius5c055462016-10-11 08:27:27 -0700185Return<void> WifiChip::requestFirmwareDebugDump(
186 requestFirmwareDebugDump_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700187 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
188 &WifiChip::requestFirmwareDebugDumpInternal,
189 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700190}
191
Roshan Pius5c055462016-10-11 08:27:27 -0700192Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700193 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
194 &WifiChip::createApIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700195}
196
Roshan Pius5c055462016-10-11 08:27:27 -0700197Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700198 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
199 &WifiChip::getApIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700200}
201
Roshan Pius5c055462016-10-11 08:27:27 -0700202Return<void> WifiChip::getApIface(const hidl_string& ifname,
203 getApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700204 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
205 &WifiChip::getApIfaceInternal, hidl_status_cb,
206 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700207}
208
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800209Return<void> WifiChip::removeApIface(const hidl_string& ifname,
210 removeApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700211 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
212 &WifiChip::removeApIfaceInternal, hidl_status_cb,
213 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800214}
215
Roshan Pius5c055462016-10-11 08:27:27 -0700216Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700217 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
218 &WifiChip::createNanIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700219}
220
Roshan Pius5c055462016-10-11 08:27:27 -0700221Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700222 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
223 &WifiChip::getNanIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700224}
225
226Return<void> WifiChip::getNanIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700227 getNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700228 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
229 &WifiChip::getNanIfaceInternal, hidl_status_cb,
230 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700231}
232
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800233Return<void> WifiChip::removeNanIface(const hidl_string& ifname,
234 removeNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700235 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
236 &WifiChip::removeNanIfaceInternal, hidl_status_cb,
237 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800238}
239
Roshan Pius5c055462016-10-11 08:27:27 -0700240Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700241 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
242 &WifiChip::createP2pIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700243}
244
Roshan Pius5c055462016-10-11 08:27:27 -0700245Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700246 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
247 &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700248}
249
250Return<void> WifiChip::getP2pIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700251 getP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700252 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
253 &WifiChip::getP2pIfaceInternal, hidl_status_cb,
254 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700255}
256
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800257Return<void> WifiChip::removeP2pIface(const hidl_string& ifname,
258 removeP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700259 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
260 &WifiChip::removeP2pIfaceInternal, hidl_status_cb,
261 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800262}
263
Roshan Pius5c055462016-10-11 08:27:27 -0700264Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700265 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
266 &WifiChip::createStaIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700267}
268
Roshan Pius5c055462016-10-11 08:27:27 -0700269Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700270 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
271 &WifiChip::getStaIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700272}
273
274Return<void> WifiChip::getStaIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700275 getStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700276 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
277 &WifiChip::getStaIfaceInternal, hidl_status_cb,
278 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700279}
280
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800281Return<void> WifiChip::removeStaIface(const hidl_string& ifname,
282 removeStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700283 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
284 &WifiChip::removeStaIfaceInternal, hidl_status_cb,
285 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800286}
287
Roshan Pius5c055462016-10-11 08:27:27 -0700288Return<void> WifiChip::createRttController(
289 const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700290 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
291 &WifiChip::createRttControllerInternal,
292 hidl_status_cb, bound_iface);
Roshan Pius59268282016-10-06 20:23:47 -0700293}
294
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700295Return<void> WifiChip::getDebugRingBuffersStatus(
296 getDebugRingBuffersStatus_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700297 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
298 &WifiChip::getDebugRingBuffersStatusInternal,
299 hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700300}
301
302Return<void> WifiChip::startLoggingToDebugRingBuffer(
Roshan Piusabcf78f2017-10-06 16:30:38 -0700303 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
304 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700305 startLoggingToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700306 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
307 &WifiChip::startLoggingToDebugRingBufferInternal,
308 hidl_status_cb, ring_name, verbose_level,
309 max_interval_in_sec, min_data_size_in_bytes);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700310}
311
312Return<void> WifiChip::forceDumpToDebugRingBuffer(
313 const hidl_string& ring_name,
314 forceDumpToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700315 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
316 &WifiChip::forceDumpToDebugRingBufferInternal,
317 hidl_status_cb, ring_name);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700318}
319
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800320Return<void> WifiChip::stopLoggingToDebugRingBuffer(
321 stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700322 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
323 &WifiChip::stopLoggingToDebugRingBufferInternal,
324 hidl_status_cb);
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800325}
326
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700327Return<void> WifiChip::getDebugHostWakeReasonStats(
328 getDebugHostWakeReasonStats_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700329 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
330 &WifiChip::getDebugHostWakeReasonStatsInternal,
331 hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700332}
333
Roshan Pius203cb032016-12-14 17:41:20 -0800334Return<void> WifiChip::enableDebugErrorAlerts(
335 bool enable, enableDebugErrorAlerts_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700336 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
337 &WifiChip::enableDebugErrorAlertsInternal,
338 hidl_status_cb, enable);
Roshan Pius203cb032016-12-14 17:41:20 -0800339}
340
Roshan Pius735ff432017-07-25 08:48:08 -0700341Return<void> WifiChip::selectTxPowerScenario(
342 TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700343 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
344 &WifiChip::selectTxPowerScenarioInternal,
345 hidl_status_cb, scenario);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700346}
347
Roshan Pius735ff432017-07-25 08:48:08 -0700348Return<void> WifiChip::resetTxPowerScenario(
349 resetTxPowerScenario_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700350 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
351 &WifiChip::resetTxPowerScenarioInternal,
352 hidl_status_cb);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700353}
354
Roshan Pius35d958c2016-10-06 16:47:38 -0700355void WifiChip::invalidateAndRemoveAllIfaces() {
Roshan Pius675609b2017-10-31 14:24:58 -0700356 invalidateAndClearAll(ap_ifaces_);
357 invalidateAndClearAll(nan_ifaces_);
358 invalidateAndClearAll(p2p_ifaces_);
359 invalidateAndClearAll(sta_ifaces_);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700360 // Since all the ifaces are invalid now, all RTT controller objects
361 // using those ifaces also need to be invalidated.
362 for (const auto& rtt : rtt_controllers_) {
363 rtt->invalidate();
364 }
365 rtt_controllers_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -0700366}
367
Roshan Pius3c868522016-10-27 12:43:49 -0700368std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700369 return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700370}
371
372WifiStatus WifiChip::registerEventCallbackInternal(
373 const sp<IWifiChipEventCallback>& event_callback) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700374 if (!event_cb_handler_.addCallback(event_callback)) {
375 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
376 }
377 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius3c868522016-10-27 12:43:49 -0700378}
379
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700380std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700381 legacy_hal::wifi_error legacy_status;
382 uint32_t legacy_feature_set;
383 uint32_t legacy_logger_feature_set;
384 std::tie(legacy_status, legacy_feature_set) =
385 legacy_hal_.lock()->getSupportedFeatureSet(getWlan0IfaceName());
386 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
387 return {createWifiStatusFromLegacyError(legacy_status), 0};
388 }
389 std::tie(legacy_status, legacy_logger_feature_set) =
390 legacy_hal_.lock()->getLoggerSupportedFeatureSet(getWlan0IfaceName());
391 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
392 return {createWifiStatusFromLegacyError(legacy_status), 0};
393 }
394 uint32_t hidl_caps;
395 if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
396 legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
397 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
398 }
399 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700400}
401
Roshan Pius3c868522016-10-27 12:43:49 -0700402std::pair<WifiStatus, std::vector<IWifiChip::ChipMode>>
403WifiChip::getAvailableModesInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700404 return {createWifiStatus(WifiStatusCode::SUCCESS), modes_};
Roshan Pius3c868522016-10-27 12:43:49 -0700405}
406
Roshan Piusba38d9c2017-12-08 07:32:08 -0800407WifiStatus WifiChip::configureChipInternal(
408 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
409 ChipModeId mode_id) {
Roshan Piuscc338202017-11-02 13:54:09 -0700410 if (!isValidModeId(mode_id)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700411 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
412 }
413 if (mode_id == current_mode_id_) {
414 LOG(DEBUG) << "Already in the specified mode " << mode_id;
415 return createWifiStatus(WifiStatusCode::SUCCESS);
416 }
Roshan Piusba38d9c2017-12-08 07:32:08 -0800417 WifiStatus status = handleChipConfiguration(lock, mode_id);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700418 if (status.code != WifiStatusCode::SUCCESS) {
419 for (const auto& callback : event_cb_handler_.getCallbacks()) {
420 if (!callback->onChipReconfigureFailure(status).isOk()) {
421 LOG(ERROR)
422 << "Failed to invoke onChipReconfigureFailure callback";
423 }
424 }
425 return status;
426 }
Roshan Piusd37341f2017-01-31 13:13:28 -0800427 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700428 if (!callback->onChipReconfigured(mode_id).isOk()) {
429 LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
430 }
Roshan Pius52947fb2016-11-18 11:38:07 -0800431 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700432 current_mode_id_ = mode_id;
Roshan Piusba38d9c2017-12-08 07:32:08 -0800433 LOG(INFO) << "Configured chip in mode " << mode_id;
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800434 return status;
Roshan Pius3c868522016-10-27 12:43:49 -0700435}
436
437std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700438 if (!isValidModeId(current_mode_id_)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700439 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE),
440 current_mode_id_};
441 }
442 return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700443}
444
445std::pair<WifiStatus, IWifiChip::ChipDebugInfo>
446WifiChip::requestChipDebugInfoInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700447 IWifiChip::ChipDebugInfo result;
448 legacy_hal::wifi_error legacy_status;
449 std::string driver_desc;
450 std::tie(legacy_status, driver_desc) =
451 legacy_hal_.lock()->getDriverVersion(getWlan0IfaceName());
452 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
453 LOG(ERROR) << "Failed to get driver version: "
454 << legacyErrorToString(legacy_status);
455 WifiStatus status = createWifiStatusFromLegacyError(
456 legacy_status, "failed to get driver version");
457 return {status, result};
458 }
459 result.driverDescription = driver_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700460
Roshan Piusabcf78f2017-10-06 16:30:38 -0700461 std::string firmware_desc;
462 std::tie(legacy_status, firmware_desc) =
463 legacy_hal_.lock()->getFirmwareVersion(getWlan0IfaceName());
464 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
465 LOG(ERROR) << "Failed to get firmware version: "
466 << legacyErrorToString(legacy_status);
467 WifiStatus status = createWifiStatusFromLegacyError(
468 legacy_status, "failed to get firmware version");
469 return {status, result};
470 }
471 result.firmwareDescription = firmware_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700472
Roshan Piusabcf78f2017-10-06 16:30:38 -0700473 return {createWifiStatus(WifiStatusCode::SUCCESS), result};
Roshan Pius3c868522016-10-27 12:43:49 -0700474}
475
476std::pair<WifiStatus, std::vector<uint8_t>>
477WifiChip::requestDriverDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700478 legacy_hal::wifi_error legacy_status;
479 std::vector<uint8_t> driver_dump;
480 std::tie(legacy_status, driver_dump) =
481 legacy_hal_.lock()->requestDriverMemoryDump(getWlan0IfaceName());
482 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
483 LOG(ERROR) << "Failed to get driver debug dump: "
484 << legacyErrorToString(legacy_status);
485 return {createWifiStatusFromLegacyError(legacy_status),
486 std::vector<uint8_t>()};
487 }
488 return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
Roshan Pius3c868522016-10-27 12:43:49 -0700489}
490
491std::pair<WifiStatus, std::vector<uint8_t>>
492WifiChip::requestFirmwareDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700493 legacy_hal::wifi_error legacy_status;
494 std::vector<uint8_t> firmware_dump;
495 std::tie(legacy_status, firmware_dump) =
496 legacy_hal_.lock()->requestFirmwareMemoryDump(getWlan0IfaceName());
497 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
498 LOG(ERROR) << "Failed to get firmware debug dump: "
499 << legacyErrorToString(legacy_status);
500 return {createWifiStatusFromLegacyError(legacy_status), {}};
501 }
502 return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
Roshan Pius3c868522016-10-27 12:43:49 -0700503}
504
505std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700506 if (!canCurrentModeSupportIfaceOfType(IfaceType::AP)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700507 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -0800508 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700509 std::string ifname = getWlan0IfaceName();
Roshan Pius675609b2017-10-31 14:24:58 -0700510 sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_);
511 ap_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700512 for (const auto& callback : event_cb_handler_.getCallbacks()) {
513 if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
514 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
515 }
516 }
Roshan Pius675609b2017-10-31 14:24:58 -0700517 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700518}
519
520std::pair<WifiStatus, std::vector<hidl_string>>
521WifiChip::getApIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700522 if (ap_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700523 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
524 }
Roshan Pius675609b2017-10-31 14:24:58 -0700525 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -0700526}
527
528std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::getApIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800529 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700530 const auto iface = findUsingName(ap_ifaces_, ifname);
531 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700532 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
533 }
Roshan Pius675609b2017-10-31 14:24:58 -0700534 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700535}
536
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800537WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700538 const auto iface = findUsingName(ap_ifaces_, ifname);
539 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700540 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800541 }
Roshan Pius675609b2017-10-31 14:24:58 -0700542 invalidateAndClear(ap_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700543 for (const auto& callback : event_cb_handler_.getCallbacks()) {
544 if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
545 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
546 }
547 }
548 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800549}
550
Roshan Pius3c868522016-10-27 12:43:49 -0700551std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700552 if (!canCurrentModeSupportIfaceOfType(IfaceType::NAN)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700553 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Etan Cohenc5700402017-03-08 16:43:38 -0800554 }
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 Piusabcf78f2017-10-06 16:30:38 -0700647 std::string ifname = getWlan0IfaceName();
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 Pius79a99752016-10-04 13:03:58 -07001064} // namespace implementation
Etan Cohen6ce50902017-09-14 07:30:57 -07001065} // namespace V1_2
Roshan Pius3c4e8a32016-10-03 14:53:58 -07001066} // namespace wifi
1067} // namespace hardware
1068} // namespace android