blob: d64dea62d557d80cab0a7d3e6ef098105fad3a77 [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>
18
Roshan Pius3c868522016-10-27 12:43:49 -070019#include "hidl_return_util.h"
Roshan Piuse2d0ab52016-12-05 15:24:20 -080020#include "hidl_struct_util.h"
Roshan Pius3c868522016-10-27 12:43:49 -070021#include "wifi_chip.h"
Roshan Pius5c055462016-10-11 08:27:27 -070022#include "wifi_status_util.h"
Roshan Pius3c4e8a32016-10-03 14:53:58 -070023
Roshan Pius35d958c2016-10-06 16:47:38 -070024namespace {
25using android::sp;
26using android::hardware::hidl_vec;
27using android::hardware::hidl_string;
Roshan Pius52947fb2016-11-18 11:38:07 -080028using android::hardware::wifi::V1_0::IWifiChip;
29using android::hardware::wifi::V1_0::IfaceType;
30
31constexpr uint32_t kStaChipModeId = 0;
32constexpr uint32_t kApChipModeId = 1;
33constexpr uint32_t kInvalidModeId = UINT32_MAX;
Roshan Pius35d958c2016-10-06 16:47:38 -070034
Roshan Pius35d958c2016-10-06 16:47:38 -070035template <typename Iface>
36void invalidateAndClear(sp<Iface>& iface) {
37 if (iface.get()) {
38 iface->invalidate();
39 iface.clear();
40 }
41}
42} // namepsace
43
Roshan Pius3c4e8a32016-10-03 14:53:58 -070044namespace android {
45namespace hardware {
46namespace wifi {
Roshan Pius79a99752016-10-04 13:03:58 -070047namespace V1_0 {
48namespace implementation {
Roshan Pius3c868522016-10-27 12:43:49 -070049using hidl_return_util::validateAndCall;
Roshan Pius3c4e8a32016-10-03 14:53:58 -070050
Roshan Pius52947fb2016-11-18 11:38:07 -080051WifiChip::WifiChip(
52 ChipId chip_id,
53 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
54 const std::weak_ptr<mode_controller::WifiModeController> mode_controller)
55 : chip_id_(chip_id),
56 legacy_hal_(legacy_hal),
57 mode_controller_(mode_controller),
58 is_valid_(true),
59 current_mode_id_(kInvalidModeId) {}
Roshan Pius3c4e8a32016-10-03 14:53:58 -070060
Roshan Piusaabe5752016-09-29 09:03:59 -070061void WifiChip::invalidate() {
Roshan Pius35d958c2016-10-06 16:47:38 -070062 invalidateAndRemoveAllIfaces();
Roshan Piusaabe5752016-09-29 09:03:59 -070063 legacy_hal_.reset();
Roshan Pius5c055462016-10-11 08:27:27 -070064 event_callbacks_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -070065 is_valid_ = false;
Roshan Pius3c4e8a32016-10-03 14:53:58 -070066}
67
Roshan Pius3c868522016-10-27 12:43:49 -070068bool WifiChip::isValid() {
69 return is_valid_;
70}
71
Roshan Pius203cb032016-12-14 17:41:20 -080072std::vector<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
73 return event_callbacks_;
74}
75
Roshan Pius5c055462016-10-11 08:27:27 -070076Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -070077 return validateAndCall(this,
78 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
79 &WifiChip::getIdInternal,
80 hidl_status_cb);
Roshan Piuscd566bd2016-10-10 08:03:42 -070081}
82
Roshan Pius3c4e8a32016-10-03 14:53:58 -070083Return<void> WifiChip::registerEventCallback(
Roshan Pius5c055462016-10-11 08:27:27 -070084 const sp<IWifiChipEventCallback>& event_callback,
85 registerEventCallback_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -070086 return validateAndCall(this,
87 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
88 &WifiChip::registerEventCallbackInternal,
89 hidl_status_cb,
90 event_callback);
Roshan Pius3c4e8a32016-10-03 14:53:58 -070091}
92
Roshan Pius7d08d7a2016-10-27 14:35:05 -070093Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
94 return validateAndCall(this,
95 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
96 &WifiChip::getCapabilitiesInternal,
97 hidl_status_cb);
98}
99
Roshan Pius5c055462016-10-11 08:27:27 -0700100Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700101 return validateAndCall(this,
102 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
103 &WifiChip::getAvailableModesInternal,
104 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700105}
106
Roshan Pius3c868522016-10-27 12:43:49 -0700107Return<void> WifiChip::configureChip(uint32_t mode_id,
Roshan Pius5c055462016-10-11 08:27:27 -0700108 configureChip_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700109 return validateAndCall(this,
110 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
111 &WifiChip::configureChipInternal,
112 hidl_status_cb,
113 mode_id);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700114}
115
Roshan Pius5c055462016-10-11 08:27:27 -0700116Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700117 return validateAndCall(this,
118 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
119 &WifiChip::getModeInternal,
120 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700121}
122
Roshan Pius5c055462016-10-11 08:27:27 -0700123Return<void> WifiChip::requestChipDebugInfo(
124 requestChipDebugInfo_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700125 return validateAndCall(this,
126 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
127 &WifiChip::requestChipDebugInfoInternal,
128 hidl_status_cb);
Roshan Pius5c055462016-10-11 08:27:27 -0700129}
130
131Return<void> WifiChip::requestDriverDebugDump(
132 requestDriverDebugDump_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700133 return validateAndCall(this,
134 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
135 &WifiChip::requestDriverDebugDumpInternal,
136 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700137}
138
Roshan Pius5c055462016-10-11 08:27:27 -0700139Return<void> WifiChip::requestFirmwareDebugDump(
140 requestFirmwareDebugDump_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700141 return validateAndCall(this,
142 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
143 &WifiChip::requestFirmwareDebugDumpInternal,
144 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700145}
146
Roshan Pius5c055462016-10-11 08:27:27 -0700147Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700148 return validateAndCall(this,
149 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
150 &WifiChip::createApIfaceInternal,
151 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700152}
153
Roshan Pius5c055462016-10-11 08:27:27 -0700154Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700155 return validateAndCall(this,
156 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
157 &WifiChip::getApIfaceNamesInternal,
158 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700159}
160
Roshan Pius5c055462016-10-11 08:27:27 -0700161Return<void> WifiChip::getApIface(const hidl_string& ifname,
162 getApIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700163 return validateAndCall(this,
164 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
165 &WifiChip::getApIfaceInternal,
166 hidl_status_cb,
167 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700168}
169
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800170Return<void> WifiChip::removeApIface(const hidl_string& ifname,
171 removeApIface_cb hidl_status_cb) {
172 return validateAndCall(this,
173 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
174 &WifiChip::removeApIfaceInternal,
175 hidl_status_cb,
176 ifname);
177}
178
Roshan Pius5c055462016-10-11 08:27:27 -0700179Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700180 return validateAndCall(this,
181 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
182 &WifiChip::createNanIfaceInternal,
183 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700184}
185
Roshan Pius5c055462016-10-11 08:27:27 -0700186Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700187 return validateAndCall(this,
188 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
189 &WifiChip::getNanIfaceNamesInternal,
190 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700191}
192
193Return<void> WifiChip::getNanIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700194 getNanIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700195 return validateAndCall(this,
196 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
197 &WifiChip::getNanIfaceInternal,
198 hidl_status_cb,
199 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700200}
201
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800202Return<void> WifiChip::removeNanIface(const hidl_string& ifname,
203 removeNanIface_cb hidl_status_cb) {
204 return validateAndCall(this,
205 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
206 &WifiChip::removeNanIfaceInternal,
207 hidl_status_cb,
208 ifname);
209}
210
Roshan Pius5c055462016-10-11 08:27:27 -0700211Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700212 return validateAndCall(this,
213 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
214 &WifiChip::createP2pIfaceInternal,
215 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700216}
217
Roshan Pius5c055462016-10-11 08:27:27 -0700218Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700219 return validateAndCall(this,
220 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
221 &WifiChip::getP2pIfaceNamesInternal,
222 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700223}
224
225Return<void> WifiChip::getP2pIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700226 getP2pIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700227 return validateAndCall(this,
228 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
229 &WifiChip::getP2pIfaceInternal,
230 hidl_status_cb,
231 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700232}
233
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800234Return<void> WifiChip::removeP2pIface(const hidl_string& ifname,
235 removeP2pIface_cb hidl_status_cb) {
236 return validateAndCall(this,
237 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
238 &WifiChip::removeP2pIfaceInternal,
239 hidl_status_cb,
240 ifname);
241}
242
Roshan Pius5c055462016-10-11 08:27:27 -0700243Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700244 return validateAndCall(this,
245 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
246 &WifiChip::createStaIfaceInternal,
247 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700248}
249
Roshan Pius5c055462016-10-11 08:27:27 -0700250Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700251 return validateAndCall(this,
252 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
253 &WifiChip::getStaIfaceNamesInternal,
254 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700255}
256
257Return<void> WifiChip::getStaIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700258 getStaIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700259 return validateAndCall(this,
260 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
261 &WifiChip::getStaIfaceInternal,
262 hidl_status_cb,
263 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700264}
265
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800266Return<void> WifiChip::removeStaIface(const hidl_string& ifname,
267 removeStaIface_cb hidl_status_cb) {
268 return validateAndCall(this,
269 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
270 &WifiChip::removeStaIfaceInternal,
271 hidl_status_cb,
272 ifname);
273}
274
Roshan Pius5c055462016-10-11 08:27:27 -0700275Return<void> WifiChip::createRttController(
276 const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700277 return validateAndCall(this,
278 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
279 &WifiChip::createRttControllerInternal,
280 hidl_status_cb,
281 bound_iface);
Roshan Pius59268282016-10-06 20:23:47 -0700282}
283
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700284Return<void> WifiChip::getDebugRingBuffersStatus(
285 getDebugRingBuffersStatus_cb hidl_status_cb) {
286 return validateAndCall(this,
287 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
288 &WifiChip::getDebugRingBuffersStatusInternal,
289 hidl_status_cb);
290}
291
292Return<void> WifiChip::startLoggingToDebugRingBuffer(
293 const hidl_string& ring_name,
294 WifiDebugRingBufferVerboseLevel verbose_level,
295 uint32_t max_interval_in_sec,
296 uint32_t min_data_size_in_bytes,
297 startLoggingToDebugRingBuffer_cb hidl_status_cb) {
298 return validateAndCall(this,
299 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
300 &WifiChip::startLoggingToDebugRingBufferInternal,
301 hidl_status_cb,
302 ring_name,
303 verbose_level,
304 max_interval_in_sec,
305 min_data_size_in_bytes);
306}
307
308Return<void> WifiChip::forceDumpToDebugRingBuffer(
309 const hidl_string& ring_name,
310 forceDumpToDebugRingBuffer_cb hidl_status_cb) {
311 return validateAndCall(this,
312 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
313 &WifiChip::forceDumpToDebugRingBufferInternal,
314 hidl_status_cb,
315 ring_name);
316}
317
318Return<void> WifiChip::getDebugHostWakeReasonStats(
319 getDebugHostWakeReasonStats_cb hidl_status_cb) {
320 return validateAndCall(this,
321 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
322 &WifiChip::getDebugHostWakeReasonStatsInternal,
323 hidl_status_cb);
324}
325
Roshan Pius203cb032016-12-14 17:41:20 -0800326Return<void> WifiChip::enableDebugErrorAlerts(
327 bool enable, enableDebugErrorAlerts_cb hidl_status_cb) {
328 return validateAndCall(this,
329 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
330 &WifiChip::enableDebugErrorAlertsInternal,
331 hidl_status_cb,
332 enable);
333}
334
Roshan Pius35d958c2016-10-06 16:47:38 -0700335void WifiChip::invalidateAndRemoveAllIfaces() {
336 invalidateAndClear(ap_iface_);
337 invalidateAndClear(nan_iface_);
338 invalidateAndClear(p2p_iface_);
339 invalidateAndClear(sta_iface_);
Roshan Pius59268282016-10-06 20:23:47 -0700340 // Since all the ifaces are invalid now, all RTT controller objects
341 // using those ifaces also need to be invalidated.
342 for (const auto& rtt : rtt_controllers_) {
343 rtt->invalidate();
344 }
345 rtt_controllers_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -0700346}
347
Roshan Pius3c868522016-10-27 12:43:49 -0700348std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
349 return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
350}
351
352WifiStatus WifiChip::registerEventCallbackInternal(
353 const sp<IWifiChipEventCallback>& event_callback) {
354 // TODO(b/31632518): remove the callback when the client is destroyed
355 event_callbacks_.emplace_back(event_callback);
356 return createWifiStatus(WifiStatusCode::SUCCESS);
357}
358
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700359std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800360 legacy_hal::wifi_error legacy_status;
361 uint32_t legacy_logger_feature_set;
362 std::tie(legacy_status, legacy_logger_feature_set) =
363 legacy_hal_.lock()->getLoggerSupportedFeatureSet();
364 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
365 return {createWifiStatusFromLegacyError(legacy_status), 0};
366 }
367 uint32_t hidl_caps;
368 if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
369 legacy_logger_feature_set, &hidl_caps)) {
370 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
371 }
372 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700373}
374
Roshan Pius3c868522016-10-27 12:43:49 -0700375std::pair<WifiStatus, std::vector<IWifiChip::ChipMode>>
376WifiChip::getAvailableModesInternal() {
Roshan Pius52947fb2016-11-18 11:38:07 -0800377 // The chip combination supported for current devices is fixed for now with
378 // 2 separate modes of operation:
379 // Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN iface operations
380 // concurrently.
381 // Mode 2 (AP mode): Will support 1 AP iface operations.
382 // TODO (b/32997844): Read this from some device specific flags in the
383 // makefile.
384 // STA mode iface combinations.
385 const IWifiChip::ChipIfaceCombinationLimit
386 sta_chip_iface_combination_limit_1 = {{IfaceType::STA}, 1};
387 const IWifiChip::ChipIfaceCombinationLimit
388 sta_chip_iface_combination_limit_2 = {{IfaceType::P2P, IfaceType::NAN},
389 1};
390 const IWifiChip::ChipIfaceCombination sta_chip_iface_combination = {
391 {sta_chip_iface_combination_limit_1, sta_chip_iface_combination_limit_2}};
392 const IWifiChip::ChipMode sta_chip_mode = {kStaChipModeId,
393 {sta_chip_iface_combination}};
394 // AP mode iface combinations.
395 const IWifiChip::ChipIfaceCombinationLimit ap_chip_iface_combination_limit = {
396 {IfaceType::AP}, 1};
397 const IWifiChip::ChipIfaceCombination ap_chip_iface_combination = {
398 {ap_chip_iface_combination_limit}};
399 const IWifiChip::ChipMode ap_chip_mode = {kApChipModeId,
400 {ap_chip_iface_combination}};
401 return {createWifiStatus(WifiStatusCode::SUCCESS),
402 {sta_chip_mode, ap_chip_mode}};
Roshan Pius3c868522016-10-27 12:43:49 -0700403}
404
Roshan Pius52947fb2016-11-18 11:38:07 -0800405WifiStatus WifiChip::configureChipInternal(uint32_t mode_id) {
406 if (mode_id != kStaChipModeId && mode_id != kApChipModeId) {
407 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
408 }
409 if (mode_id == current_mode_id_) {
410 LOG(DEBUG) << "Already in the specified mode " << mode_id;
411 return createWifiStatus(WifiStatusCode::SUCCESS);
412 }
413 // If the chip is already configured in a different mode, stop
414 // the legacy HAL and then start it after firmware mode change.
415 if (current_mode_id_ != kInvalidModeId) {
416 invalidateAndRemoveAllIfaces();
417 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop([]() {});
418 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
419 LOG(ERROR) << "Failed to stop legacy HAL: "
420 << legacyErrorToString(legacy_status);
421 // TODO(b/33038823): Need to invoke onChipReconfigureFailure()
422 return createWifiStatusFromLegacyError(legacy_status);
423 }
424 }
425 bool success;
426 if (mode_id == kStaChipModeId) {
427 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
428 } else {
429 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
430 }
431 if (!success) {
432 // TODO(b/33038823): Need to invoke onChipReconfigureFailure()
433 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
434 }
435 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
436 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
437 LOG(ERROR) << "Failed to start legacy HAL: "
438 << legacyErrorToString(legacy_status);
439 // TODO(b/33038823): Need to invoke onChipReconfigureFailure()
440 return createWifiStatusFromLegacyError(legacy_status);
441 }
442 for (const auto& callback : event_callbacks_) {
443 callback->onChipReconfigured(mode_id);
444 }
445 current_mode_id_ = mode_id;
Roshan Pius3c868522016-10-27 12:43:49 -0700446 return createWifiStatus(WifiStatusCode::SUCCESS);
447}
448
449std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
Roshan Pius52947fb2016-11-18 11:38:07 -0800450 if (current_mode_id_ == kInvalidModeId) {
451 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE),
452 current_mode_id_};
453 }
454 return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700455}
456
457std::pair<WifiStatus, IWifiChip::ChipDebugInfo>
458WifiChip::requestChipDebugInfoInternal() {
459 IWifiChip::ChipDebugInfo result;
Roshan Piusa4854ff2016-12-01 13:47:41 -0800460 legacy_hal::wifi_error legacy_status;
Roshan Pius3c868522016-10-27 12:43:49 -0700461 std::string driver_desc;
462 std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion();
Roshan Piusa4854ff2016-12-01 13:47:41 -0800463 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700464 LOG(ERROR) << "Failed to get driver version: "
465 << legacyErrorToString(legacy_status);
466 WifiStatus status = createWifiStatusFromLegacyError(
467 legacy_status, "failed to get driver version");
468 return {status, result};
469 }
470 result.driverDescription = driver_desc.c_str();
471
472 std::string firmware_desc;
473 std::tie(legacy_status, firmware_desc) =
474 legacy_hal_.lock()->getFirmwareVersion();
Roshan Piusa4854ff2016-12-01 13:47:41 -0800475 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700476 LOG(ERROR) << "Failed to get firmware version: "
477 << legacyErrorToString(legacy_status);
478 WifiStatus status = createWifiStatusFromLegacyError(
479 legacy_status, "failed to get firmware version");
480 return {status, result};
481 }
482 result.firmwareDescription = firmware_desc.c_str();
483
484 return {createWifiStatus(WifiStatusCode::SUCCESS), result};
485}
486
487std::pair<WifiStatus, std::vector<uint8_t>>
488WifiChip::requestDriverDebugDumpInternal() {
Roshan Piusa4854ff2016-12-01 13:47:41 -0800489 legacy_hal::wifi_error legacy_status;
Roshan Pius3c868522016-10-27 12:43:49 -0700490 std::vector<uint8_t> driver_dump;
491 std::tie(legacy_status, driver_dump) =
492 legacy_hal_.lock()->requestDriverMemoryDump();
Roshan Piusa4854ff2016-12-01 13:47:41 -0800493 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700494 LOG(ERROR) << "Failed to get driver debug dump: "
495 << legacyErrorToString(legacy_status);
496 return {createWifiStatusFromLegacyError(legacy_status),
497 std::vector<uint8_t>()};
498 }
499 return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
500}
501
502std::pair<WifiStatus, std::vector<uint8_t>>
503WifiChip::requestFirmwareDebugDumpInternal() {
Roshan Piusa4854ff2016-12-01 13:47:41 -0800504 legacy_hal::wifi_error legacy_status;
Roshan Pius3c868522016-10-27 12:43:49 -0700505 std::vector<uint8_t> firmware_dump;
506 std::tie(legacy_status, firmware_dump) =
507 legacy_hal_.lock()->requestFirmwareMemoryDump();
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 firmware debug dump: "
510 << legacyErrorToString(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700511 return {createWifiStatusFromLegacyError(legacy_status), {}};
Roshan Pius3c868522016-10-27 12:43:49 -0700512 }
513 return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
514}
515
516std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800517 if (current_mode_id_ != kApChipModeId || ap_iface_.get()) {
518 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
519 }
Roshan Pius3c868522016-10-27 12:43:49 -0700520 std::string ifname = legacy_hal_.lock()->getApIfaceName();
521 ap_iface_ = new WifiApIface(ifname, legacy_hal_);
522 return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};
523}
524
525std::pair<WifiStatus, std::vector<hidl_string>>
526WifiChip::getApIfaceNamesInternal() {
527 if (!ap_iface_.get()) {
528 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
529 }
530 return {createWifiStatus(WifiStatusCode::SUCCESS),
531 {legacy_hal_.lock()->getApIfaceName()}};
532}
533
534std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::getApIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800535 const std::string& ifname) {
536 if (!ap_iface_.get() || (ifname != legacy_hal_.lock()->getApIfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700537 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
538 }
539 return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};
540}
541
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800542WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
543 if (!ap_iface_.get() || (ifname != legacy_hal_.lock()->getApIfaceName())) {
544 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
545 }
546 invalidateAndClear(ap_iface_);
547 return createWifiStatus(WifiStatusCode::SUCCESS);
548}
549
Roshan Pius3c868522016-10-27 12:43:49 -0700550std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800551 // Only 1 of NAN or P2P iface can be active at a time.
552 if (current_mode_id_ != kStaChipModeId || nan_iface_.get() ||
553 p2p_iface_.get()) {
554 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
555 }
Roshan Pius3c868522016-10-27 12:43:49 -0700556 std::string ifname = legacy_hal_.lock()->getNanIfaceName();
557 nan_iface_ = new WifiNanIface(ifname, legacy_hal_);
558 return {createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_};
559}
560
561std::pair<WifiStatus, std::vector<hidl_string>>
562WifiChip::getNanIfaceNamesInternal() {
563 if (!nan_iface_.get()) {
564 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
565 }
566 return {createWifiStatus(WifiStatusCode::SUCCESS),
567 {legacy_hal_.lock()->getNanIfaceName()}};
568}
569
570std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::getNanIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800571 const std::string& ifname) {
572 if (!nan_iface_.get() || (ifname != legacy_hal_.lock()->getNanIfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700573 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
574 }
575 return {createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_};
576}
577
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800578WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
579 if (!nan_iface_.get() || (ifname != legacy_hal_.lock()->getNanIfaceName())) {
580 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
581 }
582 invalidateAndClear(nan_iface_);
583 return createWifiStatus(WifiStatusCode::SUCCESS);
584}
585
Roshan Pius3c868522016-10-27 12:43:49 -0700586std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800587 // Only 1 of NAN or P2P iface can be active at a time.
588 if (current_mode_id_ != kStaChipModeId || p2p_iface_.get() ||
589 nan_iface_.get()) {
590 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
591 }
Roshan Pius3c868522016-10-27 12:43:49 -0700592 std::string ifname = legacy_hal_.lock()->getP2pIfaceName();
593 p2p_iface_ = new WifiP2pIface(ifname, legacy_hal_);
594 return {createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_};
595}
596
597std::pair<WifiStatus, std::vector<hidl_string>>
598WifiChip::getP2pIfaceNamesInternal() {
599 if (!p2p_iface_.get()) {
600 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
601 }
602 return {createWifiStatus(WifiStatusCode::SUCCESS),
603 {legacy_hal_.lock()->getP2pIfaceName()}};
604}
605
606std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800607 const std::string& ifname) {
608 if (!p2p_iface_.get() || (ifname != legacy_hal_.lock()->getP2pIfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700609 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
610 }
611 return {createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_};
612}
613
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800614WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
615 if (!p2p_iface_.get() || (ifname != legacy_hal_.lock()->getP2pIfaceName())) {
616 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
617 }
618 invalidateAndClear(p2p_iface_);
619 return createWifiStatus(WifiStatusCode::SUCCESS);
620}
621
Roshan Pius3c868522016-10-27 12:43:49 -0700622std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800623 if (current_mode_id_ != kStaChipModeId || sta_iface_.get()) {
624 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
625 }
Roshan Pius3c868522016-10-27 12:43:49 -0700626 std::string ifname = legacy_hal_.lock()->getStaIfaceName();
627 sta_iface_ = new WifiStaIface(ifname, legacy_hal_);
628 return {createWifiStatus(WifiStatusCode::SUCCESS), sta_iface_};
629}
630
631std::pair<WifiStatus, std::vector<hidl_string>>
632WifiChip::getStaIfaceNamesInternal() {
633 if (!sta_iface_.get()) {
634 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
635 }
636 return {createWifiStatus(WifiStatusCode::SUCCESS),
637 {legacy_hal_.lock()->getStaIfaceName()}};
638}
639
640std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::getStaIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800641 const std::string& ifname) {
642 if (!sta_iface_.get() || (ifname != legacy_hal_.lock()->getStaIfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700643 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
644 }
645 return {createWifiStatus(WifiStatusCode::SUCCESS), sta_iface_};
646}
647
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800648WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
649 if (!sta_iface_.get() || (ifname != legacy_hal_.lock()->getStaIfaceName())) {
650 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
651 }
652 invalidateAndClear(sta_iface_);
653 return createWifiStatus(WifiStatusCode::SUCCESS);
654}
655
Roshan Pius3c868522016-10-27 12:43:49 -0700656std::pair<WifiStatus, sp<IWifiRttController>>
657WifiChip::createRttControllerInternal(const sp<IWifiIface>& bound_iface) {
658 sp<WifiRttController> rtt = new WifiRttController(bound_iface, legacy_hal_);
659 rtt_controllers_.emplace_back(rtt);
660 return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
661}
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700662
663std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
664WifiChip::getDebugRingBuffersStatusInternal() {
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800665 legacy_hal::wifi_error legacy_status;
666 std::vector<legacy_hal::wifi_ring_buffer_status>
667 legacy_ring_buffer_status_vec;
668 std::tie(legacy_status, legacy_ring_buffer_status_vec) =
669 legacy_hal_.lock()->getRingBuffersStatus();
670 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
671 return {createWifiStatusFromLegacyError(legacy_status), {}};
672 }
673 std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
674 if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
675 legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
676 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
677 }
678 return {createWifiStatus(WifiStatusCode::SUCCESS),
679 hidl_ring_buffer_status_vec};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700680}
681
682WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800683 const hidl_string& ring_name,
684 WifiDebugRingBufferVerboseLevel verbose_level,
685 uint32_t max_interval_in_sec,
686 uint32_t min_data_size_in_bytes) {
687 legacy_hal::wifi_error legacy_status =
688 legacy_hal_.lock()->startRingBufferLogging(
689 ring_name,
690 static_cast<
691 std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
692 verbose_level),
693 max_interval_in_sec,
694 min_data_size_in_bytes);
695 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700696}
697
698WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800699 const hidl_string& ring_name) {
700 legacy_hal::wifi_error legacy_status =
701 legacy_hal_.lock()->getRingBufferData(ring_name);
702 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700703}
704
705std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
706WifiChip::getDebugHostWakeReasonStatsInternal() {
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800707 legacy_hal::wifi_error legacy_status;
708 legacy_hal::WakeReasonStats legacy_stats;
709 std::tie(legacy_status, legacy_stats) =
710 legacy_hal_.lock()->getWakeReasonStats();
711 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
712 return {createWifiStatusFromLegacyError(legacy_status), {}};
713 }
714 WifiDebugHostWakeReasonStats hidl_stats;
715 if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats,
716 &hidl_stats)) {
717 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
718 }
719 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700720}
721
Roshan Pius203cb032016-12-14 17:41:20 -0800722WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
723 legacy_hal::wifi_error legacy_status;
724 if (enable) {
725 android::wp<WifiChip> weak_ptr_this(this);
726 const auto& on_alert_callback = [weak_ptr_this](
727 int32_t error_code, std::vector<uint8_t> debug_data) {
728 const auto shared_ptr_this = weak_ptr_this.promote();
729 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
730 LOG(ERROR) << "Callback invoked on an invalid object";
731 return;
732 }
733 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
734 callback->onDebugErrorAlert(error_code, debug_data);
735 }
736 };
737 legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
738 on_alert_callback);
739 } else {
740 legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler();
741 }
742 return createWifiStatusFromLegacyError(legacy_status);
743}
Roshan Pius79a99752016-10-04 13:03:58 -0700744} // namespace implementation
745} // namespace V1_0
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700746} // namespace wifi
747} // namespace hardware
748} // namespace android