blob: c4956e016f83a70e632a15d821c06d2558c3e74f [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 kStaChipModeId = 0;
34constexpr ChipModeId kApChipModeId = 1;
35constexpr ChipModeId kInvalidModeId = UINT32_MAX;
Roshan Pius35d958c2016-10-06 16:47:38 -070036
Roshan Pius35d958c2016-10-06 16:47:38 -070037template <typename Iface>
Roshan Pius675609b2017-10-31 14:24:58 -070038void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
39 iface->invalidate();
40 ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface),
41 ifaces.end());
42}
43
44template <typename Iface>
45void invalidateAndClearAll(std::vector<sp<Iface>>& ifaces) {
46 for (const auto& iface : ifaces) {
Roshan Piusabcf78f2017-10-06 16:30:38 -070047 iface->invalidate();
Roshan Piusabcf78f2017-10-06 16:30:38 -070048 }
Roshan Pius675609b2017-10-31 14:24:58 -070049 ifaces.clear();
50}
51
52template <typename Iface>
53std::vector<hidl_string> getNames(std::vector<sp<Iface>>& ifaces) {
54 std::vector<hidl_string> names;
55 for (const auto& iface : ifaces) {
56 names.emplace_back(iface->getName());
57 }
58 return names;
59}
60
61template <typename Iface>
62sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces,
63 const std::string& name) {
64 std::vector<hidl_string> names;
65 for (const auto& iface : ifaces) {
66 if (name == iface->getName()) {
67 return iface;
68 }
69 }
70 return nullptr;
Roshan Pius35d958c2016-10-06 16:47:38 -070071}
Roshan Pius9377a0d2017-10-06 13:18:54 -070072
73std::string getWlan0IfaceName() {
Roshan Piusabcf78f2017-10-06 16:30:38 -070074 std::array<char, PROPERTY_VALUE_MAX> buffer;
75 property_get("wifi.interface", buffer.data(), "wlan0");
76 return buffer.data();
Roshan Pius9377a0d2017-10-06 13:18:54 -070077}
78
79/** Not used yet.
80std::string getWlan1IfaceName() {
81 std::array<char, PROPERTY_VALUE_MAX> buffer;
82 property_get("wifi.concurrent.interface", buffer.data(), "wlan1");
83 return buffer.data();
84}
85*/
86
87std::string getP2pIfaceName() {
Roshan Piusabcf78f2017-10-06 16:30:38 -070088 std::array<char, PROPERTY_VALUE_MAX> buffer;
89 property_get("wifi.direct.interface", buffer.data(), "p2p0");
90 return buffer.data();
Roshan Pius9377a0d2017-10-06 13:18:54 -070091}
92
Roshan Piusabcf78f2017-10-06 16:30:38 -070093} // namespace
Roshan Pius35d958c2016-10-06 16:47:38 -070094
Roshan Pius3c4e8a32016-10-03 14:53:58 -070095namespace android {
96namespace hardware {
97namespace wifi {
Etan Cohen6ce50902017-09-14 07:30:57 -070098namespace V1_2 {
Roshan Pius79a99752016-10-04 13:03:58 -070099namespace implementation {
Roshan Pius3c868522016-10-27 12:43:49 -0700100using hidl_return_util::validateAndCall;
Roshan Piusba38d9c2017-12-08 07:32:08 -0800101using hidl_return_util::validateAndCallWithLock;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700102
Roshan Pius52947fb2016-11-18 11:38:07 -0800103WifiChip::WifiChip(
Roshan Piusabcf78f2017-10-06 16:30:38 -0700104 ChipId chip_id, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
Roshan Pius200a17d2017-11-01 13:03:35 -0700105 const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
106 const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags)
Roshan Pius52947fb2016-11-18 11:38:07 -0800107 : chip_id_(chip_id),
108 legacy_hal_(legacy_hal),
109 mode_controller_(mode_controller),
Roshan Pius200a17d2017-11-01 13:03:35 -0700110 feature_flags_(feature_flags),
Roshan Pius52947fb2016-11-18 11:38:07 -0800111 is_valid_(true),
Roshan Pius48185b22016-12-15 19:10:30 -0800112 current_mode_id_(kInvalidModeId),
113 debug_ring_buffer_cb_registered_(false) {}
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700114
Roshan Piusaabe5752016-09-29 09:03:59 -0700115void WifiChip::invalidate() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700116 invalidateAndRemoveAllIfaces();
117 legacy_hal_.reset();
118 event_cb_handler_.invalidate();
119 is_valid_ = false;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700120}
121
Roshan Piusabcf78f2017-10-06 16:30:38 -0700122bool WifiChip::isValid() { return is_valid_; }
Roshan Pius3c868522016-10-27 12:43:49 -0700123
Roshan Piusd37341f2017-01-31 13:13:28 -0800124std::set<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700125 return event_cb_handler_.getCallbacks();
Roshan Pius203cb032016-12-14 17:41:20 -0800126}
127
Roshan Pius5c055462016-10-11 08:27:27 -0700128Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700129 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
130 &WifiChip::getIdInternal, hidl_status_cb);
Roshan Piuscd566bd2016-10-10 08:03:42 -0700131}
132
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700133Return<void> WifiChip::registerEventCallback(
Roshan Pius5c055462016-10-11 08:27:27 -0700134 const sp<IWifiChipEventCallback>& event_callback,
135 registerEventCallback_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700136 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
137 &WifiChip::registerEventCallbackInternal,
138 hidl_status_cb, event_callback);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700139}
140
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700141Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700142 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
143 &WifiChip::getCapabilitiesInternal, hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700144}
145
Roshan Pius5c055462016-10-11 08:27:27 -0700146Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700147 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
148 &WifiChip::getAvailableModesInternal,
149 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700150}
151
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800152Return<void> WifiChip::configureChip(ChipModeId mode_id,
Roshan Pius5c055462016-10-11 08:27:27 -0700153 configureChip_cb hidl_status_cb) {
Roshan Piusba38d9c2017-12-08 07:32:08 -0800154 return validateAndCallWithLock(
155 this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
156 &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700157}
158
Roshan Pius5c055462016-10-11 08:27:27 -0700159Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700160 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
161 &WifiChip::getModeInternal, hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700162}
163
Roshan Pius5c055462016-10-11 08:27:27 -0700164Return<void> WifiChip::requestChipDebugInfo(
165 requestChipDebugInfo_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700166 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
167 &WifiChip::requestChipDebugInfoInternal,
168 hidl_status_cb);
Roshan Pius5c055462016-10-11 08:27:27 -0700169}
170
171Return<void> WifiChip::requestDriverDebugDump(
172 requestDriverDebugDump_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700173 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
174 &WifiChip::requestDriverDebugDumpInternal,
175 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700176}
177
Roshan Pius5c055462016-10-11 08:27:27 -0700178Return<void> WifiChip::requestFirmwareDebugDump(
179 requestFirmwareDebugDump_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700180 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
181 &WifiChip::requestFirmwareDebugDumpInternal,
182 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700183}
184
Roshan Pius5c055462016-10-11 08:27:27 -0700185Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700186 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
187 &WifiChip::createApIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700188}
189
Roshan Pius5c055462016-10-11 08:27:27 -0700190Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700191 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
192 &WifiChip::getApIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700193}
194
Roshan Pius5c055462016-10-11 08:27:27 -0700195Return<void> WifiChip::getApIface(const hidl_string& ifname,
196 getApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700197 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
198 &WifiChip::getApIfaceInternal, hidl_status_cb,
199 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700200}
201
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800202Return<void> WifiChip::removeApIface(const hidl_string& ifname,
203 removeApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700204 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
205 &WifiChip::removeApIfaceInternal, hidl_status_cb,
206 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800207}
208
Roshan Pius5c055462016-10-11 08:27:27 -0700209Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700210 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
211 &WifiChip::createNanIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700212}
213
Roshan Pius5c055462016-10-11 08:27:27 -0700214Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700215 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
216 &WifiChip::getNanIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700217}
218
219Return<void> WifiChip::getNanIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700220 getNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700221 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
222 &WifiChip::getNanIfaceInternal, hidl_status_cb,
223 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700224}
225
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800226Return<void> WifiChip::removeNanIface(const hidl_string& ifname,
227 removeNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700228 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
229 &WifiChip::removeNanIfaceInternal, hidl_status_cb,
230 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800231}
232
Roshan Pius5c055462016-10-11 08:27:27 -0700233Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700234 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
235 &WifiChip::createP2pIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700236}
237
Roshan Pius5c055462016-10-11 08:27:27 -0700238Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700239 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
240 &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700241}
242
243Return<void> WifiChip::getP2pIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700244 getP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700245 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
246 &WifiChip::getP2pIfaceInternal, hidl_status_cb,
247 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700248}
249
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800250Return<void> WifiChip::removeP2pIface(const hidl_string& ifname,
251 removeP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700252 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
253 &WifiChip::removeP2pIfaceInternal, hidl_status_cb,
254 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800255}
256
Roshan Pius5c055462016-10-11 08:27:27 -0700257Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700258 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
259 &WifiChip::createStaIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700260}
261
Roshan Pius5c055462016-10-11 08:27:27 -0700262Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700263 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
264 &WifiChip::getStaIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700265}
266
267Return<void> WifiChip::getStaIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700268 getStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700269 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
270 &WifiChip::getStaIfaceInternal, hidl_status_cb,
271 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700272}
273
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800274Return<void> WifiChip::removeStaIface(const hidl_string& ifname,
275 removeStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700276 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
277 &WifiChip::removeStaIfaceInternal, hidl_status_cb,
278 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800279}
280
Roshan Pius5c055462016-10-11 08:27:27 -0700281Return<void> WifiChip::createRttController(
282 const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700283 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
284 &WifiChip::createRttControllerInternal,
285 hidl_status_cb, bound_iface);
Roshan Pius59268282016-10-06 20:23:47 -0700286}
287
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700288Return<void> WifiChip::getDebugRingBuffersStatus(
289 getDebugRingBuffersStatus_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700290 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
291 &WifiChip::getDebugRingBuffersStatusInternal,
292 hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700293}
294
295Return<void> WifiChip::startLoggingToDebugRingBuffer(
Roshan Piusabcf78f2017-10-06 16:30:38 -0700296 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
297 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700298 startLoggingToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700299 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
300 &WifiChip::startLoggingToDebugRingBufferInternal,
301 hidl_status_cb, ring_name, verbose_level,
302 max_interval_in_sec, min_data_size_in_bytes);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700303}
304
305Return<void> WifiChip::forceDumpToDebugRingBuffer(
306 const hidl_string& ring_name,
307 forceDumpToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700308 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
309 &WifiChip::forceDumpToDebugRingBufferInternal,
310 hidl_status_cb, ring_name);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700311}
312
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800313Return<void> WifiChip::stopLoggingToDebugRingBuffer(
314 stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700315 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
316 &WifiChip::stopLoggingToDebugRingBufferInternal,
317 hidl_status_cb);
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800318}
319
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700320Return<void> WifiChip::getDebugHostWakeReasonStats(
321 getDebugHostWakeReasonStats_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700322 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
323 &WifiChip::getDebugHostWakeReasonStatsInternal,
324 hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700325}
326
Roshan Pius203cb032016-12-14 17:41:20 -0800327Return<void> WifiChip::enableDebugErrorAlerts(
328 bool enable, enableDebugErrorAlerts_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700329 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
330 &WifiChip::enableDebugErrorAlertsInternal,
331 hidl_status_cb, enable);
Roshan Pius203cb032016-12-14 17:41:20 -0800332}
333
Roshan Pius735ff432017-07-25 08:48:08 -0700334Return<void> WifiChip::selectTxPowerScenario(
335 TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700336 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
337 &WifiChip::selectTxPowerScenarioInternal,
338 hidl_status_cb, scenario);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700339}
340
Roshan Pius735ff432017-07-25 08:48:08 -0700341Return<void> WifiChip::resetTxPowerScenario(
342 resetTxPowerScenario_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700343 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
344 &WifiChip::resetTxPowerScenarioInternal,
345 hidl_status_cb);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700346}
347
Roshan Pius35d958c2016-10-06 16:47:38 -0700348void WifiChip::invalidateAndRemoveAllIfaces() {
Roshan Pius675609b2017-10-31 14:24:58 -0700349 invalidateAndClearAll(ap_ifaces_);
350 invalidateAndClearAll(nan_ifaces_);
351 invalidateAndClearAll(p2p_ifaces_);
352 invalidateAndClearAll(sta_ifaces_);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700353 // Since all the ifaces are invalid now, all RTT controller objects
354 // using those ifaces also need to be invalidated.
355 for (const auto& rtt : rtt_controllers_) {
356 rtt->invalidate();
357 }
358 rtt_controllers_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -0700359}
360
Roshan Pius3c868522016-10-27 12:43:49 -0700361std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700362 return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700363}
364
365WifiStatus WifiChip::registerEventCallbackInternal(
366 const sp<IWifiChipEventCallback>& event_callback) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700367 if (!event_cb_handler_.addCallback(event_callback)) {
368 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
369 }
370 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius3c868522016-10-27 12:43:49 -0700371}
372
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700373std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700374 legacy_hal::wifi_error legacy_status;
375 uint32_t legacy_feature_set;
376 uint32_t legacy_logger_feature_set;
377 std::tie(legacy_status, legacy_feature_set) =
378 legacy_hal_.lock()->getSupportedFeatureSet(getWlan0IfaceName());
379 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
380 return {createWifiStatusFromLegacyError(legacy_status), 0};
381 }
382 std::tie(legacy_status, legacy_logger_feature_set) =
383 legacy_hal_.lock()->getLoggerSupportedFeatureSet(getWlan0IfaceName());
384 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
385 return {createWifiStatusFromLegacyError(legacy_status), 0};
386 }
387 uint32_t hidl_caps;
388 if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
389 legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
390 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
391 }
392 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700393}
394
Roshan Pius3c868522016-10-27 12:43:49 -0700395std::pair<WifiStatus, std::vector<IWifiChip::ChipMode>>
396WifiChip::getAvailableModesInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700397 // The chip combination supported for current devices is fixed for now with
398 // 2 separate modes of operation:
399 // Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN iface operations
400 // concurrently [NAN conditional on wifiHidlFeatureAware]
401 // Mode 2 (AP mode): Will support 1 AP iface operations.
402 // TODO (b/32997844): Read this from some device specific flags in the
403 // makefile.
404 // STA mode iface combinations.
405 const IWifiChip::ChipIfaceCombinationLimit
406 sta_chip_iface_combination_limit_1 = {{IfaceType::STA}, 1};
407 IWifiChip::ChipIfaceCombinationLimit sta_chip_iface_combination_limit_2;
Roshan Pius200a17d2017-11-01 13:03:35 -0700408 if (feature_flags_.lock()->isAwareSupported()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700409 sta_chip_iface_combination_limit_2 = {{IfaceType::P2P, IfaceType::NAN},
410 1};
411 } else {
412 sta_chip_iface_combination_limit_2 = {{IfaceType::P2P}, 1};
413 }
414 const IWifiChip::ChipIfaceCombination sta_chip_iface_combination = {
415 {sta_chip_iface_combination_limit_1,
416 sta_chip_iface_combination_limit_2}};
417 const IWifiChip::ChipMode sta_chip_mode = {kStaChipModeId,
418 {sta_chip_iface_combination}};
419 // AP mode iface combinations.
420 const IWifiChip::ChipIfaceCombinationLimit ap_chip_iface_combination_limit =
421 {{IfaceType::AP}, 1};
422 const IWifiChip::ChipIfaceCombination ap_chip_iface_combination = {
423 {ap_chip_iface_combination_limit}};
424 const IWifiChip::ChipMode ap_chip_mode = {kApChipModeId,
425 {ap_chip_iface_combination}};
426 return {createWifiStatus(WifiStatusCode::SUCCESS),
427 {sta_chip_mode, ap_chip_mode}};
Roshan Pius3c868522016-10-27 12:43:49 -0700428}
429
Roshan Piusba38d9c2017-12-08 07:32:08 -0800430WifiStatus WifiChip::configureChipInternal(
431 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
432 ChipModeId mode_id) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700433 if (mode_id != kStaChipModeId && mode_id != kApChipModeId) {
434 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
435 }
436 if (mode_id == current_mode_id_) {
437 LOG(DEBUG) << "Already in the specified mode " << mode_id;
438 return createWifiStatus(WifiStatusCode::SUCCESS);
439 }
Roshan Piusba38d9c2017-12-08 07:32:08 -0800440 WifiStatus status = handleChipConfiguration(lock, mode_id);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700441 if (status.code != WifiStatusCode::SUCCESS) {
442 for (const auto& callback : event_cb_handler_.getCallbacks()) {
443 if (!callback->onChipReconfigureFailure(status).isOk()) {
444 LOG(ERROR)
445 << "Failed to invoke onChipReconfigureFailure callback";
446 }
447 }
448 return status;
449 }
Roshan Piusd37341f2017-01-31 13:13:28 -0800450 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700451 if (!callback->onChipReconfigured(mode_id).isOk()) {
452 LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
453 }
Roshan Pius52947fb2016-11-18 11:38:07 -0800454 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700455 current_mode_id_ = mode_id;
Roshan Piusba38d9c2017-12-08 07:32:08 -0800456 LOG(INFO) << "Configured chip in mode " << mode_id;
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800457 return status;
Roshan Pius3c868522016-10-27 12:43:49 -0700458}
459
460std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700461 if (current_mode_id_ == kInvalidModeId) {
462 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE),
463 current_mode_id_};
464 }
465 return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700466}
467
468std::pair<WifiStatus, IWifiChip::ChipDebugInfo>
469WifiChip::requestChipDebugInfoInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700470 IWifiChip::ChipDebugInfo result;
471 legacy_hal::wifi_error legacy_status;
472 std::string driver_desc;
473 std::tie(legacy_status, driver_desc) =
474 legacy_hal_.lock()->getDriverVersion(getWlan0IfaceName());
475 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
476 LOG(ERROR) << "Failed to get driver version: "
477 << legacyErrorToString(legacy_status);
478 WifiStatus status = createWifiStatusFromLegacyError(
479 legacy_status, "failed to get driver version");
480 return {status, result};
481 }
482 result.driverDescription = driver_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700483
Roshan Piusabcf78f2017-10-06 16:30:38 -0700484 std::string firmware_desc;
485 std::tie(legacy_status, firmware_desc) =
486 legacy_hal_.lock()->getFirmwareVersion(getWlan0IfaceName());
487 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
488 LOG(ERROR) << "Failed to get firmware version: "
489 << legacyErrorToString(legacy_status);
490 WifiStatus status = createWifiStatusFromLegacyError(
491 legacy_status, "failed to get firmware version");
492 return {status, result};
493 }
494 result.firmwareDescription = firmware_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700495
Roshan Piusabcf78f2017-10-06 16:30:38 -0700496 return {createWifiStatus(WifiStatusCode::SUCCESS), result};
Roshan Pius3c868522016-10-27 12:43:49 -0700497}
498
499std::pair<WifiStatus, std::vector<uint8_t>>
500WifiChip::requestDriverDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700501 legacy_hal::wifi_error legacy_status;
502 std::vector<uint8_t> driver_dump;
503 std::tie(legacy_status, driver_dump) =
504 legacy_hal_.lock()->requestDriverMemoryDump(getWlan0IfaceName());
505 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
506 LOG(ERROR) << "Failed to get driver debug dump: "
507 << legacyErrorToString(legacy_status);
508 return {createWifiStatusFromLegacyError(legacy_status),
509 std::vector<uint8_t>()};
510 }
511 return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
Roshan Pius3c868522016-10-27 12:43:49 -0700512}
513
514std::pair<WifiStatus, std::vector<uint8_t>>
515WifiChip::requestFirmwareDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700516 legacy_hal::wifi_error legacy_status;
517 std::vector<uint8_t> firmware_dump;
518 std::tie(legacy_status, firmware_dump) =
519 legacy_hal_.lock()->requestFirmwareMemoryDump(getWlan0IfaceName());
520 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
521 LOG(ERROR) << "Failed to get firmware debug dump: "
522 << legacyErrorToString(legacy_status);
523 return {createWifiStatusFromLegacyError(legacy_status), {}};
524 }
525 return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
Roshan Pius3c868522016-10-27 12:43:49 -0700526}
527
528std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700529 if (current_mode_id_ != kApChipModeId || !ap_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700530 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -0800531 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700532 std::string ifname = getWlan0IfaceName();
Roshan Pius675609b2017-10-31 14:24:58 -0700533 sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_);
534 ap_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700535 for (const auto& callback : event_cb_handler_.getCallbacks()) {
536 if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
537 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
538 }
539 }
Roshan Pius675609b2017-10-31 14:24:58 -0700540 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700541}
542
543std::pair<WifiStatus, std::vector<hidl_string>>
544WifiChip::getApIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700545 if (ap_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700546 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
547 }
Roshan Pius675609b2017-10-31 14:24:58 -0700548 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -0700549}
550
551std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::getApIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800552 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700553 const auto iface = findUsingName(ap_ifaces_, ifname);
554 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700555 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
556 }
Roshan Pius675609b2017-10-31 14:24:58 -0700557 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700558}
559
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800560WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700561 const auto iface = findUsingName(ap_ifaces_, ifname);
562 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700563 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800564 }
Roshan Pius675609b2017-10-31 14:24:58 -0700565 invalidateAndClear(ap_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700566 for (const auto& callback : event_cb_handler_.getCallbacks()) {
567 if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
568 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
569 }
570 }
571 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800572}
573
Roshan Pius3c868522016-10-27 12:43:49 -0700574std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700575 // Only 1 of NAN or P2P iface can be active at a time.
Roshan Pius200a17d2017-11-01 13:03:35 -0700576 if (feature_flags_.lock()->isAwareSupported()) {
Roshan Pius675609b2017-10-31 14:24:58 -0700577 if (current_mode_id_ != kStaChipModeId || !nan_ifaces_.empty() ||
578 !p2p_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700579 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
580 }
581 std::string ifname = getWlan0IfaceName();
Roshan Pius675609b2017-10-31 14:24:58 -0700582 sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_);
583 nan_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700584 for (const auto& callback : event_cb_handler_.getCallbacks()) {
585 if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
586 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
587 }
588 }
Roshan Pius675609b2017-10-31 14:24:58 -0700589 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700590 } else {
591 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Etan Cohenc5700402017-03-08 16:43:38 -0800592 }
Roshan Pius3c868522016-10-27 12:43:49 -0700593}
594
595std::pair<WifiStatus, std::vector<hidl_string>>
596WifiChip::getNanIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700597 if (nan_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700598 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
599 }
Roshan Pius675609b2017-10-31 14:24:58 -0700600 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -0700601}
602
603std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::getNanIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800604 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700605 const auto iface = findUsingName(nan_ifaces_, ifname);
606 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700607 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
608 }
Roshan Pius675609b2017-10-31 14:24:58 -0700609 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700610}
611
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800612WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700613 const auto iface = findUsingName(nan_ifaces_, ifname);
614 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700615 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800616 }
Roshan Pius675609b2017-10-31 14:24:58 -0700617 invalidateAndClear(nan_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700618 for (const auto& callback : event_cb_handler_.getCallbacks()) {
619 if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
620 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
621 }
622 }
623 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800624}
625
Roshan Pius3c868522016-10-27 12:43:49 -0700626std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700627 // Only 1 of NAN or P2P iface can be active at a time.
Roshan Pius675609b2017-10-31 14:24:58 -0700628 if (current_mode_id_ != kStaChipModeId || !p2p_ifaces_.empty() ||
629 !nan_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700630 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -0800631 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700632 std::string ifname = getP2pIfaceName();
Roshan Pius675609b2017-10-31 14:24:58 -0700633 sp<WifiP2pIface> iface = new WifiP2pIface(ifname, legacy_hal_);
634 p2p_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700635 for (const auto& callback : event_cb_handler_.getCallbacks()) {
636 if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
637 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
638 }
639 }
Roshan Pius675609b2017-10-31 14:24:58 -0700640 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700641}
642
643std::pair<WifiStatus, std::vector<hidl_string>>
644WifiChip::getP2pIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700645 if (p2p_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700646 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
647 }
Roshan Pius675609b2017-10-31 14:24:58 -0700648 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -0700649}
650
651std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800652 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700653 const auto iface = findUsingName(p2p_ifaces_, ifname);
654 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700655 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
656 }
Roshan Pius675609b2017-10-31 14:24:58 -0700657 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700658}
659
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800660WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700661 const auto iface = findUsingName(p2p_ifaces_, ifname);
662 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700663 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800664 }
Roshan Pius675609b2017-10-31 14:24:58 -0700665 invalidateAndClear(p2p_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700666 for (const auto& callback : event_cb_handler_.getCallbacks()) {
667 if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
668 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
669 }
670 }
671 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800672}
673
Roshan Pius3c868522016-10-27 12:43:49 -0700674std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700675 if (current_mode_id_ != kStaChipModeId || !sta_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700676 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -0800677 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700678 std::string ifname = getWlan0IfaceName();
Roshan Pius675609b2017-10-31 14:24:58 -0700679 sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_);
680 sta_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700681 for (const auto& callback : event_cb_handler_.getCallbacks()) {
682 if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
683 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
684 }
685 }
Roshan Pius675609b2017-10-31 14:24:58 -0700686 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700687}
688
689std::pair<WifiStatus, std::vector<hidl_string>>
690WifiChip::getStaIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700691 if (sta_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700692 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
693 }
Roshan Pius675609b2017-10-31 14:24:58 -0700694 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -0700695}
696
697std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::getStaIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800698 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700699 const auto iface = findUsingName(sta_ifaces_, ifname);
700 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700701 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
702 }
Roshan Pius675609b2017-10-31 14:24:58 -0700703 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700704}
705
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800706WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700707 const auto iface = findUsingName(sta_ifaces_, ifname);
708 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700709 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800710 }
Roshan Pius675609b2017-10-31 14:24:58 -0700711 invalidateAndClear(sta_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700712 for (const auto& callback : event_cb_handler_.getCallbacks()) {
713 if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
714 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
715 }
716 }
717 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800718}
719
Roshan Pius3c868522016-10-27 12:43:49 -0700720std::pair<WifiStatus, sp<IWifiRttController>>
721WifiChip::createRttControllerInternal(const sp<IWifiIface>& bound_iface) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700722 sp<WifiRttController> rtt =
723 new WifiRttController(getWlan0IfaceName(), bound_iface, legacy_hal_);
724 rtt_controllers_.emplace_back(rtt);
725 return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
Roshan Pius3c868522016-10-27 12:43:49 -0700726}
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700727
728std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
729WifiChip::getDebugRingBuffersStatusInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700730 legacy_hal::wifi_error legacy_status;
731 std::vector<legacy_hal::wifi_ring_buffer_status>
732 legacy_ring_buffer_status_vec;
733 std::tie(legacy_status, legacy_ring_buffer_status_vec) =
734 legacy_hal_.lock()->getRingBuffersStatus(getWlan0IfaceName());
735 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
736 return {createWifiStatusFromLegacyError(legacy_status), {}};
737 }
738 std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
739 if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
740 legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
741 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
742 }
743 return {createWifiStatus(WifiStatusCode::SUCCESS),
744 hidl_ring_buffer_status_vec};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700745}
746
747WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
Roshan Piusabcf78f2017-10-06 16:30:38 -0700748 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
749 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
750 WifiStatus status = registerDebugRingBufferCallback();
751 if (status.code != WifiStatusCode::SUCCESS) {
752 return status;
753 }
754 legacy_hal::wifi_error legacy_status =
755 legacy_hal_.lock()->startRingBufferLogging(
756 getWlan0IfaceName(), ring_name,
757 static_cast<
758 std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
759 verbose_level),
760 max_interval_in_sec, min_data_size_in_bytes);
761 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700762}
763
764WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800765 const hidl_string& ring_name) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700766 WifiStatus status = registerDebugRingBufferCallback();
767 if (status.code != WifiStatusCode::SUCCESS) {
768 return status;
769 }
770 legacy_hal::wifi_error legacy_status =
771 legacy_hal_.lock()->getRingBufferData(getWlan0IfaceName(), ring_name);
772 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700773}
774
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800775WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700776 legacy_hal::wifi_error legacy_status =
777 legacy_hal_.lock()->deregisterRingBufferCallbackHandler(
778 getWlan0IfaceName());
779 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800780}
781
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700782std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
783WifiChip::getDebugHostWakeReasonStatsInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700784 legacy_hal::wifi_error legacy_status;
785 legacy_hal::WakeReasonStats legacy_stats;
786 std::tie(legacy_status, legacy_stats) =
787 legacy_hal_.lock()->getWakeReasonStats(getWlan0IfaceName());
788 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
789 return {createWifiStatusFromLegacyError(legacy_status), {}};
790 }
791 WifiDebugHostWakeReasonStats hidl_stats;
792 if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats,
793 &hidl_stats)) {
794 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
795 }
796 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700797}
798
Roshan Pius203cb032016-12-14 17:41:20 -0800799WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700800 legacy_hal::wifi_error legacy_status;
801 if (enable) {
802 android::wp<WifiChip> weak_ptr_this(this);
803 const auto& on_alert_callback = [weak_ptr_this](
804 int32_t error_code,
805 std::vector<uint8_t> debug_data) {
806 const auto shared_ptr_this = weak_ptr_this.promote();
807 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
808 LOG(ERROR) << "Callback invoked on an invalid object";
809 return;
810 }
811 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
812 if (!callback->onDebugErrorAlert(error_code, debug_data)
813 .isOk()) {
814 LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
815 }
816 }
817 };
818 legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
Roshan Piusacededb2017-10-06 14:59:26 -0700819 getWlan0IfaceName(), on_alert_callback);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700820 } else {
821 legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
Roshan Piusacededb2017-10-06 14:59:26 -0700822 getWlan0IfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -0700823 }
824 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius203cb032016-12-14 17:41:20 -0800825}
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800826
Roshan Pius735ff432017-07-25 08:48:08 -0700827WifiStatus WifiChip::selectTxPowerScenarioInternal(TxPowerScenario scenario) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700828 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
829 getWlan0IfaceName(),
830 hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
831 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700832}
833
Roshan Pius735ff432017-07-25 08:48:08 -0700834WifiStatus WifiChip::resetTxPowerScenarioInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700835 auto legacy_status =
836 legacy_hal_.lock()->resetTxPowerScenario(getWlan0IfaceName());
837 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700838}
839
Roshan Piusba38d9c2017-12-08 07:32:08 -0800840WifiStatus WifiChip::handleChipConfiguration(
841 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
842 ChipModeId mode_id) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700843 // If the chip is already configured in a different mode, stop
844 // the legacy HAL and then start it after firmware mode change.
Roshan Piusabcf78f2017-10-06 16:30:38 -0700845 if (current_mode_id_ != kInvalidModeId) {
Roshan Piusba38d9c2017-12-08 07:32:08 -0800846 LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_
847 << " to mode " << mode_id;
848 invalidateAndRemoveAllIfaces();
849 legacy_hal::wifi_error legacy_status =
850 legacy_hal_.lock()->stop(lock, []() {});
851 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
852 LOG(ERROR) << "Failed to stop legacy HAL: "
853 << legacyErrorToString(legacy_status);
854 return createWifiStatusFromLegacyError(legacy_status);
855 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700856 }
857 bool success;
858 if (mode_id == kStaChipModeId) {
859 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
860 } else {
861 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
862 }
863 if (!success) {
864 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
865 }
866 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
867 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
868 LOG(ERROR) << "Failed to start legacy HAL: "
869 << legacyErrorToString(legacy_status);
870 return createWifiStatusFromLegacyError(legacy_status);
871 }
872 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800873}
Roshan Pius48185b22016-12-15 19:10:30 -0800874
875WifiStatus WifiChip::registerDebugRingBufferCallback() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700876 if (debug_ring_buffer_cb_registered_) {
877 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius48185b22016-12-15 19:10:30 -0800878 }
Roshan Pius3797e182017-03-30 18:01:54 -0700879
Roshan Piusabcf78f2017-10-06 16:30:38 -0700880 android::wp<WifiChip> weak_ptr_this(this);
881 const auto& on_ring_buffer_data_callback =
882 [weak_ptr_this](const std::string& /* name */,
883 const std::vector<uint8_t>& data,
884 const legacy_hal::wifi_ring_buffer_status& status) {
885 const auto shared_ptr_this = weak_ptr_this.promote();
886 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
887 LOG(ERROR) << "Callback invoked on an invalid object";
888 return;
889 }
890 WifiDebugRingBufferStatus hidl_status;
891 if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(
892 status, &hidl_status)) {
893 LOG(ERROR) << "Error converting ring buffer status";
894 return;
895 }
896 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
897 if (!callback->onDebugRingBufferDataAvailable(hidl_status, data)
898 .isOk()) {
899 LOG(ERROR)
900 << "Failed to invoke onDebugRingBufferDataAvailable"
901 << " callback on: " << toString(callback);
902 }
903 }
904 };
905 legacy_hal::wifi_error legacy_status =
906 legacy_hal_.lock()->registerRingBufferCallbackHandler(
907 getWlan0IfaceName(), on_ring_buffer_data_callback);
Roshan Pius48185b22016-12-15 19:10:30 -0800908
Roshan Piusabcf78f2017-10-06 16:30:38 -0700909 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
910 debug_ring_buffer_cb_registered_ = true;
911 }
912 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius48185b22016-12-15 19:10:30 -0800913}
914
Roshan Pius79a99752016-10-04 13:03:58 -0700915} // namespace implementation
Etan Cohen6ce50902017-09-14 07:30:57 -0700916} // namespace V1_2
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700917} // namespace wifi
918} // namespace hardware
919} // namespace android