blob: f3ff3edb3a9061a676bc960d9fd49bdae69e315f [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 {
27using android::sp;
28using android::hardware::hidl_vec;
29using android::hardware::hidl_string;
Roshan Pius2c06a3f2016-12-15 17:51:40 -080030using android::hardware::wifi::V1_0::ChipModeId;
Roshan Pius52947fb2016-11-18 11:38:07 -080031using android::hardware::wifi::V1_0::IWifiChip;
32using android::hardware::wifi::V1_0::IfaceType;
33
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>
39void invalidateAndClear(sp<Iface>& iface) {
40 if (iface.get()) {
41 iface->invalidate();
42 iface.clear();
43 }
44}
Roshan Pius9377a0d2017-10-06 13:18:54 -070045
46std::string getWlan0IfaceName() {
47 std::array<char, PROPERTY_VALUE_MAX> buffer;
48 property_get("wifi.interface", buffer.data(), "wlan0");
49 return buffer.data();
50}
51
52/** Not used yet.
53std::string getWlan1IfaceName() {
54 std::array<char, PROPERTY_VALUE_MAX> buffer;
55 property_get("wifi.concurrent.interface", buffer.data(), "wlan1");
56 return buffer.data();
57}
58*/
59
60std::string getP2pIfaceName() {
61 std::array<char, PROPERTY_VALUE_MAX> buffer;
62 property_get("wifi.direct.interface", buffer.data(), "p2p0");
63 return buffer.data();
64}
65
Roshan Pius35d958c2016-10-06 16:47:38 -070066} // namepsace
67
Roshan Pius3c4e8a32016-10-03 14:53:58 -070068namespace android {
69namespace hardware {
70namespace wifi {
Etan Cohen6ce50902017-09-14 07:30:57 -070071namespace V1_2 {
Roshan Pius79a99752016-10-04 13:03:58 -070072namespace implementation {
Roshan Pius3c868522016-10-27 12:43:49 -070073using hidl_return_util::validateAndCall;
Roshan Pius3c4e8a32016-10-03 14:53:58 -070074
Roshan Pius52947fb2016-11-18 11:38:07 -080075WifiChip::WifiChip(
76 ChipId chip_id,
77 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
78 const std::weak_ptr<mode_controller::WifiModeController> mode_controller)
79 : chip_id_(chip_id),
80 legacy_hal_(legacy_hal),
81 mode_controller_(mode_controller),
82 is_valid_(true),
Roshan Pius48185b22016-12-15 19:10:30 -080083 current_mode_id_(kInvalidModeId),
84 debug_ring_buffer_cb_registered_(false) {}
Roshan Pius3c4e8a32016-10-03 14:53:58 -070085
Roshan Piusaabe5752016-09-29 09:03:59 -070086void WifiChip::invalidate() {
Roshan Pius35d958c2016-10-06 16:47:38 -070087 invalidateAndRemoveAllIfaces();
Roshan Piusaabe5752016-09-29 09:03:59 -070088 legacy_hal_.reset();
Roshan Piusd37341f2017-01-31 13:13:28 -080089 event_cb_handler_.invalidate();
Roshan Pius35d958c2016-10-06 16:47:38 -070090 is_valid_ = false;
Roshan Pius3c4e8a32016-10-03 14:53:58 -070091}
92
Roshan Pius3c868522016-10-27 12:43:49 -070093bool WifiChip::isValid() {
94 return is_valid_;
95}
96
Roshan Piusd37341f2017-01-31 13:13:28 -080097std::set<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
98 return event_cb_handler_.getCallbacks();
Roshan Pius203cb032016-12-14 17:41:20 -080099}
100
Roshan Pius5c055462016-10-11 08:27:27 -0700101Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700102 return validateAndCall(this,
103 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
104 &WifiChip::getIdInternal,
105 hidl_status_cb);
Roshan Piuscd566bd2016-10-10 08:03:42 -0700106}
107
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700108Return<void> WifiChip::registerEventCallback(
Roshan Pius5c055462016-10-11 08:27:27 -0700109 const sp<IWifiChipEventCallback>& event_callback,
110 registerEventCallback_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700111 return validateAndCall(this,
112 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
113 &WifiChip::registerEventCallbackInternal,
114 hidl_status_cb,
115 event_callback);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700116}
117
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700118Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
119 return validateAndCall(this,
120 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
121 &WifiChip::getCapabilitiesInternal,
122 hidl_status_cb);
123}
124
Roshan Pius5c055462016-10-11 08:27:27 -0700125Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700126 return validateAndCall(this,
127 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
128 &WifiChip::getAvailableModesInternal,
129 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700130}
131
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800132Return<void> WifiChip::configureChip(ChipModeId mode_id,
Roshan Pius5c055462016-10-11 08:27:27 -0700133 configureChip_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700134 return validateAndCall(this,
135 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
136 &WifiChip::configureChipInternal,
137 hidl_status_cb,
138 mode_id);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700139}
140
Roshan Pius5c055462016-10-11 08:27:27 -0700141Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700142 return validateAndCall(this,
143 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
144 &WifiChip::getModeInternal,
145 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700146}
147
Roshan Pius5c055462016-10-11 08:27:27 -0700148Return<void> WifiChip::requestChipDebugInfo(
149 requestChipDebugInfo_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700150 return validateAndCall(this,
151 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
152 &WifiChip::requestChipDebugInfoInternal,
153 hidl_status_cb);
Roshan Pius5c055462016-10-11 08:27:27 -0700154}
155
156Return<void> WifiChip::requestDriverDebugDump(
157 requestDriverDebugDump_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700158 return validateAndCall(this,
159 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
160 &WifiChip::requestDriverDebugDumpInternal,
161 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700162}
163
Roshan Pius5c055462016-10-11 08:27:27 -0700164Return<void> WifiChip::requestFirmwareDebugDump(
165 requestFirmwareDebugDump_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700166 return validateAndCall(this,
167 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
168 &WifiChip::requestFirmwareDebugDumpInternal,
169 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700170}
171
Roshan Pius5c055462016-10-11 08:27:27 -0700172Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700173 return validateAndCall(this,
174 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
175 &WifiChip::createApIfaceInternal,
176 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700177}
178
Roshan Pius5c055462016-10-11 08:27:27 -0700179Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700180 return validateAndCall(this,
181 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
182 &WifiChip::getApIfaceNamesInternal,
183 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700184}
185
Roshan Pius5c055462016-10-11 08:27:27 -0700186Return<void> WifiChip::getApIface(const hidl_string& ifname,
187 getApIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700188 return validateAndCall(this,
189 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
190 &WifiChip::getApIfaceInternal,
191 hidl_status_cb,
192 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700193}
194
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800195Return<void> WifiChip::removeApIface(const hidl_string& ifname,
196 removeApIface_cb hidl_status_cb) {
197 return validateAndCall(this,
198 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
199 &WifiChip::removeApIfaceInternal,
200 hidl_status_cb,
201 ifname);
202}
203
Roshan Pius5c055462016-10-11 08:27:27 -0700204Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700205 return validateAndCall(this,
206 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
207 &WifiChip::createNanIfaceInternal,
208 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700209}
210
Roshan Pius5c055462016-10-11 08:27:27 -0700211Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700212 return validateAndCall(this,
213 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
214 &WifiChip::getNanIfaceNamesInternal,
215 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 Pius3c868522016-10-27 12:43:49 -0700220 return validateAndCall(this,
221 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
222 &WifiChip::getNanIfaceInternal,
223 hidl_status_cb,
224 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700225}
226
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800227Return<void> WifiChip::removeNanIface(const hidl_string& ifname,
228 removeNanIface_cb hidl_status_cb) {
229 return validateAndCall(this,
230 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
231 &WifiChip::removeNanIfaceInternal,
232 hidl_status_cb,
233 ifname);
234}
235
Roshan Pius5c055462016-10-11 08:27:27 -0700236Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700237 return validateAndCall(this,
238 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
239 &WifiChip::createP2pIfaceInternal,
240 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700241}
242
Roshan Pius5c055462016-10-11 08:27:27 -0700243Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700244 return validateAndCall(this,
245 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
246 &WifiChip::getP2pIfaceNamesInternal,
247 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700248}
249
250Return<void> WifiChip::getP2pIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700251 getP2pIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700252 return validateAndCall(this,
253 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
254 &WifiChip::getP2pIfaceInternal,
255 hidl_status_cb,
256 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700257}
258
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800259Return<void> WifiChip::removeP2pIface(const hidl_string& ifname,
260 removeP2pIface_cb hidl_status_cb) {
261 return validateAndCall(this,
262 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
263 &WifiChip::removeP2pIfaceInternal,
264 hidl_status_cb,
265 ifname);
266}
267
Roshan Pius5c055462016-10-11 08:27:27 -0700268Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700269 return validateAndCall(this,
270 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
271 &WifiChip::createStaIfaceInternal,
272 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700273}
274
Roshan Pius5c055462016-10-11 08:27:27 -0700275Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700276 return validateAndCall(this,
277 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
278 &WifiChip::getStaIfaceNamesInternal,
279 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700280}
281
282Return<void> WifiChip::getStaIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700283 getStaIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700284 return validateAndCall(this,
285 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
286 &WifiChip::getStaIfaceInternal,
287 hidl_status_cb,
288 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700289}
290
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800291Return<void> WifiChip::removeStaIface(const hidl_string& ifname,
292 removeStaIface_cb hidl_status_cb) {
293 return validateAndCall(this,
294 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
295 &WifiChip::removeStaIfaceInternal,
296 hidl_status_cb,
297 ifname);
298}
299
Roshan Pius5c055462016-10-11 08:27:27 -0700300Return<void> WifiChip::createRttController(
301 const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700302 return validateAndCall(this,
303 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
304 &WifiChip::createRttControllerInternal,
305 hidl_status_cb,
306 bound_iface);
Roshan Pius59268282016-10-06 20:23:47 -0700307}
308
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700309Return<void> WifiChip::getDebugRingBuffersStatus(
310 getDebugRingBuffersStatus_cb hidl_status_cb) {
311 return validateAndCall(this,
312 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
313 &WifiChip::getDebugRingBuffersStatusInternal,
314 hidl_status_cb);
315}
316
317Return<void> WifiChip::startLoggingToDebugRingBuffer(
318 const hidl_string& ring_name,
319 WifiDebugRingBufferVerboseLevel verbose_level,
320 uint32_t max_interval_in_sec,
321 uint32_t min_data_size_in_bytes,
322 startLoggingToDebugRingBuffer_cb hidl_status_cb) {
323 return validateAndCall(this,
324 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
325 &WifiChip::startLoggingToDebugRingBufferInternal,
326 hidl_status_cb,
327 ring_name,
328 verbose_level,
329 max_interval_in_sec,
330 min_data_size_in_bytes);
331}
332
333Return<void> WifiChip::forceDumpToDebugRingBuffer(
334 const hidl_string& ring_name,
335 forceDumpToDebugRingBuffer_cb hidl_status_cb) {
336 return validateAndCall(this,
337 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
338 &WifiChip::forceDumpToDebugRingBufferInternal,
339 hidl_status_cb,
340 ring_name);
341}
342
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800343Return<void> WifiChip::stopLoggingToDebugRingBuffer(
344 stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
345 return validateAndCall(this,
346 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
347 &WifiChip::stopLoggingToDebugRingBufferInternal,
348 hidl_status_cb);
349}
350
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700351Return<void> WifiChip::getDebugHostWakeReasonStats(
352 getDebugHostWakeReasonStats_cb hidl_status_cb) {
353 return validateAndCall(this,
354 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
355 &WifiChip::getDebugHostWakeReasonStatsInternal,
356 hidl_status_cb);
357}
358
Roshan Pius203cb032016-12-14 17:41:20 -0800359Return<void> WifiChip::enableDebugErrorAlerts(
360 bool enable, enableDebugErrorAlerts_cb hidl_status_cb) {
361 return validateAndCall(this,
362 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
363 &WifiChip::enableDebugErrorAlertsInternal,
364 hidl_status_cb,
365 enable);
366}
367
Roshan Pius735ff432017-07-25 08:48:08 -0700368Return<void> WifiChip::selectTxPowerScenario(
369 TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) {
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700370 return validateAndCall(this,
371 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Roshan Pius735ff432017-07-25 08:48:08 -0700372 &WifiChip::selectTxPowerScenarioInternal,
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700373 hidl_status_cb,
Roshan Pius735ff432017-07-25 08:48:08 -0700374 scenario);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700375}
376
Roshan Pius735ff432017-07-25 08:48:08 -0700377Return<void> WifiChip::resetTxPowerScenario(
378 resetTxPowerScenario_cb hidl_status_cb) {
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700379 return validateAndCall(this,
380 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Roshan Pius735ff432017-07-25 08:48:08 -0700381 &WifiChip::resetTxPowerScenarioInternal,
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700382 hidl_status_cb);
383}
384
Roshan Pius35d958c2016-10-06 16:47:38 -0700385void WifiChip::invalidateAndRemoveAllIfaces() {
386 invalidateAndClear(ap_iface_);
387 invalidateAndClear(nan_iface_);
388 invalidateAndClear(p2p_iface_);
389 invalidateAndClear(sta_iface_);
Roshan Pius59268282016-10-06 20:23:47 -0700390 // Since all the ifaces are invalid now, all RTT controller objects
391 // using those ifaces also need to be invalidated.
392 for (const auto& rtt : rtt_controllers_) {
393 rtt->invalidate();
394 }
395 rtt_controllers_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -0700396}
397
Roshan Pius3c868522016-10-27 12:43:49 -0700398std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
399 return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
400}
401
402WifiStatus WifiChip::registerEventCallbackInternal(
403 const sp<IWifiChipEventCallback>& event_callback) {
Roshan Piusd37341f2017-01-31 13:13:28 -0800404 if (!event_cb_handler_.addCallback(event_callback)) {
405 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
406 }
Roshan Pius3c868522016-10-27 12:43:49 -0700407 return createWifiStatus(WifiStatusCode::SUCCESS);
408}
409
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700410std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800411 legacy_hal::wifi_error legacy_status;
Roshan Pius8184d212017-07-11 08:59:29 -0700412 uint32_t legacy_feature_set;
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800413 uint32_t legacy_logger_feature_set;
Roshan Pius8184d212017-07-11 08:59:29 -0700414 std::tie(legacy_status, legacy_feature_set) =
Roshan Piusacededb2017-10-06 14:59:26 -0700415 legacy_hal_.lock()->getSupportedFeatureSet(getWlan0IfaceName());
Roshan Pius8184d212017-07-11 08:59:29 -0700416 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
417 return {createWifiStatusFromLegacyError(legacy_status), 0};
418 }
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800419 std::tie(legacy_status, legacy_logger_feature_set) =
Roshan Piusacededb2017-10-06 14:59:26 -0700420 legacy_hal_.lock()->getLoggerSupportedFeatureSet(getWlan0IfaceName());
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800421 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
422 return {createWifiStatusFromLegacyError(legacy_status), 0};
423 }
424 uint32_t hidl_caps;
425 if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
Roshan Pius8184d212017-07-11 08:59:29 -0700426 legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800427 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
428 }
429 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700430}
431
Roshan Pius3c868522016-10-27 12:43:49 -0700432std::pair<WifiStatus, std::vector<IWifiChip::ChipMode>>
433WifiChip::getAvailableModesInternal() {
Roshan Pius52947fb2016-11-18 11:38:07 -0800434 // The chip combination supported for current devices is fixed for now with
435 // 2 separate modes of operation:
436 // Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN iface operations
Etan Cohenc5700402017-03-08 16:43:38 -0800437 // concurrently [NAN conditional on wifiHidlFeatureAware]
Roshan Pius52947fb2016-11-18 11:38:07 -0800438 // Mode 2 (AP mode): Will support 1 AP iface operations.
439 // TODO (b/32997844): Read this from some device specific flags in the
440 // makefile.
441 // STA mode iface combinations.
442 const IWifiChip::ChipIfaceCombinationLimit
443 sta_chip_iface_combination_limit_1 = {{IfaceType::STA}, 1};
Etan Cohenc5700402017-03-08 16:43:38 -0800444 IWifiChip::ChipIfaceCombinationLimit sta_chip_iface_combination_limit_2;
445 if (WifiFeatureFlags::wifiHidlFeatureAware) {
446 sta_chip_iface_combination_limit_2 = {{IfaceType::P2P, IfaceType::NAN},
447 1};
448 } else {
449 sta_chip_iface_combination_limit_2 = {{IfaceType::P2P},
450 1};
451 }
Roshan Pius52947fb2016-11-18 11:38:07 -0800452 const IWifiChip::ChipIfaceCombination sta_chip_iface_combination = {
453 {sta_chip_iface_combination_limit_1, sta_chip_iface_combination_limit_2}};
454 const IWifiChip::ChipMode sta_chip_mode = {kStaChipModeId,
455 {sta_chip_iface_combination}};
456 // AP mode iface combinations.
457 const IWifiChip::ChipIfaceCombinationLimit ap_chip_iface_combination_limit = {
458 {IfaceType::AP}, 1};
459 const IWifiChip::ChipIfaceCombination ap_chip_iface_combination = {
460 {ap_chip_iface_combination_limit}};
461 const IWifiChip::ChipMode ap_chip_mode = {kApChipModeId,
462 {ap_chip_iface_combination}};
463 return {createWifiStatus(WifiStatusCode::SUCCESS),
464 {sta_chip_mode, ap_chip_mode}};
Roshan Pius3c868522016-10-27 12:43:49 -0700465}
466
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800467WifiStatus WifiChip::configureChipInternal(ChipModeId mode_id) {
Roshan Pius52947fb2016-11-18 11:38:07 -0800468 if (mode_id != kStaChipModeId && mode_id != kApChipModeId) {
469 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
470 }
471 if (mode_id == current_mode_id_) {
472 LOG(DEBUG) << "Already in the specified mode " << mode_id;
473 return createWifiStatus(WifiStatusCode::SUCCESS);
474 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800475 WifiStatus status = handleChipConfiguration(mode_id);
476 if (status.code != WifiStatusCode::SUCCESS) {
Roshan Piusd37341f2017-01-31 13:13:28 -0800477 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800478 if (!callback->onChipReconfigureFailure(status).isOk()) {
479 LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback";
480 }
Roshan Pius52947fb2016-11-18 11:38:07 -0800481 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800482 return status;
Roshan Pius52947fb2016-11-18 11:38:07 -0800483 }
Roshan Piusd37341f2017-01-31 13:13:28 -0800484 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800485 if (!callback->onChipReconfigured(mode_id).isOk()) {
486 LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
487 }
Roshan Pius52947fb2016-11-18 11:38:07 -0800488 }
489 current_mode_id_ = mode_id;
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800490 return status;
Roshan Pius3c868522016-10-27 12:43:49 -0700491}
492
493std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
Roshan Pius52947fb2016-11-18 11:38:07 -0800494 if (current_mode_id_ == kInvalidModeId) {
495 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE),
496 current_mode_id_};
497 }
498 return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700499}
500
501std::pair<WifiStatus, IWifiChip::ChipDebugInfo>
502WifiChip::requestChipDebugInfoInternal() {
503 IWifiChip::ChipDebugInfo result;
Roshan Piusa4854ff2016-12-01 13:47:41 -0800504 legacy_hal::wifi_error legacy_status;
Roshan Pius3c868522016-10-27 12:43:49 -0700505 std::string driver_desc;
Roshan Piusacededb2017-10-06 14:59:26 -0700506 std::tie(legacy_status, driver_desc) =
507 legacy_hal_.lock()->getDriverVersion(getWlan0IfaceName());
Roshan Piusa4854ff2016-12-01 13:47:41 -0800508 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700509 LOG(ERROR) << "Failed to get driver version: "
510 << legacyErrorToString(legacy_status);
511 WifiStatus status = createWifiStatusFromLegacyError(
512 legacy_status, "failed to get driver version");
513 return {status, result};
514 }
515 result.driverDescription = driver_desc.c_str();
516
517 std::string firmware_desc;
518 std::tie(legacy_status, firmware_desc) =
Roshan Piusacededb2017-10-06 14:59:26 -0700519 legacy_hal_.lock()->getFirmwareVersion(getWlan0IfaceName());
Roshan Piusa4854ff2016-12-01 13:47:41 -0800520 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700521 LOG(ERROR) << "Failed to get firmware version: "
522 << legacyErrorToString(legacy_status);
523 WifiStatus status = createWifiStatusFromLegacyError(
524 legacy_status, "failed to get firmware version");
525 return {status, result};
526 }
527 result.firmwareDescription = firmware_desc.c_str();
528
529 return {createWifiStatus(WifiStatusCode::SUCCESS), result};
530}
531
532std::pair<WifiStatus, std::vector<uint8_t>>
533WifiChip::requestDriverDebugDumpInternal() {
Roshan Piusa4854ff2016-12-01 13:47:41 -0800534 legacy_hal::wifi_error legacy_status;
Roshan Pius3c868522016-10-27 12:43:49 -0700535 std::vector<uint8_t> driver_dump;
536 std::tie(legacy_status, driver_dump) =
Roshan Piusacededb2017-10-06 14:59:26 -0700537 legacy_hal_.lock()->requestDriverMemoryDump(getWlan0IfaceName());
Roshan Piusa4854ff2016-12-01 13:47:41 -0800538 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700539 LOG(ERROR) << "Failed to get driver debug dump: "
540 << legacyErrorToString(legacy_status);
541 return {createWifiStatusFromLegacyError(legacy_status),
542 std::vector<uint8_t>()};
543 }
544 return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
545}
546
547std::pair<WifiStatus, std::vector<uint8_t>>
548WifiChip::requestFirmwareDebugDumpInternal() {
Roshan Piusa4854ff2016-12-01 13:47:41 -0800549 legacy_hal::wifi_error legacy_status;
Roshan Pius3c868522016-10-27 12:43:49 -0700550 std::vector<uint8_t> firmware_dump;
551 std::tie(legacy_status, firmware_dump) =
Roshan Piusacededb2017-10-06 14:59:26 -0700552 legacy_hal_.lock()->requestFirmwareMemoryDump(getWlan0IfaceName());
Roshan Piusa4854ff2016-12-01 13:47:41 -0800553 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700554 LOG(ERROR) << "Failed to get firmware debug dump: "
555 << legacyErrorToString(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700556 return {createWifiStatusFromLegacyError(legacy_status), {}};
Roshan Pius3c868522016-10-27 12:43:49 -0700557 }
558 return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
559}
560
561std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800562 if (current_mode_id_ != kApChipModeId || ap_iface_.get()) {
563 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
564 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700565 std::string ifname = getWlan0IfaceName();
Roshan Pius3c868522016-10-27 12:43:49 -0700566 ap_iface_ = new WifiApIface(ifname, legacy_hal_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800567 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800568 if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
569 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
570 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800571 }
Roshan Pius3c868522016-10-27 12:43:49 -0700572 return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};
573}
574
575std::pair<WifiStatus, std::vector<hidl_string>>
576WifiChip::getApIfaceNamesInternal() {
577 if (!ap_iface_.get()) {
578 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
579 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700580 return {createWifiStatus(WifiStatusCode::SUCCESS), {getWlan0IfaceName()}};
Roshan Pius3c868522016-10-27 12:43:49 -0700581}
582
583std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::getApIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800584 const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700585 if (!ap_iface_.get() || (ifname != getWlan0IfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700586 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
587 }
588 return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};
589}
590
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800591WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700592 if (!ap_iface_.get() || (ifname != getWlan0IfaceName())) {
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800593 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
594 }
595 invalidateAndClear(ap_iface_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800596 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800597 if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
598 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
599 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800600 }
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800601 return createWifiStatus(WifiStatusCode::SUCCESS);
602}
603
Roshan Pius3c868522016-10-27 12:43:49 -0700604std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800605 // Only 1 of NAN or P2P iface can be active at a time.
Etan Cohenc5700402017-03-08 16:43:38 -0800606 if (WifiFeatureFlags::wifiHidlFeatureAware) {
607 if (current_mode_id_ != kStaChipModeId || nan_iface_.get() ||
608 p2p_iface_.get()) {
609 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
610 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700611 std::string ifname = getWlan0IfaceName();
Etan Cohenc5700402017-03-08 16:43:38 -0800612 nan_iface_ = new WifiNanIface(ifname, legacy_hal_);
613 for (const auto& callback : event_cb_handler_.getCallbacks()) {
614 if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
615 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
616 }
617 }
618 return {createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_};
619 } else {
Roshan Pius073d5b92016-12-08 19:10:06 -0800620 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
621 }
Roshan Pius3c868522016-10-27 12:43:49 -0700622}
623
624std::pair<WifiStatus, std::vector<hidl_string>>
625WifiChip::getNanIfaceNamesInternal() {
626 if (!nan_iface_.get()) {
627 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
628 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700629 return {createWifiStatus(WifiStatusCode::SUCCESS), {getWlan0IfaceName()}};
Roshan Pius3c868522016-10-27 12:43:49 -0700630}
631
632std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::getNanIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800633 const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700634 if (!nan_iface_.get() || (ifname != getWlan0IfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700635 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
636 }
637 return {createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_};
638}
639
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800640WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700641 if (!nan_iface_.get() || (ifname != getWlan0IfaceName())) {
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800642 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
643 }
644 invalidateAndClear(nan_iface_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800645 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800646 if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
647 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
648 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800649 }
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800650 return createWifiStatus(WifiStatusCode::SUCCESS);
651}
652
Roshan Pius3c868522016-10-27 12:43:49 -0700653std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800654 // Only 1 of NAN or P2P iface can be active at a time.
655 if (current_mode_id_ != kStaChipModeId || p2p_iface_.get() ||
656 nan_iface_.get()) {
657 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
658 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700659 std::string ifname = getP2pIfaceName();
Roshan Pius3c868522016-10-27 12:43:49 -0700660 p2p_iface_ = new WifiP2pIface(ifname, legacy_hal_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800661 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800662 if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
663 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
664 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800665 }
Roshan Pius3c868522016-10-27 12:43:49 -0700666 return {createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_};
667}
668
669std::pair<WifiStatus, std::vector<hidl_string>>
670WifiChip::getP2pIfaceNamesInternal() {
671 if (!p2p_iface_.get()) {
672 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
673 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700674 return {createWifiStatus(WifiStatusCode::SUCCESS), {getP2pIfaceName()}};
Roshan Pius3c868522016-10-27 12:43:49 -0700675}
676
677std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800678 const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700679 if (!p2p_iface_.get() || (ifname != getP2pIfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700680 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
681 }
682 return {createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_};
683}
684
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800685WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700686 if (!p2p_iface_.get() || (ifname != getP2pIfaceName())) {
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800687 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
688 }
689 invalidateAndClear(p2p_iface_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800690 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800691 if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
692 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
693 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800694 }
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800695 return createWifiStatus(WifiStatusCode::SUCCESS);
696}
697
Roshan Pius3c868522016-10-27 12:43:49 -0700698std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800699 if (current_mode_id_ != kStaChipModeId || sta_iface_.get()) {
700 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
701 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700702 std::string ifname = getWlan0IfaceName();
Roshan Pius3c868522016-10-27 12:43:49 -0700703 sta_iface_ = new WifiStaIface(ifname, legacy_hal_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800704 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800705 if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
706 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
707 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800708 }
Roshan Pius3c868522016-10-27 12:43:49 -0700709 return {createWifiStatus(WifiStatusCode::SUCCESS), sta_iface_};
710}
711
712std::pair<WifiStatus, std::vector<hidl_string>>
713WifiChip::getStaIfaceNamesInternal() {
714 if (!sta_iface_.get()) {
715 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
716 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700717 return {createWifiStatus(WifiStatusCode::SUCCESS), {getWlan0IfaceName()}};
Roshan Pius3c868522016-10-27 12:43:49 -0700718}
719
720std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::getStaIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800721 const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700722 if (!sta_iface_.get() || (ifname != getWlan0IfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700723 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
724 }
725 return {createWifiStatus(WifiStatusCode::SUCCESS), sta_iface_};
726}
727
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800728WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700729 if (!sta_iface_.get() || (ifname != getWlan0IfaceName())) {
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800730 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
731 }
732 invalidateAndClear(sta_iface_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800733 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800734 if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
735 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
736 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800737 }
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800738 return createWifiStatus(WifiStatusCode::SUCCESS);
739}
740
Roshan Pius3c868522016-10-27 12:43:49 -0700741std::pair<WifiStatus, sp<IWifiRttController>>
742WifiChip::createRttControllerInternal(const sp<IWifiIface>& bound_iface) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700743 sp<WifiRttController> rtt =
744 new WifiRttController(getWlan0IfaceName(), bound_iface, legacy_hal_);
Roshan Pius3c868522016-10-27 12:43:49 -0700745 rtt_controllers_.emplace_back(rtt);
746 return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
747}
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700748
749std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
750WifiChip::getDebugRingBuffersStatusInternal() {
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800751 legacy_hal::wifi_error legacy_status;
752 std::vector<legacy_hal::wifi_ring_buffer_status>
753 legacy_ring_buffer_status_vec;
754 std::tie(legacy_status, legacy_ring_buffer_status_vec) =
Roshan Piusacededb2017-10-06 14:59:26 -0700755 legacy_hal_.lock()->getRingBuffersStatus(getWlan0IfaceName());
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800756 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
757 return {createWifiStatusFromLegacyError(legacy_status), {}};
758 }
759 std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
760 if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
761 legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
762 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
763 }
764 return {createWifiStatus(WifiStatusCode::SUCCESS),
765 hidl_ring_buffer_status_vec};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700766}
767
768WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800769 const hidl_string& ring_name,
770 WifiDebugRingBufferVerboseLevel verbose_level,
771 uint32_t max_interval_in_sec,
772 uint32_t min_data_size_in_bytes) {
Roshan Pius48185b22016-12-15 19:10:30 -0800773 WifiStatus status = registerDebugRingBufferCallback();
774 if (status.code != WifiStatusCode::SUCCESS) {
775 return status;
776 }
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800777 legacy_hal::wifi_error legacy_status =
778 legacy_hal_.lock()->startRingBufferLogging(
Roshan Piusacededb2017-10-06 14:59:26 -0700779 getWlan0IfaceName(),
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800780 ring_name,
781 static_cast<
782 std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
783 verbose_level),
784 max_interval_in_sec,
785 min_data_size_in_bytes);
786 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700787}
788
789WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800790 const hidl_string& ring_name) {
Roshan Pius48185b22016-12-15 19:10:30 -0800791 WifiStatus status = registerDebugRingBufferCallback();
792 if (status.code != WifiStatusCode::SUCCESS) {
793 return status;
794 }
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800795 legacy_hal::wifi_error legacy_status =
Roshan Piusacededb2017-10-06 14:59:26 -0700796 legacy_hal_.lock()->getRingBufferData(getWlan0IfaceName(), ring_name);
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800797 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700798}
799
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800800WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
801 legacy_hal::wifi_error legacy_status =
Roshan Piusacededb2017-10-06 14:59:26 -0700802 legacy_hal_.lock()->deregisterRingBufferCallbackHandler(
803 getWlan0IfaceName());
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800804 return createWifiStatusFromLegacyError(legacy_status);
805}
806
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700807std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
808WifiChip::getDebugHostWakeReasonStatsInternal() {
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800809 legacy_hal::wifi_error legacy_status;
810 legacy_hal::WakeReasonStats legacy_stats;
811 std::tie(legacy_status, legacy_stats) =
Roshan Piusacededb2017-10-06 14:59:26 -0700812 legacy_hal_.lock()->getWakeReasonStats(getWlan0IfaceName());
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800813 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
814 return {createWifiStatusFromLegacyError(legacy_status), {}};
815 }
816 WifiDebugHostWakeReasonStats hidl_stats;
817 if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats,
818 &hidl_stats)) {
819 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
820 }
821 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700822}
823
Roshan Pius203cb032016-12-14 17:41:20 -0800824WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
825 legacy_hal::wifi_error legacy_status;
826 if (enable) {
827 android::wp<WifiChip> weak_ptr_this(this);
828 const auto& on_alert_callback = [weak_ptr_this](
829 int32_t error_code, std::vector<uint8_t> debug_data) {
830 const auto shared_ptr_this = weak_ptr_this.promote();
831 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
832 LOG(ERROR) << "Callback invoked on an invalid object";
833 return;
834 }
835 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800836 if (!callback->onDebugErrorAlert(error_code, debug_data).isOk()) {
837 LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
838 }
Roshan Pius203cb032016-12-14 17:41:20 -0800839 }
840 };
Roshan Piusacededb2017-10-06 14:59:26 -0700841 legacy_status =
842 legacy_hal_.lock()->registerErrorAlertCallbackHandler(
843 getWlan0IfaceName(), on_alert_callback);
Roshan Pius203cb032016-12-14 17:41:20 -0800844 } else {
Roshan Piusacededb2017-10-06 14:59:26 -0700845 legacy_status =
846 legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
847 getWlan0IfaceName());
Roshan Pius203cb032016-12-14 17:41:20 -0800848 }
849 return createWifiStatusFromLegacyError(legacy_status);
850}
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800851
Roshan Pius735ff432017-07-25 08:48:08 -0700852WifiStatus WifiChip::selectTxPowerScenarioInternal(TxPowerScenario scenario) {
853 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
Roshan Piusacededb2017-10-06 14:59:26 -0700854 getWlan0IfaceName(),
Roshan Pius735ff432017-07-25 08:48:08 -0700855 hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
Roshan Pius8184d212017-07-11 08:59:29 -0700856 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700857}
858
Roshan Pius735ff432017-07-25 08:48:08 -0700859WifiStatus WifiChip::resetTxPowerScenarioInternal() {
Roshan Piusacededb2017-10-06 14:59:26 -0700860 auto legacy_status =
861 legacy_hal_.lock()->resetTxPowerScenario(getWlan0IfaceName());
Roshan Pius8184d212017-07-11 08:59:29 -0700862 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700863}
864
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800865WifiStatus WifiChip::handleChipConfiguration(ChipModeId mode_id) {
866 // If the chip is already configured in a different mode, stop
867 // the legacy HAL and then start it after firmware mode change.
Ningyuan Wangb1ad3a72017-04-18 14:20:41 -0700868 // Currently the underlying implementation has a deadlock issue.
869 // We should return ERROR_NOT_SUPPORTED if chip is already configured in
870 // a different mode.
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800871 if (current_mode_id_ != kInvalidModeId) {
Ningyuan Wangb1ad3a72017-04-18 14:20:41 -0700872 // TODO(b/37446050): Fix the deadlock.
873 return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800874 }
875 bool success;
876 if (mode_id == kStaChipModeId) {
877 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
878 } else {
879 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
880 }
881 if (!success) {
882 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
883 }
884 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
885 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
886 LOG(ERROR) << "Failed to start legacy HAL: "
887 << legacyErrorToString(legacy_status);
888 return createWifiStatusFromLegacyError(legacy_status);
889 }
890 return createWifiStatus(WifiStatusCode::SUCCESS);
891}
Roshan Pius48185b22016-12-15 19:10:30 -0800892
893WifiStatus WifiChip::registerDebugRingBufferCallback() {
894 if (debug_ring_buffer_cb_registered_) {
895 return createWifiStatus(WifiStatusCode::SUCCESS);
896 }
897
898 android::wp<WifiChip> weak_ptr_this(this);
899 const auto& on_ring_buffer_data_callback = [weak_ptr_this](
900 const std::string& /* name */,
901 const std::vector<uint8_t>& data,
902 const legacy_hal::wifi_ring_buffer_status& status) {
903 const auto shared_ptr_this = weak_ptr_this.promote();
904 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
905 LOG(ERROR) << "Callback invoked on an invalid object";
906 return;
907 }
908 WifiDebugRingBufferStatus hidl_status;
909 if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(
910 status, &hidl_status)) {
911 LOG(ERROR) << "Error converting ring buffer status";
912 return;
913 }
914 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800915 if (!callback->onDebugRingBufferDataAvailable(hidl_status, data).isOk()) {
916 LOG(ERROR) << "Failed to invoke onDebugRingBufferDataAvailable"
Roshan Pius3797e182017-03-30 18:01:54 -0700917 << " callback on: " << toString(callback);
918
Roshan Piusbc662202017-01-30 17:07:42 -0800919 }
Roshan Pius48185b22016-12-15 19:10:30 -0800920 }
921 };
922 legacy_hal::wifi_error legacy_status =
923 legacy_hal_.lock()->registerRingBufferCallbackHandler(
Roshan Piusacededb2017-10-06 14:59:26 -0700924 getWlan0IfaceName(), on_ring_buffer_data_callback);
Roshan Pius48185b22016-12-15 19:10:30 -0800925
926 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
927 debug_ring_buffer_cb_registered_ = true;
928 }
929 return createWifiStatusFromLegacyError(legacy_status);
930}
931
Roshan Pius79a99752016-10-04 13:03:58 -0700932} // namespace implementation
Etan Cohen6ce50902017-09-14 07:30:57 -0700933} // namespace V1_2
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700934} // namespace wifi
935} // namespace hardware
936} // namespace android