blob: 07da1ddbe8dcf2014459e8f2e9450d3b977136af [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) =
415 legacy_hal_.lock()->getSupportedFeatureSet();
416 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) =
420 legacy_hal_.lock()->getLoggerSupportedFeatureSet();
421 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;
506 std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion();
Roshan Piusa4854ff2016-12-01 13:47:41 -0800507 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700508 LOG(ERROR) << "Failed to get driver version: "
509 << legacyErrorToString(legacy_status);
510 WifiStatus status = createWifiStatusFromLegacyError(
511 legacy_status, "failed to get driver version");
512 return {status, result};
513 }
514 result.driverDescription = driver_desc.c_str();
515
516 std::string firmware_desc;
517 std::tie(legacy_status, firmware_desc) =
518 legacy_hal_.lock()->getFirmwareVersion();
Roshan Piusa4854ff2016-12-01 13:47:41 -0800519 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700520 LOG(ERROR) << "Failed to get firmware version: "
521 << legacyErrorToString(legacy_status);
522 WifiStatus status = createWifiStatusFromLegacyError(
523 legacy_status, "failed to get firmware version");
524 return {status, result};
525 }
526 result.firmwareDescription = firmware_desc.c_str();
527
528 return {createWifiStatus(WifiStatusCode::SUCCESS), result};
529}
530
531std::pair<WifiStatus, std::vector<uint8_t>>
532WifiChip::requestDriverDebugDumpInternal() {
Roshan Piusa4854ff2016-12-01 13:47:41 -0800533 legacy_hal::wifi_error legacy_status;
Roshan Pius3c868522016-10-27 12:43:49 -0700534 std::vector<uint8_t> driver_dump;
535 std::tie(legacy_status, driver_dump) =
536 legacy_hal_.lock()->requestDriverMemoryDump();
Roshan Piusa4854ff2016-12-01 13:47:41 -0800537 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700538 LOG(ERROR) << "Failed to get driver debug dump: "
539 << legacyErrorToString(legacy_status);
540 return {createWifiStatusFromLegacyError(legacy_status),
541 std::vector<uint8_t>()};
542 }
543 return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
544}
545
546std::pair<WifiStatus, std::vector<uint8_t>>
547WifiChip::requestFirmwareDebugDumpInternal() {
Roshan Piusa4854ff2016-12-01 13:47:41 -0800548 legacy_hal::wifi_error legacy_status;
Roshan Pius3c868522016-10-27 12:43:49 -0700549 std::vector<uint8_t> firmware_dump;
550 std::tie(legacy_status, firmware_dump) =
551 legacy_hal_.lock()->requestFirmwareMemoryDump();
Roshan Piusa4854ff2016-12-01 13:47:41 -0800552 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700553 LOG(ERROR) << "Failed to get firmware debug dump: "
554 << legacyErrorToString(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700555 return {createWifiStatusFromLegacyError(legacy_status), {}};
Roshan Pius3c868522016-10-27 12:43:49 -0700556 }
557 return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
558}
559
560std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800561 if (current_mode_id_ != kApChipModeId || ap_iface_.get()) {
562 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
563 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700564 std::string ifname = getWlan0IfaceName();
Roshan Pius3c868522016-10-27 12:43:49 -0700565 ap_iface_ = new WifiApIface(ifname, legacy_hal_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800566 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800567 if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
568 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
569 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800570 }
Roshan Pius3c868522016-10-27 12:43:49 -0700571 return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};
572}
573
574std::pair<WifiStatus, std::vector<hidl_string>>
575WifiChip::getApIfaceNamesInternal() {
576 if (!ap_iface_.get()) {
577 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
578 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700579 return {createWifiStatus(WifiStatusCode::SUCCESS), {getWlan0IfaceName()}};
Roshan Pius3c868522016-10-27 12:43:49 -0700580}
581
582std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::getApIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800583 const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700584 if (!ap_iface_.get() || (ifname != getWlan0IfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700585 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
586 }
587 return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};
588}
589
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800590WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700591 if (!ap_iface_.get() || (ifname != getWlan0IfaceName())) {
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800592 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
593 }
594 invalidateAndClear(ap_iface_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800595 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800596 if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
597 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
598 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800599 }
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800600 return createWifiStatus(WifiStatusCode::SUCCESS);
601}
602
Roshan Pius3c868522016-10-27 12:43:49 -0700603std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800604 // Only 1 of NAN or P2P iface can be active at a time.
Etan Cohenc5700402017-03-08 16:43:38 -0800605 if (WifiFeatureFlags::wifiHidlFeatureAware) {
606 if (current_mode_id_ != kStaChipModeId || nan_iface_.get() ||
607 p2p_iface_.get()) {
608 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
609 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700610 std::string ifname = getWlan0IfaceName();
Etan Cohenc5700402017-03-08 16:43:38 -0800611 nan_iface_ = new WifiNanIface(ifname, legacy_hal_);
612 for (const auto& callback : event_cb_handler_.getCallbacks()) {
613 if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
614 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
615 }
616 }
617 return {createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_};
618 } else {
Roshan Pius073d5b92016-12-08 19:10:06 -0800619 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
620 }
Roshan Pius3c868522016-10-27 12:43:49 -0700621}
622
623std::pair<WifiStatus, std::vector<hidl_string>>
624WifiChip::getNanIfaceNamesInternal() {
625 if (!nan_iface_.get()) {
626 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
627 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700628 return {createWifiStatus(WifiStatusCode::SUCCESS), {getWlan0IfaceName()}};
Roshan Pius3c868522016-10-27 12:43:49 -0700629}
630
631std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::getNanIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800632 const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700633 if (!nan_iface_.get() || (ifname != getWlan0IfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700634 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
635 }
636 return {createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_};
637}
638
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800639WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700640 if (!nan_iface_.get() || (ifname != getWlan0IfaceName())) {
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800641 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
642 }
643 invalidateAndClear(nan_iface_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800644 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800645 if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
646 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
647 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800648 }
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800649 return createWifiStatus(WifiStatusCode::SUCCESS);
650}
651
Roshan Pius3c868522016-10-27 12:43:49 -0700652std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800653 // Only 1 of NAN or P2P iface can be active at a time.
654 if (current_mode_id_ != kStaChipModeId || p2p_iface_.get() ||
655 nan_iface_.get()) {
656 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
657 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700658 std::string ifname = getP2pIfaceName();
Roshan Pius3c868522016-10-27 12:43:49 -0700659 p2p_iface_ = new WifiP2pIface(ifname, legacy_hal_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800660 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800661 if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
662 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
663 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800664 }
Roshan Pius3c868522016-10-27 12:43:49 -0700665 return {createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_};
666}
667
668std::pair<WifiStatus, std::vector<hidl_string>>
669WifiChip::getP2pIfaceNamesInternal() {
670 if (!p2p_iface_.get()) {
671 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
672 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700673 return {createWifiStatus(WifiStatusCode::SUCCESS), {getP2pIfaceName()}};
Roshan Pius3c868522016-10-27 12:43:49 -0700674}
675
676std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800677 const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700678 if (!p2p_iface_.get() || (ifname != getP2pIfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700679 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
680 }
681 return {createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_};
682}
683
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800684WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700685 if (!p2p_iface_.get() || (ifname != getP2pIfaceName())) {
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800686 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
687 }
688 invalidateAndClear(p2p_iface_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800689 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800690 if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
691 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
692 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800693 }
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800694 return createWifiStatus(WifiStatusCode::SUCCESS);
695}
696
Roshan Pius3c868522016-10-27 12:43:49 -0700697std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800698 if (current_mode_id_ != kStaChipModeId || sta_iface_.get()) {
699 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
700 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700701 std::string ifname = getWlan0IfaceName();
Roshan Pius3c868522016-10-27 12:43:49 -0700702 sta_iface_ = new WifiStaIface(ifname, legacy_hal_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800703 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800704 if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
705 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
706 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800707 }
Roshan Pius3c868522016-10-27 12:43:49 -0700708 return {createWifiStatus(WifiStatusCode::SUCCESS), sta_iface_};
709}
710
711std::pair<WifiStatus, std::vector<hidl_string>>
712WifiChip::getStaIfaceNamesInternal() {
713 if (!sta_iface_.get()) {
714 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
715 }
Roshan Pius9377a0d2017-10-06 13:18:54 -0700716 return {createWifiStatus(WifiStatusCode::SUCCESS), {getWlan0IfaceName()}};
Roshan Pius3c868522016-10-27 12:43:49 -0700717}
718
719std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::getStaIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800720 const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700721 if (!sta_iface_.get() || (ifname != getWlan0IfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700722 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
723 }
724 return {createWifiStatus(WifiStatusCode::SUCCESS), sta_iface_};
725}
726
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800727WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700728 if (!sta_iface_.get() || (ifname != getWlan0IfaceName())) {
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800729 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
730 }
731 invalidateAndClear(sta_iface_);
Roshan Piusd37341f2017-01-31 13:13:28 -0800732 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800733 if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
734 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
735 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800736 }
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800737 return createWifiStatus(WifiStatusCode::SUCCESS);
738}
739
Roshan Pius3c868522016-10-27 12:43:49 -0700740std::pair<WifiStatus, sp<IWifiRttController>>
741WifiChip::createRttControllerInternal(const sp<IWifiIface>& bound_iface) {
Roshan Pius9377a0d2017-10-06 13:18:54 -0700742 sp<WifiRttController> rtt =
743 new WifiRttController(getWlan0IfaceName(), bound_iface, legacy_hal_);
Roshan Pius3c868522016-10-27 12:43:49 -0700744 rtt_controllers_.emplace_back(rtt);
745 return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
746}
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700747
748std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
749WifiChip::getDebugRingBuffersStatusInternal() {
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800750 legacy_hal::wifi_error legacy_status;
751 std::vector<legacy_hal::wifi_ring_buffer_status>
752 legacy_ring_buffer_status_vec;
753 std::tie(legacy_status, legacy_ring_buffer_status_vec) =
754 legacy_hal_.lock()->getRingBuffersStatus();
755 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
756 return {createWifiStatusFromLegacyError(legacy_status), {}};
757 }
758 std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
759 if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
760 legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
761 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
762 }
763 return {createWifiStatus(WifiStatusCode::SUCCESS),
764 hidl_ring_buffer_status_vec};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700765}
766
767WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800768 const hidl_string& ring_name,
769 WifiDebugRingBufferVerboseLevel verbose_level,
770 uint32_t max_interval_in_sec,
771 uint32_t min_data_size_in_bytes) {
Roshan Pius48185b22016-12-15 19:10:30 -0800772 WifiStatus status = registerDebugRingBufferCallback();
773 if (status.code != WifiStatusCode::SUCCESS) {
774 return status;
775 }
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800776 legacy_hal::wifi_error legacy_status =
777 legacy_hal_.lock()->startRingBufferLogging(
778 ring_name,
779 static_cast<
780 std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
781 verbose_level),
782 max_interval_in_sec,
783 min_data_size_in_bytes);
784 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700785}
786
787WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800788 const hidl_string& ring_name) {
Roshan Pius48185b22016-12-15 19:10:30 -0800789 WifiStatus status = registerDebugRingBufferCallback();
790 if (status.code != WifiStatusCode::SUCCESS) {
791 return status;
792 }
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800793 legacy_hal::wifi_error legacy_status =
794 legacy_hal_.lock()->getRingBufferData(ring_name);
795 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700796}
797
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800798WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
799 legacy_hal::wifi_error legacy_status =
800 legacy_hal_.lock()->deregisterRingBufferCallbackHandler();
801 return createWifiStatusFromLegacyError(legacy_status);
802}
803
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700804std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
805WifiChip::getDebugHostWakeReasonStatsInternal() {
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800806 legacy_hal::wifi_error legacy_status;
807 legacy_hal::WakeReasonStats legacy_stats;
808 std::tie(legacy_status, legacy_stats) =
809 legacy_hal_.lock()->getWakeReasonStats();
810 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
811 return {createWifiStatusFromLegacyError(legacy_status), {}};
812 }
813 WifiDebugHostWakeReasonStats hidl_stats;
814 if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats,
815 &hidl_stats)) {
816 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
817 }
818 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700819}
820
Roshan Pius203cb032016-12-14 17:41:20 -0800821WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
822 legacy_hal::wifi_error legacy_status;
823 if (enable) {
824 android::wp<WifiChip> weak_ptr_this(this);
825 const auto& on_alert_callback = [weak_ptr_this](
826 int32_t error_code, std::vector<uint8_t> debug_data) {
827 const auto shared_ptr_this = weak_ptr_this.promote();
828 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
829 LOG(ERROR) << "Callback invoked on an invalid object";
830 return;
831 }
832 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800833 if (!callback->onDebugErrorAlert(error_code, debug_data).isOk()) {
834 LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
835 }
Roshan Pius203cb032016-12-14 17:41:20 -0800836 }
837 };
838 legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
839 on_alert_callback);
840 } else {
841 legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler();
842 }
843 return createWifiStatusFromLegacyError(legacy_status);
844}
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800845
Roshan Pius735ff432017-07-25 08:48:08 -0700846WifiStatus WifiChip::selectTxPowerScenarioInternal(TxPowerScenario scenario) {
847 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
848 hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
Roshan Pius8184d212017-07-11 08:59:29 -0700849 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700850}
851
Roshan Pius735ff432017-07-25 08:48:08 -0700852WifiStatus WifiChip::resetTxPowerScenarioInternal() {
853 auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario();
Roshan Pius8184d212017-07-11 08:59:29 -0700854 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700855}
856
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800857WifiStatus WifiChip::handleChipConfiguration(ChipModeId mode_id) {
858 // If the chip is already configured in a different mode, stop
859 // the legacy HAL and then start it after firmware mode change.
Ningyuan Wangb1ad3a72017-04-18 14:20:41 -0700860 // Currently the underlying implementation has a deadlock issue.
861 // We should return ERROR_NOT_SUPPORTED if chip is already configured in
862 // a different mode.
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800863 if (current_mode_id_ != kInvalidModeId) {
Ningyuan Wangb1ad3a72017-04-18 14:20:41 -0700864 // TODO(b/37446050): Fix the deadlock.
865 return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800866 }
867 bool success;
868 if (mode_id == kStaChipModeId) {
869 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
870 } else {
871 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
872 }
873 if (!success) {
874 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
875 }
876 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
877 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
878 LOG(ERROR) << "Failed to start legacy HAL: "
879 << legacyErrorToString(legacy_status);
880 return createWifiStatusFromLegacyError(legacy_status);
881 }
882 return createWifiStatus(WifiStatusCode::SUCCESS);
883}
Roshan Pius48185b22016-12-15 19:10:30 -0800884
885WifiStatus WifiChip::registerDebugRingBufferCallback() {
886 if (debug_ring_buffer_cb_registered_) {
887 return createWifiStatus(WifiStatusCode::SUCCESS);
888 }
889
890 android::wp<WifiChip> weak_ptr_this(this);
891 const auto& on_ring_buffer_data_callback = [weak_ptr_this](
892 const std::string& /* name */,
893 const std::vector<uint8_t>& data,
894 const legacy_hal::wifi_ring_buffer_status& status) {
895 const auto shared_ptr_this = weak_ptr_this.promote();
896 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
897 LOG(ERROR) << "Callback invoked on an invalid object";
898 return;
899 }
900 WifiDebugRingBufferStatus hidl_status;
901 if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(
902 status, &hidl_status)) {
903 LOG(ERROR) << "Error converting ring buffer status";
904 return;
905 }
906 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
Roshan Piusbc662202017-01-30 17:07:42 -0800907 if (!callback->onDebugRingBufferDataAvailable(hidl_status, data).isOk()) {
908 LOG(ERROR) << "Failed to invoke onDebugRingBufferDataAvailable"
Roshan Pius3797e182017-03-30 18:01:54 -0700909 << " callback on: " << toString(callback);
910
Roshan Piusbc662202017-01-30 17:07:42 -0800911 }
Roshan Pius48185b22016-12-15 19:10:30 -0800912 }
913 };
914 legacy_hal::wifi_error legacy_status =
915 legacy_hal_.lock()->registerRingBufferCallbackHandler(
916 on_ring_buffer_data_callback);
917
918 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
919 debug_ring_buffer_cb_registered_ = true;
920 }
921 return createWifiStatusFromLegacyError(legacy_status);
922}
923
Roshan Pius79a99752016-10-04 13:03:58 -0700924} // namespace implementation
Etan Cohen6ce50902017-09-14 07:30:57 -0700925} // namespace V1_2
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700926} // namespace wifi
927} // namespace hardware
928} // namespace android