blob: 41b386c531d3c0d7e1b760c18c32cb5e10ce5bf8 [file] [log] [blame]
Gabriel Birenf3262f92022-07-15 23:25:39 +00001/*
2 * Copyright (C) 2022 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
17#include "wifi_chip.h"
18
19#include <android-base/logging.h>
20#include <android-base/unique_fd.h>
21#include <cutils/properties.h>
22#include <fcntl.h>
23#include <net/if.h>
24#include <sys/stat.h>
25#include <sys/sysmacros.h>
26
27#include "aidl_return_util.h"
28#include "aidl_struct_util.h"
maheshkkva8aba172023-02-13 12:33:26 -080029#include "wifi_legacy_hal.h"
Gabriel Birenf3262f92022-07-15 23:25:39 +000030#include "wifi_status_util.h"
31
32#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-"
33
34namespace {
Gabriel Birenf3262f92022-07-15 23:25:39 +000035using android::base::unique_fd;
36
Gabriel Birenf3262f92022-07-15 23:25:39 +000037constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3;
38constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10;
39constexpr uint32_t kMaxRingBufferFileNum = 20;
40constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
41constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface";
42constexpr char kNoActiveWlanIfaceNamePropertyValue[] = "";
43constexpr unsigned kMaxWlanIfaces = 5;
44constexpr char kApBridgeIfacePrefix[] = "ap_br_";
45
46template <typename Iface>
47void invalidateAndClear(std::vector<std::shared_ptr<Iface>>& ifaces, std::shared_ptr<Iface> iface) {
48 iface->invalidate();
49 ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), ifaces.end());
50}
51
52template <typename Iface>
53void invalidateAndClearAll(std::vector<std::shared_ptr<Iface>>& ifaces) {
54 for (const auto& iface : ifaces) {
55 iface->invalidate();
56 }
57 ifaces.clear();
58}
59
60template <typename Iface>
61std::vector<std::string> getNames(std::vector<std::shared_ptr<Iface>>& ifaces) {
62 std::vector<std::string> names;
63 for (const auto& iface : ifaces) {
64 names.emplace_back(iface->getName());
65 }
66 return names;
67}
68
69template <typename Iface>
70std::shared_ptr<Iface> findUsingName(std::vector<std::shared_ptr<Iface>>& ifaces,
71 const std::string& name) {
72 std::vector<std::string> names;
73 for (const auto& iface : ifaces) {
74 if (name == iface->getName()) {
75 return iface;
76 }
77 }
78 return nullptr;
79}
80
81std::string getWlanIfaceName(unsigned idx) {
82 if (idx >= kMaxWlanIfaces) {
83 CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
84 return {};
85 }
86
87 std::array<char, PROPERTY_VALUE_MAX> buffer;
88 if (idx == 0 || idx == 1) {
89 const char* altPropName = (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
90 auto res = property_get(altPropName, buffer.data(), nullptr);
91 if (res > 0) return buffer.data();
92 }
93 std::string propName = "wifi.interface." + std::to_string(idx);
94 auto res = property_get(propName.c_str(), buffer.data(), nullptr);
95 if (res > 0) return buffer.data();
96
97 return "wlan" + std::to_string(idx);
98}
99
100// Returns the dedicated iface name if defined.
101// Returns two ifaces in bridged mode.
102std::vector<std::string> getPredefinedApIfaceNames(bool is_bridged) {
103 std::vector<std::string> ifnames;
104 std::array<char, PROPERTY_VALUE_MAX> buffer;
105 buffer.fill(0);
106 if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == 0) {
107 return ifnames;
108 }
109 ifnames.push_back(buffer.data());
110 if (is_bridged) {
111 buffer.fill(0);
112 if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), nullptr) == 0) {
113 return ifnames;
114 }
115 ifnames.push_back(buffer.data());
116 }
117 return ifnames;
118}
119
120std::string getPredefinedP2pIfaceName() {
121 std::array<char, PROPERTY_VALUE_MAX> primaryIfaceName;
122 char p2pParentIfname[100];
123 std::string p2pDevIfName = "";
124 std::array<char, PROPERTY_VALUE_MAX> buffer;
125 property_get("wifi.direct.interface", buffer.data(), "p2p0");
126 if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX, strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
127 /* Get the p2p parent interface name from p2p device interface name set
128 * in property */
129 strlcpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX),
130 strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX));
131 if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(), nullptr) == 0) {
132 return buffer.data();
133 }
134 /* Check if the parent interface derived from p2p device interface name
135 * is active */
136 if (strncmp(p2pParentIfname, primaryIfaceName.data(),
137 strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) != 0) {
138 /*
139 * Update the predefined p2p device interface parent interface name
140 * with current active wlan interface
141 */
142 p2pDevIfName += P2P_MGMT_DEVICE_PREFIX;
143 p2pDevIfName += primaryIfaceName.data();
144 LOG(INFO) << "update the p2p device interface name to " << p2pDevIfName.c_str();
145 return p2pDevIfName;
146 }
147 }
148 return buffer.data();
149}
150
151// Returns the dedicated iface name if one is defined.
152std::string getPredefinedNanIfaceName() {
153 std::array<char, PROPERTY_VALUE_MAX> buffer;
154 if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) {
155 return {};
156 }
157 return buffer.data();
158}
159
160void setActiveWlanIfaceNameProperty(const std::string& ifname) {
161 auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data());
162 if (res != 0) {
163 PLOG(ERROR) << "Failed to set active wlan iface name property";
164 }
165}
166
167// Delete files that meet either condition:
168// 1. Older than a predefined time in the wifi tombstone dir.
169// 2. Files in excess to a predefined amount, starting from the oldest ones
170bool removeOldFilesInternal() {
171 time_t now = time(0);
172 const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
173 std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(kTombstoneFolderPath), closedir);
174 if (!dir_dump) {
175 PLOG(ERROR) << "Failed to open directory";
176 return false;
177 }
178 struct dirent* dp;
179 bool success = true;
180 std::list<std::pair<const time_t, std::string>> valid_files;
181 while ((dp = readdir(dir_dump.get()))) {
182 if (dp->d_type != DT_REG) {
183 continue;
184 }
185 std::string cur_file_name(dp->d_name);
186 struct stat cur_file_stat;
187 std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
188 if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) {
189 PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
190 success = false;
191 continue;
192 }
193 const time_t cur_file_time = cur_file_stat.st_mtime;
194 valid_files.push_back(std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
195 }
196 valid_files.sort(); // sort the list of files by last modified time from
197 // small to big.
198 uint32_t cur_file_count = valid_files.size();
199 for (auto cur_file : valid_files) {
200 if (cur_file_count > kMaxRingBufferFileNum || cur_file.first < delete_files_before) {
201 if (unlink(cur_file.second.c_str()) != 0) {
202 PLOG(ERROR) << "Error deleting file";
203 success = false;
204 }
205 cur_file_count--;
206 } else {
207 break;
208 }
209 }
210 return success;
211}
212
Gabriel Birenf3262f92022-07-15 23:25:39 +0000213// Helper function to create a non-const char*.
214std::vector<char> makeCharVec(const std::string& str) {
215 std::vector<char> vec(str.size() + 1);
216 vec.assign(str.begin(), str.end());
217 vec.push_back('\0');
218 return vec;
219}
220
221} // namespace
222
223namespace aidl {
224namespace android {
225namespace hardware {
226namespace wifi {
227using aidl_return_util::validateAndCall;
228using aidl_return_util::validateAndCallWithLock;
229
230WifiChip::WifiChip(int32_t chip_id, bool is_primary,
231 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
232 const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
233 const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
234 const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
Gabriel Biren989c78a2023-06-14 22:42:07 +0000235 const std::function<void(const std::string&)>& handler,
236 bool using_dynamic_iface_combination)
Gabriel Birenf3262f92022-07-15 23:25:39 +0000237 : chip_id_(chip_id),
238 legacy_hal_(legacy_hal),
239 mode_controller_(mode_controller),
240 iface_util_(iface_util),
241 is_valid_(true),
242 current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
243 modes_(feature_flags.lock()->getChipModes(is_primary)),
244 debug_ring_buffer_cb_registered_(false),
Gabriel Biren989c78a2023-06-14 22:42:07 +0000245 using_dynamic_iface_combination_(using_dynamic_iface_combination),
Gabriel Birenf3262f92022-07-15 23:25:39 +0000246 subsystemCallbackHandler_(handler) {
247 setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
Sunil Ravi2be1f262023-02-15 20:56:56 +0000248}
249
250void WifiChip::retrieveDynamicIfaceCombination() {
251 if (using_dynamic_iface_combination_) return;
252
253 legacy_hal::wifi_iface_concurrency_matrix legacy_matrix;
254 legacy_hal::wifi_error legacy_status;
255
256 std::tie(legacy_status, legacy_matrix) =
257 legacy_hal_.lock()->getSupportedIfaceConcurrencyMatrix();
258 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
259 LOG(ERROR) << "Failed to get SupportedIfaceCombinations matrix from legacy HAL: "
260 << legacyErrorToString(legacy_status);
261 return;
262 }
263
264 IWifiChip::ChipMode aidl_chip_mode;
265 if (!aidl_struct_util::convertLegacyIfaceCombinationsMatrixToChipMode(legacy_matrix,
266 &aidl_chip_mode)) {
267 LOG(ERROR) << "Failed convertLegacyIfaceCombinationsMatrixToChipMode() ";
268 return;
269 }
270
271 LOG(INFO) << "Reloading iface concurrency combination from driver";
272 aidl_chip_mode.id = feature_flags::chip_mode_ids::kV3;
273 modes_.clear();
274 modes_.push_back(aidl_chip_mode);
275 using_dynamic_iface_combination_ = true;
Gabriel Birenf3262f92022-07-15 23:25:39 +0000276}
277
278std::shared_ptr<WifiChip> WifiChip::create(
279 int32_t chip_id, bool is_primary, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
280 const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
281 const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
282 const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
Gabriel Biren989c78a2023-06-14 22:42:07 +0000283 const std::function<void(const std::string&)>& handler,
284 bool using_dynamic_iface_combination) {
Gabriel Birenf3262f92022-07-15 23:25:39 +0000285 std::shared_ptr<WifiChip> ptr = ndk::SharedRefBase::make<WifiChip>(
Gabriel Biren989c78a2023-06-14 22:42:07 +0000286 chip_id, is_primary, legacy_hal, mode_controller, iface_util, feature_flags, handler,
287 using_dynamic_iface_combination);
Gabriel Birenf3262f92022-07-15 23:25:39 +0000288 std::weak_ptr<WifiChip> weak_ptr_this(ptr);
289 ptr->setWeakPtr(weak_ptr_this);
290 return ptr;
291}
292
293void WifiChip::invalidate() {
294 if (!writeRingbufferFilesInternal()) {
295 LOG(ERROR) << "Error writing files to flash";
296 }
297 invalidateAndRemoveAllIfaces();
298 setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
299 legacy_hal_.reset();
300 event_cb_handler_.invalidate();
301 is_valid_ = false;
302}
303
304void WifiChip::setWeakPtr(std::weak_ptr<WifiChip> ptr) {
305 weak_ptr_this_ = ptr;
306}
307
308bool WifiChip::isValid() {
309 return is_valid_;
310}
311
312std::set<std::shared_ptr<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
313 return event_cb_handler_.getCallbacks();
314}
315
316ndk::ScopedAStatus WifiChip::getId(int32_t* _aidl_return) {
317 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getIdInternal,
318 _aidl_return);
319}
320
321ndk::ScopedAStatus WifiChip::registerEventCallback(
322 const std::shared_ptr<IWifiChipEventCallback>& event_callback) {
323 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
324 &WifiChip::registerEventCallbackInternal, event_callback);
325}
326
Gabriel Biren2f862492023-03-09 19:13:07 +0000327ndk::ScopedAStatus WifiChip::getFeatureSet(int32_t* _aidl_return) {
Gabriel Birenf3262f92022-07-15 23:25:39 +0000328 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren2f862492023-03-09 19:13:07 +0000329 &WifiChip::getFeatureSetInternal, _aidl_return);
Gabriel Birenf3262f92022-07-15 23:25:39 +0000330}
331
332ndk::ScopedAStatus WifiChip::getAvailableModes(std::vector<IWifiChip::ChipMode>* _aidl_return) {
333 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
334 &WifiChip::getAvailableModesInternal, _aidl_return);
335}
336
337ndk::ScopedAStatus WifiChip::configureChip(int32_t in_modeId) {
338 return validateAndCallWithLock(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
339 &WifiChip::configureChipInternal, in_modeId);
340}
341
342ndk::ScopedAStatus WifiChip::getMode(int32_t* _aidl_return) {
343 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
344 &WifiChip::getModeInternal, _aidl_return);
345}
346
347ndk::ScopedAStatus WifiChip::requestChipDebugInfo(IWifiChip::ChipDebugInfo* _aidl_return) {
348 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
349 &WifiChip::requestChipDebugInfoInternal, _aidl_return);
350}
351
352ndk::ScopedAStatus WifiChip::requestDriverDebugDump(std::vector<uint8_t>* _aidl_return) {
353 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
354 &WifiChip::requestDriverDebugDumpInternal, _aidl_return);
355}
356
357ndk::ScopedAStatus WifiChip::requestFirmwareDebugDump(std::vector<uint8_t>* _aidl_return) {
358 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
359 &WifiChip::requestFirmwareDebugDumpInternal, _aidl_return);
360}
361
362ndk::ScopedAStatus WifiChip::createApIface(std::shared_ptr<IWifiApIface>* _aidl_return) {
363 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
364 &WifiChip::createApIfaceInternal, _aidl_return);
365}
366
367ndk::ScopedAStatus WifiChip::createBridgedApIface(std::shared_ptr<IWifiApIface>* _aidl_return) {
368 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
369 &WifiChip::createBridgedApIfaceInternal, _aidl_return);
370}
371
372ndk::ScopedAStatus WifiChip::getApIfaceNames(std::vector<std::string>* _aidl_return) {
373 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
374 &WifiChip::getApIfaceNamesInternal, _aidl_return);
375}
376
377ndk::ScopedAStatus WifiChip::getApIface(const std::string& in_ifname,
378 std::shared_ptr<IWifiApIface>* _aidl_return) {
379 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
380 &WifiChip::getApIfaceInternal, _aidl_return, in_ifname);
381}
382
383ndk::ScopedAStatus WifiChip::removeApIface(const std::string& in_ifname) {
384 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
385 &WifiChip::removeApIfaceInternal, in_ifname);
386}
387
388ndk::ScopedAStatus WifiChip::removeIfaceInstanceFromBridgedApIface(
389 const std::string& in_brIfaceName, const std::string& in_ifaceInstanceName) {
390 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
391 &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, in_brIfaceName,
392 in_ifaceInstanceName);
393}
394
395ndk::ScopedAStatus WifiChip::createNanIface(std::shared_ptr<IWifiNanIface>* _aidl_return) {
396 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
397 &WifiChip::createNanIfaceInternal, _aidl_return);
398}
399
400ndk::ScopedAStatus WifiChip::getNanIfaceNames(std::vector<std::string>* _aidl_return) {
401 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
402 &WifiChip::getNanIfaceNamesInternal, _aidl_return);
403}
404
405ndk::ScopedAStatus WifiChip::getNanIface(const std::string& in_ifname,
406 std::shared_ptr<IWifiNanIface>* _aidl_return) {
407 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
408 &WifiChip::getNanIfaceInternal, _aidl_return, in_ifname);
409}
410
411ndk::ScopedAStatus WifiChip::removeNanIface(const std::string& in_ifname) {
412 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
413 &WifiChip::removeNanIfaceInternal, in_ifname);
414}
415
416ndk::ScopedAStatus WifiChip::createP2pIface(std::shared_ptr<IWifiP2pIface>* _aidl_return) {
417 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
418 &WifiChip::createP2pIfaceInternal, _aidl_return);
419}
420
421ndk::ScopedAStatus WifiChip::getP2pIfaceNames(std::vector<std::string>* _aidl_return) {
422 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
423 &WifiChip::getP2pIfaceNamesInternal, _aidl_return);
424}
425
426ndk::ScopedAStatus WifiChip::getP2pIface(const std::string& in_ifname,
427 std::shared_ptr<IWifiP2pIface>* _aidl_return) {
428 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
429 &WifiChip::getP2pIfaceInternal, _aidl_return, in_ifname);
430}
431
432ndk::ScopedAStatus WifiChip::removeP2pIface(const std::string& in_ifname) {
433 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
434 &WifiChip::removeP2pIfaceInternal, in_ifname);
435}
436
437ndk::ScopedAStatus WifiChip::createStaIface(std::shared_ptr<IWifiStaIface>* _aidl_return) {
438 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
439 &WifiChip::createStaIfaceInternal, _aidl_return);
440}
441
442ndk::ScopedAStatus WifiChip::getStaIfaceNames(std::vector<std::string>* _aidl_return) {
443 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
444 &WifiChip::getStaIfaceNamesInternal, _aidl_return);
445}
446
447ndk::ScopedAStatus WifiChip::getStaIface(const std::string& in_ifname,
448 std::shared_ptr<IWifiStaIface>* _aidl_return) {
449 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
450 &WifiChip::getStaIfaceInternal, _aidl_return, in_ifname);
451}
452
453ndk::ScopedAStatus WifiChip::removeStaIface(const std::string& in_ifname) {
454 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
455 &WifiChip::removeStaIfaceInternal, in_ifname);
456}
457
458ndk::ScopedAStatus WifiChip::createRttController(
459 const std::shared_ptr<IWifiStaIface>& in_boundIface,
460 std::shared_ptr<IWifiRttController>* _aidl_return) {
461 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
462 &WifiChip::createRttControllerInternal, _aidl_return, in_boundIface);
463}
464
465ndk::ScopedAStatus WifiChip::getDebugRingBuffersStatus(
466 std::vector<WifiDebugRingBufferStatus>* _aidl_return) {
467 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
468 &WifiChip::getDebugRingBuffersStatusInternal, _aidl_return);
469}
470
471ndk::ScopedAStatus WifiChip::startLoggingToDebugRingBuffer(
472 const std::string& in_ringName, WifiDebugRingBufferVerboseLevel in_verboseLevel,
473 int32_t in_maxIntervalInSec, int32_t in_minDataSizeInBytes) {
474 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
475 &WifiChip::startLoggingToDebugRingBufferInternal, in_ringName,
476 in_verboseLevel, in_maxIntervalInSec, in_minDataSizeInBytes);
477}
478
479ndk::ScopedAStatus WifiChip::forceDumpToDebugRingBuffer(const std::string& in_ringName) {
480 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
481 &WifiChip::forceDumpToDebugRingBufferInternal, in_ringName);
482}
483
484ndk::ScopedAStatus WifiChip::flushRingBufferToFile() {
485 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
486 &WifiChip::flushRingBufferToFileInternal);
487}
488
489ndk::ScopedAStatus WifiChip::stopLoggingToDebugRingBuffer() {
490 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
491 &WifiChip::stopLoggingToDebugRingBufferInternal);
492}
493
494ndk::ScopedAStatus WifiChip::getDebugHostWakeReasonStats(
495 WifiDebugHostWakeReasonStats* _aidl_return) {
496 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
497 &WifiChip::getDebugHostWakeReasonStatsInternal, _aidl_return);
498}
499
500ndk::ScopedAStatus WifiChip::enableDebugErrorAlerts(bool in_enable) {
501 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
502 &WifiChip::enableDebugErrorAlertsInternal, in_enable);
503}
504
505ndk::ScopedAStatus WifiChip::selectTxPowerScenario(IWifiChip::TxPowerScenario in_scenario) {
506 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
507 &WifiChip::selectTxPowerScenarioInternal, in_scenario);
508}
509
510ndk::ScopedAStatus WifiChip::resetTxPowerScenario() {
511 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
512 &WifiChip::resetTxPowerScenarioInternal);
513}
514
515ndk::ScopedAStatus WifiChip::setLatencyMode(IWifiChip::LatencyMode in_mode) {
516 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
517 &WifiChip::setLatencyModeInternal, in_mode);
518}
519
Hsiu-Chang Chen802828f2023-10-21 03:16:10 +0800520binder_status_t WifiChip::dump(int fd __unused, const char**, uint32_t) {
Gabriel Birenf3262f92022-07-15 23:25:39 +0000521 {
522 std::unique_lock<std::mutex> lk(lock_t);
523 for (const auto& item : ringbuffer_map_) {
524 forceDumpToDebugRingBufferInternal(item.first);
525 }
526 // unique_lock unlocked here
527 }
528 usleep(100 * 1000); // sleep for 100 milliseconds to wait for
529 // ringbuffer updates.
530 if (!writeRingbufferFilesInternal()) {
531 LOG(ERROR) << "Error writing files to flash";
532 }
Gabriel Birenf3262f92022-07-15 23:25:39 +0000533 return STATUS_OK;
534}
535
536ndk::ScopedAStatus WifiChip::setMultiStaPrimaryConnection(const std::string& in_ifName) {
537 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
538 &WifiChip::setMultiStaPrimaryConnectionInternal, in_ifName);
539}
540
541ndk::ScopedAStatus WifiChip::setMultiStaUseCase(IWifiChip::MultiStaUseCase in_useCase) {
542 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
543 &WifiChip::setMultiStaUseCaseInternal, in_useCase);
544}
545
546ndk::ScopedAStatus WifiChip::setCoexUnsafeChannels(
547 const std::vector<IWifiChip::CoexUnsafeChannel>& in_unsafeChannels,
Gabriel Biren3b86a782023-02-04 00:42:53 +0000548 int32_t in_restrictions) {
Gabriel Birenf3262f92022-07-15 23:25:39 +0000549 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
550 &WifiChip::setCoexUnsafeChannelsInternal, in_unsafeChannels,
551 in_restrictions);
552}
553
554ndk::ScopedAStatus WifiChip::setCountryCode(const std::array<uint8_t, 2>& in_code) {
555 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
556 &WifiChip::setCountryCodeInternal, in_code);
557}
558
Gabriel Biren3b86a782023-02-04 00:42:53 +0000559ndk::ScopedAStatus WifiChip::getUsableChannels(WifiBand in_band, int32_t in_ifaceModeMask,
560 int32_t in_filterMask,
Gabriel Birenf3262f92022-07-15 23:25:39 +0000561 std::vector<WifiUsableChannel>* _aidl_return) {
562 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
563 &WifiChip::getUsableChannelsInternal, _aidl_return, in_band,
564 in_ifaceModeMask, in_filterMask);
565}
566
Oscar Shuab8313c2022-12-13 00:55:11 +0000567ndk::ScopedAStatus WifiChip::setAfcChannelAllowance(
Oscar Shu4275c872023-03-08 22:48:09 +0000568 const AfcChannelAllowance& afcChannelAllowance) {
Oscar Shuab8313c2022-12-13 00:55:11 +0000569 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Oscar Shu4275c872023-03-08 22:48:09 +0000570 &WifiChip::setAfcChannelAllowanceInternal, afcChannelAllowance);
Oscar Shuab8313c2022-12-13 00:55:11 +0000571}
572
Gabriel Birenf3262f92022-07-15 23:25:39 +0000573ndk::ScopedAStatus WifiChip::triggerSubsystemRestart() {
574 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
575 &WifiChip::triggerSubsystemRestartInternal);
576}
577
Gabriel Biren263db452023-02-24 21:07:38 +0000578ndk::ScopedAStatus WifiChip::getSupportedRadioCombinations(
579 std::vector<WifiRadioCombination>* _aidl_return) {
Gabriel Birenf3262f92022-07-15 23:25:39 +0000580 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren263db452023-02-24 21:07:38 +0000581 &WifiChip::getSupportedRadioCombinationsInternal, _aidl_return);
Gabriel Birenf3262f92022-07-15 23:25:39 +0000582}
583
Mahesh KKVc84d3772022-12-02 16:53:28 -0800584ndk::ScopedAStatus WifiChip::getWifiChipCapabilities(WifiChipCapabilities* _aidl_return) {
585 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
586 &WifiChip::getWifiChipCapabilitiesInternal, _aidl_return);
587}
588
Gabriel Biren3b86a782023-02-04 00:42:53 +0000589ndk::ScopedAStatus WifiChip::enableStaChannelForPeerNetwork(int32_t in_channelCategoryEnableFlag) {
Shuibing Daie5fbcab2022-12-19 15:37:19 -0800590 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
591 &WifiChip::enableStaChannelForPeerNetworkInternal,
592 in_channelCategoryEnableFlag);
593}
594
maheshkkva8aba172023-02-13 12:33:26 -0800595ndk::ScopedAStatus WifiChip::setMloMode(const ChipMloMode in_mode) {
596 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
597 &WifiChip::setMloModeInternal, in_mode);
598}
599
Gabriel Birenf3262f92022-07-15 23:25:39 +0000600void WifiChip::invalidateAndRemoveAllIfaces() {
601 invalidateAndClearBridgedApAll();
602 invalidateAndClearAll(ap_ifaces_);
603 invalidateAndClearAll(nan_ifaces_);
604 invalidateAndClearAll(p2p_ifaces_);
605 invalidateAndClearAll(sta_ifaces_);
606 // Since all the ifaces are invalid now, all RTT controller objects
607 // using those ifaces also need to be invalidated.
608 for (const auto& rtt : rtt_controllers_) {
609 rtt->invalidate();
610 }
611 rtt_controllers_.clear();
612}
613
614void WifiChip::invalidateAndRemoveDependencies(const std::string& removed_iface_name) {
615 for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) {
616 auto nan_iface = *it;
617 if (nan_iface->getName() == removed_iface_name) {
618 nan_iface->invalidate();
619 for (const auto& callback : event_cb_handler_.getCallbacks()) {
620 if (!callback->onIfaceRemoved(IfaceType::NAN_IFACE, removed_iface_name).isOk()) {
621 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
622 }
623 }
624 it = nan_ifaces_.erase(it);
625 } else {
626 ++it;
627 }
628 }
629
630 for (auto it = rtt_controllers_.begin(); it != rtt_controllers_.end();) {
631 auto rtt = *it;
632 if (rtt->getIfaceName() == removed_iface_name) {
633 rtt->invalidate();
634 it = rtt_controllers_.erase(it);
635 } else {
636 ++it;
637 }
638 }
639}
640
641std::pair<int32_t, ndk::ScopedAStatus> WifiChip::getIdInternal() {
642 return {chip_id_, ndk::ScopedAStatus::ok()};
643}
644
645ndk::ScopedAStatus WifiChip::registerEventCallbackInternal(
646 const std::shared_ptr<IWifiChipEventCallback>& event_callback) {
647 if (!event_cb_handler_.addCallback(event_callback)) {
648 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
649 }
650 return ndk::ScopedAStatus::ok();
651}
652
Gabriel Biren2f862492023-03-09 19:13:07 +0000653std::pair<int32_t, ndk::ScopedAStatus> WifiChip::getFeatureSetInternal() {
Gabriel Birenf3262f92022-07-15 23:25:39 +0000654 legacy_hal::wifi_error legacy_status;
655 uint64_t legacy_feature_set;
656 uint32_t legacy_logger_feature_set;
657 const auto ifname = getFirstActiveWlanIfaceName();
658 std::tie(legacy_status, legacy_feature_set) =
659 legacy_hal_.lock()->getSupportedFeatureSet(ifname);
660 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Gabriel Biren3b86a782023-02-04 00:42:53 +0000661 return {0, createWifiStatusFromLegacyError(legacy_status)};
Gabriel Birenf3262f92022-07-15 23:25:39 +0000662 }
663 std::tie(legacy_status, legacy_logger_feature_set) =
664 legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
665 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
666 // some devices don't support querying logger feature set
667 legacy_logger_feature_set = 0;
668 }
Gabriel Biren2f862492023-03-09 19:13:07 +0000669 uint32_t aidl_feature_set;
670 if (!aidl_struct_util::convertLegacyChipFeaturesToAidl(legacy_feature_set, &aidl_feature_set)) {
Gabriel Biren3b86a782023-02-04 00:42:53 +0000671 return {0, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
Gabriel Birenf3262f92022-07-15 23:25:39 +0000672 }
Gabriel Biren2f862492023-03-09 19:13:07 +0000673 return {aidl_feature_set, ndk::ScopedAStatus::ok()};
Gabriel Birenf3262f92022-07-15 23:25:39 +0000674}
675
676std::pair<std::vector<IWifiChip::ChipMode>, ndk::ScopedAStatus>
677WifiChip::getAvailableModesInternal() {
678 return {modes_, ndk::ScopedAStatus::ok()};
679}
680
681ndk::ScopedAStatus WifiChip::configureChipInternal(
682 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, int32_t mode_id) {
683 if (!isValidModeId(mode_id)) {
684 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
685 }
686 if (mode_id == current_mode_id_) {
687 LOG(DEBUG) << "Already in the specified mode " << mode_id;
688 return ndk::ScopedAStatus::ok();
689 }
690 ndk::ScopedAStatus status = handleChipConfiguration(lock, mode_id);
691 if (!status.isOk()) {
692 WifiStatusCode errorCode = static_cast<WifiStatusCode>(status.getServiceSpecificError());
693 for (const auto& callback : event_cb_handler_.getCallbacks()) {
694 if (!callback->onChipReconfigureFailure(errorCode).isOk()) {
695 LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback";
696 }
697 }
698 return status;
699 }
700 for (const auto& callback : event_cb_handler_.getCallbacks()) {
701 if (!callback->onChipReconfigured(mode_id).isOk()) {
702 LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
703 }
704 }
705 current_mode_id_ = mode_id;
706 LOG(INFO) << "Configured chip in mode " << mode_id;
707 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
708
709 legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(subsystemCallbackHandler_);
710
711 return status;
712}
713
714std::pair<int32_t, ndk::ScopedAStatus> WifiChip::getModeInternal() {
715 if (!isValidModeId(current_mode_id_)) {
716 return {current_mode_id_, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
717 }
718 return {current_mode_id_, ndk::ScopedAStatus::ok()};
719}
720
721std::pair<IWifiChip::ChipDebugInfo, ndk::ScopedAStatus> WifiChip::requestChipDebugInfoInternal() {
722 IWifiChip::ChipDebugInfo result;
723 legacy_hal::wifi_error legacy_status;
724 std::string driver_desc;
725 const auto ifname = getFirstActiveWlanIfaceName();
726 std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion(ifname);
727 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
728 LOG(ERROR) << "Failed to get driver version: " << legacyErrorToString(legacy_status);
729 ndk::ScopedAStatus status =
730 createWifiStatusFromLegacyError(legacy_status, "failed to get driver version");
731 return {std::move(result), std::move(status)};
732 }
733 result.driverDescription = driver_desc.c_str();
734
735 std::string firmware_desc;
736 std::tie(legacy_status, firmware_desc) = legacy_hal_.lock()->getFirmwareVersion(ifname);
737 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
738 LOG(ERROR) << "Failed to get firmware version: " << legacyErrorToString(legacy_status);
739 ndk::ScopedAStatus status =
740 createWifiStatusFromLegacyError(legacy_status, "failed to get firmware version");
741 return {std::move(result), std::move(status)};
742 }
743 result.firmwareDescription = firmware_desc.c_str();
744
745 return {std::move(result), ndk::ScopedAStatus::ok()};
746}
747
748std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> WifiChip::requestDriverDebugDumpInternal() {
749 legacy_hal::wifi_error legacy_status;
750 std::vector<uint8_t> driver_dump;
751 std::tie(legacy_status, driver_dump) =
752 legacy_hal_.lock()->requestDriverMemoryDump(getFirstActiveWlanIfaceName());
753 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
754 LOG(ERROR) << "Failed to get driver debug dump: " << legacyErrorToString(legacy_status);
755 return {std::vector<uint8_t>(), createWifiStatusFromLegacyError(legacy_status)};
756 }
757 return {driver_dump, ndk::ScopedAStatus::ok()};
758}
759
760std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> WifiChip::requestFirmwareDebugDumpInternal() {
761 legacy_hal::wifi_error legacy_status;
762 std::vector<uint8_t> firmware_dump;
763 std::tie(legacy_status, firmware_dump) =
764 legacy_hal_.lock()->requestFirmwareMemoryDump(getFirstActiveWlanIfaceName());
765 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
766 LOG(ERROR) << "Failed to get firmware debug dump: " << legacyErrorToString(legacy_status);
767 return {std::vector<uint8_t>(), createWifiStatusFromLegacyError(legacy_status)};
768 }
769 return {firmware_dump, ndk::ScopedAStatus::ok()};
770}
771
772ndk::ScopedAStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) {
773 legacy_hal::wifi_error legacy_status;
774 legacy_status = legacy_hal_.lock()->createVirtualInterface(
775 apVirtIf, aidl_struct_util::convertAidlIfaceTypeToLegacy(IfaceType::AP));
776 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
777 LOG(ERROR) << "Failed to add interface: " << apVirtIf << " "
778 << legacyErrorToString(legacy_status);
779 return createWifiStatusFromLegacyError(legacy_status);
780 }
781 return ndk::ScopedAStatus::ok();
782}
783
784std::shared_ptr<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) {
785 std::vector<std::string> ap_instances;
786 for (auto const& it : br_ifaces_ap_instances_) {
787 if (it.first == ifname) {
788 ap_instances = it.second;
789 }
790 }
791 std::shared_ptr<WifiApIface> iface =
792 ndk::SharedRefBase::make<WifiApIface>(ifname, ap_instances, legacy_hal_, iface_util_);
793 ap_ifaces_.push_back(iface);
794 for (const auto& callback : event_cb_handler_.getCallbacks()) {
795 if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
796 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
797 }
798 }
799 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
800 return iface;
801}
802
803std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> WifiChip::createApIfaceInternal() {
804 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP)) {
805 return {std::shared_ptr<WifiApIface>(),
806 createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
807 }
808 std::string ifname = allocateApIfaceName();
809 ndk::ScopedAStatus status = createVirtualApInterface(ifname);
810 if (!status.isOk()) {
811 return {std::shared_ptr<WifiApIface>(), std::move(status)};
812 }
813 std::shared_ptr<WifiApIface> iface = newWifiApIface(ifname);
814 return {iface, ndk::ScopedAStatus::ok()};
815}
816
817std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus>
818WifiChip::createBridgedApIfaceInternal() {
819 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP_BRIDGED)) {
820 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
821 }
822 std::vector<std::string> ap_instances = allocateBridgedApInstanceNames();
823 if (ap_instances.size() < 2) {
824 LOG(ERROR) << "Fail to allocate two instances";
825 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
826 }
827 std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0];
828 for (int i = 0; i < 2; i++) {
829 ndk::ScopedAStatus status = createVirtualApInterface(ap_instances[i]);
830 if (!status.isOk()) {
831 if (i != 0) { // The failure happened when creating second virtual
832 // iface.
833 legacy_hal_.lock()->deleteVirtualInterface(
834 ap_instances.front()); // Remove the first virtual iface.
835 }
836 return {nullptr, std::move(status)};
837 }
838 }
839 br_ifaces_ap_instances_[br_ifname] = ap_instances;
840 if (!iface_util_->createBridge(br_ifname)) {
841 LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
Sunil Ravi780bef02023-06-01 21:43:04 +0000842 deleteApIface(br_ifname);
Gabriel Birenf3262f92022-07-15 23:25:39 +0000843 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
844 }
845 for (auto const& instance : ap_instances) {
846 // Bind ap instance interface to AP bridge
847 if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
848 LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str();
Sunil Ravi780bef02023-06-01 21:43:04 +0000849 deleteApIface(br_ifname);
Gabriel Birenf3262f92022-07-15 23:25:39 +0000850 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
851 }
852 }
853 std::shared_ptr<WifiApIface> iface = newWifiApIface(br_ifname);
854 return {iface, ndk::ScopedAStatus::ok()};
855}
856
857std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getApIfaceNamesInternal() {
858 if (ap_ifaces_.empty()) {
859 return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
860 }
861 return {getNames(ap_ifaces_), ndk::ScopedAStatus::ok()};
862}
863
864std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> WifiChip::getApIfaceInternal(
865 const std::string& ifname) {
866 const auto iface = findUsingName(ap_ifaces_, ifname);
867 if (!iface.get()) {
868 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
869 }
870 return {iface, ndk::ScopedAStatus::ok()};
871}
872
873ndk::ScopedAStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
874 const auto iface = findUsingName(ap_ifaces_, ifname);
875 if (!iface.get()) {
876 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
877 }
878 // Invalidate & remove any dependent objects first.
879 // Note: This is probably not required because we never create
880 // nan/rtt objects over AP iface. But, there is no harm to do it
881 // here and not make that assumption all over the place.
882 invalidateAndRemoveDependencies(ifname);
Sunil Ravi780bef02023-06-01 21:43:04 +0000883 deleteApIface(ifname);
Gabriel Birenf3262f92022-07-15 23:25:39 +0000884 invalidateAndClear(ap_ifaces_, iface);
885 for (const auto& callback : event_cb_handler_.getCallbacks()) {
886 if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
887 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
888 }
889 }
890 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
891 return ndk::ScopedAStatus::ok();
892}
893
894ndk::ScopedAStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
895 const std::string& ifname, const std::string& ifInstanceName) {
896 const auto iface = findUsingName(ap_ifaces_, ifname);
897 if (!iface.get() || ifInstanceName.empty()) {
898 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
899 }
900 // Requires to remove one of the instance in bridge mode
901 for (auto const& it : br_ifaces_ap_instances_) {
902 if (it.first == ifname) {
903 std::vector<std::string> ap_instances = it.second;
904 for (auto const& iface : ap_instances) {
905 if (iface == ifInstanceName) {
906 if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
907 LOG(ERROR) << "Failed to remove interface: " << ifInstanceName << " from "
908 << ifname;
909 return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE);
910 }
911 legacy_hal::wifi_error legacy_status =
912 legacy_hal_.lock()->deleteVirtualInterface(iface);
913 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
914 LOG(ERROR) << "Failed to del interface: " << iface << " "
915 << legacyErrorToString(legacy_status);
916 return createWifiStatusFromLegacyError(legacy_status);
917 }
918 ap_instances.erase(
919 std::remove(ap_instances.begin(), ap_instances.end(), ifInstanceName),
920 ap_instances.end());
921 br_ifaces_ap_instances_[ifname] = ap_instances;
922 break;
923 }
924 }
925 break;
926 }
927 }
928 iface->removeInstance(ifInstanceName);
929 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
930
931 return ndk::ScopedAStatus::ok();
932}
933
934std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> WifiChip::createNanIfaceInternal() {
935 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::NAN_IFACE)) {
936 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
937 }
938 bool is_dedicated_iface = true;
939 std::string ifname = getPredefinedNanIfaceName();
940 if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) {
941 // Use the first shared STA iface (wlan0) if a dedicated aware iface is
942 // not defined.
943 ifname = getFirstActiveWlanIfaceName();
944 is_dedicated_iface = false;
945 }
946 std::shared_ptr<WifiNanIface> iface =
947 WifiNanIface::create(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
948 nan_ifaces_.push_back(iface);
949 for (const auto& callback : event_cb_handler_.getCallbacks()) {
950 if (!callback->onIfaceAdded(IfaceType::NAN_IFACE, ifname).isOk()) {
951 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
952 }
953 }
954 return {iface, ndk::ScopedAStatus::ok()};
955}
956
957std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getNanIfaceNamesInternal() {
958 if (nan_ifaces_.empty()) {
959 return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
960 }
961 return {getNames(nan_ifaces_), ndk::ScopedAStatus::ok()};
962}
963
964std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> WifiChip::getNanIfaceInternal(
965 const std::string& ifname) {
966 const auto iface = findUsingName(nan_ifaces_, ifname);
967 if (!iface.get()) {
968 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
969 }
970 return {iface, ndk::ScopedAStatus::ok()};
971}
972
973ndk::ScopedAStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
974 const auto iface = findUsingName(nan_ifaces_, ifname);
975 if (!iface.get()) {
976 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
977 }
978 invalidateAndClear(nan_ifaces_, iface);
979 for (const auto& callback : event_cb_handler_.getCallbacks()) {
980 if (!callback->onIfaceRemoved(IfaceType::NAN_IFACE, ifname).isOk()) {
981 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
982 }
983 }
984 return ndk::ScopedAStatus::ok();
985}
986
987std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> WifiChip::createP2pIfaceInternal() {
988 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::P2P)) {
989 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
990 }
991 std::string ifname = getPredefinedP2pIfaceName();
992 std::shared_ptr<WifiP2pIface> iface =
993 ndk::SharedRefBase::make<WifiP2pIface>(ifname, legacy_hal_);
994 p2p_ifaces_.push_back(iface);
995 for (const auto& callback : event_cb_handler_.getCallbacks()) {
996 if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
997 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
998 }
999 }
1000 return {iface, ndk::ScopedAStatus::ok()};
1001}
1002
1003std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getP2pIfaceNamesInternal() {
1004 if (p2p_ifaces_.empty()) {
1005 return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
1006 }
1007 return {getNames(p2p_ifaces_), ndk::ScopedAStatus::ok()};
1008}
1009
1010std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> WifiChip::getP2pIfaceInternal(
1011 const std::string& ifname) {
1012 const auto iface = findUsingName(p2p_ifaces_, ifname);
1013 if (!iface.get()) {
1014 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
1015 }
1016 return {iface, ndk::ScopedAStatus::ok()};
1017}
1018
1019ndk::ScopedAStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
1020 const auto iface = findUsingName(p2p_ifaces_, ifname);
1021 if (!iface.get()) {
1022 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1023 }
1024 invalidateAndClear(p2p_ifaces_, iface);
1025 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1026 if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
1027 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1028 }
1029 }
1030 return ndk::ScopedAStatus::ok();
1031}
1032
1033std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> WifiChip::createStaIfaceInternal() {
1034 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
1035 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
1036 }
1037 std::string ifname = allocateStaIfaceName();
1038 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->createVirtualInterface(
1039 ifname, aidl_struct_util::convertAidlIfaceTypeToLegacy(IfaceType::STA));
1040 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1041 LOG(ERROR) << "Failed to add interface: " << ifname << " "
1042 << legacyErrorToString(legacy_status);
1043 return {nullptr, createWifiStatusFromLegacyError(legacy_status)};
1044 }
Gabriel Biren2f7bec812023-01-31 01:07:38 +00001045 std::shared_ptr<WifiStaIface> iface = WifiStaIface::create(ifname, legacy_hal_, iface_util_);
Gabriel Birenf3262f92022-07-15 23:25:39 +00001046 sta_ifaces_.push_back(iface);
1047 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1048 if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
1049 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1050 }
1051 }
1052 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1053 return {iface, ndk::ScopedAStatus::ok()};
1054}
1055
1056std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getStaIfaceNamesInternal() {
1057 if (sta_ifaces_.empty()) {
1058 return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
1059 }
1060 return {getNames(sta_ifaces_), ndk::ScopedAStatus::ok()};
1061}
1062
1063std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> WifiChip::getStaIfaceInternal(
1064 const std::string& ifname) {
1065 const auto iface = findUsingName(sta_ifaces_, ifname);
1066 if (!iface.get()) {
1067 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
1068 }
1069 return {iface, ndk::ScopedAStatus::ok()};
1070}
1071
1072ndk::ScopedAStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
1073 const auto iface = findUsingName(sta_ifaces_, ifname);
1074 if (!iface.get()) {
1075 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1076 }
1077 // Invalidate & remove any dependent objects first.
1078 invalidateAndRemoveDependencies(ifname);
1079 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(ifname);
1080 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1081 LOG(ERROR) << "Failed to remove interface: " << ifname << " "
1082 << legacyErrorToString(legacy_status);
1083 }
1084 invalidateAndClear(sta_ifaces_, iface);
1085 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1086 if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
1087 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1088 }
1089 }
1090 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1091 return ndk::ScopedAStatus::ok();
1092}
1093
1094std::pair<std::shared_ptr<IWifiRttController>, ndk::ScopedAStatus>
1095WifiChip::createRttControllerInternal(const std::shared_ptr<IWifiStaIface>& bound_iface) {
1096 if (sta_ifaces_.size() == 0 &&
1097 !canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
1098 LOG(ERROR) << "createRttControllerInternal: Chip cannot support STAs "
1099 "(and RTT by extension)";
1100 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
1101 }
1102 std::shared_ptr<WifiRttController> rtt =
1103 WifiRttController::create(getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
1104 rtt_controllers_.emplace_back(rtt);
1105 return {rtt, ndk::ScopedAStatus::ok()};
1106}
1107
1108std::pair<std::vector<WifiDebugRingBufferStatus>, ndk::ScopedAStatus>
1109WifiChip::getDebugRingBuffersStatusInternal() {
1110 legacy_hal::wifi_error legacy_status;
1111 std::vector<legacy_hal::wifi_ring_buffer_status> legacy_ring_buffer_status_vec;
1112 std::tie(legacy_status, legacy_ring_buffer_status_vec) =
1113 legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
1114 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1115 return {std::vector<WifiDebugRingBufferStatus>(),
1116 createWifiStatusFromLegacyError(legacy_status)};
1117 }
1118 std::vector<WifiDebugRingBufferStatus> aidl_ring_buffer_status_vec;
1119 if (!aidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToAidl(
1120 legacy_ring_buffer_status_vec, &aidl_ring_buffer_status_vec)) {
1121 return {std::vector<WifiDebugRingBufferStatus>(),
1122 createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
1123 }
1124 return {aidl_ring_buffer_status_vec, ndk::ScopedAStatus::ok()};
1125}
1126
1127ndk::ScopedAStatus WifiChip::startLoggingToDebugRingBufferInternal(
1128 const std::string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
1129 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
1130 ndk::ScopedAStatus status = registerDebugRingBufferCallback();
1131 if (!status.isOk()) {
1132 return status;
1133 }
1134 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRingBufferLogging(
1135 getFirstActiveWlanIfaceName(), ring_name,
1136 static_cast<std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(verbose_level),
1137 max_interval_in_sec, min_data_size_in_bytes);
1138 ringbuffer_map_.insert(
1139 std::pair<std::string, Ringbuffer>(ring_name, Ringbuffer(kMaxBufferSizeBytes)));
1140 // if verbose logging enabled, turn up HAL daemon logging as well.
1141 if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
1142 ::android::base::SetMinimumLogSeverity(::android::base::DEBUG);
1143 } else {
1144 ::android::base::SetMinimumLogSeverity(::android::base::VERBOSE);
1145 }
1146 return createWifiStatusFromLegacyError(legacy_status);
1147}
1148
1149ndk::ScopedAStatus WifiChip::forceDumpToDebugRingBufferInternal(const std::string& ring_name) {
1150 ndk::ScopedAStatus status = registerDebugRingBufferCallback();
1151 if (!status.isOk()) {
1152 return status;
1153 }
1154 legacy_hal::wifi_error legacy_status =
1155 legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), ring_name);
1156
1157 return createWifiStatusFromLegacyError(legacy_status);
1158}
1159
1160ndk::ScopedAStatus WifiChip::flushRingBufferToFileInternal() {
1161 if (!writeRingbufferFilesInternal()) {
1162 LOG(ERROR) << "Error writing files to flash";
1163 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1164 }
1165 return ndk::ScopedAStatus::ok();
1166}
1167
1168ndk::ScopedAStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
1169 legacy_hal::wifi_error legacy_status =
1170 legacy_hal_.lock()->deregisterRingBufferCallbackHandler(getFirstActiveWlanIfaceName());
1171 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1172 debug_ring_buffer_cb_registered_ = false;
1173 }
1174 return createWifiStatusFromLegacyError(legacy_status);
1175}
1176
1177std::pair<WifiDebugHostWakeReasonStats, ndk::ScopedAStatus>
1178WifiChip::getDebugHostWakeReasonStatsInternal() {
1179 legacy_hal::wifi_error legacy_status;
1180 legacy_hal::WakeReasonStats legacy_stats;
1181 std::tie(legacy_status, legacy_stats) =
1182 legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
1183 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1184 return {WifiDebugHostWakeReasonStats{}, createWifiStatusFromLegacyError(legacy_status)};
1185 }
1186 WifiDebugHostWakeReasonStats aidl_stats;
1187 if (!aidl_struct_util::convertLegacyWakeReasonStatsToAidl(legacy_stats, &aidl_stats)) {
1188 return {WifiDebugHostWakeReasonStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
1189 }
1190 return {aidl_stats, ndk::ScopedAStatus::ok()};
1191}
1192
1193ndk::ScopedAStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
1194 legacy_hal::wifi_error legacy_status;
1195 if (enable) {
1196 std::weak_ptr<WifiChip> weak_ptr_this = weak_ptr_this_;
1197 const auto& on_alert_callback = [weak_ptr_this](int32_t error_code,
1198 std::vector<uint8_t> debug_data) {
1199 const auto shared_ptr_this = weak_ptr_this.lock();
1200 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1201 LOG(ERROR) << "Callback invoked on an invalid object";
1202 return;
1203 }
1204 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
1205 if (!callback->onDebugErrorAlert(error_code, debug_data).isOk()) {
1206 LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
1207 }
1208 }
1209 };
1210 legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
1211 getFirstActiveWlanIfaceName(), on_alert_callback);
1212 } else {
1213 legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
1214 getFirstActiveWlanIfaceName());
1215 }
1216 return createWifiStatusFromLegacyError(legacy_status);
1217}
1218
1219ndk::ScopedAStatus WifiChip::selectTxPowerScenarioInternal(IWifiChip::TxPowerScenario scenario) {
1220 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
1221 getFirstActiveWlanIfaceName(),
1222 aidl_struct_util::convertAidlTxPowerScenarioToLegacy(scenario));
1223 return createWifiStatusFromLegacyError(legacy_status);
1224}
1225
1226ndk::ScopedAStatus WifiChip::resetTxPowerScenarioInternal() {
1227 auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
1228 return createWifiStatusFromLegacyError(legacy_status);
1229}
1230
1231ndk::ScopedAStatus WifiChip::setLatencyModeInternal(IWifiChip::LatencyMode mode) {
1232 auto legacy_status = legacy_hal_.lock()->setLatencyMode(
1233 getFirstActiveWlanIfaceName(), aidl_struct_util::convertAidlLatencyModeToLegacy(mode));
1234 return createWifiStatusFromLegacyError(legacy_status);
1235}
1236
1237ndk::ScopedAStatus WifiChip::setMultiStaPrimaryConnectionInternal(const std::string& ifname) {
1238 auto legacy_status = legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname);
1239 return createWifiStatusFromLegacyError(legacy_status);
1240}
1241
1242ndk::ScopedAStatus WifiChip::setMultiStaUseCaseInternal(IWifiChip::MultiStaUseCase use_case) {
1243 auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase(
1244 aidl_struct_util::convertAidlMultiStaUseCaseToLegacy(use_case));
1245 return createWifiStatusFromLegacyError(legacy_status);
1246}
1247
1248ndk::ScopedAStatus WifiChip::setCoexUnsafeChannelsInternal(
Gabriel Biren3b86a782023-02-04 00:42:53 +00001249 std::vector<IWifiChip::CoexUnsafeChannel> unsafe_channels, int32_t aidl_restrictions) {
Gabriel Birenf3262f92022-07-15 23:25:39 +00001250 std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels;
1251 if (!aidl_struct_util::convertAidlVectorOfCoexUnsafeChannelToLegacy(unsafe_channels,
1252 &legacy_unsafe_channels)) {
1253 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1254 }
Gabriel Birenf3262f92022-07-15 23:25:39 +00001255 uint32_t legacy_restrictions = 0;
1256 if (aidl_restrictions & static_cast<uint32_t>(CoexRestriction::WIFI_DIRECT)) {
1257 legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_DIRECT;
1258 }
1259 if (aidl_restrictions & static_cast<uint32_t>(CoexRestriction::SOFTAP)) {
1260 legacy_restrictions |= legacy_hal::wifi_coex_restriction::SOFTAP;
1261 }
1262 if (aidl_restrictions & static_cast<uint32_t>(CoexRestriction::WIFI_AWARE)) {
1263 legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE;
1264 }
1265 auto legacy_status =
1266 legacy_hal_.lock()->setCoexUnsafeChannels(legacy_unsafe_channels, legacy_restrictions);
1267 return createWifiStatusFromLegacyError(legacy_status);
1268}
1269
1270ndk::ScopedAStatus WifiChip::setCountryCodeInternal(const std::array<uint8_t, 2>& code) {
1271 auto legacy_status = legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code);
1272 return createWifiStatusFromLegacyError(legacy_status);
1273}
1274
1275std::pair<std::vector<WifiUsableChannel>, ndk::ScopedAStatus> WifiChip::getUsableChannelsInternal(
Gabriel Biren3b86a782023-02-04 00:42:53 +00001276 WifiBand band, int32_t ifaceModeMask, int32_t filterMask) {
Gabriel Birenf3262f92022-07-15 23:25:39 +00001277 legacy_hal::wifi_error legacy_status;
1278 std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels;
1279 std::tie(legacy_status, legacy_usable_channels) = legacy_hal_.lock()->getUsableChannels(
1280 aidl_struct_util::convertAidlWifiBandToLegacyMacBand(band),
Gabriel Biren3b86a782023-02-04 00:42:53 +00001281 aidl_struct_util::convertAidlWifiIfaceModeToLegacy(ifaceModeMask),
1282 aidl_struct_util::convertAidlUsableChannelFilterToLegacy(filterMask));
Gabriel Birenf3262f92022-07-15 23:25:39 +00001283
1284 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1285 return {std::vector<WifiUsableChannel>(), createWifiStatusFromLegacyError(legacy_status)};
1286 }
1287 std::vector<WifiUsableChannel> aidl_usable_channels;
1288 if (!aidl_struct_util::convertLegacyWifiUsableChannelsToAidl(legacy_usable_channels,
1289 &aidl_usable_channels)) {
1290 return {std::vector<WifiUsableChannel>(), createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
1291 }
1292 return {aidl_usable_channels, ndk::ScopedAStatus::ok()};
1293}
1294
Oscar Shuab8313c2022-12-13 00:55:11 +00001295ndk::ScopedAStatus WifiChip::setAfcChannelAllowanceInternal(
Oscar Shu4275c872023-03-08 22:48:09 +00001296 const AfcChannelAllowance& afcChannelAllowance) {
1297 LOG(INFO) << "setAfcChannelAllowance is not yet supported. availableAfcFrequencyInfos size="
1298 << afcChannelAllowance.availableAfcFrequencyInfos.size()
1299 << " availableAfcChannelInfos size="
1300 << afcChannelAllowance.availableAfcChannelInfos.size()
1301 << " availabilityExpireTimeMs=" << afcChannelAllowance.availabilityExpireTimeMs;
Oscar Shuab8313c2022-12-13 00:55:11 +00001302 return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
1303}
1304
Gabriel Biren263db452023-02-24 21:07:38 +00001305std::pair<std::vector<WifiRadioCombination>, ndk::ScopedAStatus>
1306WifiChip::getSupportedRadioCombinationsInternal() {
Gabriel Birenf3262f92022-07-15 23:25:39 +00001307 legacy_hal::wifi_error legacy_status;
1308 legacy_hal::wifi_radio_combination_matrix* legacy_matrix;
Gabriel Biren263db452023-02-24 21:07:38 +00001309 std::vector<WifiRadioCombination> aidl_combinations;
Gabriel Birenf3262f92022-07-15 23:25:39 +00001310
1311 std::tie(legacy_status, legacy_matrix) =
1312 legacy_hal_.lock()->getSupportedRadioCombinationsMatrix();
1313 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1314 LOG(ERROR) << "Failed to get SupportedRadioCombinations matrix from legacy HAL: "
1315 << legacyErrorToString(legacy_status);
Ye Jiao84310762023-06-16 17:21:01 +08001316 if (legacy_matrix != nullptr) {
1317 free(legacy_matrix);
1318 }
Gabriel Biren263db452023-02-24 21:07:38 +00001319 return {aidl_combinations, createWifiStatusFromLegacyError(legacy_status)};
Gabriel Birenf3262f92022-07-15 23:25:39 +00001320 }
1321
Gabriel Birenf3262f92022-07-15 23:25:39 +00001322 if (!aidl_struct_util::convertLegacyRadioCombinationsMatrixToAidl(legacy_matrix,
Gabriel Biren263db452023-02-24 21:07:38 +00001323 &aidl_combinations)) {
Gabriel Birenf3262f92022-07-15 23:25:39 +00001324 LOG(ERROR) << "Failed convertLegacyRadioCombinationsMatrixToAidl() ";
Ye Jiao84310762023-06-16 17:21:01 +08001325 if (legacy_matrix != nullptr) {
1326 free(legacy_matrix);
1327 }
Gabriel Biren263db452023-02-24 21:07:38 +00001328 return {aidl_combinations, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
Gabriel Birenf3262f92022-07-15 23:25:39 +00001329 }
Ye Jiao84310762023-06-16 17:21:01 +08001330
1331 if (legacy_matrix != nullptr) {
1332 free(legacy_matrix);
1333 }
Gabriel Biren263db452023-02-24 21:07:38 +00001334 return {aidl_combinations, ndk::ScopedAStatus::ok()};
Gabriel Birenf3262f92022-07-15 23:25:39 +00001335}
1336
Mahesh KKVc84d3772022-12-02 16:53:28 -08001337std::pair<WifiChipCapabilities, ndk::ScopedAStatus> WifiChip::getWifiChipCapabilitiesInternal() {
1338 legacy_hal::wifi_error legacy_status;
1339 legacy_hal::wifi_chip_capabilities legacy_chip_capabilities;
1340 std::tie(legacy_status, legacy_chip_capabilities) =
1341 legacy_hal_.lock()->getWifiChipCapabilities();
1342 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1343 LOG(ERROR) << "Failed to get chip capabilities from legacy HAL: "
1344 << legacyErrorToString(legacy_status);
1345 return {WifiChipCapabilities(), createWifiStatusFromLegacyError(legacy_status)};
1346 }
1347 WifiChipCapabilities aidl_chip_capabilities;
1348 if (!aidl_struct_util::convertLegacyWifiChipCapabilitiesToAidl(legacy_chip_capabilities,
1349 aidl_chip_capabilities)) {
1350 LOG(ERROR) << "Failed convertLegacyWifiChipCapabilitiesToAidl() ";
1351 return {WifiChipCapabilities(), createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
1352 }
1353
1354 return {aidl_chip_capabilities, ndk::ScopedAStatus::ok()};
1355}
1356
Shuibing Daie5fbcab2022-12-19 15:37:19 -08001357ndk::ScopedAStatus WifiChip::enableStaChannelForPeerNetworkInternal(
Gabriel Biren3b86a782023-02-04 00:42:53 +00001358 int32_t channelCategoryEnableFlag) {
Shuibing Daie5fbcab2022-12-19 15:37:19 -08001359 auto legacy_status = legacy_hal_.lock()->enableStaChannelForPeerNetwork(
Gabriel Biren3b86a782023-02-04 00:42:53 +00001360 aidl_struct_util::convertAidlChannelCategoryToLegacy(channelCategoryEnableFlag));
Shuibing Daie5fbcab2022-12-19 15:37:19 -08001361 return createWifiStatusFromLegacyError(legacy_status);
1362}
1363
Gabriel Birenf3262f92022-07-15 23:25:39 +00001364ndk::ScopedAStatus WifiChip::triggerSubsystemRestartInternal() {
1365 auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart();
1366 return createWifiStatusFromLegacyError(legacy_status);
1367}
1368
1369ndk::ScopedAStatus WifiChip::handleChipConfiguration(
1370 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, int32_t mode_id) {
1371 // If the chip is already configured in a different mode, stop
1372 // the legacy HAL and then start it after firmware mode change.
1373 if (isValidModeId(current_mode_id_)) {
1374 LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ << " to mode " << mode_id;
1375 invalidateAndRemoveAllIfaces();
1376 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop(lock, []() {});
1377 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1378 LOG(ERROR) << "Failed to stop legacy HAL: " << legacyErrorToString(legacy_status);
1379 return createWifiStatusFromLegacyError(legacy_status);
1380 }
1381 }
1382 // Firmware mode change not needed for V2 devices.
1383 bool success = true;
1384 if (mode_id == feature_flags::chip_mode_ids::kV1Sta) {
1385 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
1386 } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) {
1387 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
1388 }
1389 if (!success) {
1390 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1391 }
1392 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
1393 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1394 LOG(ERROR) << "Failed to start legacy HAL: " << legacyErrorToString(legacy_status);
1395 return createWifiStatusFromLegacyError(legacy_status);
1396 }
1397 // Every time the HAL is restarted, we need to register the
1398 // radio mode change callback.
1399 ndk::ScopedAStatus status = registerRadioModeChangeCallback();
1400 if (!status.isOk()) {
1401 // This is probably not a critical failure?
1402 LOG(ERROR) << "Failed to register radio mode change callback";
1403 }
1404 // Extract and save the version information into property.
1405 std::pair<IWifiChip::ChipDebugInfo, ndk::ScopedAStatus> version_info;
1406 version_info = WifiChip::requestChipDebugInfoInternal();
1407 if (version_info.second.isOk()) {
1408 property_set("vendor.wlan.firmware.version",
1409 version_info.first.firmwareDescription.c_str());
1410 property_set("vendor.wlan.driver.version", version_info.first.driverDescription.c_str());
1411 }
Sunil Ravi2be1f262023-02-15 20:56:56 +00001412 // Get the driver supported interface combination.
1413 retrieveDynamicIfaceCombination();
Gabriel Birenf3262f92022-07-15 23:25:39 +00001414
1415 return ndk::ScopedAStatus::ok();
1416}
1417
1418ndk::ScopedAStatus WifiChip::registerDebugRingBufferCallback() {
1419 if (debug_ring_buffer_cb_registered_) {
1420 return ndk::ScopedAStatus::ok();
1421 }
1422
1423 std::weak_ptr<WifiChip> weak_ptr_this = weak_ptr_this_;
1424 const auto& on_ring_buffer_data_callback =
1425 [weak_ptr_this](const std::string& name, const std::vector<uint8_t>& data,
1426 const legacy_hal::wifi_ring_buffer_status& status) {
1427 const auto shared_ptr_this = weak_ptr_this.lock();
1428 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1429 LOG(ERROR) << "Callback invoked on an invalid object";
1430 return;
1431 }
1432 WifiDebugRingBufferStatus aidl_status;
1433 Ringbuffer::AppendStatus appendstatus;
1434 if (!aidl_struct_util::convertLegacyDebugRingBufferStatusToAidl(status,
1435 &aidl_status)) {
1436 LOG(ERROR) << "Error converting ring buffer status";
1437 return;
1438 }
1439 {
1440 std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t);
1441 const auto& target = shared_ptr_this->ringbuffer_map_.find(name);
1442 if (target != shared_ptr_this->ringbuffer_map_.end()) {
1443 Ringbuffer& cur_buffer = target->second;
1444 appendstatus = cur_buffer.append(data);
1445 } else {
1446 LOG(ERROR) << "Ringname " << name << " not found";
1447 return;
1448 }
1449 // unique_lock unlocked here
1450 }
1451 if (appendstatus == Ringbuffer::AppendStatus::FAIL_RING_BUFFER_CORRUPTED) {
1452 LOG(ERROR) << "Ringname " << name << " is corrupted. Clear the ring buffer";
1453 shared_ptr_this->writeRingbufferFilesInternal();
1454 return;
1455 }
1456 };
1457 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->registerRingBufferCallbackHandler(
1458 getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback);
1459
1460 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1461 debug_ring_buffer_cb_registered_ = true;
1462 }
1463 return createWifiStatusFromLegacyError(legacy_status);
1464}
1465
1466ndk::ScopedAStatus WifiChip::registerRadioModeChangeCallback() {
1467 std::weak_ptr<WifiChip> weak_ptr_this = weak_ptr_this_;
1468 const auto& on_radio_mode_change_callback =
1469 [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
1470 const auto shared_ptr_this = weak_ptr_this.lock();
1471 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1472 LOG(ERROR) << "Callback invoked on an invalid object";
1473 return;
1474 }
1475 std::vector<IWifiChipEventCallback::RadioModeInfo> aidl_radio_mode_infos;
1476 if (!aidl_struct_util::convertLegacyWifiMacInfosToAidl(mac_infos,
1477 &aidl_radio_mode_infos)) {
1478 LOG(ERROR) << "Error converting wifi mac info";
1479 return;
1480 }
1481 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
1482 if (!callback->onRadioModeChange(aidl_radio_mode_infos).isOk()) {
1483 LOG(ERROR) << "Failed to invoke onRadioModeChange callback";
1484 }
1485 }
1486 };
1487 legacy_hal::wifi_error legacy_status =
1488 legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
1489 getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
1490 return createWifiStatusFromLegacyError(legacy_status);
1491}
1492
1493std::vector<IWifiChip::ChipConcurrencyCombination>
1494WifiChip::getCurrentModeConcurrencyCombinations() {
1495 if (!isValidModeId(current_mode_id_)) {
1496 LOG(ERROR) << "Chip not configured in a mode yet";
1497 return std::vector<IWifiChip::ChipConcurrencyCombination>();
1498 }
1499 for (const auto& mode : modes_) {
1500 if (mode.id == current_mode_id_) {
1501 return mode.availableCombinations;
1502 }
1503 }
1504 CHECK(0) << "Expected to find concurrency combinations for current mode!";
1505 return std::vector<IWifiChip::ChipConcurrencyCombination>();
1506}
1507
1508// Returns a map indexed by IfaceConcurrencyType with the number of ifaces currently
1509// created of the corresponding concurrency type.
1510std::map<IfaceConcurrencyType, size_t> WifiChip::getCurrentConcurrencyCombination() {
1511 std::map<IfaceConcurrencyType, size_t> iface_counts;
1512 uint32_t num_ap = 0;
1513 uint32_t num_ap_bridged = 0;
1514 for (const auto& ap_iface : ap_ifaces_) {
1515 std::string ap_iface_name = ap_iface->getName();
1516 if (br_ifaces_ap_instances_.count(ap_iface_name) > 0 &&
1517 br_ifaces_ap_instances_[ap_iface_name].size() > 1) {
1518 num_ap_bridged++;
1519 } else {
1520 num_ap++;
1521 }
1522 }
1523 iface_counts[IfaceConcurrencyType::AP] = num_ap;
1524 iface_counts[IfaceConcurrencyType::AP_BRIDGED] = num_ap_bridged;
1525 iface_counts[IfaceConcurrencyType::NAN_IFACE] = nan_ifaces_.size();
1526 iface_counts[IfaceConcurrencyType::P2P] = p2p_ifaces_.size();
1527 iface_counts[IfaceConcurrencyType::STA] = sta_ifaces_.size();
1528 return iface_counts;
1529}
1530
1531// This expands the provided concurrency combinations to a more parseable
1532// form. Returns a vector of available combinations possible with the number
1533// of each concurrency type in the combination.
1534// This method is a port of HalDeviceManager.expandConcurrencyCombos() from framework.
1535std::vector<std::map<IfaceConcurrencyType, size_t>> WifiChip::expandConcurrencyCombinations(
1536 const IWifiChip::ChipConcurrencyCombination& combination) {
1537 int32_t num_expanded_combos = 1;
1538 for (const auto& limit : combination.limits) {
1539 for (int32_t i = 0; i < limit.maxIfaces; i++) {
1540 num_expanded_combos *= limit.types.size();
1541 }
1542 }
1543
1544 // Allocate the vector of expanded combos and reset all concurrency type counts to 0
1545 // in each combo.
1546 std::vector<std::map<IfaceConcurrencyType, size_t>> expanded_combos;
1547 expanded_combos.resize(num_expanded_combos);
1548 for (auto& expanded_combo : expanded_combos) {
1549 for (const auto type : {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED,
1550 IfaceConcurrencyType::NAN_IFACE, IfaceConcurrencyType::P2P,
1551 IfaceConcurrencyType::STA}) {
1552 expanded_combo[type] = 0;
1553 }
1554 }
1555 int32_t span = num_expanded_combos;
1556 for (const auto& limit : combination.limits) {
1557 for (int32_t i = 0; i < limit.maxIfaces; i++) {
1558 span /= limit.types.size();
1559 for (int32_t k = 0; k < num_expanded_combos; ++k) {
1560 const auto iface_type = limit.types[(k / span) % limit.types.size()];
1561 expanded_combos[k][iface_type]++;
1562 }
1563 }
1564 }
1565 return expanded_combos;
1566}
1567
1568bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
1569 const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
1570 IfaceConcurrencyType requested_type) {
1571 const auto current_combo = getCurrentConcurrencyCombination();
1572
1573 // Check if we have space for 1 more iface of |type| in this combo
1574 for (const auto type :
1575 {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED,
1576 IfaceConcurrencyType::NAN_IFACE, IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
1577 size_t num_ifaces_needed = current_combo.at(type);
1578 if (type == requested_type) {
1579 num_ifaces_needed++;
1580 }
1581 size_t num_ifaces_allowed = expanded_combo.at(type);
1582 if (num_ifaces_needed > num_ifaces_allowed) {
1583 return false;
1584 }
1585 }
1586 return true;
1587}
1588
1589// This method does the following:
1590// a) Enumerate all possible concurrency combos by expanding the current
1591// ChipConcurrencyCombination.
1592// b) Check if the requested concurrency type can be added to the current mode
1593// with the concurrency combination that is already active.
1594bool WifiChip::canCurrentModeSupportConcurrencyTypeWithCurrentTypes(
1595 IfaceConcurrencyType requested_type) {
1596 if (!isValidModeId(current_mode_id_)) {
1597 LOG(ERROR) << "Chip not configured in a mode yet";
1598 return false;
1599 }
1600 const auto combinations = getCurrentModeConcurrencyCombinations();
1601 for (const auto& combination : combinations) {
1602 const auto expanded_combos = expandConcurrencyCombinations(combination);
1603 for (const auto& expanded_combo : expanded_combos) {
1604 if (canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(expanded_combo,
1605 requested_type)) {
1606 return true;
1607 }
1608 }
1609 }
1610 return false;
1611}
1612
1613// Note: This does not consider concurrency types already active. It only checks if the
1614// provided expanded concurrency combination can support the requested combo.
1615bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyCombo(
1616 const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
1617 const std::map<IfaceConcurrencyType, size_t>& req_combo) {
1618 // Check if we have space for 1 more |type| in this combo
1619 for (const auto type :
1620 {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED,
1621 IfaceConcurrencyType::NAN_IFACE, IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
1622 if (req_combo.count(type) == 0) {
1623 // Concurrency type not in the req_combo.
1624 continue;
1625 }
1626 size_t num_ifaces_needed = req_combo.at(type);
1627 size_t num_ifaces_allowed = expanded_combo.at(type);
1628 if (num_ifaces_needed > num_ifaces_allowed) {
1629 return false;
1630 }
1631 }
1632 return true;
1633}
1634
1635// This method does the following:
1636// a) Enumerate all possible concurrency combos by expanding the current
1637// ChipConcurrencyCombination.
1638// b) Check if the requested concurrency combo can be added to the current mode.
1639// Note: This does not consider concurrency types already active. It only checks if the
1640// current mode can support the requested combo.
1641bool WifiChip::canCurrentModeSupportConcurrencyCombo(
1642 const std::map<IfaceConcurrencyType, size_t>& req_combo) {
1643 if (!isValidModeId(current_mode_id_)) {
1644 LOG(ERROR) << "Chip not configured in a mode yet";
1645 return false;
1646 }
1647 const auto combinations = getCurrentModeConcurrencyCombinations();
1648 for (const auto& combination : combinations) {
1649 const auto expanded_combos = expandConcurrencyCombinations(combination);
1650 for (const auto& expanded_combo : expanded_combos) {
1651 if (canExpandedConcurrencyComboSupportConcurrencyCombo(expanded_combo, req_combo)) {
1652 return true;
1653 }
1654 }
1655 }
1656 return false;
1657}
1658
1659// This method does the following:
1660// a) Enumerate all possible concurrency combos by expanding the current
1661// ChipConcurrencyCombination.
1662// b) Check if the requested concurrency type can be added to the current mode.
1663bool WifiChip::canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type) {
1664 // Check if we can support at least 1 of the requested concurrency type.
1665 std::map<IfaceConcurrencyType, size_t> req_iface_combo;
1666 req_iface_combo[requested_type] = 1;
1667 return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
1668}
1669
1670bool WifiChip::isValidModeId(int32_t mode_id) {
1671 for (const auto& mode : modes_) {
1672 if (mode.id == mode_id) {
1673 return true;
1674 }
1675 }
1676 return false;
1677}
1678
1679bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
1680 // Check if we can support at least 1 STA & 1 AP concurrently.
1681 std::map<IfaceConcurrencyType, size_t> req_iface_combo;
1682 req_iface_combo[IfaceConcurrencyType::STA] = 1;
1683 req_iface_combo[IfaceConcurrencyType::AP] = 1;
1684 return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
1685}
1686
1687bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() {
1688 // Check if we can support at least 2 STA concurrently.
1689 std::map<IfaceConcurrencyType, size_t> req_iface_combo;
1690 req_iface_combo[IfaceConcurrencyType::STA] = 2;
1691 return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
1692}
1693
1694std::string WifiChip::getFirstActiveWlanIfaceName() {
1695 if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName();
1696 if (ap_ifaces_.size() > 0) {
1697 // If the first active wlan iface is bridged iface.
1698 // Return first instance name.
1699 for (auto const& it : br_ifaces_ap_instances_) {
1700 if (it.first == ap_ifaces_[0]->getName()) {
1701 return it.second[0];
1702 }
1703 }
1704 return ap_ifaces_[0]->getName();
1705 }
1706 // This could happen if the chip call is made before any STA/AP
1707 // iface is created. Default to wlan0 for such cases.
1708 LOG(WARNING) << "No active wlan interfaces in use! Using default";
1709 return getWlanIfaceNameWithType(IfaceType::STA, 0);
1710}
1711
1712// Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx|
1713// not already in use.
1714// Note: This doesn't check the actual presence of these interfaces.
1715std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx) {
1716 for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
1717 const auto ifname = getWlanIfaceNameWithType(type, idx);
1718 if (findUsingNameFromBridgedApInstances(ifname)) continue;
1719 if (findUsingName(ap_ifaces_, ifname)) continue;
1720 if (findUsingName(sta_ifaces_, ifname)) continue;
1721 return ifname;
1722 }
1723 // This should never happen. We screwed up somewhere if it did.
1724 CHECK(false) << "All wlan interfaces in use already!";
1725 return {};
1726}
1727
1728uint32_t WifiChip::startIdxOfApIface() {
1729 if (isDualStaConcurrencyAllowedInCurrentMode()) {
1730 // When the HAL support dual STAs, AP should start with idx 2.
1731 return 2;
1732 } else if (isStaApConcurrencyAllowedInCurrentMode()) {
1733 // When the HAL support STA + AP but it doesn't support dual STAs.
1734 // AP should start with idx 1.
1735 return 1;
1736 }
1737 // No concurrency support.
1738 return 0;
1739}
1740
1741// AP iface names start with idx 1 for modes supporting
1742// concurrent STA and not dual AP, else start with idx 0.
1743std::string WifiChip::allocateApIfaceName() {
1744 // Check if we have a dedicated iface for AP.
1745 std::vector<std::string> ifnames = getPredefinedApIfaceNames(true);
1746 for (auto const& ifname : ifnames) {
1747 if (findUsingName(ap_ifaces_, ifname)) continue;
1748 return ifname;
1749 }
1750 return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
1751}
1752
1753std::vector<std::string> WifiChip::allocateBridgedApInstanceNames() {
1754 // Check if we have a dedicated iface for AP.
1755 std::vector<std::string> instances = getPredefinedApIfaceNames(true);
1756 if (instances.size() == 2) {
1757 return instances;
1758 } else {
1759 int num_ifaces_need_to_allocate = 2 - instances.size();
1760 for (int i = 0; i < num_ifaces_need_to_allocate; i++) {
1761 std::string instance_name =
1762 allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface() + i);
1763 if (!instance_name.empty()) {
1764 instances.push_back(instance_name);
1765 }
1766 }
1767 }
1768 return instances;
1769}
1770
1771// STA iface names start with idx 0.
1772// Primary STA iface will always be 0.
1773std::string WifiChip::allocateStaIfaceName() {
1774 return allocateApOrStaIfaceName(IfaceType::STA, 0);
1775}
1776
1777bool WifiChip::writeRingbufferFilesInternal() {
1778 if (!removeOldFilesInternal()) {
1779 LOG(ERROR) << "Error occurred while deleting old tombstone files";
1780 return false;
1781 }
1782 // write ringbuffers to file
1783 {
1784 std::unique_lock<std::mutex> lk(lock_t);
1785 for (auto& item : ringbuffer_map_) {
1786 Ringbuffer& cur_buffer = item.second;
1787 if (cur_buffer.getData().empty()) {
1788 continue;
1789 }
1790 const std::string file_path_raw = kTombstoneFolderPath + item.first + "XXXXXXXXXX";
1791 const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
1792 if (dump_fd == -1) {
1793 PLOG(ERROR) << "create file failed";
1794 return false;
1795 }
1796 unique_fd file_auto_closer(dump_fd);
1797 for (const auto& cur_block : cur_buffer.getData()) {
1798 if (cur_block.size() <= 0 || cur_block.size() > kMaxBufferSizeBytes) {
1799 PLOG(ERROR) << "Ring buffer: " << item.first
1800 << " is corrupted. Invalid block size: " << cur_block.size();
1801 break;
1802 }
1803 if (write(dump_fd, cur_block.data(), sizeof(cur_block[0]) * cur_block.size()) ==
1804 -1) {
1805 PLOG(ERROR) << "Error writing to file";
1806 }
1807 }
1808 cur_buffer.clear();
1809 }
1810 // unique_lock unlocked here
1811 }
1812 return true;
1813}
1814
1815std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) {
1816 std::string ifname;
1817
1818 // let the legacy hal override the interface name
1819 legacy_hal::wifi_error err = legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname);
1820 if (err == legacy_hal::WIFI_SUCCESS) return ifname;
1821
1822 return getWlanIfaceName(idx);
1823}
1824
1825void WifiChip::invalidateAndClearBridgedApAll() {
1826 for (auto const& it : br_ifaces_ap_instances_) {
1827 for (auto const& iface : it.second) {
1828 iface_util_->removeIfaceFromBridge(it.first, iface);
1829 legacy_hal_.lock()->deleteVirtualInterface(iface);
1830 }
1831 iface_util_->deleteBridge(it.first);
1832 }
1833 br_ifaces_ap_instances_.clear();
1834}
1835
Sunil Ravi780bef02023-06-01 21:43:04 +00001836void WifiChip::deleteApIface(const std::string& if_name) {
1837 if (if_name.empty()) return;
1838 // delete bridged interfaces if any
Gabriel Birenf3262f92022-07-15 23:25:39 +00001839 for (auto const& it : br_ifaces_ap_instances_) {
Sunil Ravi780bef02023-06-01 21:43:04 +00001840 if (it.first == if_name) {
Gabriel Birenf3262f92022-07-15 23:25:39 +00001841 for (auto const& iface : it.second) {
Sunil Ravi780bef02023-06-01 21:43:04 +00001842 iface_util_->removeIfaceFromBridge(if_name, iface);
Gabriel Birenf3262f92022-07-15 23:25:39 +00001843 legacy_hal_.lock()->deleteVirtualInterface(iface);
1844 }
Sunil Ravi780bef02023-06-01 21:43:04 +00001845 iface_util_->deleteBridge(if_name);
1846 br_ifaces_ap_instances_.erase(if_name);
1847 // ifname is bridged AP, return here.
1848 return;
Gabriel Birenf3262f92022-07-15 23:25:39 +00001849 }
1850 }
Sunil Ravi780bef02023-06-01 21:43:04 +00001851
1852 // No bridged AP case, delete AP iface
1853 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(if_name);
1854 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1855 LOG(ERROR) << "Failed to remove interface: " << if_name << " "
1856 << legacyErrorToString(legacy_status);
1857 }
Gabriel Birenf3262f92022-07-15 23:25:39 +00001858}
1859
1860bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) {
1861 for (auto const& it : br_ifaces_ap_instances_) {
1862 if (it.first == name) {
1863 return true;
1864 }
1865 for (auto const& iface : it.second) {
1866 if (iface == name) {
1867 return true;
1868 }
1869 }
1870 }
1871 return false;
1872}
1873
maheshkkva8aba172023-02-13 12:33:26 -08001874ndk::ScopedAStatus WifiChip::setMloModeInternal(const WifiChip::ChipMloMode in_mode) {
1875 legacy_hal::wifi_mlo_mode mode;
1876 switch (in_mode) {
1877 case WifiChip::ChipMloMode::DEFAULT:
1878 mode = legacy_hal::wifi_mlo_mode::WIFI_MLO_MODE_DEFAULT;
1879 break;
1880 case WifiChip::ChipMloMode::LOW_LATENCY:
1881 mode = legacy_hal::wifi_mlo_mode::WIFI_MLO_MODE_LOW_LATENCY;
1882 break;
1883 case WifiChip::ChipMloMode::HIGH_THROUGHPUT:
1884 mode = legacy_hal::wifi_mlo_mode::WIFI_MLO_MODE_HIGH_THROUGHPUT;
1885 break;
1886 case WifiChip::ChipMloMode::LOW_POWER:
1887 mode = legacy_hal::wifi_mlo_mode::WIFI_MLO_MODE_LOW_POWER;
1888 break;
1889 default:
1890 PLOG(ERROR) << "Error: invalid mode: " << toString(in_mode);
1891 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1892 }
1893 return createWifiStatusFromLegacyError(legacy_hal_.lock()->setMloMode(mode));
1894}
1895
Gabriel Birenf3262f92022-07-15 23:25:39 +00001896} // namespace wifi
1897} // namespace hardware
1898} // namespace android
1899} // namespace aidl