blob: 87b47cbff6e5fef70525176fe8eb100a4eb69158 [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 Pius2c06a3f2016-12-15 17:51:40 -080028using android::hardware::wifi::V1_0::ChipModeId;
Roshan Pius52947fb2016-11-18 11:38:07 -080029using android::hardware::wifi::V1_0::IWifiChip;
30using android::hardware::wifi::V1_0::IfaceType;
31
Roshan Pius2c06a3f2016-12-15 17:51:40 -080032constexpr ChipModeId kStaChipModeId = 0;
33constexpr ChipModeId kApChipModeId = 1;
34constexpr ChipModeId kInvalidModeId = UINT32_MAX;
Roshan Pius35d958c2016-10-06 16:47:38 -070035
Roshan Pius35d958c2016-10-06 16:47:38 -070036template <typename Iface>
37void invalidateAndClear(sp<Iface>& iface) {
38 if (iface.get()) {
39 iface->invalidate();
40 iface.clear();
41 }
42}
43} // namepsace
44
Roshan Pius3c4e8a32016-10-03 14:53:58 -070045namespace android {
46namespace hardware {
47namespace wifi {
Roshan Pius79a99752016-10-04 13:03:58 -070048namespace V1_0 {
49namespace implementation {
Roshan Pius3c868522016-10-27 12:43:49 -070050using hidl_return_util::validateAndCall;
Roshan Pius3c4e8a32016-10-03 14:53:58 -070051
Roshan Pius52947fb2016-11-18 11:38:07 -080052WifiChip::WifiChip(
53 ChipId chip_id,
54 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
55 const std::weak_ptr<mode_controller::WifiModeController> mode_controller)
56 : chip_id_(chip_id),
57 legacy_hal_(legacy_hal),
58 mode_controller_(mode_controller),
59 is_valid_(true),
60 current_mode_id_(kInvalidModeId) {}
Roshan Pius3c4e8a32016-10-03 14:53:58 -070061
Roshan Piusaabe5752016-09-29 09:03:59 -070062void WifiChip::invalidate() {
Roshan Pius35d958c2016-10-06 16:47:38 -070063 invalidateAndRemoveAllIfaces();
Roshan Piusaabe5752016-09-29 09:03:59 -070064 legacy_hal_.reset();
Roshan Pius5c055462016-10-11 08:27:27 -070065 event_callbacks_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -070066 is_valid_ = false;
Roshan Pius3c4e8a32016-10-03 14:53:58 -070067}
68
Roshan Pius3c868522016-10-27 12:43:49 -070069bool WifiChip::isValid() {
70 return is_valid_;
71}
72
Roshan Pius203cb032016-12-14 17:41:20 -080073std::vector<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
74 return event_callbacks_;
75}
76
Roshan Pius5c055462016-10-11 08:27:27 -070077Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -070078 return validateAndCall(this,
79 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
80 &WifiChip::getIdInternal,
81 hidl_status_cb);
Roshan Piuscd566bd2016-10-10 08:03:42 -070082}
83
Roshan Pius3c4e8a32016-10-03 14:53:58 -070084Return<void> WifiChip::registerEventCallback(
Roshan Pius5c055462016-10-11 08:27:27 -070085 const sp<IWifiChipEventCallback>& event_callback,
86 registerEventCallback_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -070087 return validateAndCall(this,
88 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
89 &WifiChip::registerEventCallbackInternal,
90 hidl_status_cb,
91 event_callback);
Roshan Pius3c4e8a32016-10-03 14:53:58 -070092}
93
Roshan Pius7d08d7a2016-10-27 14:35:05 -070094Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
95 return validateAndCall(this,
96 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
97 &WifiChip::getCapabilitiesInternal,
98 hidl_status_cb);
99}
100
Roshan Pius5c055462016-10-11 08:27:27 -0700101Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700102 return validateAndCall(this,
103 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
104 &WifiChip::getAvailableModesInternal,
105 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700106}
107
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800108Return<void> WifiChip::configureChip(ChipModeId mode_id,
Roshan Pius5c055462016-10-11 08:27:27 -0700109 configureChip_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700110 return validateAndCall(this,
111 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
112 &WifiChip::configureChipInternal,
113 hidl_status_cb,
114 mode_id);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700115}
116
Roshan Pius5c055462016-10-11 08:27:27 -0700117Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700118 return validateAndCall(this,
119 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
120 &WifiChip::getModeInternal,
121 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700122}
123
Roshan Pius5c055462016-10-11 08:27:27 -0700124Return<void> WifiChip::requestChipDebugInfo(
125 requestChipDebugInfo_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700126 return validateAndCall(this,
127 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
128 &WifiChip::requestChipDebugInfoInternal,
129 hidl_status_cb);
Roshan Pius5c055462016-10-11 08:27:27 -0700130}
131
132Return<void> WifiChip::requestDriverDebugDump(
133 requestDriverDebugDump_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700134 return validateAndCall(this,
135 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
136 &WifiChip::requestDriverDebugDumpInternal,
137 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700138}
139
Roshan Pius5c055462016-10-11 08:27:27 -0700140Return<void> WifiChip::requestFirmwareDebugDump(
141 requestFirmwareDebugDump_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700142 return validateAndCall(this,
143 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
144 &WifiChip::requestFirmwareDebugDumpInternal,
145 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700146}
147
Roshan Pius5c055462016-10-11 08:27:27 -0700148Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700149 return validateAndCall(this,
150 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
151 &WifiChip::createApIfaceInternal,
152 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700153}
154
Roshan Pius5c055462016-10-11 08:27:27 -0700155Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700156 return validateAndCall(this,
157 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
158 &WifiChip::getApIfaceNamesInternal,
159 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700160}
161
Roshan Pius5c055462016-10-11 08:27:27 -0700162Return<void> WifiChip::getApIface(const hidl_string& ifname,
163 getApIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700164 return validateAndCall(this,
165 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
166 &WifiChip::getApIfaceInternal,
167 hidl_status_cb,
168 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700169}
170
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800171Return<void> WifiChip::removeApIface(const hidl_string& ifname,
172 removeApIface_cb hidl_status_cb) {
173 return validateAndCall(this,
174 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
175 &WifiChip::removeApIfaceInternal,
176 hidl_status_cb,
177 ifname);
178}
179
Roshan Pius5c055462016-10-11 08:27:27 -0700180Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700181 return validateAndCall(this,
182 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
183 &WifiChip::createNanIfaceInternal,
184 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700185}
186
Roshan Pius5c055462016-10-11 08:27:27 -0700187Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700188 return validateAndCall(this,
189 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
190 &WifiChip::getNanIfaceNamesInternal,
191 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700192}
193
194Return<void> WifiChip::getNanIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700195 getNanIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700196 return validateAndCall(this,
197 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
198 &WifiChip::getNanIfaceInternal,
199 hidl_status_cb,
200 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700201}
202
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800203Return<void> WifiChip::removeNanIface(const hidl_string& ifname,
204 removeNanIface_cb hidl_status_cb) {
205 return validateAndCall(this,
206 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
207 &WifiChip::removeNanIfaceInternal,
208 hidl_status_cb,
209 ifname);
210}
211
Roshan Pius5c055462016-10-11 08:27:27 -0700212Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700213 return validateAndCall(this,
214 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
215 &WifiChip::createP2pIfaceInternal,
216 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700217}
218
Roshan Pius5c055462016-10-11 08:27:27 -0700219Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700220 return validateAndCall(this,
221 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
222 &WifiChip::getP2pIfaceNamesInternal,
223 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700224}
225
226Return<void> WifiChip::getP2pIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700227 getP2pIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700228 return validateAndCall(this,
229 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
230 &WifiChip::getP2pIfaceInternal,
231 hidl_status_cb,
232 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700233}
234
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800235Return<void> WifiChip::removeP2pIface(const hidl_string& ifname,
236 removeP2pIface_cb hidl_status_cb) {
237 return validateAndCall(this,
238 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
239 &WifiChip::removeP2pIfaceInternal,
240 hidl_status_cb,
241 ifname);
242}
243
Roshan Pius5c055462016-10-11 08:27:27 -0700244Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700245 return validateAndCall(this,
246 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
247 &WifiChip::createStaIfaceInternal,
248 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700249}
250
Roshan Pius5c055462016-10-11 08:27:27 -0700251Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700252 return validateAndCall(this,
253 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
254 &WifiChip::getStaIfaceNamesInternal,
255 hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700256}
257
258Return<void> WifiChip::getStaIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700259 getStaIface_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700260 return validateAndCall(this,
261 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
262 &WifiChip::getStaIfaceInternal,
263 hidl_status_cb,
264 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700265}
266
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800267Return<void> WifiChip::removeStaIface(const hidl_string& ifname,
268 removeStaIface_cb hidl_status_cb) {
269 return validateAndCall(this,
270 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
271 &WifiChip::removeStaIfaceInternal,
272 hidl_status_cb,
273 ifname);
274}
275
Roshan Pius5c055462016-10-11 08:27:27 -0700276Return<void> WifiChip::createRttController(
277 const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) {
Roshan Pius3c868522016-10-27 12:43:49 -0700278 return validateAndCall(this,
279 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
280 &WifiChip::createRttControllerInternal,
281 hidl_status_cb,
282 bound_iface);
Roshan Pius59268282016-10-06 20:23:47 -0700283}
284
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700285Return<void> WifiChip::getDebugRingBuffersStatus(
286 getDebugRingBuffersStatus_cb hidl_status_cb) {
287 return validateAndCall(this,
288 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
289 &WifiChip::getDebugRingBuffersStatusInternal,
290 hidl_status_cb);
291}
292
293Return<void> WifiChip::startLoggingToDebugRingBuffer(
294 const hidl_string& ring_name,
295 WifiDebugRingBufferVerboseLevel verbose_level,
296 uint32_t max_interval_in_sec,
297 uint32_t min_data_size_in_bytes,
298 startLoggingToDebugRingBuffer_cb hidl_status_cb) {
299 return validateAndCall(this,
300 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
301 &WifiChip::startLoggingToDebugRingBufferInternal,
302 hidl_status_cb,
303 ring_name,
304 verbose_level,
305 max_interval_in_sec,
306 min_data_size_in_bytes);
307}
308
309Return<void> WifiChip::forceDumpToDebugRingBuffer(
310 const hidl_string& ring_name,
311 forceDumpToDebugRingBuffer_cb hidl_status_cb) {
312 return validateAndCall(this,
313 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
314 &WifiChip::forceDumpToDebugRingBufferInternal,
315 hidl_status_cb,
316 ring_name);
317}
318
319Return<void> WifiChip::getDebugHostWakeReasonStats(
320 getDebugHostWakeReasonStats_cb hidl_status_cb) {
321 return validateAndCall(this,
322 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
323 &WifiChip::getDebugHostWakeReasonStatsInternal,
324 hidl_status_cb);
325}
326
Roshan Pius203cb032016-12-14 17:41:20 -0800327Return<void> WifiChip::enableDebugErrorAlerts(
328 bool enable, enableDebugErrorAlerts_cb hidl_status_cb) {
329 return validateAndCall(this,
330 WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
331 &WifiChip::enableDebugErrorAlertsInternal,
332 hidl_status_cb,
333 enable);
334}
335
Roshan Pius35d958c2016-10-06 16:47:38 -0700336void WifiChip::invalidateAndRemoveAllIfaces() {
337 invalidateAndClear(ap_iface_);
338 invalidateAndClear(nan_iface_);
339 invalidateAndClear(p2p_iface_);
340 invalidateAndClear(sta_iface_);
Roshan Pius59268282016-10-06 20:23:47 -0700341 // Since all the ifaces are invalid now, all RTT controller objects
342 // using those ifaces also need to be invalidated.
343 for (const auto& rtt : rtt_controllers_) {
344 rtt->invalidate();
345 }
346 rtt_controllers_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -0700347}
348
Roshan Pius3c868522016-10-27 12:43:49 -0700349std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
350 return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
351}
352
353WifiStatus WifiChip::registerEventCallbackInternal(
354 const sp<IWifiChipEventCallback>& event_callback) {
355 // TODO(b/31632518): remove the callback when the client is destroyed
356 event_callbacks_.emplace_back(event_callback);
357 return createWifiStatus(WifiStatusCode::SUCCESS);
358}
359
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700360std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800361 legacy_hal::wifi_error legacy_status;
362 uint32_t legacy_logger_feature_set;
363 std::tie(legacy_status, legacy_logger_feature_set) =
364 legacy_hal_.lock()->getLoggerSupportedFeatureSet();
365 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
366 return {createWifiStatusFromLegacyError(legacy_status), 0};
367 }
368 uint32_t hidl_caps;
369 if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
370 legacy_logger_feature_set, &hidl_caps)) {
371 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
372 }
373 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700374}
375
Roshan Pius3c868522016-10-27 12:43:49 -0700376std::pair<WifiStatus, std::vector<IWifiChip::ChipMode>>
377WifiChip::getAvailableModesInternal() {
Roshan Pius52947fb2016-11-18 11:38:07 -0800378 // The chip combination supported for current devices is fixed for now with
379 // 2 separate modes of operation:
380 // Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN iface operations
381 // concurrently.
382 // Mode 2 (AP mode): Will support 1 AP iface operations.
383 // TODO (b/32997844): Read this from some device specific flags in the
384 // makefile.
385 // STA mode iface combinations.
386 const IWifiChip::ChipIfaceCombinationLimit
387 sta_chip_iface_combination_limit_1 = {{IfaceType::STA}, 1};
388 const IWifiChip::ChipIfaceCombinationLimit
389 sta_chip_iface_combination_limit_2 = {{IfaceType::P2P, IfaceType::NAN},
390 1};
391 const IWifiChip::ChipIfaceCombination sta_chip_iface_combination = {
392 {sta_chip_iface_combination_limit_1, sta_chip_iface_combination_limit_2}};
393 const IWifiChip::ChipMode sta_chip_mode = {kStaChipModeId,
394 {sta_chip_iface_combination}};
395 // AP mode iface combinations.
396 const IWifiChip::ChipIfaceCombinationLimit ap_chip_iface_combination_limit = {
397 {IfaceType::AP}, 1};
398 const IWifiChip::ChipIfaceCombination ap_chip_iface_combination = {
399 {ap_chip_iface_combination_limit}};
400 const IWifiChip::ChipMode ap_chip_mode = {kApChipModeId,
401 {ap_chip_iface_combination}};
402 return {createWifiStatus(WifiStatusCode::SUCCESS),
403 {sta_chip_mode, ap_chip_mode}};
Roshan Pius3c868522016-10-27 12:43:49 -0700404}
405
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800406WifiStatus WifiChip::configureChipInternal(ChipModeId mode_id) {
Roshan Pius52947fb2016-11-18 11:38:07 -0800407 if (mode_id != kStaChipModeId && mode_id != kApChipModeId) {
408 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
409 }
410 if (mode_id == current_mode_id_) {
411 LOG(DEBUG) << "Already in the specified mode " << mode_id;
412 return createWifiStatus(WifiStatusCode::SUCCESS);
413 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800414 WifiStatus status = handleChipConfiguration(mode_id);
415 if (status.code != WifiStatusCode::SUCCESS) {
416 for (const auto& callback : event_callbacks_) {
417 callback->onChipReconfigureFailure(status);
Roshan Pius52947fb2016-11-18 11:38:07 -0800418 }
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800419 return status;
Roshan Pius52947fb2016-11-18 11:38:07 -0800420 }
421 for (const auto& callback : event_callbacks_) {
422 callback->onChipReconfigured(mode_id);
423 }
424 current_mode_id_ = mode_id;
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800425 return status;
Roshan Pius3c868522016-10-27 12:43:49 -0700426}
427
428std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
Roshan Pius52947fb2016-11-18 11:38:07 -0800429 if (current_mode_id_ == kInvalidModeId) {
430 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE),
431 current_mode_id_};
432 }
433 return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700434}
435
436std::pair<WifiStatus, IWifiChip::ChipDebugInfo>
437WifiChip::requestChipDebugInfoInternal() {
438 IWifiChip::ChipDebugInfo result;
Roshan Piusa4854ff2016-12-01 13:47:41 -0800439 legacy_hal::wifi_error legacy_status;
Roshan Pius3c868522016-10-27 12:43:49 -0700440 std::string driver_desc;
441 std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion();
Roshan Piusa4854ff2016-12-01 13:47:41 -0800442 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700443 LOG(ERROR) << "Failed to get driver version: "
444 << legacyErrorToString(legacy_status);
445 WifiStatus status = createWifiStatusFromLegacyError(
446 legacy_status, "failed to get driver version");
447 return {status, result};
448 }
449 result.driverDescription = driver_desc.c_str();
450
451 std::string firmware_desc;
452 std::tie(legacy_status, firmware_desc) =
453 legacy_hal_.lock()->getFirmwareVersion();
Roshan Piusa4854ff2016-12-01 13:47:41 -0800454 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700455 LOG(ERROR) << "Failed to get firmware version: "
456 << legacyErrorToString(legacy_status);
457 WifiStatus status = createWifiStatusFromLegacyError(
458 legacy_status, "failed to get firmware version");
459 return {status, result};
460 }
461 result.firmwareDescription = firmware_desc.c_str();
462
463 return {createWifiStatus(WifiStatusCode::SUCCESS), result};
464}
465
466std::pair<WifiStatus, std::vector<uint8_t>>
467WifiChip::requestDriverDebugDumpInternal() {
Roshan Piusa4854ff2016-12-01 13:47:41 -0800468 legacy_hal::wifi_error legacy_status;
Roshan Pius3c868522016-10-27 12:43:49 -0700469 std::vector<uint8_t> driver_dump;
470 std::tie(legacy_status, driver_dump) =
471 legacy_hal_.lock()->requestDriverMemoryDump();
Roshan Piusa4854ff2016-12-01 13:47:41 -0800472 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700473 LOG(ERROR) << "Failed to get driver debug dump: "
474 << legacyErrorToString(legacy_status);
475 return {createWifiStatusFromLegacyError(legacy_status),
476 std::vector<uint8_t>()};
477 }
478 return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
479}
480
481std::pair<WifiStatus, std::vector<uint8_t>>
482WifiChip::requestFirmwareDebugDumpInternal() {
Roshan Piusa4854ff2016-12-01 13:47:41 -0800483 legacy_hal::wifi_error legacy_status;
Roshan Pius3c868522016-10-27 12:43:49 -0700484 std::vector<uint8_t> firmware_dump;
485 std::tie(legacy_status, firmware_dump) =
486 legacy_hal_.lock()->requestFirmwareMemoryDump();
Roshan Piusa4854ff2016-12-01 13:47:41 -0800487 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Roshan Pius3c868522016-10-27 12:43:49 -0700488 LOG(ERROR) << "Failed to get firmware debug dump: "
489 << legacyErrorToString(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700490 return {createWifiStatusFromLegacyError(legacy_status), {}};
Roshan Pius3c868522016-10-27 12:43:49 -0700491 }
492 return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
493}
494
495std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800496 if (current_mode_id_ != kApChipModeId || ap_iface_.get()) {
497 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
498 }
Roshan Pius3c868522016-10-27 12:43:49 -0700499 std::string ifname = legacy_hal_.lock()->getApIfaceName();
500 ap_iface_ = new WifiApIface(ifname, legacy_hal_);
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800501 for (const auto& callback : event_callbacks_) {
502 callback->onIfaceAdded(IfaceType::AP, ifname);
503 }
Roshan Pius3c868522016-10-27 12:43:49 -0700504 return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};
505}
506
507std::pair<WifiStatus, std::vector<hidl_string>>
508WifiChip::getApIfaceNamesInternal() {
509 if (!ap_iface_.get()) {
510 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
511 }
512 return {createWifiStatus(WifiStatusCode::SUCCESS),
513 {legacy_hal_.lock()->getApIfaceName()}};
514}
515
516std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::getApIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800517 const std::string& ifname) {
518 if (!ap_iface_.get() || (ifname != legacy_hal_.lock()->getApIfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700519 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
520 }
521 return {createWifiStatus(WifiStatusCode::SUCCESS), ap_iface_};
522}
523
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800524WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
525 if (!ap_iface_.get() || (ifname != legacy_hal_.lock()->getApIfaceName())) {
526 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
527 }
528 invalidateAndClear(ap_iface_);
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800529 for (const auto& callback : event_callbacks_) {
530 callback->onIfaceRemoved(IfaceType::AP, ifname);
531 }
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800532 return createWifiStatus(WifiStatusCode::SUCCESS);
533}
534
Roshan Pius3c868522016-10-27 12:43:49 -0700535std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800536 // Only 1 of NAN or P2P iface can be active at a time.
537 if (current_mode_id_ != kStaChipModeId || nan_iface_.get() ||
538 p2p_iface_.get()) {
539 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
540 }
Roshan Pius3c868522016-10-27 12:43:49 -0700541 std::string ifname = legacy_hal_.lock()->getNanIfaceName();
542 nan_iface_ = new WifiNanIface(ifname, legacy_hal_);
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800543 for (const auto& callback : event_callbacks_) {
544 callback->onIfaceAdded(IfaceType::NAN, ifname);
545 }
Roshan Pius3c868522016-10-27 12:43:49 -0700546 return {createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_};
547}
548
549std::pair<WifiStatus, std::vector<hidl_string>>
550WifiChip::getNanIfaceNamesInternal() {
551 if (!nan_iface_.get()) {
552 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
553 }
554 return {createWifiStatus(WifiStatusCode::SUCCESS),
555 {legacy_hal_.lock()->getNanIfaceName()}};
556}
557
558std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::getNanIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800559 const std::string& ifname) {
560 if (!nan_iface_.get() || (ifname != legacy_hal_.lock()->getNanIfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700561 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
562 }
563 return {createWifiStatus(WifiStatusCode::SUCCESS), nan_iface_};
564}
565
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800566WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
567 if (!nan_iface_.get() || (ifname != legacy_hal_.lock()->getNanIfaceName())) {
568 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
569 }
570 invalidateAndClear(nan_iface_);
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800571 for (const auto& callback : event_callbacks_) {
572 callback->onIfaceRemoved(IfaceType::NAN, ifname);
573 }
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800574 return createWifiStatus(WifiStatusCode::SUCCESS);
575}
576
Roshan Pius3c868522016-10-27 12:43:49 -0700577std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800578 // Only 1 of NAN or P2P iface can be active at a time.
579 if (current_mode_id_ != kStaChipModeId || p2p_iface_.get() ||
580 nan_iface_.get()) {
581 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
582 }
Roshan Pius3c868522016-10-27 12:43:49 -0700583 std::string ifname = legacy_hal_.lock()->getP2pIfaceName();
584 p2p_iface_ = new WifiP2pIface(ifname, legacy_hal_);
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800585 for (const auto& callback : event_callbacks_) {
586 callback->onIfaceAdded(IfaceType::P2P, ifname);
587 }
Roshan Pius3c868522016-10-27 12:43:49 -0700588 return {createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_};
589}
590
591std::pair<WifiStatus, std::vector<hidl_string>>
592WifiChip::getP2pIfaceNamesInternal() {
593 if (!p2p_iface_.get()) {
594 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
595 }
596 return {createWifiStatus(WifiStatusCode::SUCCESS),
597 {legacy_hal_.lock()->getP2pIfaceName()}};
598}
599
600std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800601 const std::string& ifname) {
602 if (!p2p_iface_.get() || (ifname != legacy_hal_.lock()->getP2pIfaceName())) {
Roshan Pius3c868522016-10-27 12:43:49 -0700603 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
604 }
605 return {createWifiStatus(WifiStatusCode::SUCCESS), p2p_iface_};
606}
607
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800608WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
609 if (!p2p_iface_.get() || (ifname != legacy_hal_.lock()->getP2pIfaceName())) {
610 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
611 }
612 invalidateAndClear(p2p_iface_);
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800613 for (const auto& callback : event_callbacks_) {
614 callback->onIfaceRemoved(IfaceType::P2P, ifname);
615 }
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800616 return createWifiStatus(WifiStatusCode::SUCCESS);
617}
618
Roshan Pius3c868522016-10-27 12:43:49 -0700619std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() {
Roshan Pius073d5b92016-12-08 19:10:06 -0800620 if (current_mode_id_ != kStaChipModeId || sta_iface_.get()) {
621 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
622 }
Roshan Pius3c868522016-10-27 12:43:49 -0700623 std::string ifname = legacy_hal_.lock()->getStaIfaceName();
624 sta_iface_ = new WifiStaIface(ifname, legacy_hal_);
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800625 for (const auto& callback : event_callbacks_) {
626 callback->onIfaceAdded(IfaceType::STA, ifname);
627 }
Roshan Pius3c868522016-10-27 12:43:49 -0700628 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_);
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800653 for (const auto& callback : event_callbacks_) {
654 callback->onIfaceRemoved(IfaceType::STA, ifname);
655 }
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800656 return createWifiStatus(WifiStatusCode::SUCCESS);
657}
658
Roshan Pius3c868522016-10-27 12:43:49 -0700659std::pair<WifiStatus, sp<IWifiRttController>>
660WifiChip::createRttControllerInternal(const sp<IWifiIface>& bound_iface) {
661 sp<WifiRttController> rtt = new WifiRttController(bound_iface, legacy_hal_);
662 rtt_controllers_.emplace_back(rtt);
663 return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
664}
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700665
666std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
667WifiChip::getDebugRingBuffersStatusInternal() {
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800668 legacy_hal::wifi_error legacy_status;
669 std::vector<legacy_hal::wifi_ring_buffer_status>
670 legacy_ring_buffer_status_vec;
671 std::tie(legacy_status, legacy_ring_buffer_status_vec) =
672 legacy_hal_.lock()->getRingBuffersStatus();
673 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
674 return {createWifiStatusFromLegacyError(legacy_status), {}};
675 }
676 std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
677 if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
678 legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
679 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
680 }
681 return {createWifiStatus(WifiStatusCode::SUCCESS),
682 hidl_ring_buffer_status_vec};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700683}
684
685WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800686 const hidl_string& ring_name,
687 WifiDebugRingBufferVerboseLevel verbose_level,
688 uint32_t max_interval_in_sec,
689 uint32_t min_data_size_in_bytes) {
690 legacy_hal::wifi_error legacy_status =
691 legacy_hal_.lock()->startRingBufferLogging(
692 ring_name,
693 static_cast<
694 std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
695 verbose_level),
696 max_interval_in_sec,
697 min_data_size_in_bytes);
698 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700699}
700
701WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800702 const hidl_string& ring_name) {
703 legacy_hal::wifi_error legacy_status =
704 legacy_hal_.lock()->getRingBufferData(ring_name);
705 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700706}
707
708std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
709WifiChip::getDebugHostWakeReasonStatsInternal() {
Roshan Piuse2d0ab52016-12-05 15:24:20 -0800710 legacy_hal::wifi_error legacy_status;
711 legacy_hal::WakeReasonStats legacy_stats;
712 std::tie(legacy_status, legacy_stats) =
713 legacy_hal_.lock()->getWakeReasonStats();
714 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
715 return {createWifiStatusFromLegacyError(legacy_status), {}};
716 }
717 WifiDebugHostWakeReasonStats hidl_stats;
718 if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats,
719 &hidl_stats)) {
720 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
721 }
722 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700723}
724
Roshan Pius203cb032016-12-14 17:41:20 -0800725WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
726 legacy_hal::wifi_error legacy_status;
727 if (enable) {
728 android::wp<WifiChip> weak_ptr_this(this);
729 const auto& on_alert_callback = [weak_ptr_this](
730 int32_t error_code, std::vector<uint8_t> debug_data) {
731 const auto shared_ptr_this = weak_ptr_this.promote();
732 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
733 LOG(ERROR) << "Callback invoked on an invalid object";
734 return;
735 }
736 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
737 callback->onDebugErrorAlert(error_code, debug_data);
738 }
739 };
740 legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
741 on_alert_callback);
742 } else {
743 legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler();
744 }
745 return createWifiStatusFromLegacyError(legacy_status);
746}
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800747
748WifiStatus WifiChip::handleChipConfiguration(ChipModeId mode_id) {
749 // If the chip is already configured in a different mode, stop
750 // the legacy HAL and then start it after firmware mode change.
751 if (current_mode_id_ != kInvalidModeId) {
752 invalidateAndRemoveAllIfaces();
753 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop([]() {});
754 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
755 LOG(ERROR) << "Failed to stop legacy HAL: "
756 << legacyErrorToString(legacy_status);
757 return createWifiStatusFromLegacyError(legacy_status);
758 }
759 }
760 bool success;
761 if (mode_id == kStaChipModeId) {
762 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
763 } else {
764 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
765 }
766 if (!success) {
767 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
768 }
769 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
770 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
771 LOG(ERROR) << "Failed to start legacy HAL: "
772 << legacyErrorToString(legacy_status);
773 return createWifiStatusFromLegacyError(legacy_status);
774 }
775 return createWifiStatus(WifiStatusCode::SUCCESS);
776}
Roshan Pius79a99752016-10-04 13:03:58 -0700777} // namespace implementation
778} // namespace V1_0
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700779} // namespace wifi
780} // namespace hardware
781} // namespace android