blob: 49cf8882b18e08e631cd19f255b810477e4dc78c [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"
Etan Cohenc5700402017-03-08 16:43:38 -080023#include "wifi_feature_flags.h"
Roshan Pius5c055462016-10-11 08:27:27 -070024#include "wifi_status_util.h"
Roshan Pius3c4e8a32016-10-03 14:53:58 -070025
Roshan Pius35d958c2016-10-06 16:47:38 -070026namespace {
Roshan Pius35d958c2016-10-06 16:47:38 -070027using android::hardware::hidl_string;
Roshan Piusabcf78f2017-10-06 16:30:38 -070028using android::hardware::hidl_vec;
Roshan Pius2c06a3f2016-12-15 17:51:40 -080029using android::hardware::wifi::V1_0::ChipModeId;
Roshan Pius52947fb2016-11-18 11:38:07 -080030using android::hardware::wifi::V1_0::IfaceType;
Roshan Pius675609b2017-10-31 14:24:58 -070031using android::hardware::wifi::V1_0::IWifiChip;
Roshan Piusabcf78f2017-10-06 16:30:38 -070032using android::sp;
Roshan Pius52947fb2016-11-18 11:38:07 -080033
Roshan Pius2c06a3f2016-12-15 17:51:40 -080034constexpr ChipModeId kStaChipModeId = 0;
35constexpr ChipModeId kApChipModeId = 1;
36constexpr ChipModeId kInvalidModeId = UINT32_MAX;
Roshan Pius35d958c2016-10-06 16:47:38 -070037
Roshan Pius35d958c2016-10-06 16:47:38 -070038template <typename Iface>
Roshan Pius675609b2017-10-31 14:24:58 -070039void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
40 iface->invalidate();
41 ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface),
42 ifaces.end());
43}
44
45template <typename Iface>
46void invalidateAndClearAll(std::vector<sp<Iface>>& ifaces) {
47 for (const auto& iface : ifaces) {
Roshan Piusabcf78f2017-10-06 16:30:38 -070048 iface->invalidate();
Roshan Piusabcf78f2017-10-06 16:30:38 -070049 }
Roshan Pius675609b2017-10-31 14:24:58 -070050 ifaces.clear();
51}
52
53template <typename Iface>
54std::vector<hidl_string> getNames(std::vector<sp<Iface>>& ifaces) {
55 std::vector<hidl_string> names;
56 for (const auto& iface : ifaces) {
57 names.emplace_back(iface->getName());
58 }
59 return names;
60}
61
62template <typename Iface>
63sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces,
64 const std::string& name) {
65 std::vector<hidl_string> names;
66 for (const auto& iface : ifaces) {
67 if (name == iface->getName()) {
68 return iface;
69 }
70 }
71 return nullptr;
Roshan Pius35d958c2016-10-06 16:47:38 -070072}
Roshan Pius9377a0d2017-10-06 13:18:54 -070073
74std::string getWlan0IfaceName() {
Roshan Piusabcf78f2017-10-06 16:30:38 -070075 std::array<char, PROPERTY_VALUE_MAX> buffer;
76 property_get("wifi.interface", buffer.data(), "wlan0");
77 return buffer.data();
Roshan Pius9377a0d2017-10-06 13:18:54 -070078}
79
80/** Not used yet.
81std::string getWlan1IfaceName() {
82 std::array<char, PROPERTY_VALUE_MAX> buffer;
83 property_get("wifi.concurrent.interface", buffer.data(), "wlan1");
84 return buffer.data();
85}
86*/
87
88std::string getP2pIfaceName() {
Roshan Piusabcf78f2017-10-06 16:30:38 -070089 std::array<char, PROPERTY_VALUE_MAX> buffer;
90 property_get("wifi.direct.interface", buffer.data(), "p2p0");
91 return buffer.data();
Roshan Pius9377a0d2017-10-06 13:18:54 -070092}
93
Roshan Piusabcf78f2017-10-06 16:30:38 -070094} // namespace
Roshan Pius35d958c2016-10-06 16:47:38 -070095
Roshan Pius3c4e8a32016-10-03 14:53:58 -070096namespace android {
97namespace hardware {
98namespace wifi {
Etan Cohen6ce50902017-09-14 07:30:57 -070099namespace V1_2 {
Roshan Pius79a99752016-10-04 13:03:58 -0700100namespace implementation {
Roshan Pius3c868522016-10-27 12:43:49 -0700101using hidl_return_util::validateAndCall;
Roshan Piusba38d9c2017-12-08 07:32:08 -0800102using hidl_return_util::validateAndCallWithLock;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700103
Roshan Pius52947fb2016-11-18 11:38:07 -0800104WifiChip::WifiChip(
Roshan Piusabcf78f2017-10-06 16:30:38 -0700105 ChipId chip_id, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
Roshan Pius52947fb2016-11-18 11:38:07 -0800106 const std::weak_ptr<mode_controller::WifiModeController> mode_controller)
107 : chip_id_(chip_id),
108 legacy_hal_(legacy_hal),
109 mode_controller_(mode_controller),
110 is_valid_(true),
Roshan Pius48185b22016-12-15 19:10:30 -0800111 current_mode_id_(kInvalidModeId),
112 debug_ring_buffer_cb_registered_(false) {}
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700113
Roshan Piusaabe5752016-09-29 09:03:59 -0700114void WifiChip::invalidate() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700115 invalidateAndRemoveAllIfaces();
116 legacy_hal_.reset();
117 event_cb_handler_.invalidate();
118 is_valid_ = false;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700119}
120
Roshan Piusabcf78f2017-10-06 16:30:38 -0700121bool WifiChip::isValid() { return is_valid_; }
Roshan Pius3c868522016-10-27 12:43:49 -0700122
Roshan Piusd37341f2017-01-31 13:13:28 -0800123std::set<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700124 return event_cb_handler_.getCallbacks();
Roshan Pius203cb032016-12-14 17:41:20 -0800125}
126
Roshan Pius5c055462016-10-11 08:27:27 -0700127Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700128 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
129 &WifiChip::getIdInternal, hidl_status_cb);
Roshan Piuscd566bd2016-10-10 08:03:42 -0700130}
131
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700132Return<void> WifiChip::registerEventCallback(
Roshan Pius5c055462016-10-11 08:27:27 -0700133 const sp<IWifiChipEventCallback>& event_callback,
134 registerEventCallback_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700135 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
136 &WifiChip::registerEventCallbackInternal,
137 hidl_status_cb, event_callback);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700138}
139
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700140Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700141 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
142 &WifiChip::getCapabilitiesInternal, hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700143}
144
Roshan Pius5c055462016-10-11 08:27:27 -0700145Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700146 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
147 &WifiChip::getAvailableModesInternal,
148 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700149}
150
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800151Return<void> WifiChip::configureChip(ChipModeId mode_id,
Roshan Pius5c055462016-10-11 08:27:27 -0700152 configureChip_cb hidl_status_cb) {
Roshan Piusba38d9c2017-12-08 07:32:08 -0800153 return validateAndCallWithLock(
154 this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
155 &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700156}
157
Roshan Pius5c055462016-10-11 08:27:27 -0700158Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700159 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
160 &WifiChip::getModeInternal, hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700161}
162
Roshan Pius5c055462016-10-11 08:27:27 -0700163Return<void> WifiChip::requestChipDebugInfo(
164 requestChipDebugInfo_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700165 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
166 &WifiChip::requestChipDebugInfoInternal,
167 hidl_status_cb);
Roshan Pius5c055462016-10-11 08:27:27 -0700168}
169
170Return<void> WifiChip::requestDriverDebugDump(
171 requestDriverDebugDump_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700172 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
173 &WifiChip::requestDriverDebugDumpInternal,
174 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700175}
176
Roshan Pius5c055462016-10-11 08:27:27 -0700177Return<void> WifiChip::requestFirmwareDebugDump(
178 requestFirmwareDebugDump_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700179 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
180 &WifiChip::requestFirmwareDebugDumpInternal,
181 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700182}
183
Roshan Pius5c055462016-10-11 08:27:27 -0700184Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700185 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
186 &WifiChip::createApIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700187}
188
Roshan Pius5c055462016-10-11 08:27:27 -0700189Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700190 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
191 &WifiChip::getApIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700192}
193
Roshan Pius5c055462016-10-11 08:27:27 -0700194Return<void> WifiChip::getApIface(const hidl_string& ifname,
195 getApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700196 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
197 &WifiChip::getApIfaceInternal, hidl_status_cb,
198 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700199}
200
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800201Return<void> WifiChip::removeApIface(const hidl_string& ifname,
202 removeApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700203 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
204 &WifiChip::removeApIfaceInternal, hidl_status_cb,
205 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800206}
207
Roshan Pius5c055462016-10-11 08:27:27 -0700208Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700209 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
210 &WifiChip::createNanIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700211}
212
Roshan Pius5c055462016-10-11 08:27:27 -0700213Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700214 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
215 &WifiChip::getNanIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700216}
217
218Return<void> WifiChip::getNanIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700219 getNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700220 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
221 &WifiChip::getNanIfaceInternal, hidl_status_cb,
222 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700223}
224
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800225Return<void> WifiChip::removeNanIface(const hidl_string& ifname,
226 removeNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700227 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
228 &WifiChip::removeNanIfaceInternal, hidl_status_cb,
229 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800230}
231
Roshan Pius5c055462016-10-11 08:27:27 -0700232Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700233 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
234 &WifiChip::createP2pIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700235}
236
Roshan Pius5c055462016-10-11 08:27:27 -0700237Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700238 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
239 &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700240}
241
242Return<void> WifiChip::getP2pIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700243 getP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700244 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
245 &WifiChip::getP2pIfaceInternal, hidl_status_cb,
246 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700247}
248
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800249Return<void> WifiChip::removeP2pIface(const hidl_string& ifname,
250 removeP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700251 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
252 &WifiChip::removeP2pIfaceInternal, hidl_status_cb,
253 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800254}
255
Roshan Pius5c055462016-10-11 08:27:27 -0700256Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700257 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
258 &WifiChip::createStaIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700259}
260
Roshan Pius5c055462016-10-11 08:27:27 -0700261Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700262 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
263 &WifiChip::getStaIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700264}
265
266Return<void> WifiChip::getStaIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700267 getStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700268 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
269 &WifiChip::getStaIfaceInternal, hidl_status_cb,
270 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700271}
272
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800273Return<void> WifiChip::removeStaIface(const hidl_string& ifname,
274 removeStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700275 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
276 &WifiChip::removeStaIfaceInternal, hidl_status_cb,
277 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800278}
279
Roshan Pius5c055462016-10-11 08:27:27 -0700280Return<void> WifiChip::createRttController(
281 const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700282 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
283 &WifiChip::createRttControllerInternal,
284 hidl_status_cb, bound_iface);
Roshan Pius59268282016-10-06 20:23:47 -0700285}
286
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700287Return<void> WifiChip::getDebugRingBuffersStatus(
288 getDebugRingBuffersStatus_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700289 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
290 &WifiChip::getDebugRingBuffersStatusInternal,
291 hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700292}
293
294Return<void> WifiChip::startLoggingToDebugRingBuffer(
Roshan Piusabcf78f2017-10-06 16:30:38 -0700295 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
296 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700297 startLoggingToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700298 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
299 &WifiChip::startLoggingToDebugRingBufferInternal,
300 hidl_status_cb, ring_name, verbose_level,
301 max_interval_in_sec, min_data_size_in_bytes);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700302}
303
304Return<void> WifiChip::forceDumpToDebugRingBuffer(
305 const hidl_string& ring_name,
306 forceDumpToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700307 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
308 &WifiChip::forceDumpToDebugRingBufferInternal,
309 hidl_status_cb, ring_name);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700310}
311
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800312Return<void> WifiChip::stopLoggingToDebugRingBuffer(
313 stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700314 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
315 &WifiChip::stopLoggingToDebugRingBufferInternal,
316 hidl_status_cb);
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800317}
318
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700319Return<void> WifiChip::getDebugHostWakeReasonStats(
320 getDebugHostWakeReasonStats_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700321 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
322 &WifiChip::getDebugHostWakeReasonStatsInternal,
323 hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700324}
325
Roshan Pius203cb032016-12-14 17:41:20 -0800326Return<void> WifiChip::enableDebugErrorAlerts(
327 bool enable, enableDebugErrorAlerts_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700328 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
329 &WifiChip::enableDebugErrorAlertsInternal,
330 hidl_status_cb, enable);
Roshan Pius203cb032016-12-14 17:41:20 -0800331}
332
Roshan Pius735ff432017-07-25 08:48:08 -0700333Return<void> WifiChip::selectTxPowerScenario(
334 TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700335 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
336 &WifiChip::selectTxPowerScenarioInternal,
337 hidl_status_cb, scenario);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700338}
339
Roshan Pius735ff432017-07-25 08:48:08 -0700340Return<void> WifiChip::resetTxPowerScenario(
341 resetTxPowerScenario_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700342 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
343 &WifiChip::resetTxPowerScenarioInternal,
344 hidl_status_cb);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700345}
346
Roshan Pius35d958c2016-10-06 16:47:38 -0700347void WifiChip::invalidateAndRemoveAllIfaces() {
Roshan Pius675609b2017-10-31 14:24:58 -0700348 invalidateAndClearAll(ap_ifaces_);
349 invalidateAndClearAll(nan_ifaces_);
350 invalidateAndClearAll(p2p_ifaces_);
351 invalidateAndClearAll(sta_ifaces_);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700352 // Since all the ifaces are invalid now, all RTT controller objects
353 // using those ifaces also need to be invalidated.
354 for (const auto& rtt : rtt_controllers_) {
355 rtt->invalidate();
356 }
357 rtt_controllers_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -0700358}
359
Roshan Pius3c868522016-10-27 12:43:49 -0700360std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700361 return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700362}
363
364WifiStatus WifiChip::registerEventCallbackInternal(
365 const sp<IWifiChipEventCallback>& event_callback) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700366 if (!event_cb_handler_.addCallback(event_callback)) {
367 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
368 }
369 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius3c868522016-10-27 12:43:49 -0700370}
371
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700372std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700373 legacy_hal::wifi_error legacy_status;
374 uint32_t legacy_feature_set;
375 uint32_t legacy_logger_feature_set;
376 std::tie(legacy_status, legacy_feature_set) =
377 legacy_hal_.lock()->getSupportedFeatureSet(getWlan0IfaceName());
378 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
379 return {createWifiStatusFromLegacyError(legacy_status), 0};
380 }
381 std::tie(legacy_status, legacy_logger_feature_set) =
382 legacy_hal_.lock()->getLoggerSupportedFeatureSet(getWlan0IfaceName());
383 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
384 return {createWifiStatusFromLegacyError(legacy_status), 0};
385 }
386 uint32_t hidl_caps;
387 if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
388 legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
389 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
390 }
391 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700392}
393
Roshan Pius3c868522016-10-27 12:43:49 -0700394std::pair<WifiStatus, std::vector<IWifiChip::ChipMode>>
395WifiChip::getAvailableModesInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700396 // The chip combination supported for current devices is fixed for now with
397 // 2 separate modes of operation:
398 // Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN iface operations
399 // concurrently [NAN conditional on wifiHidlFeatureAware]
400 // Mode 2 (AP mode): Will support 1 AP iface operations.
401 // TODO (b/32997844): Read this from some device specific flags in the
402 // makefile.
403 // STA mode iface combinations.
404 const IWifiChip::ChipIfaceCombinationLimit
405 sta_chip_iface_combination_limit_1 = {{IfaceType::STA}, 1};
406 IWifiChip::ChipIfaceCombinationLimit sta_chip_iface_combination_limit_2;
407 if (WifiFeatureFlags::wifiHidlFeatureAware) {
408 sta_chip_iface_combination_limit_2 = {{IfaceType::P2P, IfaceType::NAN},
409 1};
410 } else {
411 sta_chip_iface_combination_limit_2 = {{IfaceType::P2P}, 1};
412 }
413 const IWifiChip::ChipIfaceCombination sta_chip_iface_combination = {
414 {sta_chip_iface_combination_limit_1,
415 sta_chip_iface_combination_limit_2}};
416 const IWifiChip::ChipMode sta_chip_mode = {kStaChipModeId,
417 {sta_chip_iface_combination}};
418 // AP mode iface combinations.
419 const IWifiChip::ChipIfaceCombinationLimit ap_chip_iface_combination_limit =
420 {{IfaceType::AP}, 1};
421 const IWifiChip::ChipIfaceCombination ap_chip_iface_combination = {
422 {ap_chip_iface_combination_limit}};
423 const IWifiChip::ChipMode ap_chip_mode = {kApChipModeId,
424 {ap_chip_iface_combination}};
425 return {createWifiStatus(WifiStatusCode::SUCCESS),
426 {sta_chip_mode, ap_chip_mode}};
Roshan Pius3c868522016-10-27 12:43:49 -0700427}
428
Roshan Piusba38d9c2017-12-08 07:32:08 -0800429WifiStatus WifiChip::configureChipInternal(
430 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
431 ChipModeId mode_id) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700432 if (mode_id != kStaChipModeId && mode_id != kApChipModeId) {
433 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
434 }
435 if (mode_id == current_mode_id_) {
436 LOG(DEBUG) << "Already in the specified mode " << mode_id;
437 return createWifiStatus(WifiStatusCode::SUCCESS);
438 }
Roshan Piusba38d9c2017-12-08 07:32:08 -0800439 WifiStatus status = handleChipConfiguration(lock, mode_id);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700440 if (status.code != WifiStatusCode::SUCCESS) {
441 for (const auto& callback : event_cb_handler_.getCallbacks()) {
442 if (!callback->onChipReconfigureFailure(status).isOk()) {
443 LOG(ERROR)
444 << "Failed to invoke onChipReconfigureFailure callback";
445 }
446 }
447 return status;
448 }
Roshan Piusd37341f2017-01-31 13:13:28 -0800449 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700450 if (!callback->onChipReconfigured(mode_id).isOk()) {
451 LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
452 }
Roshan Pius52947fb2016-11-18 11:38:07 -0800453 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700454 current_mode_id_ = mode_id;
Roshan Piusba38d9c2017-12-08 07:32:08 -0800455 LOG(INFO) << "Configured chip in mode " << mode_id;
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800456 return status;
Roshan Pius3c868522016-10-27 12:43:49 -0700457}
458
459std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700460 if (current_mode_id_ == kInvalidModeId) {
461 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE),
462 current_mode_id_};
463 }
464 return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700465}
466
467std::pair<WifiStatus, IWifiChip::ChipDebugInfo>
468WifiChip::requestChipDebugInfoInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700469 IWifiChip::ChipDebugInfo result;
470 legacy_hal::wifi_error legacy_status;
471 std::string driver_desc;
472 std::tie(legacy_status, driver_desc) =
473 legacy_hal_.lock()->getDriverVersion(getWlan0IfaceName());
474 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
475 LOG(ERROR) << "Failed to get driver version: "
476 << legacyErrorToString(legacy_status);
477 WifiStatus status = createWifiStatusFromLegacyError(
478 legacy_status, "failed to get driver version");
479 return {status, result};
480 }
481 result.driverDescription = driver_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700482
Roshan Piusabcf78f2017-10-06 16:30:38 -0700483 std::string firmware_desc;
484 std::tie(legacy_status, firmware_desc) =
485 legacy_hal_.lock()->getFirmwareVersion(getWlan0IfaceName());
486 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
487 LOG(ERROR) << "Failed to get firmware version: "
488 << legacyErrorToString(legacy_status);
489 WifiStatus status = createWifiStatusFromLegacyError(
490 legacy_status, "failed to get firmware version");
491 return {status, result};
492 }
493 result.firmwareDescription = firmware_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700494
Roshan Piusabcf78f2017-10-06 16:30:38 -0700495 return {createWifiStatus(WifiStatusCode::SUCCESS), result};
Roshan Pius3c868522016-10-27 12:43:49 -0700496}
497
498std::pair<WifiStatus, std::vector<uint8_t>>
499WifiChip::requestDriverDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700500 legacy_hal::wifi_error legacy_status;
501 std::vector<uint8_t> driver_dump;
502 std::tie(legacy_status, driver_dump) =
503 legacy_hal_.lock()->requestDriverMemoryDump(getWlan0IfaceName());
504 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
505 LOG(ERROR) << "Failed to get driver debug dump: "
506 << legacyErrorToString(legacy_status);
507 return {createWifiStatusFromLegacyError(legacy_status),
508 std::vector<uint8_t>()};
509 }
510 return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
Roshan Pius3c868522016-10-27 12:43:49 -0700511}
512
513std::pair<WifiStatus, std::vector<uint8_t>>
514WifiChip::requestFirmwareDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700515 legacy_hal::wifi_error legacy_status;
516 std::vector<uint8_t> firmware_dump;
517 std::tie(legacy_status, firmware_dump) =
518 legacy_hal_.lock()->requestFirmwareMemoryDump(getWlan0IfaceName());
519 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
520 LOG(ERROR) << "Failed to get firmware debug dump: "
521 << legacyErrorToString(legacy_status);
522 return {createWifiStatusFromLegacyError(legacy_status), {}};
523 }
524 return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
Roshan Pius3c868522016-10-27 12:43:49 -0700525}
526
527std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700528 if (current_mode_id_ != kApChipModeId || !ap_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700529 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -0800530 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700531 std::string ifname = getWlan0IfaceName();
Roshan Pius675609b2017-10-31 14:24:58 -0700532 sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_);
533 ap_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700534 for (const auto& callback : event_cb_handler_.getCallbacks()) {
535 if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
536 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
537 }
538 }
Roshan Pius675609b2017-10-31 14:24:58 -0700539 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700540}
541
542std::pair<WifiStatus, std::vector<hidl_string>>
543WifiChip::getApIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700544 if (ap_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700545 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
546 }
Roshan Pius675609b2017-10-31 14:24:58 -0700547 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -0700548}
549
550std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::getApIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800551 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700552 const auto iface = findUsingName(ap_ifaces_, ifname);
553 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700554 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
555 }
Roshan Pius675609b2017-10-31 14:24:58 -0700556 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700557}
558
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800559WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700560 const auto iface = findUsingName(ap_ifaces_, ifname);
561 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700562 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800563 }
Roshan Pius675609b2017-10-31 14:24:58 -0700564 invalidateAndClear(ap_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700565 for (const auto& callback : event_cb_handler_.getCallbacks()) {
566 if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
567 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
568 }
569 }
570 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800571}
572
Roshan Pius3c868522016-10-27 12:43:49 -0700573std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700574 // Only 1 of NAN or P2P iface can be active at a time.
575 if (WifiFeatureFlags::wifiHidlFeatureAware) {
Roshan Pius675609b2017-10-31 14:24:58 -0700576 if (current_mode_id_ != kStaChipModeId || !nan_ifaces_.empty() ||
577 !p2p_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700578 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
579 }
580 std::string ifname = getWlan0IfaceName();
Roshan Pius675609b2017-10-31 14:24:58 -0700581 sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_);
582 nan_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700583 for (const auto& callback : event_cb_handler_.getCallbacks()) {
584 if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
585 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
586 }
587 }
Roshan Pius675609b2017-10-31 14:24:58 -0700588 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700589 } else {
590 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Etan Cohenc5700402017-03-08 16:43:38 -0800591 }
Roshan Pius3c868522016-10-27 12:43:49 -0700592}
593
594std::pair<WifiStatus, std::vector<hidl_string>>
595WifiChip::getNanIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700596 if (nan_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700597 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
598 }
Roshan Pius675609b2017-10-31 14:24:58 -0700599 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -0700600}
601
602std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::getNanIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800603 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700604 const auto iface = findUsingName(nan_ifaces_, ifname);
605 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700606 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
607 }
Roshan Pius675609b2017-10-31 14:24:58 -0700608 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700609}
610
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800611WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700612 const auto iface = findUsingName(nan_ifaces_, ifname);
613 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700614 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800615 }
Roshan Pius675609b2017-10-31 14:24:58 -0700616 invalidateAndClear(nan_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700617 for (const auto& callback : event_cb_handler_.getCallbacks()) {
618 if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
619 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
620 }
621 }
622 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800623}
624
Roshan Pius3c868522016-10-27 12:43:49 -0700625std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700626 // Only 1 of NAN or P2P iface can be active at a time.
Roshan Pius675609b2017-10-31 14:24:58 -0700627 if (current_mode_id_ != kStaChipModeId || !p2p_ifaces_.empty() ||
628 !nan_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700629 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -0800630 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700631 std::string ifname = getP2pIfaceName();
Roshan Pius675609b2017-10-31 14:24:58 -0700632 sp<WifiP2pIface> iface = new WifiP2pIface(ifname, legacy_hal_);
633 p2p_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700634 for (const auto& callback : event_cb_handler_.getCallbacks()) {
635 if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
636 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
637 }
638 }
Roshan Pius675609b2017-10-31 14:24:58 -0700639 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700640}
641
642std::pair<WifiStatus, std::vector<hidl_string>>
643WifiChip::getP2pIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700644 if (p2p_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700645 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
646 }
Roshan Pius675609b2017-10-31 14:24:58 -0700647 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -0700648}
649
650std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800651 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700652 const auto iface = findUsingName(p2p_ifaces_, ifname);
653 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700654 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
655 }
Roshan Pius675609b2017-10-31 14:24:58 -0700656 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700657}
658
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800659WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700660 const auto iface = findUsingName(p2p_ifaces_, ifname);
661 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700662 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800663 }
Roshan Pius675609b2017-10-31 14:24:58 -0700664 invalidateAndClear(p2p_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700665 for (const auto& callback : event_cb_handler_.getCallbacks()) {
666 if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
667 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
668 }
669 }
670 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800671}
672
Roshan Pius3c868522016-10-27 12:43:49 -0700673std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700674 if (current_mode_id_ != kStaChipModeId || !sta_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700675 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -0800676 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700677 std::string ifname = getWlan0IfaceName();
Roshan Pius675609b2017-10-31 14:24:58 -0700678 sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_);
679 sta_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700680 for (const auto& callback : event_cb_handler_.getCallbacks()) {
681 if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
682 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
683 }
684 }
Roshan Pius675609b2017-10-31 14:24:58 -0700685 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700686}
687
688std::pair<WifiStatus, std::vector<hidl_string>>
689WifiChip::getStaIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700690 if (sta_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700691 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
692 }
Roshan Pius675609b2017-10-31 14:24:58 -0700693 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -0700694}
695
696std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::getStaIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800697 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700698 const auto iface = findUsingName(sta_ifaces_, ifname);
699 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700700 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
701 }
Roshan Pius675609b2017-10-31 14:24:58 -0700702 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -0700703}
704
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800705WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700706 const auto iface = findUsingName(sta_ifaces_, ifname);
707 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700708 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800709 }
Roshan Pius675609b2017-10-31 14:24:58 -0700710 invalidateAndClear(sta_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700711 for (const auto& callback : event_cb_handler_.getCallbacks()) {
712 if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
713 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
714 }
715 }
716 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800717}
718
Roshan Pius3c868522016-10-27 12:43:49 -0700719std::pair<WifiStatus, sp<IWifiRttController>>
720WifiChip::createRttControllerInternal(const sp<IWifiIface>& bound_iface) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700721 sp<WifiRttController> rtt =
722 new WifiRttController(getWlan0IfaceName(), bound_iface, legacy_hal_);
723 rtt_controllers_.emplace_back(rtt);
724 return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
Roshan Pius3c868522016-10-27 12:43:49 -0700725}
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700726
727std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
728WifiChip::getDebugRingBuffersStatusInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700729 legacy_hal::wifi_error legacy_status;
730 std::vector<legacy_hal::wifi_ring_buffer_status>
731 legacy_ring_buffer_status_vec;
732 std::tie(legacy_status, legacy_ring_buffer_status_vec) =
733 legacy_hal_.lock()->getRingBuffersStatus(getWlan0IfaceName());
734 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
735 return {createWifiStatusFromLegacyError(legacy_status), {}};
736 }
737 std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
738 if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
739 legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
740 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
741 }
742 return {createWifiStatus(WifiStatusCode::SUCCESS),
743 hidl_ring_buffer_status_vec};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700744}
745
746WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
Roshan Piusabcf78f2017-10-06 16:30:38 -0700747 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
748 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
749 WifiStatus status = registerDebugRingBufferCallback();
750 if (status.code != WifiStatusCode::SUCCESS) {
751 return status;
752 }
753 legacy_hal::wifi_error legacy_status =
754 legacy_hal_.lock()->startRingBufferLogging(
755 getWlan0IfaceName(), ring_name,
756 static_cast<
757 std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
758 verbose_level),
759 max_interval_in_sec, min_data_size_in_bytes);
760 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700761}
762
763WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800764 const hidl_string& ring_name) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700765 WifiStatus status = registerDebugRingBufferCallback();
766 if (status.code != WifiStatusCode::SUCCESS) {
767 return status;
768 }
769 legacy_hal::wifi_error legacy_status =
770 legacy_hal_.lock()->getRingBufferData(getWlan0IfaceName(), ring_name);
771 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700772}
773
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800774WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700775 legacy_hal::wifi_error legacy_status =
776 legacy_hal_.lock()->deregisterRingBufferCallbackHandler(
777 getWlan0IfaceName());
778 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800779}
780
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700781std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
782WifiChip::getDebugHostWakeReasonStatsInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700783 legacy_hal::wifi_error legacy_status;
784 legacy_hal::WakeReasonStats legacy_stats;
785 std::tie(legacy_status, legacy_stats) =
786 legacy_hal_.lock()->getWakeReasonStats(getWlan0IfaceName());
787 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
788 return {createWifiStatusFromLegacyError(legacy_status), {}};
789 }
790 WifiDebugHostWakeReasonStats hidl_stats;
791 if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats,
792 &hidl_stats)) {
793 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
794 }
795 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700796}
797
Roshan Pius203cb032016-12-14 17:41:20 -0800798WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700799 legacy_hal::wifi_error legacy_status;
800 if (enable) {
801 android::wp<WifiChip> weak_ptr_this(this);
802 const auto& on_alert_callback = [weak_ptr_this](
803 int32_t error_code,
804 std::vector<uint8_t> debug_data) {
805 const auto shared_ptr_this = weak_ptr_this.promote();
806 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
807 LOG(ERROR) << "Callback invoked on an invalid object";
808 return;
809 }
810 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
811 if (!callback->onDebugErrorAlert(error_code, debug_data)
812 .isOk()) {
813 LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
814 }
815 }
816 };
817 legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
Roshan Piusacededb2017-10-06 14:59:26 -0700818 getWlan0IfaceName(), on_alert_callback);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700819 } else {
820 legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
Roshan Piusacededb2017-10-06 14:59:26 -0700821 getWlan0IfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -0700822 }
823 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius203cb032016-12-14 17:41:20 -0800824}
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800825
Roshan Pius735ff432017-07-25 08:48:08 -0700826WifiStatus WifiChip::selectTxPowerScenarioInternal(TxPowerScenario scenario) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700827 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
828 getWlan0IfaceName(),
829 hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
830 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700831}
832
Roshan Pius735ff432017-07-25 08:48:08 -0700833WifiStatus WifiChip::resetTxPowerScenarioInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700834 auto legacy_status =
835 legacy_hal_.lock()->resetTxPowerScenario(getWlan0IfaceName());
836 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700837}
838
Roshan Piusba38d9c2017-12-08 07:32:08 -0800839WifiStatus WifiChip::handleChipConfiguration(
840 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
841 ChipModeId mode_id) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700842 // If the chip is already configured in a different mode, stop
843 // the legacy HAL and then start it after firmware mode change.
Roshan Piusabcf78f2017-10-06 16:30:38 -0700844 if (current_mode_id_ != kInvalidModeId) {
Roshan Piusba38d9c2017-12-08 07:32:08 -0800845 LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_
846 << " to mode " << mode_id;
847 invalidateAndRemoveAllIfaces();
848 legacy_hal::wifi_error legacy_status =
849 legacy_hal_.lock()->stop(lock, []() {});
850 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
851 LOG(ERROR) << "Failed to stop legacy HAL: "
852 << legacyErrorToString(legacy_status);
853 return createWifiStatusFromLegacyError(legacy_status);
854 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700855 }
856 bool success;
857 if (mode_id == kStaChipModeId) {
858 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
859 } else {
860 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
861 }
862 if (!success) {
863 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
864 }
865 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
866 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
867 LOG(ERROR) << "Failed to start legacy HAL: "
868 << legacyErrorToString(legacy_status);
869 return createWifiStatusFromLegacyError(legacy_status);
870 }
871 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800872}
Roshan Pius48185b22016-12-15 19:10:30 -0800873
874WifiStatus WifiChip::registerDebugRingBufferCallback() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700875 if (debug_ring_buffer_cb_registered_) {
876 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius48185b22016-12-15 19:10:30 -0800877 }
Roshan Pius3797e182017-03-30 18:01:54 -0700878
Roshan Piusabcf78f2017-10-06 16:30:38 -0700879 android::wp<WifiChip> weak_ptr_this(this);
880 const auto& on_ring_buffer_data_callback =
881 [weak_ptr_this](const std::string& /* name */,
882 const std::vector<uint8_t>& data,
883 const legacy_hal::wifi_ring_buffer_status& status) {
884 const auto shared_ptr_this = weak_ptr_this.promote();
885 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
886 LOG(ERROR) << "Callback invoked on an invalid object";
887 return;
888 }
889 WifiDebugRingBufferStatus hidl_status;
890 if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(
891 status, &hidl_status)) {
892 LOG(ERROR) << "Error converting ring buffer status";
893 return;
894 }
895 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
896 if (!callback->onDebugRingBufferDataAvailable(hidl_status, data)
897 .isOk()) {
898 LOG(ERROR)
899 << "Failed to invoke onDebugRingBufferDataAvailable"
900 << " callback on: " << toString(callback);
901 }
902 }
903 };
904 legacy_hal::wifi_error legacy_status =
905 legacy_hal_.lock()->registerRingBufferCallbackHandler(
906 getWlan0IfaceName(), on_ring_buffer_data_callback);
Roshan Pius48185b22016-12-15 19:10:30 -0800907
Roshan Piusabcf78f2017-10-06 16:30:38 -0700908 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
909 debug_ring_buffer_cb_registered_ = true;
910 }
911 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius48185b22016-12-15 19:10:30 -0800912}
913
Roshan Pius79a99752016-10-04 13:03:58 -0700914} // namespace implementation
Etan Cohen6ce50902017-09-14 07:30:57 -0700915} // namespace V1_2
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700916} // namespace wifi
917} // namespace hardware
918} // namespace android