blob: 6bdff4214955ae52625f659f6088a783017c4ae0 [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
xshu5899e8e2018-01-09 15:36:03 -080017#include <fcntl.h>
18
Roshan Pius3c4e8a32016-10-03 14:53:58 -070019#include <android-base/logging.h>
xshu5899e8e2018-01-09 15:36:03 -080020#include <android-base/unique_fd.h>
Roshan Pius9377a0d2017-10-06 13:18:54 -070021#include <cutils/properties.h>
lesl94d28242020-11-18 22:17:37 +080022#include <net/if.h>
xshu5899e8e2018-01-09 15:36:03 -080023#include <sys/stat.h>
24#include <sys/sysmacros.h>
Roshan Pius3c4e8a32016-10-03 14:53:58 -070025
Roshan Pius3c868522016-10-27 12:43:49 -070026#include "hidl_return_util.h"
Roshan Piuse2d0ab52016-12-05 15:24:20 -080027#include "hidl_struct_util.h"
Roshan Pius3c868522016-10-27 12:43:49 -070028#include "wifi_chip.h"
Roshan Pius5c055462016-10-11 08:27:27 -070029#include "wifi_status_util.h"
Roshan Pius3c4e8a32016-10-03 14:53:58 -070030
Sunil Ravi6adbab12021-10-15 16:55:53 -070031#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-"
32
Roshan Pius35d958c2016-10-06 16:47:38 -070033namespace {
Jong Wook Kimda830c92018-07-23 15:29:38 -070034using android::sp;
xshu5899e8e2018-01-09 15:36:03 -080035using android::base::unique_fd;
Roshan Pius35d958c2016-10-06 16:47:38 -070036using android::hardware::hidl_string;
Roshan Piusabcf78f2017-10-06 16:30:38 -070037using android::hardware::hidl_vec;
Roshan Pius2c06a3f2016-12-15 17:51:40 -080038using android::hardware::wifi::V1_0::ChipModeId;
Roshan Pius52947fb2016-11-18 11:38:07 -080039using android::hardware::wifi::V1_0::IfaceType;
Roshan Pius675609b2017-10-31 14:24:58 -070040using android::hardware::wifi::V1_0::IWifiChip;
Roshan Pius52947fb2016-11-18 11:38:07 -080041
xshu5899e8e2018-01-09 15:36:03 -080042constexpr char kCpioMagic[] = "070701";
Roger Wangb294c762018-11-02 15:34:39 +080043constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3;
44constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10;
xshu37126c92018-04-13 16:24:45 -070045constexpr uint32_t kMaxRingBufferFileNum = 20;
xshu5899e8e2018-01-09 15:36:03 -080046constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
Roshan Pius8574e7f2019-04-01 13:30:40 -070047constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface";
48constexpr char kNoActiveWlanIfaceNamePropertyValue[] = "";
49constexpr unsigned kMaxWlanIfaces = 5;
lesl94d28242020-11-18 22:17:37 +080050constexpr char kApBridgeIfacePrefix[] = "ap_br_";
xshu5899e8e2018-01-09 15:36:03 -080051
Roshan Pius35d958c2016-10-06 16:47:38 -070052template <typename Iface>
Roshan Pius675609b2017-10-31 14:24:58 -070053void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
54 iface->invalidate();
55 ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface),
56 ifaces.end());
57}
58
59template <typename Iface>
60void invalidateAndClearAll(std::vector<sp<Iface>>& ifaces) {
61 for (const auto& iface : ifaces) {
Roshan Piusabcf78f2017-10-06 16:30:38 -070062 iface->invalidate();
Roshan Piusabcf78f2017-10-06 16:30:38 -070063 }
Roshan Pius675609b2017-10-31 14:24:58 -070064 ifaces.clear();
65}
66
67template <typename Iface>
68std::vector<hidl_string> getNames(std::vector<sp<Iface>>& ifaces) {
69 std::vector<hidl_string> names;
70 for (const auto& iface : ifaces) {
71 names.emplace_back(iface->getName());
72 }
73 return names;
74}
75
76template <typename Iface>
77sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces,
78 const std::string& name) {
79 std::vector<hidl_string> names;
80 for (const auto& iface : ifaces) {
81 if (name == iface->getName()) {
82 return iface;
83 }
84 }
85 return nullptr;
Roshan Pius35d958c2016-10-06 16:47:38 -070086}
Roshan Pius9377a0d2017-10-06 13:18:54 -070087
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -080088std::string getWlanIfaceName(unsigned idx) {
89 if (idx >= kMaxWlanIfaces) {
90 CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
91 return {};
92 }
Roshan Pius9377a0d2017-10-06 13:18:54 -070093
Roshan Pius8e3c7ef2017-11-03 09:43:08 -070094 std::array<char, PROPERTY_VALUE_MAX> buffer;
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -080095 if (idx == 0 || idx == 1) {
96 const char* altPropName =
97 (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
Roshan Pius5b333462019-03-01 14:07:22 -080098 auto res = property_get(altPropName, buffer.data(), nullptr);
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -080099 if (res > 0) return buffer.data();
100 }
Roshan Pius5b333462019-03-01 14:07:22 -0800101 std::string propName = "wifi.interface." + std::to_string(idx);
102 auto res = property_get(propName.c_str(), buffer.data(), nullptr);
103 if (res > 0) return buffer.data();
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -0800104
105 return "wlan" + std::to_string(idx);
Roshan Pius9377a0d2017-10-06 13:18:54 -0700106}
Roshan Pius9377a0d2017-10-06 13:18:54 -0700107
lesl261818b2020-11-27 12:37:35 +0800108// Returns the dedicated iface name if defined.
109// Returns two ifaces in bridged mode.
110std::vector<std::string> getPredefinedApIfaceNames(bool is_bridged) {
111 std::vector<std::string> ifnames;
Roshan Pius78cb5992020-04-30 12:39:21 -0700112 std::array<char, PROPERTY_VALUE_MAX> buffer;
lesl261818b2020-11-27 12:37:35 +0800113 buffer.fill(0);
Roshan Pius78cb5992020-04-30 12:39:21 -0700114 if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) ==
115 0) {
lesl261818b2020-11-27 12:37:35 +0800116 return ifnames;
Roshan Pius78cb5992020-04-30 12:39:21 -0700117 }
lesl261818b2020-11-27 12:37:35 +0800118 ifnames.push_back(buffer.data());
119 if (is_bridged) {
120 buffer.fill(0);
lesl5a46c952020-12-14 17:14:12 +0800121 if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(),
122 nullptr) == 0) {
lesl261818b2020-11-27 12:37:35 +0800123 return ifnames;
124 }
125 ifnames.push_back(buffer.data());
126 }
127 return ifnames;
Roshan Pius78cb5992020-04-30 12:39:21 -0700128}
129
lesl261818b2020-11-27 12:37:35 +0800130std::string getPredefinedP2pIfaceName() {
Sunil Ravi6adbab12021-10-15 16:55:53 -0700131 std::array<char, PROPERTY_VALUE_MAX> primaryIfaceName;
132 char p2pParentIfname[100];
133 std::string p2pDevIfName = "";
Roshan Piusabcf78f2017-10-06 16:30:38 -0700134 std::array<char, PROPERTY_VALUE_MAX> buffer;
135 property_get("wifi.direct.interface", buffer.data(), "p2p0");
Sunil Ravi6adbab12021-10-15 16:55:53 -0700136 if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX,
137 strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
138 /* Get the p2p parent interface name from p2p device interface name set
139 * in property */
140 strncpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX),
141 strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX));
142 if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(),
143 nullptr) == 0) {
144 return buffer.data();
145 }
146 /* Check if the parent interface derived from p2p device interface name
147 * is active */
148 if (strncmp(p2pParentIfname, primaryIfaceName.data(),
149 strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) !=
150 0) {
151 /*
152 * Update the predefined p2p device interface parent interface name
153 * with current active wlan interface
154 */
155 p2pDevIfName += P2P_MGMT_DEVICE_PREFIX;
156 p2pDevIfName += primaryIfaceName.data();
157 LOG(INFO) << "update the p2p device interface name to "
158 << p2pDevIfName.c_str();
159 return p2pDevIfName;
160 }
161 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700162 return buffer.data();
Roshan Pius9377a0d2017-10-06 13:18:54 -0700163}
164
Roshan Pius5ba0a902020-04-14 11:55:42 -0700165// Returns the dedicated iface name if one is defined.
lesl261818b2020-11-27 12:37:35 +0800166std::string getPredefinedNanIfaceName() {
Roshan Pius5ba0a902020-04-14 11:55:42 -0700167 std::array<char, PROPERTY_VALUE_MAX> buffer;
168 if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) {
169 return {};
170 }
171 return buffer.data();
172}
173
Roshan Pius8574e7f2019-04-01 13:30:40 -0700174void setActiveWlanIfaceNameProperty(const std::string& ifname) {
175 auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data());
176 if (res != 0) {
177 PLOG(ERROR) << "Failed to set active wlan iface name property";
178 }
179}
180
xshu37126c92018-04-13 16:24:45 -0700181// delete files that meet either conditions:
182// 1. older than a predefined time in the wifi tombstone dir.
183// 2. Files in excess to a predefined amount, starting from the oldest ones
xshu5899e8e2018-01-09 15:36:03 -0800184bool removeOldFilesInternal() {
185 time_t now = time(0);
186 const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
Josh Gaoa568e532018-06-04 18:16:00 -0700187 std::unique_ptr<DIR, decltype(&closedir)> dir_dump(
188 opendir(kTombstoneFolderPath), closedir);
xshu5899e8e2018-01-09 15:36:03 -0800189 if (!dir_dump) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800190 PLOG(ERROR) << "Failed to open directory";
xshu5899e8e2018-01-09 15:36:03 -0800191 return false;
192 }
xshu5899e8e2018-01-09 15:36:03 -0800193 struct dirent* dp;
194 bool success = true;
xshu37126c92018-04-13 16:24:45 -0700195 std::list<std::pair<const time_t, std::string>> valid_files;
Josh Gaoa568e532018-06-04 18:16:00 -0700196 while ((dp = readdir(dir_dump.get()))) {
xshu5899e8e2018-01-09 15:36:03 -0800197 if (dp->d_type != DT_REG) {
198 continue;
199 }
200 std::string cur_file_name(dp->d_name);
201 struct stat cur_file_stat;
202 std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
xshu4cb33162018-01-24 15:40:06 -0800203 if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800204 PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
xshu5899e8e2018-01-09 15:36:03 -0800205 success = false;
xshu4cb33162018-01-24 15:40:06 -0800206 continue;
207 }
xshu37126c92018-04-13 16:24:45 -0700208 const time_t cur_file_time = cur_file_stat.st_mtime;
209 valid_files.push_back(
210 std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
211 }
212 valid_files.sort(); // sort the list of files by last modified time from
213 // small to big.
214 uint32_t cur_file_count = valid_files.size();
215 for (auto cur_file : valid_files) {
216 if (cur_file_count > kMaxRingBufferFileNum ||
217 cur_file.first < delete_files_before) {
218 if (unlink(cur_file.second.c_str()) != 0) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800219 PLOG(ERROR) << "Error deleting file";
xshu37126c92018-04-13 16:24:45 -0700220 success = false;
221 }
222 cur_file_count--;
223 } else {
224 break;
xshu5899e8e2018-01-09 15:36:03 -0800225 }
226 }
227 return success;
228}
229
xshu4cb33162018-01-24 15:40:06 -0800230// Helper function for |cpioArchiveFilesInDir|
231bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name,
232 size_t file_name_len) {
233 std::array<char, 32 * 1024> read_buf;
234 ssize_t llen =
235 sprintf(read_buf.data(),
236 "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
237 kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid,
238 st.st_gid, static_cast<int>(st.st_nlink),
239 static_cast<int>(st.st_mtime), static_cast<int>(st.st_size),
240 major(st.st_dev), minor(st.st_dev), major(st.st_rdev),
241 minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0);
242 if (write(out_fd, read_buf.data(), llen) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800243 PLOG(ERROR) << "Error writing cpio header to file " << file_name;
xshu4cb33162018-01-24 15:40:06 -0800244 return false;
245 }
246 if (write(out_fd, file_name, file_name_len) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800247 PLOG(ERROR) << "Error writing filename to file " << file_name;
xshu4cb33162018-01-24 15:40:06 -0800248 return false;
249 }
250
251 // NUL Pad header up to 4 multiple bytes.
252 llen = (llen + file_name_len) % 4;
253 if (llen != 0) {
254 const uint32_t zero = 0;
255 if (write(out_fd, &zero, 4 - llen) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800256 PLOG(ERROR) << "Error padding 0s to file " << file_name;
xshu4cb33162018-01-24 15:40:06 -0800257 return false;
258 }
259 }
260 return true;
261}
262
263// Helper function for |cpioArchiveFilesInDir|
264size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) {
265 // writing content of file
266 std::array<char, 32 * 1024> read_buf;
267 ssize_t llen = st.st_size;
268 size_t n_error = 0;
269 while (llen > 0) {
270 ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size());
271 if (bytes_read == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800272 PLOG(ERROR) << "Error reading file";
xshu4cb33162018-01-24 15:40:06 -0800273 return ++n_error;
274 }
275 llen -= bytes_read;
276 if (write(out_fd, read_buf.data(), bytes_read) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800277 PLOG(ERROR) << "Error writing data to file";
xshu4cb33162018-01-24 15:40:06 -0800278 return ++n_error;
279 }
280 if (bytes_read == 0) { // this should never happen, but just in case
281 // to unstuck from while loop
Elliott Hughes4db4add2019-03-08 12:42:57 -0800282 PLOG(ERROR) << "Unexpected read result";
xshu4cb33162018-01-24 15:40:06 -0800283 n_error++;
284 break;
285 }
286 }
287 llen = st.st_size % 4;
288 if (llen != 0) {
289 const uint32_t zero = 0;
290 if (write(out_fd, &zero, 4 - llen) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800291 PLOG(ERROR) << "Error padding 0s to file";
xshu4cb33162018-01-24 15:40:06 -0800292 return ++n_error;
293 }
294 }
295 return n_error;
296}
297
298// Helper function for |cpioArchiveFilesInDir|
299bool cpioWriteFileTrailer(int out_fd) {
300 std::array<char, 4096> read_buf;
301 read_buf.fill(0);
302 if (write(out_fd, read_buf.data(),
303 sprintf(read_buf.data(), "070701%040X%056X%08XTRAILER!!!", 1,
304 0x0b, 0) +
305 4) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800306 PLOG(ERROR) << "Error writing trailing bytes";
xshu4cb33162018-01-24 15:40:06 -0800307 return false;
308 }
309 return true;
310}
311
xshu5899e8e2018-01-09 15:36:03 -0800312// Archives all files in |input_dir| and writes result into |out_fd|
313// Logic obtained from //external/toybox/toys/posix/cpio.c "Output cpio archive"
314// portion
xshu4cb33162018-01-24 15:40:06 -0800315size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) {
xshu5899e8e2018-01-09 15:36:03 -0800316 struct dirent* dp;
317 size_t n_error = 0;
Josh Gaoa568e532018-06-04 18:16:00 -0700318 std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir),
319 closedir);
xshu5899e8e2018-01-09 15:36:03 -0800320 if (!dir_dump) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800321 PLOG(ERROR) << "Failed to open directory";
xshu4cb33162018-01-24 15:40:06 -0800322 return ++n_error;
xshu5899e8e2018-01-09 15:36:03 -0800323 }
Josh Gaoa568e532018-06-04 18:16:00 -0700324 while ((dp = readdir(dir_dump.get()))) {
xshu5899e8e2018-01-09 15:36:03 -0800325 if (dp->d_type != DT_REG) {
326 continue;
327 }
328 std::string cur_file_name(dp->d_name);
xshu5899e8e2018-01-09 15:36:03 -0800329 struct stat st;
xshu5899e8e2018-01-09 15:36:03 -0800330 const std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
xshu4cb33162018-01-24 15:40:06 -0800331 if (stat(cur_file_path.c_str(), &st) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800332 PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
xshu5899e8e2018-01-09 15:36:03 -0800333 n_error++;
xshu4cb33162018-01-24 15:40:06 -0800334 continue;
335 }
336 const int fd_read = open(cur_file_path.c_str(), O_RDONLY);
337 if (fd_read == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800338 PLOG(ERROR) << "Failed to open file " << cur_file_path;
xshu4cb33162018-01-24 15:40:06 -0800339 n_error++;
340 continue;
341 }
xshuf392fb42020-08-13 16:57:00 -0700342 std::string file_name_with_last_modified_time =
343 cur_file_name + "-" + std::to_string(st.st_mtime);
344 // string.size() does not include the null terminator. The cpio FreeBSD
345 // file header expects the null character to be included in the length.
346 const size_t file_name_len =
347 file_name_with_last_modified_time.size() + 1;
xshu4cb33162018-01-24 15:40:06 -0800348 unique_fd file_auto_closer(fd_read);
xshuf392fb42020-08-13 16:57:00 -0700349 if (!cpioWriteHeader(out_fd, st,
350 file_name_with_last_modified_time.c_str(),
xshu4cb33162018-01-24 15:40:06 -0800351 file_name_len)) {
352 return ++n_error;
353 }
354 size_t write_error = cpioWriteFileContent(fd_read, out_fd, st);
355 if (write_error) {
356 return n_error + write_error;
xshu5899e8e2018-01-09 15:36:03 -0800357 }
358 }
xshu4cb33162018-01-24 15:40:06 -0800359 if (!cpioWriteFileTrailer(out_fd)) {
360 return ++n_error;
xshu5899e8e2018-01-09 15:36:03 -0800361 }
362 return n_error;
363}
364
365// Helper function to create a non-const char*.
366std::vector<char> makeCharVec(const std::string& str) {
367 std::vector<char> vec(str.size() + 1);
368 vec.assign(str.begin(), str.end());
369 vec.push_back('\0');
370 return vec;
371}
372
Roshan Piusabcf78f2017-10-06 16:30:38 -0700373} // namespace
Roshan Pius35d958c2016-10-06 16:47:38 -0700374
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700375namespace android {
376namespace hardware {
377namespace wifi {
Jimmy Chend460df32019-11-29 17:31:22 +0200378namespace V1_5 {
Roshan Pius79a99752016-10-04 13:03:58 -0700379namespace implementation {
Roshan Pius3c868522016-10-27 12:43:49 -0700380using hidl_return_util::validateAndCall;
Roshan Piusba38d9c2017-12-08 07:32:08 -0800381using hidl_return_util::validateAndCallWithLock;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700382
Roshan Pius52947fb2016-11-18 11:38:07 -0800383WifiChip::WifiChip(
Jimmy Chen2dddd792019-12-23 17:50:39 +0200384 ChipId chip_id, bool is_primary,
385 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
Roshan Pius200a17d2017-11-01 13:03:35 -0700386 const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
Roshan Pius8c1a67b2021-03-02 10:00:23 -0800387 const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
Ahmed ElArabawy2134bf72020-06-18 15:07:12 -0700388 const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
389 const std::function<void(const std::string&)>& handler)
Roshan Pius52947fb2016-11-18 11:38:07 -0800390 : chip_id_(chip_id),
391 legacy_hal_(legacy_hal),
392 mode_controller_(mode_controller),
Roshan Pius99dab382019-02-14 07:57:10 -0800393 iface_util_(iface_util),
Roshan Pius52947fb2016-11-18 11:38:07 -0800394 is_valid_(true),
Tomasz Wasilczykb424da72018-11-15 11:52:57 -0800395 current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
Jimmy Chen2dddd792019-12-23 17:50:39 +0200396 modes_(feature_flags.lock()->getChipModes(is_primary)),
Ahmed ElArabawy2134bf72020-06-18 15:07:12 -0700397 debug_ring_buffer_cb_registered_(false),
398 subsystemCallbackHandler_(handler) {
Roshan Pius8574e7f2019-04-01 13:30:40 -0700399 setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
400}
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700401
Roshan Piusaabe5752016-09-29 09:03:59 -0700402void WifiChip::invalidate() {
xshu37126c92018-04-13 16:24:45 -0700403 if (!writeRingbufferFilesInternal()) {
404 LOG(ERROR) << "Error writing files to flash";
405 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700406 invalidateAndRemoveAllIfaces();
Roshan Pius8574e7f2019-04-01 13:30:40 -0700407 setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700408 legacy_hal_.reset();
409 event_cb_handler_.invalidate();
410 is_valid_ = false;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700411}
412
Roshan Piusabcf78f2017-10-06 16:30:38 -0700413bool WifiChip::isValid() { return is_valid_; }
Roshan Pius3c868522016-10-27 12:43:49 -0700414
Jimmy Chend460df32019-11-29 17:31:22 +0200415std::set<sp<V1_4::IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700416 return event_cb_handler_.getCallbacks();
Roshan Pius203cb032016-12-14 17:41:20 -0800417}
418
Roshan Pius5c055462016-10-11 08:27:27 -0700419Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700420 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
421 &WifiChip::getIdInternal, hidl_status_cb);
Roshan Piuscd566bd2016-10-10 08:03:42 -0700422}
423
Jong Wook Kimda830c92018-07-23 15:29:38 -0700424// Deprecated support for this callback
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700425Return<void> WifiChip::registerEventCallback(
Roshan Pius1ce92cf2018-01-22 16:12:19 -0800426 const sp<V1_0::IWifiChipEventCallback>& event_callback,
Roshan Pius5c055462016-10-11 08:27:27 -0700427 registerEventCallback_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700428 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
429 &WifiChip::registerEventCallbackInternal,
430 hidl_status_cb, event_callback);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700431}
432
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700433Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700434 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
435 &WifiChip::getCapabilitiesInternal, hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700436}
437
Roshan Pius5c055462016-10-11 08:27:27 -0700438Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700439 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
440 &WifiChip::getAvailableModesInternal,
441 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700442}
443
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800444Return<void> WifiChip::configureChip(ChipModeId mode_id,
Roshan Pius5c055462016-10-11 08:27:27 -0700445 configureChip_cb hidl_status_cb) {
Roshan Piusba38d9c2017-12-08 07:32:08 -0800446 return validateAndCallWithLock(
447 this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
448 &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700449}
450
Roshan Pius5c055462016-10-11 08:27:27 -0700451Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700452 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
453 &WifiChip::getModeInternal, hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700454}
455
Roshan Pius5c055462016-10-11 08:27:27 -0700456Return<void> WifiChip::requestChipDebugInfo(
457 requestChipDebugInfo_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700458 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
459 &WifiChip::requestChipDebugInfoInternal,
460 hidl_status_cb);
Roshan Pius5c055462016-10-11 08:27:27 -0700461}
462
463Return<void> WifiChip::requestDriverDebugDump(
464 requestDriverDebugDump_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700465 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
466 &WifiChip::requestDriverDebugDumpInternal,
467 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700468}
469
Roshan Pius5c055462016-10-11 08:27:27 -0700470Return<void> WifiChip::requestFirmwareDebugDump(
471 requestFirmwareDebugDump_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700472 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
473 &WifiChip::requestFirmwareDebugDumpInternal,
474 hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700475}
476
Roshan Pius5c055462016-10-11 08:27:27 -0700477Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700478 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
479 &WifiChip::createApIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700480}
481
lesl94d28242020-11-18 22:17:37 +0800482Return<void> WifiChip::createBridgedApIface(
483 createBridgedApIface_cb hidl_status_cb) {
484 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
485 &WifiChip::createBridgedApIfaceInternal,
486 hidl_status_cb);
487}
488
Roshan Pius5c055462016-10-11 08:27:27 -0700489Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700490 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
491 &WifiChip::getApIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700492}
493
Roshan Pius5c055462016-10-11 08:27:27 -0700494Return<void> WifiChip::getApIface(const hidl_string& ifname,
495 getApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700496 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
497 &WifiChip::getApIfaceInternal, hidl_status_cb,
498 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700499}
500
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800501Return<void> WifiChip::removeApIface(const hidl_string& ifname,
502 removeApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700503 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
504 &WifiChip::removeApIfaceInternal, hidl_status_cb,
505 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800506}
507
lesl94d28242020-11-18 22:17:37 +0800508Return<void> WifiChip::removeIfaceInstanceFromBridgedApIface(
509 const hidl_string& ifname, const hidl_string& ifInstanceName,
510 removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) {
511 return validateAndCall(
512 this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
513 &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal,
514 hidl_status_cb, ifname, ifInstanceName);
515}
516
Roshan Pius5c055462016-10-11 08:27:27 -0700517Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700518 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
519 &WifiChip::createNanIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700520}
521
Roshan Pius5c055462016-10-11 08:27:27 -0700522Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700523 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
524 &WifiChip::getNanIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700525}
526
527Return<void> WifiChip::getNanIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700528 getNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700529 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
530 &WifiChip::getNanIfaceInternal, hidl_status_cb,
531 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700532}
533
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800534Return<void> WifiChip::removeNanIface(const hidl_string& ifname,
535 removeNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700536 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
537 &WifiChip::removeNanIfaceInternal, hidl_status_cb,
538 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800539}
540
Roshan Pius5c055462016-10-11 08:27:27 -0700541Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700542 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
543 &WifiChip::createP2pIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700544}
545
Roshan Pius5c055462016-10-11 08:27:27 -0700546Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700547 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
548 &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700549}
550
551Return<void> WifiChip::getP2pIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700552 getP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700553 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
554 &WifiChip::getP2pIfaceInternal, hidl_status_cb,
555 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700556}
557
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800558Return<void> WifiChip::removeP2pIface(const hidl_string& ifname,
559 removeP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700560 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
561 &WifiChip::removeP2pIfaceInternal, hidl_status_cb,
562 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800563}
564
Roshan Pius5c055462016-10-11 08:27:27 -0700565Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700566 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
567 &WifiChip::createStaIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700568}
569
Roshan Pius5c055462016-10-11 08:27:27 -0700570Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700571 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
572 &WifiChip::getStaIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700573}
574
575Return<void> WifiChip::getStaIface(const hidl_string& ifname,
Roshan Pius5c055462016-10-11 08:27:27 -0700576 getStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700577 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
578 &WifiChip::getStaIfaceInternal, hidl_status_cb,
579 ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700580}
581
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800582Return<void> WifiChip::removeStaIface(const hidl_string& ifname,
583 removeStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700584 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
585 &WifiChip::removeStaIfaceInternal, hidl_status_cb,
586 ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800587}
588
Roshan Pius5c055462016-10-11 08:27:27 -0700589Return<void> WifiChip::createRttController(
590 const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700591 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
592 &WifiChip::createRttControllerInternal,
593 hidl_status_cb, bound_iface);
Roshan Pius59268282016-10-06 20:23:47 -0700594}
595
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700596Return<void> WifiChip::getDebugRingBuffersStatus(
597 getDebugRingBuffersStatus_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700598 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
599 &WifiChip::getDebugRingBuffersStatusInternal,
600 hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700601}
602
603Return<void> WifiChip::startLoggingToDebugRingBuffer(
Roshan Piusabcf78f2017-10-06 16:30:38 -0700604 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
605 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700606 startLoggingToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700607 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
608 &WifiChip::startLoggingToDebugRingBufferInternal,
609 hidl_status_cb, ring_name, verbose_level,
610 max_interval_in_sec, min_data_size_in_bytes);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700611}
612
613Return<void> WifiChip::forceDumpToDebugRingBuffer(
614 const hidl_string& ring_name,
615 forceDumpToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700616 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
617 &WifiChip::forceDumpToDebugRingBufferInternal,
618 hidl_status_cb, ring_name);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700619}
620
Roger Wangb294c762018-11-02 15:34:39 +0800621Return<void> WifiChip::flushRingBufferToFile(
622 flushRingBufferToFile_cb hidl_status_cb) {
623 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
624 &WifiChip::flushRingBufferToFileInternal,
625 hidl_status_cb);
626}
627
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800628Return<void> WifiChip::stopLoggingToDebugRingBuffer(
629 stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700630 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
631 &WifiChip::stopLoggingToDebugRingBufferInternal,
632 hidl_status_cb);
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800633}
634
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700635Return<void> WifiChip::getDebugHostWakeReasonStats(
636 getDebugHostWakeReasonStats_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700637 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
638 &WifiChip::getDebugHostWakeReasonStatsInternal,
639 hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700640}
641
Roshan Pius203cb032016-12-14 17:41:20 -0800642Return<void> WifiChip::enableDebugErrorAlerts(
643 bool enable, enableDebugErrorAlerts_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700644 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
645 &WifiChip::enableDebugErrorAlertsInternal,
646 hidl_status_cb, enable);
Roshan Pius203cb032016-12-14 17:41:20 -0800647}
648
Roshan Pius735ff432017-07-25 08:48:08 -0700649Return<void> WifiChip::selectTxPowerScenario(
Jong Wook Kimda830c92018-07-23 15:29:38 -0700650 V1_1::IWifiChip::TxPowerScenario scenario,
651 selectTxPowerScenario_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700652 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
653 &WifiChip::selectTxPowerScenarioInternal,
654 hidl_status_cb, scenario);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700655}
656
Roshan Pius735ff432017-07-25 08:48:08 -0700657Return<void> WifiChip::resetTxPowerScenario(
658 resetTxPowerScenario_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700659 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
660 &WifiChip::resetTxPowerScenarioInternal,
661 hidl_status_cb);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700662}
663
Ahmed ElArabawyeaf82402018-10-26 09:46:04 -0700664Return<void> WifiChip::setLatencyMode(LatencyMode mode,
665 setLatencyMode_cb hidl_status_cb) {
666 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
667 &WifiChip::setLatencyModeInternal, hidl_status_cb,
668 mode);
669}
670
Roshan Pius1ce92cf2018-01-22 16:12:19 -0800671Return<void> WifiChip::registerEventCallback_1_2(
Jong Wook Kimda830c92018-07-23 15:29:38 -0700672 const sp<V1_2::IWifiChipEventCallback>& event_callback,
Roshan Pius1ce92cf2018-01-22 16:12:19 -0800673 registerEventCallback_cb hidl_status_cb) {
674 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
675 &WifiChip::registerEventCallbackInternal_1_2,
676 hidl_status_cb, event_callback);
677}
678
Ahmed ElArabawy6a1accf2018-01-23 10:57:29 -0800679Return<void> WifiChip::selectTxPowerScenario_1_2(
Jong Wook Kimda830c92018-07-23 15:29:38 -0700680 TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) {
Ahmed ElArabawy6a1accf2018-01-23 10:57:29 -0800681 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Jong Wook Kimda830c92018-07-23 15:29:38 -0700682 &WifiChip::selectTxPowerScenarioInternal_1_2,
683 hidl_status_cb, scenario);
Ahmed ElArabawy6a1accf2018-01-23 10:57:29 -0800684}
685
Ahmed ElArabawyeaf82402018-10-26 09:46:04 -0700686Return<void> WifiChip::getCapabilities_1_3(getCapabilities_cb hidl_status_cb) {
687 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
688 &WifiChip::getCapabilitiesInternal_1_3,
689 hidl_status_cb);
690}
691
Jimmy Chen1bdf1a72019-12-23 17:53:40 +0200692Return<void> WifiChip::getCapabilities_1_5(
693 getCapabilities_1_5_cb hidl_status_cb) {
694 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
695 &WifiChip::getCapabilitiesInternal_1_5,
696 hidl_status_cb);
697}
698
xshu5899e8e2018-01-09 15:36:03 -0800699Return<void> WifiChip::debug(const hidl_handle& handle,
700 const hidl_vec<hidl_string>&) {
701 if (handle != nullptr && handle->numFds >= 1) {
xshu0a0fe512020-07-22 17:53:37 -0700702 {
703 std::unique_lock<std::mutex> lk(lock_t);
704 for (const auto& item : ringbuffer_map_) {
705 forceDumpToDebugRingBufferInternal(item.first);
706 }
707 // unique_lock unlocked here
708 }
709 usleep(100 * 1000); // sleep for 100 milliseconds to wait for
710 // ringbuffer updates.
xshu5899e8e2018-01-09 15:36:03 -0800711 int fd = handle->data[0];
712 if (!writeRingbufferFilesInternal()) {
713 LOG(ERROR) << "Error writing files to flash";
714 }
xshu4cb33162018-01-24 15:40:06 -0800715 uint32_t n_error = cpioArchiveFilesInDir(fd, kTombstoneFolderPath);
xshu5899e8e2018-01-09 15:36:03 -0800716 if (n_error != 0) {
717 LOG(ERROR) << n_error << " errors occured in cpio function";
718 }
719 fsync(fd);
720 } else {
721 LOG(ERROR) << "File handle error";
722 }
723 return Void();
724}
725
Ahmed ElArabawyeeb53382019-10-10 20:18:31 -0700726Return<void> WifiChip::createRttController_1_4(
727 const sp<IWifiIface>& bound_iface,
728 createRttController_1_4_cb hidl_status_cb) {
729 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
730 &WifiChip::createRttControllerInternal_1_4,
731 hidl_status_cb, bound_iface);
732}
733
Ahmed ElArabawyfd809fc2019-11-15 18:19:15 -0800734Return<void> WifiChip::registerEventCallback_1_4(
Jimmy Chend460df32019-11-29 17:31:22 +0200735 const sp<V1_4::IWifiChipEventCallback>& event_callback,
Ahmed ElArabawyfd809fc2019-11-15 18:19:15 -0800736 registerEventCallback_cb hidl_status_cb) {
737 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
738 &WifiChip::registerEventCallbackInternal_1_4,
739 hidl_status_cb, event_callback);
740}
741
Roshan Piuse9d1e7d2020-11-04 11:44:16 -0800742Return<void> WifiChip::setMultiStaPrimaryConnection(
743 const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) {
744 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
745 &WifiChip::setMultiStaPrimaryConnectionInternal,
746 hidl_status_cb, ifname);
747}
748
749Return<void> WifiChip::setMultiStaUseCase(
750 MultiStaUseCase use_case, setMultiStaUseCase_cb hidl_status_cb) {
751 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
752 &WifiChip::setMultiStaUseCaseInternal,
753 hidl_status_cb, use_case);
754}
755
Quang Luong94bcce52020-11-25 17:52:19 -0800756Return<void> WifiChip::setCoexUnsafeChannels(
757 const hidl_vec<CoexUnsafeChannel>& unsafeChannels,
Quang Luongab70a832020-12-14 13:01:32 -0800758 hidl_bitfield<CoexRestriction> restrictions,
Quang Luong94bcce52020-11-25 17:52:19 -0800759 setCoexUnsafeChannels_cb hidl_status_cb) {
760 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
761 &WifiChip::setCoexUnsafeChannelsInternal,
762 hidl_status_cb, unsafeChannels, restrictions);
763}
764
Kumar Anandda62c382020-11-18 17:17:47 -0800765Return<void> WifiChip::setCountryCode(const hidl_array<int8_t, 2>& code,
766 setCountryCode_cb hidl_status_cb) {
767 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
768 &WifiChip::setCountryCodeInternal, hidl_status_cb,
769 code);
770}
771
Kumar Anand2a630a32021-01-21 14:09:14 -0800772Return<void> WifiChip::getUsableChannels(
773 WifiBand band, hidl_bitfield<WifiIfaceMode> ifaceModeMask,
Kumar Anandaea86e02021-02-10 16:22:31 -0800774 hidl_bitfield<UsableChannelFilter> filterMask,
Kumar Anand2a630a32021-01-21 14:09:14 -0800775 getUsableChannels_cb _hidl_cb) {
776 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
777 &WifiChip::getUsableChannelsInternal, _hidl_cb, band,
Kumar Anandaea86e02021-02-10 16:22:31 -0800778 ifaceModeMask, filterMask);
Kumar Anand2a630a32021-01-21 14:09:14 -0800779}
780
chenpaulc6f57032021-03-05 17:06:50 +0800781Return<void> WifiChip::triggerSubsystemRestart(
782 triggerSubsystemRestart_cb hidl_status_cb) {
783 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
784 &WifiChip::triggerSubsystemRestartInternal,
785 hidl_status_cb);
786}
787
Roshan Pius35d958c2016-10-06 16:47:38 -0700788void WifiChip::invalidateAndRemoveAllIfaces() {
lesl94d28242020-11-18 22:17:37 +0800789 invalidateAndClearBridgedApAll();
Roshan Pius675609b2017-10-31 14:24:58 -0700790 invalidateAndClearAll(ap_ifaces_);
791 invalidateAndClearAll(nan_ifaces_);
792 invalidateAndClearAll(p2p_ifaces_);
793 invalidateAndClearAll(sta_ifaces_);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700794 // Since all the ifaces are invalid now, all RTT controller objects
795 // using those ifaces also need to be invalidated.
796 for (const auto& rtt : rtt_controllers_) {
797 rtt->invalidate();
798 }
799 rtt_controllers_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -0700800}
801
Roshan Pius82368502019-05-16 12:53:02 -0700802void WifiChip::invalidateAndRemoveDependencies(
803 const std::string& removed_iface_name) {
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200804 for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) {
805 auto nan_iface = *it;
Roshan Pius82368502019-05-16 12:53:02 -0700806 if (nan_iface->getName() == removed_iface_name) {
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200807 nan_iface->invalidate();
Roshan Pius82368502019-05-16 12:53:02 -0700808 for (const auto& callback : event_cb_handler_.getCallbacks()) {
809 if (!callback
810 ->onIfaceRemoved(IfaceType::NAN, removed_iface_name)
811 .isOk()) {
812 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
813 }
814 }
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200815 it = nan_ifaces_.erase(it);
816 } else {
817 ++it;
Roshan Pius82368502019-05-16 12:53:02 -0700818 }
819 }
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200820
821 for (auto it = rtt_controllers_.begin(); it != rtt_controllers_.end();) {
822 auto rtt = *it;
Roshan Pius82368502019-05-16 12:53:02 -0700823 if (rtt->getIfaceName() == removed_iface_name) {
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200824 rtt->invalidate();
825 it = rtt_controllers_.erase(it);
826 } else {
827 ++it;
Roshan Pius82368502019-05-16 12:53:02 -0700828 }
829 }
830}
831
Roshan Pius3c868522016-10-27 12:43:49 -0700832std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700833 return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700834}
835
836WifiStatus WifiChip::registerEventCallbackInternal(
Roshan Pius1ce92cf2018-01-22 16:12:19 -0800837 const sp<V1_0::IWifiChipEventCallback>& /* event_callback */) {
838 // Deprecated support for this callback.
839 return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
Roshan Pius3c868522016-10-27 12:43:49 -0700840}
841
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700842std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
Ahmed ElArabawyeaf82402018-10-26 09:46:04 -0700843 // Deprecated support for this callback.
844 return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
845}
846
Jimmy Chend460df32019-11-29 17:31:22 +0200847std::pair<WifiStatus, std::vector<V1_4::IWifiChip::ChipMode>>
Roshan Pius3c868522016-10-27 12:43:49 -0700848WifiChip::getAvailableModesInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700849 return {createWifiStatus(WifiStatusCode::SUCCESS), modes_};
Roshan Pius3c868522016-10-27 12:43:49 -0700850}
851
Roshan Piusba38d9c2017-12-08 07:32:08 -0800852WifiStatus WifiChip::configureChipInternal(
853 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
854 ChipModeId mode_id) {
Roshan Piuscc338202017-11-02 13:54:09 -0700855 if (!isValidModeId(mode_id)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700856 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
857 }
858 if (mode_id == current_mode_id_) {
859 LOG(DEBUG) << "Already in the specified mode " << mode_id;
860 return createWifiStatus(WifiStatusCode::SUCCESS);
861 }
Roshan Piusba38d9c2017-12-08 07:32:08 -0800862 WifiStatus status = handleChipConfiguration(lock, mode_id);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700863 if (status.code != WifiStatusCode::SUCCESS) {
864 for (const auto& callback : event_cb_handler_.getCallbacks()) {
865 if (!callback->onChipReconfigureFailure(status).isOk()) {
866 LOG(ERROR)
867 << "Failed to invoke onChipReconfigureFailure callback";
868 }
869 }
870 return status;
871 }
Roshan Piusd37341f2017-01-31 13:13:28 -0800872 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700873 if (!callback->onChipReconfigured(mode_id).isOk()) {
874 LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
875 }
Roshan Pius52947fb2016-11-18 11:38:07 -0800876 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700877 current_mode_id_ = mode_id;
Roshan Piusba38d9c2017-12-08 07:32:08 -0800878 LOG(INFO) << "Configured chip in mode " << mode_id;
Roshan Pius8574e7f2019-04-01 13:30:40 -0700879 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
Ahmed ElArabawy2134bf72020-06-18 15:07:12 -0700880
881 legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(
882 subsystemCallbackHandler_);
883
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800884 return status;
Roshan Pius3c868522016-10-27 12:43:49 -0700885}
886
887std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700888 if (!isValidModeId(current_mode_id_)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700889 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE),
890 current_mode_id_};
891 }
892 return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700893}
894
Jimmy Chend460df32019-11-29 17:31:22 +0200895std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo>
Roshan Pius3c868522016-10-27 12:43:49 -0700896WifiChip::requestChipDebugInfoInternal() {
Jimmy Chend460df32019-11-29 17:31:22 +0200897 V1_4::IWifiChip::ChipDebugInfo result;
Roshan Piusabcf78f2017-10-06 16:30:38 -0700898 legacy_hal::wifi_error legacy_status;
899 std::string driver_desc;
Roshan Pius6036c022019-03-27 10:41:58 -0700900 const auto ifname = getFirstActiveWlanIfaceName();
Roshan Piusabcf78f2017-10-06 16:30:38 -0700901 std::tie(legacy_status, driver_desc) =
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -0800902 legacy_hal_.lock()->getDriverVersion(ifname);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700903 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
904 LOG(ERROR) << "Failed to get driver version: "
905 << legacyErrorToString(legacy_status);
906 WifiStatus status = createWifiStatusFromLegacyError(
907 legacy_status, "failed to get driver version");
908 return {status, result};
909 }
910 result.driverDescription = driver_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700911
Roshan Piusabcf78f2017-10-06 16:30:38 -0700912 std::string firmware_desc;
913 std::tie(legacy_status, firmware_desc) =
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -0800914 legacy_hal_.lock()->getFirmwareVersion(ifname);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700915 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
916 LOG(ERROR) << "Failed to get firmware version: "
917 << legacyErrorToString(legacy_status);
918 WifiStatus status = createWifiStatusFromLegacyError(
919 legacy_status, "failed to get firmware version");
920 return {status, result};
921 }
922 result.firmwareDescription = firmware_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700923
Roshan Piusabcf78f2017-10-06 16:30:38 -0700924 return {createWifiStatus(WifiStatusCode::SUCCESS), result};
Roshan Pius3c868522016-10-27 12:43:49 -0700925}
926
927std::pair<WifiStatus, std::vector<uint8_t>>
928WifiChip::requestDriverDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700929 legacy_hal::wifi_error legacy_status;
930 std::vector<uint8_t> driver_dump;
931 std::tie(legacy_status, driver_dump) =
Roshan Pius6036c022019-03-27 10:41:58 -0700932 legacy_hal_.lock()->requestDriverMemoryDump(
933 getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -0700934 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
935 LOG(ERROR) << "Failed to get driver debug dump: "
936 << legacyErrorToString(legacy_status);
937 return {createWifiStatusFromLegacyError(legacy_status),
938 std::vector<uint8_t>()};
939 }
940 return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
Roshan Pius3c868522016-10-27 12:43:49 -0700941}
942
943std::pair<WifiStatus, std::vector<uint8_t>>
944WifiChip::requestFirmwareDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700945 legacy_hal::wifi_error legacy_status;
946 std::vector<uint8_t> firmware_dump;
947 std::tie(legacy_status, firmware_dump) =
Roshan Pius6036c022019-03-27 10:41:58 -0700948 legacy_hal_.lock()->requestFirmwareMemoryDump(
949 getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -0700950 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
951 LOG(ERROR) << "Failed to get firmware debug dump: "
952 << legacyErrorToString(legacy_status);
953 return {createWifiStatusFromLegacyError(legacy_status), {}};
954 }
955 return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
Roshan Pius3c868522016-10-27 12:43:49 -0700956}
957
lesl94d28242020-11-18 22:17:37 +0800958WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) {
959 legacy_hal::wifi_error legacy_status;
960 legacy_status = legacy_hal_.lock()->createVirtualInterface(
961 apVirtIf,
962 hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP));
Sunil Raviddab4bb2020-02-03 22:45:19 -0800963 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
lesl94d28242020-11-18 22:17:37 +0800964 LOG(ERROR) << "Failed to add interface: " << apVirtIf << " "
Sunil Raviddab4bb2020-02-03 22:45:19 -0800965 << legacyErrorToString(legacy_status);
lesl94d28242020-11-18 22:17:37 +0800966 return createWifiStatusFromLegacyError(legacy_status);
Sunil Raviddab4bb2020-02-03 22:45:19 -0800967 }
lesl94d28242020-11-18 22:17:37 +0800968 return createWifiStatus(WifiStatusCode::SUCCESS);
969}
970
971sp<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) {
lesl420c4fc2020-11-23 19:33:04 +0800972 std::vector<std::string> ap_instances;
973 for (auto const& it : br_ifaces_ap_instances_) {
974 if (it.first == ifname) {
975 ap_instances = it.second;
976 }
977 }
978 sp<WifiApIface> iface =
979 new WifiApIface(ifname, ap_instances, legacy_hal_, iface_util_);
Roshan Pius675609b2017-10-31 14:24:58 -0700980 ap_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700981 for (const auto& callback : event_cb_handler_.getCallbacks()) {
982 if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
983 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
984 }
985 }
Roshan Pius8574e7f2019-04-01 13:30:40 -0700986 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
lesl94d28242020-11-18 22:17:37 +0800987 return iface;
988}
989
lesl420c4fc2020-11-23 19:33:04 +0800990std::pair<WifiStatus, sp<V1_5::IWifiApIface>>
991WifiChip::createApIfaceInternal() {
lesl94d28242020-11-18 22:17:37 +0800992 if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
993 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
994 }
995 std::string ifname = allocateApIfaceName();
996 WifiStatus status = createVirtualApInterface(ifname);
997 if (status.code != WifiStatusCode::SUCCESS) {
998 return {status, {}};
999 }
1000 sp<WifiApIface> iface = newWifiApIface(ifname);
1001 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1002}
1003
lesl420c4fc2020-11-23 19:33:04 +08001004std::pair<WifiStatus, sp<V1_5::IWifiApIface>>
lesl94d28242020-11-18 22:17:37 +08001005WifiChip::createBridgedApIfaceInternal() {
1006 if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
1007 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1008 }
lesl261818b2020-11-27 12:37:35 +08001009 std::vector<std::string> ap_instances = allocateBridgedApInstanceNames();
1010 if (ap_instances.size() < 2) {
1011 LOG(ERROR) << "Fail to allocate two instances";
1012 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1013 }
1014 std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0];
lesl94d28242020-11-18 22:17:37 +08001015 for (int i = 0; i < 2; i++) {
lesl261818b2020-11-27 12:37:35 +08001016 WifiStatus status = createVirtualApInterface(ap_instances[i]);
lesl94d28242020-11-18 22:17:37 +08001017 if (status.code != WifiStatusCode::SUCCESS) {
lesl261818b2020-11-27 12:37:35 +08001018 if (i != 0) { // The failure happened when creating second virtual
1019 // iface.
lesl94d28242020-11-18 22:17:37 +08001020 legacy_hal_.lock()->deleteVirtualInterface(
lesl261818b2020-11-27 12:37:35 +08001021 ap_instances.front()); // Remove the first virtual iface.
lesl94d28242020-11-18 22:17:37 +08001022 }
1023 return {status, {}};
1024 }
lesl94d28242020-11-18 22:17:37 +08001025 }
1026 br_ifaces_ap_instances_[br_ifname] = ap_instances;
Roshan Pius8c1a67b2021-03-02 10:00:23 -08001027 if (!iface_util_->createBridge(br_ifname)) {
lesl94d28242020-11-18 22:17:37 +08001028 LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
1029 invalidateAndClearBridgedAp(br_ifname);
1030 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1031 }
1032 for (auto const& instance : ap_instances) {
1033 // Bind ap instance interface to AP bridge
Roshan Pius8c1a67b2021-03-02 10:00:23 -08001034 if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
lesl94d28242020-11-18 22:17:37 +08001035 LOG(ERROR) << "Failed add if to Bridge - if_name="
1036 << instance.c_str();
1037 invalidateAndClearBridgedAp(br_ifname);
1038 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1039 }
1040 }
1041 sp<WifiApIface> iface = newWifiApIface(br_ifname);
Roshan Pius675609b2017-10-31 14:24:58 -07001042 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001043}
1044
1045std::pair<WifiStatus, std::vector<hidl_string>>
1046WifiChip::getApIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -07001047 if (ap_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001048 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
1049 }
Roshan Pius675609b2017-10-31 14:24:58 -07001050 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -07001051}
1052
lesl420c4fc2020-11-23 19:33:04 +08001053std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::getApIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001054 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001055 const auto iface = findUsingName(ap_ifaces_, ifname);
1056 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001057 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
1058 }
Roshan Pius675609b2017-10-31 14:24:58 -07001059 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001060}
1061
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001062WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001063 const auto iface = findUsingName(ap_ifaces_, ifname);
1064 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001065 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -08001066 }
Roshan Pius82368502019-05-16 12:53:02 -07001067 // Invalidate & remove any dependent objects first.
1068 // Note: This is probably not required because we never create
1069 // nan/rtt objects over AP iface. But, there is no harm to do it
1070 // here and not make that assumption all over the place.
1071 invalidateAndRemoveDependencies(ifname);
lesl94d28242020-11-18 22:17:37 +08001072 // Clear the bridge interface and the iface instance.
1073 invalidateAndClearBridgedAp(ifname);
Roshan Pius675609b2017-10-31 14:24:58 -07001074 invalidateAndClear(ap_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001075 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1076 if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
1077 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1078 }
1079 }
Roshan Pius8574e7f2019-04-01 13:30:40 -07001080 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001081 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001082}
1083
lesl94d28242020-11-18 22:17:37 +08001084WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
1085 const std::string& ifname, const std::string& ifInstanceName) {
lesl94d28242020-11-18 22:17:37 +08001086 const auto iface = findUsingName(ap_ifaces_, ifname);
lesl819e3722021-01-07 09:49:04 +08001087 if (!iface.get() || ifInstanceName.empty()) {
lesl94d28242020-11-18 22:17:37 +08001088 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1089 }
1090 // Requires to remove one of the instance in bridge mode
1091 for (auto const& it : br_ifaces_ap_instances_) {
1092 if (it.first == ifname) {
Les Lee03d642f2021-06-21 21:25:20 +08001093 std::vector<std::string> ap_instances = it.second;
1094 for (auto const& iface : ap_instances) {
lesl94d28242020-11-18 22:17:37 +08001095 if (iface == ifInstanceName) {
Roshan Pius8c1a67b2021-03-02 10:00:23 -08001096 if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
George Burgess IV2c0a47d2021-01-20 21:14:13 -08001097 LOG(ERROR)
1098 << "Failed to remove interface: " << ifInstanceName
1099 << " from " << ifname;
lesl94d28242020-11-18 22:17:37 +08001100 return createWifiStatus(
1101 WifiStatusCode::ERROR_NOT_AVAILABLE);
1102 }
George Burgess IV2c0a47d2021-01-20 21:14:13 -08001103 legacy_hal::wifi_error legacy_status =
lesl94d28242020-11-18 22:17:37 +08001104 legacy_hal_.lock()->deleteVirtualInterface(iface);
1105 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1106 LOG(ERROR) << "Failed to del interface: " << iface
1107 << " " << legacyErrorToString(legacy_status);
1108 return createWifiStatusFromLegacyError(legacy_status);
1109 }
Les Lee03d642f2021-06-21 21:25:20 +08001110 ap_instances.erase(
1111 std::remove(ap_instances.begin(), ap_instances.end(),
1112 ifInstanceName),
1113 ap_instances.end());
1114 br_ifaces_ap_instances_[ifname] = ap_instances;
1115 break;
lesl94d28242020-11-18 22:17:37 +08001116 }
1117 }
1118 break;
1119 }
1120 }
lesl669c9062021-01-22 19:37:47 +08001121 iface->removeInstance(ifInstanceName);
Les Lee03d642f2021-06-21 21:25:20 +08001122 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1123
lesl94d28242020-11-18 22:17:37 +08001124 return createWifiStatus(WifiStatusCode::SUCCESS);
1125}
1126
Jimmy Chend460df32019-11-29 17:31:22 +02001127std::pair<WifiStatus, sp<V1_4::IWifiNanIface>>
1128WifiChip::createNanIfaceInternal() {
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001129 if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001130 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Etan Cohenc5700402017-03-08 16:43:38 -08001131 }
Roshan Pius5ba0a902020-04-14 11:55:42 -07001132 bool is_dedicated_iface = true;
lesl261818b2020-11-27 12:37:35 +08001133 std::string ifname = getPredefinedNanIfaceName();
Roshan Pius8c1a67b2021-03-02 10:00:23 -08001134 if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) {
Roshan Pius5ba0a902020-04-14 11:55:42 -07001135 // Use the first shared STA iface (wlan0) if a dedicated aware iface is
1136 // not defined.
1137 ifname = getFirstActiveWlanIfaceName();
1138 is_dedicated_iface = false;
1139 }
1140 sp<WifiNanIface> iface =
1141 new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
Roshan Piuscc338202017-11-02 13:54:09 -07001142 nan_ifaces_.push_back(iface);
1143 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1144 if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
1145 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1146 }
1147 }
1148 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001149}
1150
1151std::pair<WifiStatus, std::vector<hidl_string>>
1152WifiChip::getNanIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -07001153 if (nan_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001154 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
1155 }
Roshan Pius675609b2017-10-31 14:24:58 -07001156 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -07001157}
1158
Jimmy Chend460df32019-11-29 17:31:22 +02001159std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::getNanIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001160 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001161 const auto iface = findUsingName(nan_ifaces_, ifname);
1162 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001163 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
1164 }
Roshan Pius675609b2017-10-31 14:24:58 -07001165 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001166}
1167
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001168WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001169 const auto iface = findUsingName(nan_ifaces_, ifname);
1170 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001171 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -08001172 }
Roshan Pius675609b2017-10-31 14:24:58 -07001173 invalidateAndClear(nan_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001174 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1175 if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
1176 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1177 }
1178 }
1179 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001180}
1181
Roshan Pius3c868522016-10-27 12:43:49 -07001182std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001183 if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::P2P)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001184 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -08001185 }
lesl261818b2020-11-27 12:37:35 +08001186 std::string ifname = getPredefinedP2pIfaceName();
Roshan Pius675609b2017-10-31 14:24:58 -07001187 sp<WifiP2pIface> iface = new WifiP2pIface(ifname, legacy_hal_);
1188 p2p_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001189 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1190 if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
1191 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1192 }
1193 }
Roshan Pius675609b2017-10-31 14:24:58 -07001194 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001195}
1196
1197std::pair<WifiStatus, std::vector<hidl_string>>
1198WifiChip::getP2pIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -07001199 if (p2p_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001200 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
1201 }
Roshan Pius675609b2017-10-31 14:24:58 -07001202 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -07001203}
1204
1205std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001206 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001207 const auto iface = findUsingName(p2p_ifaces_, ifname);
1208 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001209 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
1210 }
Roshan Pius675609b2017-10-31 14:24:58 -07001211 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001212}
1213
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001214WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001215 const auto iface = findUsingName(p2p_ifaces_, ifname);
1216 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001217 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -08001218 }
Roshan Pius675609b2017-10-31 14:24:58 -07001219 invalidateAndClear(p2p_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001220 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1221 if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
1222 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1223 }
1224 }
1225 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001226}
1227
Roshan Piuse9d1e7d2020-11-04 11:44:16 -08001228std::pair<WifiStatus, sp<V1_5::IWifiStaIface>>
Ahmed ElArabawyb23485d2019-12-09 15:24:16 -08001229WifiChip::createStaIfaceInternal() {
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001230 if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001231 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -08001232 }
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001233 std::string ifname = allocateStaIfaceName();
Sunil Raviddab4bb2020-02-03 22:45:19 -08001234 legacy_hal::wifi_error legacy_status =
1235 legacy_hal_.lock()->createVirtualInterface(
1236 ifname,
1237 hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA));
1238 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1239 LOG(ERROR) << "Failed to add interface: " << ifname << " "
1240 << legacyErrorToString(legacy_status);
1241 return {createWifiStatusFromLegacyError(legacy_status), {}};
1242 }
Roshan Pius99dab382019-02-14 07:57:10 -08001243 sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_);
Roshan Pius675609b2017-10-31 14:24:58 -07001244 sta_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001245 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1246 if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
1247 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1248 }
1249 }
Roshan Pius8574e7f2019-04-01 13:30:40 -07001250 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
Roshan Pius675609b2017-10-31 14:24:58 -07001251 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001252}
1253
1254std::pair<WifiStatus, std::vector<hidl_string>>
1255WifiChip::getStaIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -07001256 if (sta_ifaces_.empty()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001257 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
1258 }
Roshan Pius675609b2017-10-31 14:24:58 -07001259 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -07001260}
1261
Roshan Piuse9d1e7d2020-11-04 11:44:16 -08001262std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> WifiChip::getStaIfaceInternal(
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001263 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001264 const auto iface = findUsingName(sta_ifaces_, ifname);
1265 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001266 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
1267 }
Roshan Pius675609b2017-10-31 14:24:58 -07001268 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001269}
1270
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001271WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001272 const auto iface = findUsingName(sta_ifaces_, ifname);
1273 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001274 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -08001275 }
Roshan Pius82368502019-05-16 12:53:02 -07001276 // Invalidate & remove any dependent objects first.
1277 invalidateAndRemoveDependencies(ifname);
Sunil Raviddab4bb2020-02-03 22:45:19 -08001278 legacy_hal::wifi_error legacy_status =
1279 legacy_hal_.lock()->deleteVirtualInterface(ifname);
1280 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1281 LOG(ERROR) << "Failed to remove interface: " << ifname << " "
1282 << legacyErrorToString(legacy_status);
1283 }
Roshan Pius675609b2017-10-31 14:24:58 -07001284 invalidateAndClear(sta_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001285 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1286 if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
1287 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1288 }
1289 }
Roshan Pius8574e7f2019-04-01 13:30:40 -07001290 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001291 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001292}
1293
Ahmed ElArabawyeeb53382019-10-10 20:18:31 -07001294std::pair<WifiStatus, sp<V1_0::IWifiRttController>>
1295WifiChip::createRttControllerInternal(const sp<IWifiIface>& /*bound_iface*/) {
1296 LOG(ERROR) << "createRttController is not supported on this HAL";
Ahmed ElArabawy36defb32019-12-29 21:24:27 -08001297 return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
Roshan Pius3c868522016-10-27 12:43:49 -07001298}
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001299
1300std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
1301WifiChip::getDebugRingBuffersStatusInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001302 legacy_hal::wifi_error legacy_status;
1303 std::vector<legacy_hal::wifi_ring_buffer_status>
1304 legacy_ring_buffer_status_vec;
1305 std::tie(legacy_status, legacy_ring_buffer_status_vec) =
Roshan Pius6036c022019-03-27 10:41:58 -07001306 legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001307 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1308 return {createWifiStatusFromLegacyError(legacy_status), {}};
1309 }
1310 std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
1311 if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
1312 legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
1313 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
1314 }
1315 return {createWifiStatus(WifiStatusCode::SUCCESS),
1316 hidl_ring_buffer_status_vec};
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001317}
1318
1319WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
Roshan Piusabcf78f2017-10-06 16:30:38 -07001320 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
1321 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
1322 WifiStatus status = registerDebugRingBufferCallback();
1323 if (status.code != WifiStatusCode::SUCCESS) {
1324 return status;
1325 }
1326 legacy_hal::wifi_error legacy_status =
1327 legacy_hal_.lock()->startRingBufferLogging(
Roshan Pius6036c022019-03-27 10:41:58 -07001328 getFirstActiveWlanIfaceName(), ring_name,
Roshan Piusabcf78f2017-10-06 16:30:38 -07001329 static_cast<
1330 std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
1331 verbose_level),
1332 max_interval_in_sec, min_data_size_in_bytes);
xshu5899e8e2018-01-09 15:36:03 -08001333 ringbuffer_map_.insert(std::pair<std::string, Ringbuffer>(
1334 ring_name, Ringbuffer(kMaxBufferSizeBytes)));
Roshan Piusa63b53f2019-11-18 11:03:13 -08001335 // if verbose logging enabled, turn up HAL daemon logging as well.
1336 if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
1337 android::base::SetMinimumLogSeverity(android::base::DEBUG);
1338 } else {
1339 android::base::SetMinimumLogSeverity(android::base::VERBOSE);
1340 }
Roshan Piusabcf78f2017-10-06 16:30:38 -07001341 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001342}
1343
1344WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
Roshan Piuse2d0ab52016-12-05 15:24:20 -08001345 const hidl_string& ring_name) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001346 WifiStatus status = registerDebugRingBufferCallback();
1347 if (status.code != WifiStatusCode::SUCCESS) {
1348 return status;
1349 }
1350 legacy_hal::wifi_error legacy_status =
Roshan Pius6036c022019-03-27 10:41:58 -07001351 legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(),
1352 ring_name);
xshu5899e8e2018-01-09 15:36:03 -08001353
Roshan Piusabcf78f2017-10-06 16:30:38 -07001354 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001355}
1356
Roger Wangb294c762018-11-02 15:34:39 +08001357WifiStatus WifiChip::flushRingBufferToFileInternal() {
1358 if (!writeRingbufferFilesInternal()) {
1359 LOG(ERROR) << "Error writing files to flash";
1360 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1361 }
1362 return createWifiStatus(WifiStatusCode::SUCCESS);
1363}
1364
Roshan Pius8c0c8e92017-02-24 08:07:42 -08001365WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001366 legacy_hal::wifi_error legacy_status =
1367 legacy_hal_.lock()->deregisterRingBufferCallbackHandler(
Roshan Pius6036c022019-03-27 10:41:58 -07001368 getFirstActiveWlanIfaceName());
xshu0a0fe512020-07-22 17:53:37 -07001369 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1370 debug_ring_buffer_cb_registered_ = false;
1371 }
Roshan Piusabcf78f2017-10-06 16:30:38 -07001372 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius8c0c8e92017-02-24 08:07:42 -08001373}
1374
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001375std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
1376WifiChip::getDebugHostWakeReasonStatsInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001377 legacy_hal::wifi_error legacy_status;
1378 legacy_hal::WakeReasonStats legacy_stats;
1379 std::tie(legacy_status, legacy_stats) =
Roshan Pius6036c022019-03-27 10:41:58 -07001380 legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001381 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1382 return {createWifiStatusFromLegacyError(legacy_status), {}};
1383 }
1384 WifiDebugHostWakeReasonStats hidl_stats;
1385 if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats,
1386 &hidl_stats)) {
1387 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
1388 }
1389 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001390}
1391
Roshan Pius203cb032016-12-14 17:41:20 -08001392WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001393 legacy_hal::wifi_error legacy_status;
1394 if (enable) {
1395 android::wp<WifiChip> weak_ptr_this(this);
1396 const auto& on_alert_callback = [weak_ptr_this](
1397 int32_t error_code,
1398 std::vector<uint8_t> debug_data) {
1399 const auto shared_ptr_this = weak_ptr_this.promote();
1400 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1401 LOG(ERROR) << "Callback invoked on an invalid object";
1402 return;
1403 }
1404 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
1405 if (!callback->onDebugErrorAlert(error_code, debug_data)
1406 .isOk()) {
1407 LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
1408 }
1409 }
1410 };
1411 legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
Roshan Pius6036c022019-03-27 10:41:58 -07001412 getFirstActiveWlanIfaceName(), on_alert_callback);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001413 } else {
1414 legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
Roshan Pius6036c022019-03-27 10:41:58 -07001415 getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001416 }
1417 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius203cb032016-12-14 17:41:20 -08001418}
Roshan Pius2c06a3f2016-12-15 17:51:40 -08001419
Ahmed ElArabawy6a1accf2018-01-23 10:57:29 -08001420WifiStatus WifiChip::selectTxPowerScenarioInternal(
Jong Wook Kimda830c92018-07-23 15:29:38 -07001421 V1_1::IWifiChip::TxPowerScenario scenario) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001422 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
Roshan Pius6036c022019-03-27 10:41:58 -07001423 getFirstActiveWlanIfaceName(),
Roshan Piusabcf78f2017-10-06 16:30:38 -07001424 hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
1425 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -07001426}
1427
Roshan Pius735ff432017-07-25 08:48:08 -07001428WifiStatus WifiChip::resetTxPowerScenarioInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001429 auto legacy_status =
Roshan Pius6036c022019-03-27 10:41:58 -07001430 legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001431 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -07001432}
1433
Ahmed ElArabawyeaf82402018-10-26 09:46:04 -07001434WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) {
1435 auto legacy_status = legacy_hal_.lock()->setLatencyMode(
Roshan Pius6036c022019-03-27 10:41:58 -07001436 getFirstActiveWlanIfaceName(),
Ahmed ElArabawyeaf82402018-10-26 09:46:04 -07001437 hidl_struct_util::convertHidlLatencyModeToLegacy(mode));
1438 return createWifiStatusFromLegacyError(legacy_status);
1439}
1440
Roshan Pius1ce92cf2018-01-22 16:12:19 -08001441WifiStatus WifiChip::registerEventCallbackInternal_1_2(
Ahmed ElArabawyfd809fc2019-11-15 18:19:15 -08001442 const sp<V1_2::IWifiChipEventCallback>& /* event_callback */) {
1443 // Deprecated support for this callback.
1444 return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
Roshan Pius1ce92cf2018-01-22 16:12:19 -08001445}
1446
Jong Wook Kimda830c92018-07-23 15:29:38 -07001447WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(
1448 TxPowerScenario scenario) {
Ahmed ElArabawy6a1accf2018-01-23 10:57:29 -08001449 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
Roshan Pius6036c022019-03-27 10:41:58 -07001450 getFirstActiveWlanIfaceName(),
Ahmed ElArabawy6a1accf2018-01-23 10:57:29 -08001451 hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario));
1452 return createWifiStatusFromLegacyError(legacy_status);
1453}
1454
Ahmed ElArabawyeeb53382019-10-10 20:18:31 -07001455std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_3() {
Jimmy Chen1bdf1a72019-12-23 17:53:40 +02001456 // Deprecated support for this callback.
1457 return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
1458}
1459
1460std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_5() {
Ahmed ElArabawyeeb53382019-10-10 20:18:31 -07001461 legacy_hal::wifi_error legacy_status;
Jimmy Chen1bdf1a72019-12-23 17:53:40 +02001462 uint64_t legacy_feature_set;
Ahmed ElArabawyeeb53382019-10-10 20:18:31 -07001463 uint32_t legacy_logger_feature_set;
1464 const auto ifname = getFirstActiveWlanIfaceName();
1465 std::tie(legacy_status, legacy_feature_set) =
1466 legacy_hal_.lock()->getSupportedFeatureSet(ifname);
1467 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1468 return {createWifiStatusFromLegacyError(legacy_status), 0};
1469 }
1470 std::tie(legacy_status, legacy_logger_feature_set) =
1471 legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
1472 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1473 // some devices don't support querying logger feature set
1474 legacy_logger_feature_set = 0;
1475 }
1476 uint32_t hidl_caps;
1477 if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
1478 legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
1479 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
1480 }
1481 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
1482}
1483
Jimmy Chend460df32019-11-29 17:31:22 +02001484std::pair<WifiStatus, sp<V1_4::IWifiRttController>>
Ahmed ElArabawyeeb53382019-10-10 20:18:31 -07001485WifiChip::createRttControllerInternal_1_4(const sp<IWifiIface>& bound_iface) {
1486 if (sta_ifaces_.size() == 0 &&
1487 !canCurrentModeSupportIfaceOfType(IfaceType::STA)) {
1488 LOG(ERROR)
1489 << "createRttControllerInternal_1_4: Chip cannot support STAs "
1490 "(and RTT by extension)";
1491 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1492 }
1493 sp<WifiRttController> rtt = new WifiRttController(
1494 getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
1495 rtt_controllers_.emplace_back(rtt);
1496 return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
1497}
1498
Ahmed ElArabawyfd809fc2019-11-15 18:19:15 -08001499WifiStatus WifiChip::registerEventCallbackInternal_1_4(
Jimmy Chend460df32019-11-29 17:31:22 +02001500 const sp<V1_4::IWifiChipEventCallback>& event_callback) {
Ahmed ElArabawyfd809fc2019-11-15 18:19:15 -08001501 if (!event_cb_handler_.addCallback(event_callback)) {
1502 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1503 }
1504 return createWifiStatus(WifiStatusCode::SUCCESS);
1505}
1506
Roshan Piuse9d1e7d2020-11-04 11:44:16 -08001507WifiStatus WifiChip::setMultiStaPrimaryConnectionInternal(
1508 const std::string& ifname) {
1509 auto legacy_status =
1510 legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname);
1511 return createWifiStatusFromLegacyError(legacy_status);
1512}
1513
1514WifiStatus WifiChip::setMultiStaUseCaseInternal(MultiStaUseCase use_case) {
1515 auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase(
1516 hidl_struct_util::convertHidlMultiStaUseCaseToLegacy(use_case));
1517 return createWifiStatusFromLegacyError(legacy_status);
1518}
1519
Quang Luong94bcce52020-11-25 17:52:19 -08001520WifiStatus WifiChip::setCoexUnsafeChannelsInternal(
1521 std::vector<CoexUnsafeChannel> unsafe_channels, uint32_t restrictions) {
1522 std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels;
1523 if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy(
1524 unsafe_channels, &legacy_unsafe_channels)) {
1525 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1526 }
Quang Luongab70a832020-12-14 13:01:32 -08001527 uint32_t legacy_restrictions = 0;
1528 if (restrictions & CoexRestriction::WIFI_DIRECT) {
1529 legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_DIRECT;
1530 }
1531 if (restrictions & CoexRestriction::SOFTAP) {
1532 legacy_restrictions |= legacy_hal::wifi_coex_restriction::SOFTAP;
1533 }
1534 if (restrictions & CoexRestriction::WIFI_AWARE) {
1535 legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE;
1536 }
Quang Luong94bcce52020-11-25 17:52:19 -08001537 auto legacy_status = legacy_hal_.lock()->setCoexUnsafeChannels(
Quang Luongab70a832020-12-14 13:01:32 -08001538 legacy_unsafe_channels, legacy_restrictions);
Quang Luong94bcce52020-11-25 17:52:19 -08001539 return createWifiStatusFromLegacyError(legacy_status);
1540}
1541
Kumar Anandda62c382020-11-18 17:17:47 -08001542WifiStatus WifiChip::setCountryCodeInternal(const std::array<int8_t, 2>& code) {
1543 auto legacy_status =
1544 legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code);
1545 return createWifiStatusFromLegacyError(legacy_status);
1546}
1547
Kumar Anand2a630a32021-01-21 14:09:14 -08001548std::pair<WifiStatus, std::vector<WifiUsableChannel>>
Kumar Anandaea86e02021-02-10 16:22:31 -08001549WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask,
1550 uint32_t filterMask) {
Kumar Anand2a630a32021-01-21 14:09:14 -08001551 legacy_hal::wifi_error legacy_status;
1552 std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels;
1553 std::tie(legacy_status, legacy_usable_channels) =
1554 legacy_hal_.lock()->getUsableChannels(
1555 hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band),
Kumar Anandaea86e02021-02-10 16:22:31 -08001556 hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask),
1557 hidl_struct_util::convertHidlUsableChannelFilterToLegacy(
1558 filterMask));
1559
Kumar Anand2a630a32021-01-21 14:09:14 -08001560 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1561 return {createWifiStatusFromLegacyError(legacy_status), {}};
1562 }
1563 std::vector<WifiUsableChannel> hidl_usable_channels;
1564 if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl(
1565 legacy_usable_channels, &hidl_usable_channels)) {
1566 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
1567 }
1568 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels};
1569}
1570
chenpaulc6f57032021-03-05 17:06:50 +08001571WifiStatus WifiChip::triggerSubsystemRestartInternal() {
1572 auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart();
1573 return createWifiStatusFromLegacyError(legacy_status);
1574}
1575
Roshan Piusba38d9c2017-12-08 07:32:08 -08001576WifiStatus WifiChip::handleChipConfiguration(
1577 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
1578 ChipModeId mode_id) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001579 // If the chip is already configured in a different mode, stop
1580 // the legacy HAL and then start it after firmware mode change.
Roshan Piuscc338202017-11-02 13:54:09 -07001581 if (isValidModeId(current_mode_id_)) {
Roshan Piusba38d9c2017-12-08 07:32:08 -08001582 LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_
1583 << " to mode " << mode_id;
1584 invalidateAndRemoveAllIfaces();
1585 legacy_hal::wifi_error legacy_status =
1586 legacy_hal_.lock()->stop(lock, []() {});
1587 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1588 LOG(ERROR) << "Failed to stop legacy HAL: "
1589 << legacyErrorToString(legacy_status);
1590 return createWifiStatusFromLegacyError(legacy_status);
1591 }
Roshan Piusabcf78f2017-10-06 16:30:38 -07001592 }
Roshan Piuscc338202017-11-02 13:54:09 -07001593 // Firmware mode change not needed for V2 devices.
1594 bool success = true;
Tomasz Wasilczykb424da72018-11-15 11:52:57 -08001595 if (mode_id == feature_flags::chip_mode_ids::kV1Sta) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001596 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
Tomasz Wasilczykb424da72018-11-15 11:52:57 -08001597 } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001598 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
1599 }
1600 if (!success) {
1601 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1602 }
1603 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
1604 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1605 LOG(ERROR) << "Failed to start legacy HAL: "
1606 << legacyErrorToString(legacy_status);
1607 return createWifiStatusFromLegacyError(legacy_status);
1608 }
Roshan Pius85c64412018-01-22 17:58:40 -08001609 // Every time the HAL is restarted, we need to register the
1610 // radio mode change callback.
1611 WifiStatus status = registerRadioModeChangeCallback();
1612 if (status.code != WifiStatusCode::SUCCESS) {
1613 // This probably is not a critical failure?
1614 LOG(ERROR) << "Failed to register radio mode change callback";
1615 }
chenpaulf5eca292019-03-14 11:08:03 +08001616 // Extract and save the version information into property.
Jimmy Chend460df32019-11-29 17:31:22 +02001617 std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo> version_info;
chenpaulf5eca292019-03-14 11:08:03 +08001618 version_info = WifiChip::requestChipDebugInfoInternal();
1619 if (WifiStatusCode::SUCCESS == version_info.first.code) {
1620 property_set("vendor.wlan.firmware.version",
1621 version_info.second.firmwareDescription.c_str());
1622 property_set("vendor.wlan.driver.version",
1623 version_info.second.driverDescription.c_str());
1624 }
1625
Roshan Piusabcf78f2017-10-06 16:30:38 -07001626 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius2c06a3f2016-12-15 17:51:40 -08001627}
Roshan Pius48185b22016-12-15 19:10:30 -08001628
1629WifiStatus WifiChip::registerDebugRingBufferCallback() {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001630 if (debug_ring_buffer_cb_registered_) {
1631 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius48185b22016-12-15 19:10:30 -08001632 }
Roshan Pius3797e182017-03-30 18:01:54 -07001633
Roshan Piusabcf78f2017-10-06 16:30:38 -07001634 android::wp<WifiChip> weak_ptr_this(this);
1635 const auto& on_ring_buffer_data_callback =
xshu5899e8e2018-01-09 15:36:03 -08001636 [weak_ptr_this](const std::string& name,
Roshan Piusabcf78f2017-10-06 16:30:38 -07001637 const std::vector<uint8_t>& data,
1638 const legacy_hal::wifi_ring_buffer_status& status) {
1639 const auto shared_ptr_this = weak_ptr_this.promote();
1640 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1641 LOG(ERROR) << "Callback invoked on an invalid object";
1642 return;
1643 }
1644 WifiDebugRingBufferStatus hidl_status;
1645 if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(
1646 status, &hidl_status)) {
1647 LOG(ERROR) << "Error converting ring buffer status";
1648 return;
1649 }
Veerendranath Jakkam25b3a6f2020-04-14 22:04:39 +05301650 {
1651 std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t);
1652 const auto& target =
1653 shared_ptr_this->ringbuffer_map_.find(name);
1654 if (target != shared_ptr_this->ringbuffer_map_.end()) {
1655 Ringbuffer& cur_buffer = target->second;
1656 cur_buffer.append(data);
1657 } else {
1658 LOG(ERROR) << "Ringname " << name << " not found";
1659 return;
1660 }
xshu0a0fe512020-07-22 17:53:37 -07001661 // unique_lock unlocked here
Roshan Piusabcf78f2017-10-06 16:30:38 -07001662 }
1663 };
1664 legacy_hal::wifi_error legacy_status =
1665 legacy_hal_.lock()->registerRingBufferCallbackHandler(
Roshan Pius6036c022019-03-27 10:41:58 -07001666 getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback);
Roshan Pius48185b22016-12-15 19:10:30 -08001667
Roshan Piusabcf78f2017-10-06 16:30:38 -07001668 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1669 debug_ring_buffer_cb_registered_ = true;
1670 }
1671 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius48185b22016-12-15 19:10:30 -08001672}
1673
Roshan Pius85c64412018-01-22 17:58:40 -08001674WifiStatus WifiChip::registerRadioModeChangeCallback() {
1675 android::wp<WifiChip> weak_ptr_this(this);
1676 const auto& on_radio_mode_change_callback =
1677 [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
1678 const auto shared_ptr_this = weak_ptr_this.promote();
1679 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1680 LOG(ERROR) << "Callback invoked on an invalid object";
1681 return;
1682 }
Jimmy Chend460df32019-11-29 17:31:22 +02001683 std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>
Roshan Pius85c64412018-01-22 17:58:40 -08001684 hidl_radio_mode_infos;
1685 if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(
1686 mac_infos, &hidl_radio_mode_infos)) {
1687 LOG(ERROR) << "Error converting wifi mac info";
1688 return;
1689 }
1690 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
Ahmed ElArabawyfd809fc2019-11-15 18:19:15 -08001691 if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos)
Roshan Pius85c64412018-01-22 17:58:40 -08001692 .isOk()) {
Ahmed ElArabawyfd809fc2019-11-15 18:19:15 -08001693 LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4"
Roshan Pius85c64412018-01-22 17:58:40 -08001694 << " callback on: " << toString(callback);
1695 }
1696 }
1697 };
1698 legacy_hal::wifi_error legacy_status =
1699 legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
Roshan Pius6036c022019-03-27 10:41:58 -07001700 getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
Roshan Pius85c64412018-01-22 17:58:40 -08001701 return createWifiStatusFromLegacyError(legacy_status);
1702}
1703
Jimmy Chend460df32019-11-29 17:31:22 +02001704std::vector<V1_4::IWifiChip::ChipIfaceCombination>
Roshan Piuscc338202017-11-02 13:54:09 -07001705WifiChip::getCurrentModeIfaceCombinations() {
1706 if (!isValidModeId(current_mode_id_)) {
1707 LOG(ERROR) << "Chip not configured in a mode yet";
1708 return {};
1709 }
1710 for (const auto& mode : modes_) {
1711 if (mode.id == current_mode_id_) {
1712 return mode.availableCombinations;
1713 }
1714 }
1715 CHECK(0) << "Expected to find iface combinations for current mode!";
1716 return {};
1717}
1718
1719// Returns a map indexed by IfaceType with the number of ifaces currently
1720// created of the corresponding type.
1721std::map<IfaceType, size_t> WifiChip::getCurrentIfaceCombination() {
1722 std::map<IfaceType, size_t> iface_counts;
1723 iface_counts[IfaceType::AP] = ap_ifaces_.size();
1724 iface_counts[IfaceType::NAN] = nan_ifaces_.size();
1725 iface_counts[IfaceType::P2P] = p2p_ifaces_.size();
1726 iface_counts[IfaceType::STA] = sta_ifaces_.size();
1727 return iface_counts;
1728}
1729
1730// This expands the provided iface combinations to a more parseable
1731// form. Returns a vector of available combinations possible with the number
1732// of ifaces of each type in the combination.
1733// This method is a port of HalDeviceManager.expandIfaceCombos() from framework.
1734std::vector<std::map<IfaceType, size_t>> WifiChip::expandIfaceCombinations(
Jimmy Chend460df32019-11-29 17:31:22 +02001735 const V1_4::IWifiChip::ChipIfaceCombination& combination) {
Roshan Piuscc338202017-11-02 13:54:09 -07001736 uint32_t num_expanded_combos = 1;
1737 for (const auto& limit : combination.limits) {
1738 for (uint32_t i = 0; i < limit.maxIfaces; i++) {
1739 num_expanded_combos *= limit.types.size();
1740 }
1741 }
1742
1743 // Allocate the vector of expanded combos and reset all iface counts to 0
1744 // in each combo.
1745 std::vector<std::map<IfaceType, size_t>> expanded_combos;
1746 expanded_combos.resize(num_expanded_combos);
1747 for (auto& expanded_combo : expanded_combos) {
1748 for (const auto type :
1749 {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
1750 expanded_combo[type] = 0;
1751 }
1752 }
1753 uint32_t span = num_expanded_combos;
1754 for (const auto& limit : combination.limits) {
1755 for (uint32_t i = 0; i < limit.maxIfaces; i++) {
1756 span /= limit.types.size();
1757 for (uint32_t k = 0; k < num_expanded_combos; ++k) {
1758 const auto iface_type =
1759 limit.types[(k / span) % limit.types.size()];
1760 expanded_combos[k][iface_type]++;
1761 }
1762 }
1763 }
1764 return expanded_combos;
1765}
1766
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001767bool WifiChip::canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
1768 const std::map<IfaceType, size_t>& expanded_combo,
1769 IfaceType requested_type) {
Roshan Piuscc338202017-11-02 13:54:09 -07001770 const auto current_combo = getCurrentIfaceCombination();
1771
1772 // Check if we have space for 1 more iface of |type| in this combo
1773 for (const auto type :
1774 {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
1775 size_t num_ifaces_needed = current_combo.at(type);
1776 if (type == requested_type) {
1777 num_ifaces_needed++;
1778 }
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001779 size_t num_ifaces_allowed = expanded_combo.at(type);
Roshan Piuscc338202017-11-02 13:54:09 -07001780 if (num_ifaces_needed > num_ifaces_allowed) {
1781 return false;
1782 }
1783 }
1784 return true;
1785}
1786
1787// This method does the following:
1788// a) Enumerate all possible iface combos by expanding the current
1789// ChipIfaceCombination.
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001790// b) Check if the requested iface type can be added to the current mode
1791// with the iface combination that is already active.
1792bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(
1793 IfaceType requested_type) {
Roshan Piuscc338202017-11-02 13:54:09 -07001794 if (!isValidModeId(current_mode_id_)) {
1795 LOG(ERROR) << "Chip not configured in a mode yet";
1796 return false;
1797 }
1798 const auto combinations = getCurrentModeIfaceCombinations();
1799 for (const auto& combination : combinations) {
1800 const auto expanded_combos = expandIfaceCombinations(combination);
1801 for (const auto& expanded_combo : expanded_combos) {
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001802 if (canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
1803 expanded_combo, requested_type)) {
Roshan Piuscc338202017-11-02 13:54:09 -07001804 return true;
1805 }
1806 }
1807 }
1808 return false;
1809}
1810
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001811// Note: This does not consider ifaces already active. It only checks if the
1812// provided expanded iface combination can support the requested combo.
1813bool WifiChip::canExpandedIfaceComboSupportIfaceCombo(
1814 const std::map<IfaceType, size_t>& expanded_combo,
1815 const std::map<IfaceType, size_t>& req_combo) {
1816 // Check if we have space for 1 more iface of |type| in this combo
1817 for (const auto type :
1818 {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
1819 if (req_combo.count(type) == 0) {
1820 // Iface of "type" not in the req_combo.
1821 continue;
1822 }
1823 size_t num_ifaces_needed = req_combo.at(type);
1824 size_t num_ifaces_allowed = expanded_combo.at(type);
1825 if (num_ifaces_needed > num_ifaces_allowed) {
1826 return false;
1827 }
1828 }
1829 return true;
1830}
1831// This method does the following:
1832// a) Enumerate all possible iface combos by expanding the current
1833// ChipIfaceCombination.
1834// b) Check if the requested iface combo can be added to the current mode.
1835// Note: This does not consider ifaces already active. It only checks if the
1836// current mode can support the requested combo.
1837bool WifiChip::canCurrentModeSupportIfaceCombo(
1838 const std::map<IfaceType, size_t>& req_combo) {
1839 if (!isValidModeId(current_mode_id_)) {
1840 LOG(ERROR) << "Chip not configured in a mode yet";
1841 return false;
1842 }
1843 const auto combinations = getCurrentModeIfaceCombinations();
1844 for (const auto& combination : combinations) {
1845 const auto expanded_combos = expandIfaceCombinations(combination);
1846 for (const auto& expanded_combo : expanded_combos) {
1847 if (canExpandedIfaceComboSupportIfaceCombo(expanded_combo,
1848 req_combo)) {
1849 return true;
1850 }
1851 }
1852 }
1853 return false;
1854}
1855
1856// This method does the following:
1857// a) Enumerate all possible iface combos by expanding the current
1858// ChipIfaceCombination.
1859// b) Check if the requested iface type can be added to the current mode.
1860bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType requested_type) {
lesl261818b2020-11-27 12:37:35 +08001861 // Check if we can support at least 1 iface of type.
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001862 std::map<IfaceType, size_t> req_iface_combo;
1863 req_iface_combo[requested_type] = 1;
1864 return canCurrentModeSupportIfaceCombo(req_iface_combo);
1865}
1866
Roshan Piuscc338202017-11-02 13:54:09 -07001867bool WifiChip::isValidModeId(ChipModeId mode_id) {
1868 for (const auto& mode : modes_) {
1869 if (mode.id == mode_id) {
1870 return true;
1871 }
1872 }
1873 return false;
1874}
1875
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001876bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
lesl261818b2020-11-27 12:37:35 +08001877 // Check if we can support at least 1 STA & 1 AP concurrently.
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001878 std::map<IfaceType, size_t> req_iface_combo;
1879 req_iface_combo[IfaceType::AP] = 1;
1880 req_iface_combo[IfaceType::STA] = 1;
1881 return canCurrentModeSupportIfaceCombo(req_iface_combo);
1882}
1883
lesl261818b2020-11-27 12:37:35 +08001884bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() {
1885 // Check if we can support at least 2 STA concurrently.
James Mattisd2e4c072019-05-22 16:14:48 -07001886 std::map<IfaceType, size_t> req_iface_combo;
lesl261818b2020-11-27 12:37:35 +08001887 req_iface_combo[IfaceType::STA] = 2;
James Mattisd2e4c072019-05-22 16:14:48 -07001888 return canCurrentModeSupportIfaceCombo(req_iface_combo);
1889}
1890
Roshan Pius6036c022019-03-27 10:41:58 -07001891std::string WifiChip::getFirstActiveWlanIfaceName() {
Roshan Pius444473f2019-04-19 08:41:20 -07001892 if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName();
leslf012b652021-01-08 15:22:49 +08001893 if (ap_ifaces_.size() > 0) {
1894 // If the first active wlan iface is bridged iface.
1895 // Return first instance name.
1896 for (auto const& it : br_ifaces_ap_instances_) {
1897 if (it.first == ap_ifaces_[0]->getName()) {
1898 return it.second[0];
1899 }
1900 }
1901 return ap_ifaces_[0]->getName();
1902 }
Roshan Pius6036c022019-03-27 10:41:58 -07001903 // This could happen if the chip call is made before any STA/AP
1904 // iface is created. Default to wlan0 for such cases.
Roshan Pius444473f2019-04-19 08:41:20 -07001905 LOG(WARNING) << "No active wlan interfaces in use! Using default";
Jimmy Chen2dddd792019-12-23 17:50:39 +02001906 return getWlanIfaceNameWithType(IfaceType::STA, 0);
Roshan Pius6036c022019-03-27 10:41:58 -07001907}
1908
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001909// Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx|
1910// not already in use.
1911// Note: This doesn't check the actual presence of these interfaces.
Jimmy Chen2dddd792019-12-23 17:50:39 +02001912std::string WifiChip::allocateApOrStaIfaceName(IfaceType type,
1913 uint32_t start_idx) {
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001914 for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
Jimmy Chen2dddd792019-12-23 17:50:39 +02001915 const auto ifname = getWlanIfaceNameWithType(type, idx);
lesl94d28242020-11-18 22:17:37 +08001916 if (findUsingNameFromBridgedApInstances(ifname)) continue;
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -08001917 if (findUsingName(ap_ifaces_, ifname)) continue;
1918 if (findUsingName(sta_ifaces_, ifname)) continue;
1919 return ifname;
Roshan Pius8e3c7ef2017-11-03 09:43:08 -07001920 }
1921 // This should never happen. We screwed up somewhere if it did.
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -08001922 CHECK(false) << "All wlan interfaces in use already!";
Roshan Pius8e3c7ef2017-11-03 09:43:08 -07001923 return {};
1924}
1925
lesl261818b2020-11-27 12:37:35 +08001926uint32_t WifiChip::startIdxOfApIface() {
1927 if (isDualStaConcurrencyAllowedInCurrentMode()) {
1928 // When the HAL support dual STAs, AP should start with idx 2.
1929 return 2;
1930 } else if (isStaApConcurrencyAllowedInCurrentMode()) {
1931 // When the HAL support STA + AP but it doesn't support dual STAs.
1932 // AP should start with idx 1.
1933 return 1;
1934 }
1935 // No concurrency support.
1936 return 0;
1937}
1938
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001939// AP iface names start with idx 1 for modes supporting
James Mattisd2e4c072019-05-22 16:14:48 -07001940// concurrent STA and not dual AP, else start with idx 0.
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001941std::string WifiChip::allocateApIfaceName() {
Roshan Pius78cb5992020-04-30 12:39:21 -07001942 // Check if we have a dedicated iface for AP.
lesl261818b2020-11-27 12:37:35 +08001943 std::vector<std::string> ifnames = getPredefinedApIfaceNames(false);
1944 if (!ifnames.empty()) {
1945 return ifnames[0];
Roshan Pius78cb5992020-04-30 12:39:21 -07001946 }
lesl261818b2020-11-27 12:37:35 +08001947 return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
1948}
1949
1950std::vector<std::string> WifiChip::allocateBridgedApInstanceNames() {
1951 // Check if we have a dedicated iface for AP.
1952 std::vector<std::string> instances = getPredefinedApIfaceNames(true);
1953 if (instances.size() == 2) {
1954 return instances;
1955 } else {
1956 int num_ifaces_need_to_allocate = 2 - instances.size();
1957 for (int i = 0; i < num_ifaces_need_to_allocate; i++) {
lesl5a46c952020-12-14 17:14:12 +08001958 std::string instance_name = allocateApOrStaIfaceName(
1959 IfaceType::AP, startIdxOfApIface() + i);
lesl261818b2020-11-27 12:37:35 +08001960 if (!instance_name.empty()) {
1961 instances.push_back(instance_name);
1962 }
1963 }
1964 }
1965 return instances;
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001966}
1967
1968// STA iface names start with idx 0.
1969// Primary STA iface will always be 0.
1970std::string WifiChip::allocateStaIfaceName() {
Jimmy Chen2dddd792019-12-23 17:50:39 +02001971 return allocateApOrStaIfaceName(IfaceType::STA, 0);
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001972}
1973
xshu5899e8e2018-01-09 15:36:03 -08001974bool WifiChip::writeRingbufferFilesInternal() {
1975 if (!removeOldFilesInternal()) {
1976 LOG(ERROR) << "Error occurred while deleting old tombstone files";
1977 return false;
1978 }
1979 // write ringbuffers to file
Veerendranath Jakkam25b3a6f2020-04-14 22:04:39 +05301980 {
1981 std::unique_lock<std::mutex> lk(lock_t);
xshuc905ea62021-07-11 19:57:02 -07001982 for (auto& item : ringbuffer_map_) {
1983 Ringbuffer& cur_buffer = item.second;
Veerendranath Jakkam25b3a6f2020-04-14 22:04:39 +05301984 if (cur_buffer.getData().empty()) {
1985 continue;
1986 }
1987 const std::string file_path_raw =
1988 kTombstoneFolderPath + item.first + "XXXXXXXXXX";
1989 const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
1990 if (dump_fd == -1) {
1991 PLOG(ERROR) << "create file failed";
1992 return false;
1993 }
1994 unique_fd file_auto_closer(dump_fd);
1995 for (const auto& cur_block : cur_buffer.getData()) {
1996 if (write(dump_fd, cur_block.data(),
1997 sizeof(cur_block[0]) * cur_block.size()) == -1) {
1998 PLOG(ERROR) << "Error writing to file";
1999 }
xshu5899e8e2018-01-09 15:36:03 -08002000 }
xshuc905ea62021-07-11 19:57:02 -07002001 cur_buffer.clear();
xshu5899e8e2018-01-09 15:36:03 -08002002 }
xshu0a0fe512020-07-22 17:53:37 -07002003 // unique_lock unlocked here
xshu5899e8e2018-01-09 15:36:03 -08002004 }
2005 return true;
2006}
2007
Jimmy Chen2dddd792019-12-23 17:50:39 +02002008std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) {
2009 std::string ifname;
2010
2011 // let the legacy hal override the interface name
2012 legacy_hal::wifi_error err =
2013 legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname);
2014 if (err == legacy_hal::WIFI_SUCCESS) return ifname;
2015
2016 return getWlanIfaceName(idx);
2017}
2018
lesl94d28242020-11-18 22:17:37 +08002019void WifiChip::invalidateAndClearBridgedApAll() {
2020 for (auto const& it : br_ifaces_ap_instances_) {
2021 for (auto const& iface : it.second) {
Roshan Pius8c1a67b2021-03-02 10:00:23 -08002022 iface_util_->removeIfaceFromBridge(it.first, iface);
lesl94d28242020-11-18 22:17:37 +08002023 legacy_hal_.lock()->deleteVirtualInterface(iface);
2024 }
Roshan Pius8c1a67b2021-03-02 10:00:23 -08002025 iface_util_->deleteBridge(it.first);
lesl94d28242020-11-18 22:17:37 +08002026 }
2027 br_ifaces_ap_instances_.clear();
2028}
2029
2030void WifiChip::invalidateAndClearBridgedAp(const std::string& br_name) {
2031 if (br_name.empty()) return;
2032 // delete managed interfaces
2033 for (auto const& it : br_ifaces_ap_instances_) {
2034 if (it.first == br_name) {
2035 for (auto const& iface : it.second) {
Roshan Pius8c1a67b2021-03-02 10:00:23 -08002036 iface_util_->removeIfaceFromBridge(br_name, iface);
lesl94d28242020-11-18 22:17:37 +08002037 legacy_hal_.lock()->deleteVirtualInterface(iface);
2038 }
Roshan Pius8c1a67b2021-03-02 10:00:23 -08002039 iface_util_->deleteBridge(br_name);
lesl94d28242020-11-18 22:17:37 +08002040 br_ifaces_ap_instances_.erase(br_name);
2041 break;
2042 }
2043 }
2044 return;
2045}
2046
2047bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) {
2048 for (auto const& it : br_ifaces_ap_instances_) {
2049 if (it.first == name) {
2050 return true;
2051 }
2052 for (auto const& iface : it.second) {
2053 if (iface == name) {
2054 return true;
2055 }
2056 }
2057 }
2058 return false;
2059}
2060
Roshan Pius79a99752016-10-04 13:03:58 -07002061} // namespace implementation
Jimmy Chend460df32019-11-29 17:31:22 +02002062} // namespace V1_5
Roshan Pius3c4e8a32016-10-03 14:53:58 -07002063} // namespace wifi
2064} // namespace hardware
2065} // namespace android