blob: 076f35144857eb3c33e5cb3b8f29583b0059ded7 [file] [log] [blame]
Roshan Pius3c4e8a32016-10-03 14:53:58 -07001/*
Gabriel Birene58e2632022-07-15 23:25:39 +00002 * Copyright (C) 2022 The Android Open Source Project
Roshan Pius3c4e8a32016-10-03 14:53:58 -07003 *
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
Gabriel Birene58e2632022-07-15 23:25:39 +000017#include "wifi_chip.h"
xshu5899e8e2018-01-09 15:36:03 -080018
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>
Gabriel Birene58e2632022-07-15 23:25:39 +000022#include <fcntl.h>
lesl94d28242020-11-18 22:17:37 +080023#include <net/if.h>
xshu5899e8e2018-01-09 15:36:03 -080024#include <sys/stat.h>
25#include <sys/sysmacros.h>
Roshan Pius3c4e8a32016-10-03 14:53:58 -070026
Gabriel Birene58e2632022-07-15 23:25:39 +000027#include "aidl_return_util.h"
28#include "aidl_struct_util.h"
Roshan Pius5c055462016-10-11 08:27:27 -070029#include "wifi_status_util.h"
Roshan Pius3c4e8a32016-10-03 14:53:58 -070030
Sunil Ravi7f2822a2021-10-15 16:55:53 -070031#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-"
32
Roshan Pius35d958c2016-10-06 16:47:38 -070033namespace {
Gabriel Birene58e2632022-07-15 23:25:39 +000034using aidl::android::hardware::wifi::IfaceType;
35using aidl::android::hardware::wifi::IWifiChip;
36using CoexRestriction = aidl::android::hardware::wifi::IWifiChip::CoexRestriction;
xshu5899e8e2018-01-09 15:36:03 -080037using android::base::unique_fd;
Roshan Pius52947fb2016-11-18 11:38:07 -080038
xshu5899e8e2018-01-09 15:36:03 -080039constexpr char kCpioMagic[] = "070701";
Roger Wangb294c762018-11-02 15:34:39 +080040constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3;
41constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10;
xshu37126c92018-04-13 16:24:45 -070042constexpr uint32_t kMaxRingBufferFileNum = 20;
xshu5899e8e2018-01-09 15:36:03 -080043constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
Roshan Pius8574e7f2019-04-01 13:30:40 -070044constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface";
45constexpr char kNoActiveWlanIfaceNamePropertyValue[] = "";
46constexpr unsigned kMaxWlanIfaces = 5;
lesl94d28242020-11-18 22:17:37 +080047constexpr char kApBridgeIfacePrefix[] = "ap_br_";
xshu5899e8e2018-01-09 15:36:03 -080048
Roshan Pius35d958c2016-10-06 16:47:38 -070049template <typename Iface>
Gabriel Birene58e2632022-07-15 23:25:39 +000050void invalidateAndClear(std::vector<std::shared_ptr<Iface>>& ifaces, std::shared_ptr<Iface> iface) {
Roshan Pius675609b2017-10-31 14:24:58 -070051 iface->invalidate();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -080052 ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), ifaces.end());
Roshan Pius675609b2017-10-31 14:24:58 -070053}
54
55template <typename Iface>
Gabriel Birene58e2632022-07-15 23:25:39 +000056void invalidateAndClearAll(std::vector<std::shared_ptr<Iface>>& ifaces) {
Roshan Pius675609b2017-10-31 14:24:58 -070057 for (const auto& iface : ifaces) {
Roshan Piusabcf78f2017-10-06 16:30:38 -070058 iface->invalidate();
Roshan Piusabcf78f2017-10-06 16:30:38 -070059 }
Roshan Pius675609b2017-10-31 14:24:58 -070060 ifaces.clear();
61}
62
63template <typename Iface>
Gabriel Birene58e2632022-07-15 23:25:39 +000064std::vector<std::string> getNames(std::vector<std::shared_ptr<Iface>>& ifaces) {
65 std::vector<std::string> names;
Roshan Pius675609b2017-10-31 14:24:58 -070066 for (const auto& iface : ifaces) {
67 names.emplace_back(iface->getName());
68 }
69 return names;
70}
71
72template <typename Iface>
Gabriel Birene58e2632022-07-15 23:25:39 +000073std::shared_ptr<Iface> findUsingName(std::vector<std::shared_ptr<Iface>>& ifaces,
74 const std::string& name) {
75 std::vector<std::string> names;
Roshan Pius675609b2017-10-31 14:24:58 -070076 for (const auto& iface : ifaces) {
77 if (name == iface->getName()) {
78 return iface;
79 }
80 }
81 return nullptr;
Roshan Pius35d958c2016-10-06 16:47:38 -070082}
Roshan Pius9377a0d2017-10-06 13:18:54 -070083
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -080084std::string getWlanIfaceName(unsigned idx) {
85 if (idx >= kMaxWlanIfaces) {
86 CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
87 return {};
88 }
Roshan Pius9377a0d2017-10-06 13:18:54 -070089
Roshan Pius8e3c7ef2017-11-03 09:43:08 -070090 std::array<char, PROPERTY_VALUE_MAX> buffer;
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -080091 if (idx == 0 || idx == 1) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -080092 const char* altPropName = (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
Roshan Pius5b333462019-03-01 14:07:22 -080093 auto res = property_get(altPropName, buffer.data(), nullptr);
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -080094 if (res > 0) return buffer.data();
95 }
Roshan Pius5b333462019-03-01 14:07:22 -080096 std::string propName = "wifi.interface." + std::to_string(idx);
97 auto res = property_get(propName.c_str(), buffer.data(), nullptr);
98 if (res > 0) return buffer.data();
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -080099
100 return "wlan" + std::to_string(idx);
Roshan Pius9377a0d2017-10-06 13:18:54 -0700101}
Roshan Pius9377a0d2017-10-06 13:18:54 -0700102
lesl261818b2020-11-27 12:37:35 +0800103// Returns the dedicated iface name if defined.
104// Returns two ifaces in bridged mode.
105std::vector<std::string> getPredefinedApIfaceNames(bool is_bridged) {
106 std::vector<std::string> ifnames;
Roshan Pius78cb5992020-04-30 12:39:21 -0700107 std::array<char, PROPERTY_VALUE_MAX> buffer;
lesl261818b2020-11-27 12:37:35 +0800108 buffer.fill(0);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800109 if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == 0) {
lesl261818b2020-11-27 12:37:35 +0800110 return ifnames;
Roshan Pius78cb5992020-04-30 12:39:21 -0700111 }
lesl261818b2020-11-27 12:37:35 +0800112 ifnames.push_back(buffer.data());
113 if (is_bridged) {
114 buffer.fill(0);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800115 if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), nullptr) == 0) {
lesl261818b2020-11-27 12:37:35 +0800116 return ifnames;
117 }
118 ifnames.push_back(buffer.data());
119 }
120 return ifnames;
Roshan Pius78cb5992020-04-30 12:39:21 -0700121}
122
lesl261818b2020-11-27 12:37:35 +0800123std::string getPredefinedP2pIfaceName() {
Sunil Ravi7f2822a2021-10-15 16:55:53 -0700124 std::array<char, PROPERTY_VALUE_MAX> primaryIfaceName;
125 char p2pParentIfname[100];
126 std::string p2pDevIfName = "";
Roshan Piusabcf78f2017-10-06 16:30:38 -0700127 std::array<char, PROPERTY_VALUE_MAX> buffer;
128 property_get("wifi.direct.interface", buffer.data(), "p2p0");
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800129 if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX, strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
Sunil Ravi7f2822a2021-10-15 16:55:53 -0700130 /* Get the p2p parent interface name from p2p device interface name set
131 * in property */
Gabriel Biren11d4ab82022-03-31 00:08:02 +0000132 strlcpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX),
Sunil Ravi7f2822a2021-10-15 16:55:53 -0700133 strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX));
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800134 if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(), nullptr) == 0) {
Sunil Ravi7f2822a2021-10-15 16:55:53 -0700135 return buffer.data();
136 }
137 /* Check if the parent interface derived from p2p device interface name
138 * is active */
139 if (strncmp(p2pParentIfname, primaryIfaceName.data(),
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800140 strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) != 0) {
Sunil Ravi7f2822a2021-10-15 16:55:53 -0700141 /*
142 * Update the predefined p2p device interface parent interface name
143 * with current active wlan interface
144 */
145 p2pDevIfName += P2P_MGMT_DEVICE_PREFIX;
146 p2pDevIfName += primaryIfaceName.data();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800147 LOG(INFO) << "update the p2p device interface name to " << p2pDevIfName.c_str();
Sunil Ravi7f2822a2021-10-15 16:55:53 -0700148 return p2pDevIfName;
149 }
150 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700151 return buffer.data();
Roshan Pius9377a0d2017-10-06 13:18:54 -0700152}
153
Roshan Pius5ba0a902020-04-14 11:55:42 -0700154// Returns the dedicated iface name if one is defined.
lesl261818b2020-11-27 12:37:35 +0800155std::string getPredefinedNanIfaceName() {
Roshan Pius5ba0a902020-04-14 11:55:42 -0700156 std::array<char, PROPERTY_VALUE_MAX> buffer;
157 if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) {
158 return {};
159 }
160 return buffer.data();
161}
162
Roshan Pius8574e7f2019-04-01 13:30:40 -0700163void setActiveWlanIfaceNameProperty(const std::string& ifname) {
164 auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data());
165 if (res != 0) {
166 PLOG(ERROR) << "Failed to set active wlan iface name property";
167 }
168}
169
Gabriel Birene58e2632022-07-15 23:25:39 +0000170// Delete files that meet either condition:
171// 1. Older than a predefined time in the wifi tombstone dir.
xshu37126c92018-04-13 16:24:45 -0700172// 2. Files in excess to a predefined amount, starting from the oldest ones
xshu5899e8e2018-01-09 15:36:03 -0800173bool removeOldFilesInternal() {
174 time_t now = time(0);
175 const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800176 std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(kTombstoneFolderPath), closedir);
xshu5899e8e2018-01-09 15:36:03 -0800177 if (!dir_dump) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800178 PLOG(ERROR) << "Failed to open directory";
xshu5899e8e2018-01-09 15:36:03 -0800179 return false;
180 }
xshu5899e8e2018-01-09 15:36:03 -0800181 struct dirent* dp;
182 bool success = true;
xshu37126c92018-04-13 16:24:45 -0700183 std::list<std::pair<const time_t, std::string>> valid_files;
Josh Gaoa568e532018-06-04 18:16:00 -0700184 while ((dp = readdir(dir_dump.get()))) {
xshu5899e8e2018-01-09 15:36:03 -0800185 if (dp->d_type != DT_REG) {
186 continue;
187 }
188 std::string cur_file_name(dp->d_name);
189 struct stat cur_file_stat;
190 std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
xshu4cb33162018-01-24 15:40:06 -0800191 if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800192 PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
xshu5899e8e2018-01-09 15:36:03 -0800193 success = false;
xshu4cb33162018-01-24 15:40:06 -0800194 continue;
195 }
xshu37126c92018-04-13 16:24:45 -0700196 const time_t cur_file_time = cur_file_stat.st_mtime;
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800197 valid_files.push_back(std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
xshu37126c92018-04-13 16:24:45 -0700198 }
199 valid_files.sort(); // sort the list of files by last modified time from
200 // small to big.
201 uint32_t cur_file_count = valid_files.size();
202 for (auto cur_file : valid_files) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800203 if (cur_file_count > kMaxRingBufferFileNum || cur_file.first < delete_files_before) {
xshu37126c92018-04-13 16:24:45 -0700204 if (unlink(cur_file.second.c_str()) != 0) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800205 PLOG(ERROR) << "Error deleting file";
xshu37126c92018-04-13 16:24:45 -0700206 success = false;
207 }
208 cur_file_count--;
209 } else {
210 break;
xshu5899e8e2018-01-09 15:36:03 -0800211 }
212 }
213 return success;
214}
215
xshu4cb33162018-01-24 15:40:06 -0800216// Helper function for |cpioArchiveFilesInDir|
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800217bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, size_t file_name_len) {
Gabriel Biren11d4ab82022-03-31 00:08:02 +0000218 const int buf_size = 32 * 1024;
219 std::array<char, buf_size> read_buf;
220 ssize_t llen = snprintf(
221 read_buf.data(), buf_size, "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
222 kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid, st.st_gid,
223 static_cast<int>(st.st_nlink), static_cast<int>(st.st_mtime),
224 static_cast<int>(st.st_size), major(st.st_dev), minor(st.st_dev), major(st.st_rdev),
225 minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0);
226 if (write(out_fd, read_buf.data(), llen < buf_size ? llen : buf_size - 1) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800227 PLOG(ERROR) << "Error writing cpio header to file " << file_name;
xshu4cb33162018-01-24 15:40:06 -0800228 return false;
229 }
230 if (write(out_fd, file_name, file_name_len) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800231 PLOG(ERROR) << "Error writing filename to file " << file_name;
xshu4cb33162018-01-24 15:40:06 -0800232 return false;
233 }
234
235 // NUL Pad header up to 4 multiple bytes.
236 llen = (llen + file_name_len) % 4;
237 if (llen != 0) {
238 const uint32_t zero = 0;
239 if (write(out_fd, &zero, 4 - llen) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800240 PLOG(ERROR) << "Error padding 0s to file " << file_name;
xshu4cb33162018-01-24 15:40:06 -0800241 return false;
242 }
243 }
244 return true;
245}
246
247// Helper function for |cpioArchiveFilesInDir|
248size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) {
249 // writing content of file
250 std::array<char, 32 * 1024> read_buf;
251 ssize_t llen = st.st_size;
252 size_t n_error = 0;
253 while (llen > 0) {
254 ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size());
255 if (bytes_read == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800256 PLOG(ERROR) << "Error reading file";
xshu4cb33162018-01-24 15:40:06 -0800257 return ++n_error;
258 }
259 llen -= bytes_read;
260 if (write(out_fd, read_buf.data(), bytes_read) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800261 PLOG(ERROR) << "Error writing data to file";
xshu4cb33162018-01-24 15:40:06 -0800262 return ++n_error;
263 }
264 if (bytes_read == 0) { // this should never happen, but just in case
265 // to unstuck from while loop
Elliott Hughes4db4add2019-03-08 12:42:57 -0800266 PLOG(ERROR) << "Unexpected read result";
xshu4cb33162018-01-24 15:40:06 -0800267 n_error++;
268 break;
269 }
270 }
271 llen = st.st_size % 4;
272 if (llen != 0) {
273 const uint32_t zero = 0;
274 if (write(out_fd, &zero, 4 - llen) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800275 PLOG(ERROR) << "Error padding 0s to file";
xshu4cb33162018-01-24 15:40:06 -0800276 return ++n_error;
277 }
278 }
279 return n_error;
280}
281
282// Helper function for |cpioArchiveFilesInDir|
283bool cpioWriteFileTrailer(int out_fd) {
Gabriel Biren11d4ab82022-03-31 00:08:02 +0000284 const int buf_size = 4096;
285 std::array<char, buf_size> read_buf;
xshu4cb33162018-01-24 15:40:06 -0800286 read_buf.fill(0);
Gabriel Biren11d4ab82022-03-31 00:08:02 +0000287 ssize_t llen = snprintf(read_buf.data(), 4096, "070701%040X%056X%08XTRAILER!!!", 1, 0x0b, 0);
288 if (write(out_fd, read_buf.data(), (llen < buf_size ? llen : buf_size - 1) + 4) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800289 PLOG(ERROR) << "Error writing trailing bytes";
xshu4cb33162018-01-24 15:40:06 -0800290 return false;
291 }
292 return true;
293}
294
xshu5899e8e2018-01-09 15:36:03 -0800295// Archives all files in |input_dir| and writes result into |out_fd|
296// Logic obtained from //external/toybox/toys/posix/cpio.c "Output cpio archive"
297// portion
xshu4cb33162018-01-24 15:40:06 -0800298size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) {
xshu5899e8e2018-01-09 15:36:03 -0800299 struct dirent* dp;
300 size_t n_error = 0;
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800301 std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir), closedir);
xshu5899e8e2018-01-09 15:36:03 -0800302 if (!dir_dump) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800303 PLOG(ERROR) << "Failed to open directory";
xshu4cb33162018-01-24 15:40:06 -0800304 return ++n_error;
xshu5899e8e2018-01-09 15:36:03 -0800305 }
Josh Gaoa568e532018-06-04 18:16:00 -0700306 while ((dp = readdir(dir_dump.get()))) {
xshu5899e8e2018-01-09 15:36:03 -0800307 if (dp->d_type != DT_REG) {
308 continue;
309 }
310 std::string cur_file_name(dp->d_name);
xshu5899e8e2018-01-09 15:36:03 -0800311 struct stat st;
xshu5899e8e2018-01-09 15:36:03 -0800312 const std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
xshu4cb33162018-01-24 15:40:06 -0800313 if (stat(cur_file_path.c_str(), &st) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800314 PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
xshu5899e8e2018-01-09 15:36:03 -0800315 n_error++;
xshu4cb33162018-01-24 15:40:06 -0800316 continue;
317 }
318 const int fd_read = open(cur_file_path.c_str(), O_RDONLY);
319 if (fd_read == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800320 PLOG(ERROR) << "Failed to open file " << cur_file_path;
xshu4cb33162018-01-24 15:40:06 -0800321 n_error++;
322 continue;
323 }
xshuf392fb42020-08-13 16:57:00 -0700324 std::string file_name_with_last_modified_time =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800325 cur_file_name + "-" + std::to_string(st.st_mtime);
xshuf392fb42020-08-13 16:57:00 -0700326 // string.size() does not include the null terminator. The cpio FreeBSD
327 // file header expects the null character to be included in the length.
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800328 const size_t file_name_len = file_name_with_last_modified_time.size() + 1;
xshu4cb33162018-01-24 15:40:06 -0800329 unique_fd file_auto_closer(fd_read);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800330 if (!cpioWriteHeader(out_fd, st, file_name_with_last_modified_time.c_str(),
xshu4cb33162018-01-24 15:40:06 -0800331 file_name_len)) {
332 return ++n_error;
333 }
334 size_t write_error = cpioWriteFileContent(fd_read, out_fd, st);
335 if (write_error) {
336 return n_error + write_error;
xshu5899e8e2018-01-09 15:36:03 -0800337 }
338 }
xshu4cb33162018-01-24 15:40:06 -0800339 if (!cpioWriteFileTrailer(out_fd)) {
340 return ++n_error;
xshu5899e8e2018-01-09 15:36:03 -0800341 }
342 return n_error;
343}
344
345// Helper function to create a non-const char*.
346std::vector<char> makeCharVec(const std::string& str) {
347 std::vector<char> vec(str.size() + 1);
348 vec.assign(str.begin(), str.end());
349 vec.push_back('\0');
350 return vec;
351}
352
Roshan Piusabcf78f2017-10-06 16:30:38 -0700353} // namespace
Roshan Pius35d958c2016-10-06 16:47:38 -0700354
Gabriel Birene58e2632022-07-15 23:25:39 +0000355namespace aidl {
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700356namespace android {
357namespace hardware {
358namespace wifi {
Gabriel Birene58e2632022-07-15 23:25:39 +0000359using aidl_return_util::validateAndCall;
360using aidl_return_util::validateAndCallWithLock;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700361
Gabriel Birene58e2632022-07-15 23:25:39 +0000362WifiChip::WifiChip(int32_t chip_id, bool is_primary,
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800363 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
364 const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
365 const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
366 const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
367 const std::function<void(const std::string&)>& handler)
Roshan Pius52947fb2016-11-18 11:38:07 -0800368 : chip_id_(chip_id),
369 legacy_hal_(legacy_hal),
370 mode_controller_(mode_controller),
Roshan Pius99dab382019-02-14 07:57:10 -0800371 iface_util_(iface_util),
Roshan Pius52947fb2016-11-18 11:38:07 -0800372 is_valid_(true),
Tomasz Wasilczykb424da72018-11-15 11:52:57 -0800373 current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
Jimmy Chen2dddd792019-12-23 17:50:39 +0200374 modes_(feature_flags.lock()->getChipModes(is_primary)),
Ahmed ElArabawy2134bf72020-06-18 15:07:12 -0700375 debug_ring_buffer_cb_registered_(false),
376 subsystemCallbackHandler_(handler) {
Roshan Pius8574e7f2019-04-01 13:30:40 -0700377 setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
378}
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700379
Gabriel Birene58e2632022-07-15 23:25:39 +0000380std::shared_ptr<WifiChip> WifiChip::create(
381 int32_t chip_id, bool is_primary, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
382 const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
383 const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
384 const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
385 const std::function<void(const std::string&)>& handler) {
386 std::shared_ptr<WifiChip> ptr = ndk::SharedRefBase::make<WifiChip>(
387 chip_id, is_primary, legacy_hal, mode_controller, iface_util, feature_flags, handler);
388 std::weak_ptr<WifiChip> weak_ptr_this(ptr);
389 ptr->setWeakPtr(weak_ptr_this);
390 return ptr;
391}
392
Roshan Piusaabe5752016-09-29 09:03:59 -0700393void WifiChip::invalidate() {
xshu37126c92018-04-13 16:24:45 -0700394 if (!writeRingbufferFilesInternal()) {
395 LOG(ERROR) << "Error writing files to flash";
396 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700397 invalidateAndRemoveAllIfaces();
Roshan Pius8574e7f2019-04-01 13:30:40 -0700398 setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700399 legacy_hal_.reset();
400 event_cb_handler_.invalidate();
401 is_valid_ = false;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700402}
403
Gabriel Birene58e2632022-07-15 23:25:39 +0000404void WifiChip::setWeakPtr(std::weak_ptr<WifiChip> ptr) {
405 weak_ptr_this_ = ptr;
406}
407
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800408bool WifiChip::isValid() {
409 return is_valid_;
410}
Roshan Pius3c868522016-10-27 12:43:49 -0700411
Gabriel Birene58e2632022-07-15 23:25:39 +0000412std::set<std::shared_ptr<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700413 return event_cb_handler_.getCallbacks();
Roshan Pius203cb032016-12-14 17:41:20 -0800414}
415
Gabriel Birene58e2632022-07-15 23:25:39 +0000416ndk::ScopedAStatus WifiChip::getId(int32_t* _aidl_return) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800417 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getIdInternal,
Gabriel Birene58e2632022-07-15 23:25:39 +0000418 _aidl_return);
Roshan Piuscd566bd2016-10-10 08:03:42 -0700419}
420
Gabriel Birene58e2632022-07-15 23:25:39 +0000421ndk::ScopedAStatus WifiChip::registerEventCallback(
422 const std::shared_ptr<IWifiChipEventCallback>& event_callback) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700423 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000424 &WifiChip::registerEventCallbackInternal, event_callback);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700425}
426
Gabriel Birene58e2632022-07-15 23:25:39 +0000427ndk::ScopedAStatus WifiChip::getCapabilities(IWifiChip::ChipCapabilityMask* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700428 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000429 &WifiChip::getCapabilitiesInternal, _aidl_return);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700430}
431
Gabriel Birene58e2632022-07-15 23:25:39 +0000432ndk::ScopedAStatus WifiChip::getAvailableModes(std::vector<IWifiChip::ChipMode>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700433 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000434 &WifiChip::getAvailableModesInternal, _aidl_return);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700435}
436
Gabriel Birene58e2632022-07-15 23:25:39 +0000437ndk::ScopedAStatus WifiChip::configureChip(int32_t in_modeId) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800438 return validateAndCallWithLock(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000439 &WifiChip::configureChipInternal, in_modeId);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700440}
441
Gabriel Birene58e2632022-07-15 23:25:39 +0000442ndk::ScopedAStatus WifiChip::getMode(int32_t* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700443 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000444 &WifiChip::getModeInternal, _aidl_return);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700445}
446
Gabriel Birene58e2632022-07-15 23:25:39 +0000447ndk::ScopedAStatus WifiChip::requestChipDebugInfo(IWifiChip::ChipDebugInfo* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700448 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000449 &WifiChip::requestChipDebugInfoInternal, _aidl_return);
Roshan Pius5c055462016-10-11 08:27:27 -0700450}
451
Gabriel Birene58e2632022-07-15 23:25:39 +0000452ndk::ScopedAStatus WifiChip::requestDriverDebugDump(std::vector<uint8_t>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700453 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000454 &WifiChip::requestDriverDebugDumpInternal, _aidl_return);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700455}
456
Gabriel Birene58e2632022-07-15 23:25:39 +0000457ndk::ScopedAStatus WifiChip::requestFirmwareDebugDump(std::vector<uint8_t>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700458 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000459 &WifiChip::requestFirmwareDebugDumpInternal, _aidl_return);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700460}
461
Gabriel Birene58e2632022-07-15 23:25:39 +0000462ndk::ScopedAStatus WifiChip::createApIface(std::shared_ptr<IWifiApIface>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700463 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000464 &WifiChip::createApIfaceInternal, _aidl_return);
Roshan Pius35d958c2016-10-06 16:47:38 -0700465}
466
Gabriel Birene58e2632022-07-15 23:25:39 +0000467ndk::ScopedAStatus WifiChip::createBridgedApIface(std::shared_ptr<IWifiApIface>* _aidl_return) {
lesl94d28242020-11-18 22:17:37 +0800468 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000469 &WifiChip::createBridgedApIfaceInternal, _aidl_return);
lesl94d28242020-11-18 22:17:37 +0800470}
471
Gabriel Birene58e2632022-07-15 23:25:39 +0000472ndk::ScopedAStatus WifiChip::getApIfaceNames(std::vector<std::string>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700473 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000474 &WifiChip::getApIfaceNamesInternal, _aidl_return);
Roshan Pius35d958c2016-10-06 16:47:38 -0700475}
476
Gabriel Birene58e2632022-07-15 23:25:39 +0000477ndk::ScopedAStatus WifiChip::getApIface(const std::string& in_ifname,
478 std::shared_ptr<IWifiApIface>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700479 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000480 &WifiChip::getApIfaceInternal, _aidl_return, in_ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700481}
482
Gabriel Birene58e2632022-07-15 23:25:39 +0000483ndk::ScopedAStatus WifiChip::removeApIface(const std::string& in_ifname) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700484 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000485 &WifiChip::removeApIfaceInternal, in_ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800486}
487
Gabriel Birene58e2632022-07-15 23:25:39 +0000488ndk::ScopedAStatus WifiChip::removeIfaceInstanceFromBridgedApIface(
489 const std::string& in_brIfaceName, const std::string& in_ifaceInstanceName) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800490 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000491 &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, in_brIfaceName,
492 in_ifaceInstanceName);
lesl94d28242020-11-18 22:17:37 +0800493}
494
Gabriel Birene58e2632022-07-15 23:25:39 +0000495ndk::ScopedAStatus WifiChip::createNanIface(std::shared_ptr<IWifiNanIface>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700496 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000497 &WifiChip::createNanIfaceInternal, _aidl_return);
Roshan Pius35d958c2016-10-06 16:47:38 -0700498}
499
Gabriel Birene58e2632022-07-15 23:25:39 +0000500ndk::ScopedAStatus WifiChip::getNanIfaceNames(std::vector<std::string>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700501 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000502 &WifiChip::getNanIfaceNamesInternal, _aidl_return);
Roshan Pius35d958c2016-10-06 16:47:38 -0700503}
504
Gabriel Birene58e2632022-07-15 23:25:39 +0000505ndk::ScopedAStatus WifiChip::getNanIface(const std::string& in_ifname,
506 std::shared_ptr<IWifiNanIface>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700507 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000508 &WifiChip::getNanIfaceInternal, _aidl_return, in_ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700509}
510
Gabriel Birene58e2632022-07-15 23:25:39 +0000511ndk::ScopedAStatus WifiChip::removeNanIface(const std::string& in_ifname) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700512 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000513 &WifiChip::removeNanIfaceInternal, in_ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800514}
515
Gabriel Birene58e2632022-07-15 23:25:39 +0000516ndk::ScopedAStatus WifiChip::createP2pIface(std::shared_ptr<IWifiP2pIface>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700517 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000518 &WifiChip::createP2pIfaceInternal, _aidl_return);
Roshan Pius35d958c2016-10-06 16:47:38 -0700519}
520
Gabriel Birene58e2632022-07-15 23:25:39 +0000521ndk::ScopedAStatus WifiChip::getP2pIfaceNames(std::vector<std::string>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700522 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000523 &WifiChip::getP2pIfaceNamesInternal, _aidl_return);
Roshan Pius35d958c2016-10-06 16:47:38 -0700524}
525
Gabriel Birene58e2632022-07-15 23:25:39 +0000526ndk::ScopedAStatus WifiChip::getP2pIface(const std::string& in_ifname,
527 std::shared_ptr<IWifiP2pIface>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700528 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000529 &WifiChip::getP2pIfaceInternal, _aidl_return, in_ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700530}
531
Gabriel Birene58e2632022-07-15 23:25:39 +0000532ndk::ScopedAStatus WifiChip::removeP2pIface(const std::string& in_ifname) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700533 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000534 &WifiChip::removeP2pIfaceInternal, in_ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800535}
536
Gabriel Birene58e2632022-07-15 23:25:39 +0000537ndk::ScopedAStatus WifiChip::createStaIface(std::shared_ptr<IWifiStaIface>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700538 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000539 &WifiChip::createStaIfaceInternal, _aidl_return);
Roshan Pius35d958c2016-10-06 16:47:38 -0700540}
541
Gabriel Birene58e2632022-07-15 23:25:39 +0000542ndk::ScopedAStatus WifiChip::getStaIfaceNames(std::vector<std::string>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700543 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000544 &WifiChip::getStaIfaceNamesInternal, _aidl_return);
Roshan Pius35d958c2016-10-06 16:47:38 -0700545}
546
Gabriel Birene58e2632022-07-15 23:25:39 +0000547ndk::ScopedAStatus WifiChip::getStaIface(const std::string& in_ifname,
548 std::shared_ptr<IWifiStaIface>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700549 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000550 &WifiChip::getStaIfaceInternal, _aidl_return, in_ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700551}
552
Gabriel Birene58e2632022-07-15 23:25:39 +0000553ndk::ScopedAStatus WifiChip::removeStaIface(const std::string& in_ifname) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700554 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000555 &WifiChip::removeStaIfaceInternal, in_ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800556}
557
Gabriel Birene58e2632022-07-15 23:25:39 +0000558ndk::ScopedAStatus WifiChip::createRttController(
559 const std::shared_ptr<IWifiStaIface>& in_boundIface,
560 std::shared_ptr<IWifiRttController>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700561 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000562 &WifiChip::createRttControllerInternal, _aidl_return, in_boundIface);
Roshan Pius59268282016-10-06 20:23:47 -0700563}
564
Gabriel Birene58e2632022-07-15 23:25:39 +0000565ndk::ScopedAStatus WifiChip::getDebugRingBuffersStatus(
566 std::vector<WifiDebugRingBufferStatus>* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700567 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000568 &WifiChip::getDebugRingBuffersStatusInternal, _aidl_return);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700569}
570
Gabriel Birene58e2632022-07-15 23:25:39 +0000571ndk::ScopedAStatus WifiChip::startLoggingToDebugRingBuffer(
572 const std::string& in_ringName, WifiDebugRingBufferVerboseLevel in_verboseLevel,
573 int32_t in_maxIntervalInSec, int32_t in_minDataSizeInBytes) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700574 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000575 &WifiChip::startLoggingToDebugRingBufferInternal, in_ringName,
576 in_verboseLevel, in_maxIntervalInSec, in_minDataSizeInBytes);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700577}
578
Gabriel Birene58e2632022-07-15 23:25:39 +0000579ndk::ScopedAStatus WifiChip::forceDumpToDebugRingBuffer(const std::string& in_ringName) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700580 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000581 &WifiChip::forceDumpToDebugRingBufferInternal, in_ringName);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700582}
583
Gabriel Birene58e2632022-07-15 23:25:39 +0000584ndk::ScopedAStatus WifiChip::flushRingBufferToFile() {
Roger Wangb294c762018-11-02 15:34:39 +0800585 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000586 &WifiChip::flushRingBufferToFileInternal);
Roger Wangb294c762018-11-02 15:34:39 +0800587}
588
Gabriel Birene58e2632022-07-15 23:25:39 +0000589ndk::ScopedAStatus WifiChip::stopLoggingToDebugRingBuffer() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700590 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000591 &WifiChip::stopLoggingToDebugRingBufferInternal);
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800592}
593
Gabriel Birene58e2632022-07-15 23:25:39 +0000594ndk::ScopedAStatus WifiChip::getDebugHostWakeReasonStats(
595 WifiDebugHostWakeReasonStats* _aidl_return) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700596 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000597 &WifiChip::getDebugHostWakeReasonStatsInternal, _aidl_return);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700598}
599
Gabriel Birene58e2632022-07-15 23:25:39 +0000600ndk::ScopedAStatus WifiChip::enableDebugErrorAlerts(bool in_enable) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700601 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000602 &WifiChip::enableDebugErrorAlertsInternal, in_enable);
Roshan Pius203cb032016-12-14 17:41:20 -0800603}
604
Gabriel Birene58e2632022-07-15 23:25:39 +0000605ndk::ScopedAStatus WifiChip::selectTxPowerScenario(IWifiChip::TxPowerScenario in_scenario) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700606 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000607 &WifiChip::selectTxPowerScenarioInternal, in_scenario);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700608}
609
Gabriel Birene58e2632022-07-15 23:25:39 +0000610ndk::ScopedAStatus WifiChip::resetTxPowerScenario() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700611 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000612 &WifiChip::resetTxPowerScenarioInternal);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700613}
614
Gabriel Birene58e2632022-07-15 23:25:39 +0000615ndk::ScopedAStatus WifiChip::setLatencyMode(IWifiChip::LatencyMode in_mode) {
Ahmed ElArabawyeaf82402018-10-26 09:46:04 -0700616 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000617 &WifiChip::setLatencyModeInternal, in_mode);
Ahmed ElArabawyeaf82402018-10-26 09:46:04 -0700618}
619
Gabriel Birene58e2632022-07-15 23:25:39 +0000620binder_status_t WifiChip::dump(int fd, const char**, uint32_t) {
621 {
622 std::unique_lock<std::mutex> lk(lock_t);
623 for (const auto& item : ringbuffer_map_) {
624 forceDumpToDebugRingBufferInternal(item.first);
xshu0a0fe512020-07-22 17:53:37 -0700625 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000626 // unique_lock unlocked here
xshu5899e8e2018-01-09 15:36:03 -0800627 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000628 usleep(100 * 1000); // sleep for 100 milliseconds to wait for
629 // ringbuffer updates.
630 if (!writeRingbufferFilesInternal()) {
631 LOG(ERROR) << "Error writing files to flash";
632 }
633 uint32_t n_error = cpioArchiveFilesInDir(fd, kTombstoneFolderPath);
634 if (n_error != 0) {
635 LOG(ERROR) << n_error << " errors occurred in cpio function";
636 }
637 fsync(fd);
638 return STATUS_OK;
xshu5899e8e2018-01-09 15:36:03 -0800639}
640
Gabriel Birene58e2632022-07-15 23:25:39 +0000641ndk::ScopedAStatus WifiChip::setMultiStaPrimaryConnection(const std::string& in_ifName) {
Ahmed ElArabawyeeb53382019-10-10 20:18:31 -0700642 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000643 &WifiChip::setMultiStaPrimaryConnectionInternal, in_ifName);
Ahmed ElArabawyeeb53382019-10-10 20:18:31 -0700644}
645
Gabriel Birene58e2632022-07-15 23:25:39 +0000646ndk::ScopedAStatus WifiChip::setMultiStaUseCase(IWifiChip::MultiStaUseCase in_useCase) {
Ahmed ElArabawyfd809fc2019-11-15 18:19:15 -0800647 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000648 &WifiChip::setMultiStaUseCaseInternal, in_useCase);
Ahmed ElArabawyfd809fc2019-11-15 18:19:15 -0800649}
650
Gabriel Birene58e2632022-07-15 23:25:39 +0000651ndk::ScopedAStatus WifiChip::setCoexUnsafeChannels(
652 const std::vector<IWifiChip::CoexUnsafeChannel>& in_unsafeChannels,
653 CoexRestriction in_restrictions) {
Roshan Piuse9d1e7d2020-11-04 11:44:16 -0800654 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000655 &WifiChip::setCoexUnsafeChannelsInternal, in_unsafeChannels,
656 in_restrictions);
Roshan Piuse9d1e7d2020-11-04 11:44:16 -0800657}
658
Gabriel Birene58e2632022-07-15 23:25:39 +0000659ndk::ScopedAStatus WifiChip::setCountryCode(const std::array<uint8_t, 2>& in_code) {
Kumar Anandda62c382020-11-18 17:17:47 -0800660 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000661 &WifiChip::setCountryCodeInternal, in_code);
Kumar Anandda62c382020-11-18 17:17:47 -0800662}
663
Gabriel Birene58e2632022-07-15 23:25:39 +0000664ndk::ScopedAStatus WifiChip::getUsableChannels(WifiBand in_band, WifiIfaceMode in_ifaceModeMask,
665 UsableChannelFilter in_filterMask,
666 std::vector<WifiUsableChannel>* _aidl_return) {
Kumar Anand2a630a32021-01-21 14:09:14 -0800667 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000668 &WifiChip::getUsableChannelsInternal, _aidl_return, in_band,
669 in_ifaceModeMask, in_filterMask);
Kumar Anand2a630a32021-01-21 14:09:14 -0800670}
671
Gabriel Birene58e2632022-07-15 23:25:39 +0000672ndk::ScopedAStatus WifiChip::triggerSubsystemRestart() {
chenpaulc6f57032021-03-05 17:06:50 +0800673 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000674 &WifiChip::triggerSubsystemRestartInternal);
chenpaulc6f57032021-03-05 17:06:50 +0800675}
676
Gabriel Birene58e2632022-07-15 23:25:39 +0000677ndk::ScopedAStatus WifiChip::getSupportedRadioCombinationsMatrix(
678 WifiRadioCombinationMatrix* _aidl_return) {
Ahmed ElArabawy05571e42022-01-19 11:54:11 -0800679 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Birene58e2632022-07-15 23:25:39 +0000680 &WifiChip::getSupportedRadioCombinationsMatrixInternal, _aidl_return);
Quang Luong5d8805e2022-01-28 15:46:40 -0800681}
682
Roshan Pius35d958c2016-10-06 16:47:38 -0700683void WifiChip::invalidateAndRemoveAllIfaces() {
lesl94d28242020-11-18 22:17:37 +0800684 invalidateAndClearBridgedApAll();
Roshan Pius675609b2017-10-31 14:24:58 -0700685 invalidateAndClearAll(ap_ifaces_);
686 invalidateAndClearAll(nan_ifaces_);
687 invalidateAndClearAll(p2p_ifaces_);
688 invalidateAndClearAll(sta_ifaces_);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700689 // Since all the ifaces are invalid now, all RTT controller objects
690 // using those ifaces also need to be invalidated.
691 for (const auto& rtt : rtt_controllers_) {
692 rtt->invalidate();
693 }
694 rtt_controllers_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -0700695}
696
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800697void WifiChip::invalidateAndRemoveDependencies(const std::string& removed_iface_name) {
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200698 for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) {
699 auto nan_iface = *it;
Roshan Pius82368502019-05-16 12:53:02 -0700700 if (nan_iface->getName() == removed_iface_name) {
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200701 nan_iface->invalidate();
Roshan Pius82368502019-05-16 12:53:02 -0700702 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Gabriel Birene58e2632022-07-15 23:25:39 +0000703 if (!callback->onIfaceRemoved(IfaceType::NAN_IFACE, removed_iface_name).isOk()) {
Roshan Pius82368502019-05-16 12:53:02 -0700704 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
705 }
706 }
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200707 it = nan_ifaces_.erase(it);
708 } else {
709 ++it;
Roshan Pius82368502019-05-16 12:53:02 -0700710 }
711 }
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200712
713 for (auto it = rtt_controllers_.begin(); it != rtt_controllers_.end();) {
714 auto rtt = *it;
Roshan Pius82368502019-05-16 12:53:02 -0700715 if (rtt->getIfaceName() == removed_iface_name) {
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200716 rtt->invalidate();
717 it = rtt_controllers_.erase(it);
718 } else {
719 ++it;
Roshan Pius82368502019-05-16 12:53:02 -0700720 }
721 }
722}
723
Gabriel Birene58e2632022-07-15 23:25:39 +0000724std::pair<int32_t, ndk::ScopedAStatus> WifiChip::getIdInternal() {
725 return {chip_id_, ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -0700726}
727
Gabriel Birene58e2632022-07-15 23:25:39 +0000728ndk::ScopedAStatus WifiChip::registerEventCallbackInternal(
729 const std::shared_ptr<IWifiChipEventCallback>& event_callback) {
730 if (!event_cb_handler_.addCallback(event_callback)) {
731 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
Quang Luong6d661672022-02-16 13:08:39 -0800732 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000733 return ndk::ScopedAStatus::ok();
Roshan Pius3c868522016-10-27 12:43:49 -0700734}
735
Gabriel Birene58e2632022-07-15 23:25:39 +0000736std::pair<IWifiChip::ChipCapabilityMask, ndk::ScopedAStatus> WifiChip::getCapabilitiesInternal() {
737 legacy_hal::wifi_error legacy_status;
738 uint64_t legacy_feature_set;
739 uint32_t legacy_logger_feature_set;
740 const auto ifname = getFirstActiveWlanIfaceName();
741 std::tie(legacy_status, legacy_feature_set) =
742 legacy_hal_.lock()->getSupportedFeatureSet(ifname);
743 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
744 return {IWifiChip::ChipCapabilityMask{}, createWifiStatusFromLegacyError(legacy_status)};
745 }
746 std::tie(legacy_status, legacy_logger_feature_set) =
747 legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
748 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
749 // some devices don't support querying logger feature set
750 legacy_logger_feature_set = 0;
751 }
752 uint32_t aidl_caps;
753 if (!aidl_struct_util::convertLegacyFeaturesToAidlChipCapabilities(
754 legacy_feature_set, legacy_logger_feature_set, &aidl_caps)) {
755 return {IWifiChip::ChipCapabilityMask{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
756 }
757 return {static_cast<IWifiChip::ChipCapabilityMask>(aidl_caps), ndk::ScopedAStatus::ok()};
758}
759
760std::pair<std::vector<IWifiChip::ChipMode>, ndk::ScopedAStatus>
761WifiChip::getAvailableModesInternal() {
762 return {modes_, ndk::ScopedAStatus::ok()};
763}
764
765ndk::ScopedAStatus WifiChip::configureChipInternal(
766 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, int32_t mode_id) {
Roshan Piuscc338202017-11-02 13:54:09 -0700767 if (!isValidModeId(mode_id)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700768 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
769 }
770 if (mode_id == current_mode_id_) {
771 LOG(DEBUG) << "Already in the specified mode " << mode_id;
Gabriel Birene58e2632022-07-15 23:25:39 +0000772 return ndk::ScopedAStatus::ok();
Roshan Piusabcf78f2017-10-06 16:30:38 -0700773 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000774 ndk::ScopedAStatus status = handleChipConfiguration(lock, mode_id);
775 if (!status.isOk()) {
776 WifiStatusCode errorCode = static_cast<WifiStatusCode>(status.getServiceSpecificError());
Roshan Piusabcf78f2017-10-06 16:30:38 -0700777 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Gabriel Birene58e2632022-07-15 23:25:39 +0000778 if (!callback->onChipReconfigureFailure(errorCode).isOk()) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800779 LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback";
Roshan Piusabcf78f2017-10-06 16:30:38 -0700780 }
781 }
782 return status;
783 }
Roshan Piusd37341f2017-01-31 13:13:28 -0800784 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700785 if (!callback->onChipReconfigured(mode_id).isOk()) {
786 LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
787 }
Roshan Pius52947fb2016-11-18 11:38:07 -0800788 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700789 current_mode_id_ = mode_id;
Roshan Piusba38d9c2017-12-08 07:32:08 -0800790 LOG(INFO) << "Configured chip in mode " << mode_id;
Roshan Pius8574e7f2019-04-01 13:30:40 -0700791 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
Ahmed ElArabawy2134bf72020-06-18 15:07:12 -0700792
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800793 legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(subsystemCallbackHandler_);
Ahmed ElArabawy2134bf72020-06-18 15:07:12 -0700794
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800795 return status;
Roshan Pius3c868522016-10-27 12:43:49 -0700796}
797
Gabriel Birene58e2632022-07-15 23:25:39 +0000798std::pair<int32_t, ndk::ScopedAStatus> WifiChip::getModeInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700799 if (!isValidModeId(current_mode_id_)) {
Gabriel Birene58e2632022-07-15 23:25:39 +0000800 return {current_mode_id_, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700801 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000802 return {current_mode_id_, ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -0700803}
804
Gabriel Birene58e2632022-07-15 23:25:39 +0000805std::pair<IWifiChip::ChipDebugInfo, ndk::ScopedAStatus> WifiChip::requestChipDebugInfoInternal() {
806 IWifiChip::ChipDebugInfo result;
Roshan Piusabcf78f2017-10-06 16:30:38 -0700807 legacy_hal::wifi_error legacy_status;
808 std::string driver_desc;
Roshan Pius6036c022019-03-27 10:41:58 -0700809 const auto ifname = getFirstActiveWlanIfaceName();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800810 std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion(ifname);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700811 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800812 LOG(ERROR) << "Failed to get driver version: " << legacyErrorToString(legacy_status);
Gabriel Birene58e2632022-07-15 23:25:39 +0000813 ndk::ScopedAStatus status =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800814 createWifiStatusFromLegacyError(legacy_status, "failed to get driver version");
Gabriel Birene58e2632022-07-15 23:25:39 +0000815 return {std::move(result), std::move(status)};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700816 }
817 result.driverDescription = driver_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700818
Roshan Piusabcf78f2017-10-06 16:30:38 -0700819 std::string firmware_desc;
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800820 std::tie(legacy_status, firmware_desc) = legacy_hal_.lock()->getFirmwareVersion(ifname);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700821 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800822 LOG(ERROR) << "Failed to get firmware version: " << legacyErrorToString(legacy_status);
Gabriel Birene58e2632022-07-15 23:25:39 +0000823 ndk::ScopedAStatus status =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800824 createWifiStatusFromLegacyError(legacy_status, "failed to get firmware version");
Gabriel Birene58e2632022-07-15 23:25:39 +0000825 return {std::move(result), std::move(status)};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700826 }
827 result.firmwareDescription = firmware_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700828
Gabriel Birene58e2632022-07-15 23:25:39 +0000829 return {std::move(result), ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -0700830}
831
Gabriel Birene58e2632022-07-15 23:25:39 +0000832std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> WifiChip::requestDriverDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700833 legacy_hal::wifi_error legacy_status;
834 std::vector<uint8_t> driver_dump;
835 std::tie(legacy_status, driver_dump) =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800836 legacy_hal_.lock()->requestDriverMemoryDump(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -0700837 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800838 LOG(ERROR) << "Failed to get driver debug dump: " << legacyErrorToString(legacy_status);
Gabriel Birene58e2632022-07-15 23:25:39 +0000839 return {std::vector<uint8_t>(), createWifiStatusFromLegacyError(legacy_status)};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700840 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000841 return {driver_dump, ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -0700842}
843
Gabriel Birene58e2632022-07-15 23:25:39 +0000844std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> WifiChip::requestFirmwareDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700845 legacy_hal::wifi_error legacy_status;
846 std::vector<uint8_t> firmware_dump;
847 std::tie(legacy_status, firmware_dump) =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800848 legacy_hal_.lock()->requestFirmwareMemoryDump(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -0700849 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800850 LOG(ERROR) << "Failed to get firmware debug dump: " << legacyErrorToString(legacy_status);
Gabriel Birene58e2632022-07-15 23:25:39 +0000851 return {std::vector<uint8_t>(), createWifiStatusFromLegacyError(legacy_status)};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700852 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000853 return {firmware_dump, ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -0700854}
855
Gabriel Birene58e2632022-07-15 23:25:39 +0000856ndk::ScopedAStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) {
lesl94d28242020-11-18 22:17:37 +0800857 legacy_hal::wifi_error legacy_status;
858 legacy_status = legacy_hal_.lock()->createVirtualInterface(
Gabriel Birene58e2632022-07-15 23:25:39 +0000859 apVirtIf, aidl_struct_util::convertAidlIfaceTypeToLegacy(IfaceType::AP));
Sunil Raviddab4bb2020-02-03 22:45:19 -0800860 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
lesl94d28242020-11-18 22:17:37 +0800861 LOG(ERROR) << "Failed to add interface: " << apVirtIf << " "
Sunil Raviddab4bb2020-02-03 22:45:19 -0800862 << legacyErrorToString(legacy_status);
lesl94d28242020-11-18 22:17:37 +0800863 return createWifiStatusFromLegacyError(legacy_status);
Sunil Raviddab4bb2020-02-03 22:45:19 -0800864 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000865 return ndk::ScopedAStatus::ok();
lesl94d28242020-11-18 22:17:37 +0800866}
867
Gabriel Birene58e2632022-07-15 23:25:39 +0000868std::shared_ptr<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) {
lesl420c4fc2020-11-23 19:33:04 +0800869 std::vector<std::string> ap_instances;
870 for (auto const& it : br_ifaces_ap_instances_) {
871 if (it.first == ifname) {
872 ap_instances = it.second;
873 }
874 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000875 std::shared_ptr<WifiApIface> iface =
876 ndk::SharedRefBase::make<WifiApIface>(ifname, ap_instances, legacy_hal_, iface_util_);
Roshan Pius675609b2017-10-31 14:24:58 -0700877 ap_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700878 for (const auto& callback : event_cb_handler_.getCallbacks()) {
879 if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
880 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
881 }
882 }
Roshan Pius8574e7f2019-04-01 13:30:40 -0700883 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
lesl94d28242020-11-18 22:17:37 +0800884 return iface;
885}
886
Gabriel Birene58e2632022-07-15 23:25:39 +0000887std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> WifiChip::createApIfaceInternal() {
Quang Luong5d8805e2022-01-28 15:46:40 -0800888 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP)) {
Gabriel Birene58e2632022-07-15 23:25:39 +0000889 return {std::shared_ptr<WifiApIface>(),
890 createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
lesl94d28242020-11-18 22:17:37 +0800891 }
892 std::string ifname = allocateApIfaceName();
Gabriel Birene58e2632022-07-15 23:25:39 +0000893 ndk::ScopedAStatus status = createVirtualApInterface(ifname);
894 if (!status.isOk()) {
895 return {std::shared_ptr<WifiApIface>(), std::move(status)};
lesl94d28242020-11-18 22:17:37 +0800896 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000897 std::shared_ptr<WifiApIface> iface = newWifiApIface(ifname);
898 return {iface, ndk::ScopedAStatus::ok()};
lesl94d28242020-11-18 22:17:37 +0800899}
900
Gabriel Birene58e2632022-07-15 23:25:39 +0000901std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus>
902WifiChip::createBridgedApIfaceInternal() {
Quang Luong5d8805e2022-01-28 15:46:40 -0800903 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP_BRIDGED)) {
Gabriel Birene58e2632022-07-15 23:25:39 +0000904 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
lesl94d28242020-11-18 22:17:37 +0800905 }
lesl261818b2020-11-27 12:37:35 +0800906 std::vector<std::string> ap_instances = allocateBridgedApInstanceNames();
907 if (ap_instances.size() < 2) {
908 LOG(ERROR) << "Fail to allocate two instances";
Gabriel Birene58e2632022-07-15 23:25:39 +0000909 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
lesl261818b2020-11-27 12:37:35 +0800910 }
911 std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0];
lesl94d28242020-11-18 22:17:37 +0800912 for (int i = 0; i < 2; i++) {
Gabriel Birene58e2632022-07-15 23:25:39 +0000913 ndk::ScopedAStatus status = createVirtualApInterface(ap_instances[i]);
914 if (!status.isOk()) {
lesl261818b2020-11-27 12:37:35 +0800915 if (i != 0) { // The failure happened when creating second virtual
916 // iface.
lesl94d28242020-11-18 22:17:37 +0800917 legacy_hal_.lock()->deleteVirtualInterface(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800918 ap_instances.front()); // Remove the first virtual iface.
lesl94d28242020-11-18 22:17:37 +0800919 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000920 return {nullptr, std::move(status)};
lesl94d28242020-11-18 22:17:37 +0800921 }
lesl94d28242020-11-18 22:17:37 +0800922 }
923 br_ifaces_ap_instances_[br_ifname] = ap_instances;
Roshan Pius8c1a67b2021-03-02 10:00:23 -0800924 if (!iface_util_->createBridge(br_ifname)) {
lesl94d28242020-11-18 22:17:37 +0800925 LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
Gabriel Birene58e2632022-07-15 23:25:39 +0000926 invalidateAndClearBridgedAp(br_ifname);
927 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
lesl94d28242020-11-18 22:17:37 +0800928 }
929 for (auto const& instance : ap_instances) {
930 // Bind ap instance interface to AP bridge
Roshan Pius8c1a67b2021-03-02 10:00:23 -0800931 if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800932 LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str();
Gabriel Birene58e2632022-07-15 23:25:39 +0000933 invalidateAndClearBridgedAp(br_ifname);
934 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
lesl94d28242020-11-18 22:17:37 +0800935 }
936 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000937 std::shared_ptr<WifiApIface> iface = newWifiApIface(br_ifname);
938 return {iface, ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -0700939}
940
Gabriel Birene58e2632022-07-15 23:25:39 +0000941std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getApIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -0700942 if (ap_ifaces_.empty()) {
Gabriel Birene58e2632022-07-15 23:25:39 +0000943 return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700944 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000945 return {getNames(ap_ifaces_), ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -0700946}
947
Gabriel Birene58e2632022-07-15 23:25:39 +0000948std::pair<std::shared_ptr<IWifiApIface>, ndk::ScopedAStatus> WifiChip::getApIfaceInternal(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800949 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700950 const auto iface = findUsingName(ap_ifaces_, ifname);
951 if (!iface.get()) {
Gabriel Birene58e2632022-07-15 23:25:39 +0000952 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700953 }
Gabriel Birene58e2632022-07-15 23:25:39 +0000954 return {iface, ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -0700955}
956
Gabriel Birene58e2632022-07-15 23:25:39 +0000957ndk::ScopedAStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -0700958 const auto iface = findUsingName(ap_ifaces_, ifname);
959 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700960 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -0800961 }
Roshan Pius82368502019-05-16 12:53:02 -0700962 // Invalidate & remove any dependent objects first.
963 // Note: This is probably not required because we never create
964 // nan/rtt objects over AP iface. But, there is no harm to do it
965 // here and not make that assumption all over the place.
966 invalidateAndRemoveDependencies(ifname);
Gabriel Birene58e2632022-07-15 23:25:39 +0000967 // Clear the bridge interface and the iface instance.
968 invalidateAndClearBridgedAp(ifname);
Roshan Pius675609b2017-10-31 14:24:58 -0700969 invalidateAndClear(ap_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700970 for (const auto& callback : event_cb_handler_.getCallbacks()) {
971 if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
972 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
973 }
974 }
Roshan Pius8574e7f2019-04-01 13:30:40 -0700975 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
Gabriel Birene58e2632022-07-15 23:25:39 +0000976 return ndk::ScopedAStatus::ok();
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800977}
978
Gabriel Birene58e2632022-07-15 23:25:39 +0000979ndk::ScopedAStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800980 const std::string& ifname, const std::string& ifInstanceName) {
lesl94d28242020-11-18 22:17:37 +0800981 const auto iface = findUsingName(ap_ifaces_, ifname);
lesl819e3722021-01-07 09:49:04 +0800982 if (!iface.get() || ifInstanceName.empty()) {
lesl94d28242020-11-18 22:17:37 +0800983 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
984 }
985 // Requires to remove one of the instance in bridge mode
986 for (auto const& it : br_ifaces_ap_instances_) {
987 if (it.first == ifname) {
Les Lee03d642f2021-06-21 21:25:20 +0800988 std::vector<std::string> ap_instances = it.second;
989 for (auto const& iface : ap_instances) {
lesl94d28242020-11-18 22:17:37 +0800990 if (iface == ifInstanceName) {
Roshan Pius8c1a67b2021-03-02 10:00:23 -0800991 if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800992 LOG(ERROR) << "Failed to remove interface: " << ifInstanceName << " from "
993 << ifname;
994 return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE);
lesl94d28242020-11-18 22:17:37 +0800995 }
George Burgess IV2c0a47d2021-01-20 21:14:13 -0800996 legacy_hal::wifi_error legacy_status =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800997 legacy_hal_.lock()->deleteVirtualInterface(iface);
lesl94d28242020-11-18 22:17:37 +0800998 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800999 LOG(ERROR) << "Failed to del interface: " << iface << " "
1000 << legacyErrorToString(legacy_status);
lesl94d28242020-11-18 22:17:37 +08001001 return createWifiStatusFromLegacyError(legacy_status);
1002 }
Les Lee03d642f2021-06-21 21:25:20 +08001003 ap_instances.erase(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001004 std::remove(ap_instances.begin(), ap_instances.end(), ifInstanceName),
1005 ap_instances.end());
Les Lee03d642f2021-06-21 21:25:20 +08001006 br_ifaces_ap_instances_[ifname] = ap_instances;
1007 break;
lesl94d28242020-11-18 22:17:37 +08001008 }
1009 }
1010 break;
1011 }
1012 }
lesl669c9062021-01-22 19:37:47 +08001013 iface->removeInstance(ifInstanceName);
Les Lee03d642f2021-06-21 21:25:20 +08001014 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1015
Gabriel Birene58e2632022-07-15 23:25:39 +00001016 return ndk::ScopedAStatus::ok();
lesl94d28242020-11-18 22:17:37 +08001017}
1018
Gabriel Birene58e2632022-07-15 23:25:39 +00001019std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> WifiChip::createNanIfaceInternal() {
1020 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::NAN_IFACE)) {
1021 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
Etan Cohenc5700402017-03-08 16:43:38 -08001022 }
Roshan Pius5ba0a902020-04-14 11:55:42 -07001023 bool is_dedicated_iface = true;
lesl261818b2020-11-27 12:37:35 +08001024 std::string ifname = getPredefinedNanIfaceName();
Roshan Pius8c1a67b2021-03-02 10:00:23 -08001025 if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) {
Roshan Pius5ba0a902020-04-14 11:55:42 -07001026 // Use the first shared STA iface (wlan0) if a dedicated aware iface is
1027 // not defined.
1028 ifname = getFirstActiveWlanIfaceName();
1029 is_dedicated_iface = false;
1030 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001031 std::shared_ptr<WifiNanIface> iface =
1032 WifiNanIface::create(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
Roshan Piuscc338202017-11-02 13:54:09 -07001033 nan_ifaces_.push_back(iface);
1034 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001035 if (!callback->onIfaceAdded(IfaceType::NAN_IFACE, ifname).isOk()) {
Roshan Piuscc338202017-11-02 13:54:09 -07001036 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1037 }
1038 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001039 return {iface, ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -07001040}
1041
Gabriel Birene58e2632022-07-15 23:25:39 +00001042std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getNanIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -07001043 if (nan_ifaces_.empty()) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001044 return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001045 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001046 return {getNames(nan_ifaces_), ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -07001047}
1048
Gabriel Birene58e2632022-07-15 23:25:39 +00001049std::pair<std::shared_ptr<IWifiNanIface>, ndk::ScopedAStatus> WifiChip::getNanIfaceInternal(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001050 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001051 const auto iface = findUsingName(nan_ifaces_, ifname);
1052 if (!iface.get()) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001053 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001054 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001055 return {iface, ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -07001056}
1057
Gabriel Birene58e2632022-07-15 23:25:39 +00001058ndk::ScopedAStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001059 const auto iface = findUsingName(nan_ifaces_, ifname);
1060 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001061 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -08001062 }
Roshan Pius675609b2017-10-31 14:24:58 -07001063 invalidateAndClear(nan_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001064 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001065 if (!callback->onIfaceRemoved(IfaceType::NAN_IFACE, ifname).isOk()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001066 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1067 }
1068 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001069 return ndk::ScopedAStatus::ok();
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001070}
1071
Gabriel Birene58e2632022-07-15 23:25:39 +00001072std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> WifiChip::createP2pIfaceInternal() {
Quang Luong5d8805e2022-01-28 15:46:40 -08001073 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::P2P)) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001074 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
Roshan Piusbc662202017-01-30 17:07:42 -08001075 }
lesl261818b2020-11-27 12:37:35 +08001076 std::string ifname = getPredefinedP2pIfaceName();
Gabriel Birene58e2632022-07-15 23:25:39 +00001077 std::shared_ptr<WifiP2pIface> iface =
1078 ndk::SharedRefBase::make<WifiP2pIface>(ifname, legacy_hal_);
Roshan Pius675609b2017-10-31 14:24:58 -07001079 p2p_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001080 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1081 if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
1082 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1083 }
1084 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001085 return {iface, ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -07001086}
1087
Gabriel Birene58e2632022-07-15 23:25:39 +00001088std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getP2pIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -07001089 if (p2p_ifaces_.empty()) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001090 return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001091 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001092 return {getNames(p2p_ifaces_), ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -07001093}
1094
Gabriel Birene58e2632022-07-15 23:25:39 +00001095std::pair<std::shared_ptr<IWifiP2pIface>, ndk::ScopedAStatus> WifiChip::getP2pIfaceInternal(
1096 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001097 const auto iface = findUsingName(p2p_ifaces_, ifname);
1098 if (!iface.get()) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001099 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001100 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001101 return {iface, ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -07001102}
1103
Gabriel Birene58e2632022-07-15 23:25:39 +00001104ndk::ScopedAStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001105 const auto iface = findUsingName(p2p_ifaces_, ifname);
1106 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001107 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -08001108 }
Roshan Pius675609b2017-10-31 14:24:58 -07001109 invalidateAndClear(p2p_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001110 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1111 if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
1112 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1113 }
1114 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001115 return ndk::ScopedAStatus::ok();
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001116}
1117
Gabriel Birene58e2632022-07-15 23:25:39 +00001118std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> WifiChip::createStaIfaceInternal() {
Quang Luong5d8805e2022-01-28 15:46:40 -08001119 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001120 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
Roshan Piusbc662202017-01-30 17:07:42 -08001121 }
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001122 std::string ifname = allocateStaIfaceName();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001123 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->createVirtualInterface(
Gabriel Birene58e2632022-07-15 23:25:39 +00001124 ifname, aidl_struct_util::convertAidlIfaceTypeToLegacy(IfaceType::STA));
Sunil Raviddab4bb2020-02-03 22:45:19 -08001125 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1126 LOG(ERROR) << "Failed to add interface: " << ifname << " "
1127 << legacyErrorToString(legacy_status);
Gabriel Birene58e2632022-07-15 23:25:39 +00001128 return {nullptr, createWifiStatusFromLegacyError(legacy_status)};
Sunil Raviddab4bb2020-02-03 22:45:19 -08001129 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001130 std::shared_ptr<WifiStaIface> iface =
1131 ndk::SharedRefBase::make<WifiStaIface>(ifname, legacy_hal_, iface_util_);
Roshan Pius675609b2017-10-31 14:24:58 -07001132 sta_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001133 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1134 if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
1135 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1136 }
1137 }
Roshan Pius8574e7f2019-04-01 13:30:40 -07001138 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
Gabriel Birene58e2632022-07-15 23:25:39 +00001139 return {iface, ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -07001140}
1141
Gabriel Birene58e2632022-07-15 23:25:39 +00001142std::pair<std::vector<std::string>, ndk::ScopedAStatus> WifiChip::getStaIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -07001143 if (sta_ifaces_.empty()) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001144 return {std::vector<std::string>(), ndk::ScopedAStatus::ok()};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001145 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001146 return {getNames(sta_ifaces_), ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -07001147}
1148
Gabriel Birene58e2632022-07-15 23:25:39 +00001149std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus> WifiChip::getStaIfaceInternal(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001150 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001151 const auto iface = findUsingName(sta_ifaces_, ifname);
1152 if (!iface.get()) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001153 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001154 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001155 return {iface, ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -07001156}
1157
Gabriel Birene58e2632022-07-15 23:25:39 +00001158ndk::ScopedAStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001159 const auto iface = findUsingName(sta_ifaces_, ifname);
1160 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001161 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -08001162 }
Roshan Pius82368502019-05-16 12:53:02 -07001163 // Invalidate & remove any dependent objects first.
1164 invalidateAndRemoveDependencies(ifname);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001165 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(ifname);
Sunil Raviddab4bb2020-02-03 22:45:19 -08001166 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1167 LOG(ERROR) << "Failed to remove interface: " << ifname << " "
1168 << legacyErrorToString(legacy_status);
1169 }
Roshan Pius675609b2017-10-31 14:24:58 -07001170 invalidateAndClear(sta_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001171 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1172 if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
1173 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1174 }
1175 }
Roshan Pius8574e7f2019-04-01 13:30:40 -07001176 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
Gabriel Birene58e2632022-07-15 23:25:39 +00001177 return ndk::ScopedAStatus::ok();
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001178}
1179
Gabriel Birene58e2632022-07-15 23:25:39 +00001180std::pair<std::shared_ptr<IWifiRttController>, ndk::ScopedAStatus>
1181WifiChip::createRttControllerInternal(const std::shared_ptr<IWifiStaIface>& bound_iface) {
1182 if (sta_ifaces_.size() == 0 &&
1183 !canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
1184 LOG(ERROR) << "createRttControllerInternal: Chip cannot support STAs "
1185 "(and RTT by extension)";
1186 return {nullptr, createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE)};
1187 }
1188 std::shared_ptr<WifiRttController> rtt =
1189 WifiRttController::create(getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
1190 rtt_controllers_.emplace_back(rtt);
1191 return {rtt, ndk::ScopedAStatus::ok()};
Roshan Pius3c868522016-10-27 12:43:49 -07001192}
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001193
Gabriel Birene58e2632022-07-15 23:25:39 +00001194std::pair<std::vector<WifiDebugRingBufferStatus>, ndk::ScopedAStatus>
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001195WifiChip::getDebugRingBuffersStatusInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001196 legacy_hal::wifi_error legacy_status;
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001197 std::vector<legacy_hal::wifi_ring_buffer_status> legacy_ring_buffer_status_vec;
Roshan Piusabcf78f2017-10-06 16:30:38 -07001198 std::tie(legacy_status, legacy_ring_buffer_status_vec) =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001199 legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001200 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001201 return {std::vector<WifiDebugRingBufferStatus>(),
1202 createWifiStatusFromLegacyError(legacy_status)};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001203 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001204 std::vector<WifiDebugRingBufferStatus> aidl_ring_buffer_status_vec;
1205 if (!aidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToAidl(
1206 legacy_ring_buffer_status_vec, &aidl_ring_buffer_status_vec)) {
1207 return {std::vector<WifiDebugRingBufferStatus>(),
1208 createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001209 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001210 return {aidl_ring_buffer_status_vec, ndk::ScopedAStatus::ok()};
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001211}
1212
Gabriel Birene58e2632022-07-15 23:25:39 +00001213ndk::ScopedAStatus WifiChip::startLoggingToDebugRingBufferInternal(
1214 const std::string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001215 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001216 ndk::ScopedAStatus status = registerDebugRingBufferCallback();
1217 if (!status.isOk()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001218 return status;
1219 }
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001220 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRingBufferLogging(
Roshan Pius6036c022019-03-27 10:41:58 -07001221 getFirstActiveWlanIfaceName(), ring_name,
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001222 static_cast<std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(verbose_level),
Roshan Piusabcf78f2017-10-06 16:30:38 -07001223 max_interval_in_sec, min_data_size_in_bytes);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001224 ringbuffer_map_.insert(
1225 std::pair<std::string, Ringbuffer>(ring_name, Ringbuffer(kMaxBufferSizeBytes)));
Roshan Piusa63b53f2019-11-18 11:03:13 -08001226 // if verbose logging enabled, turn up HAL daemon logging as well.
1227 if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001228 ::android::base::SetMinimumLogSeverity(::android::base::DEBUG);
Roshan Piusa63b53f2019-11-18 11:03:13 -08001229 } else {
Gabriel Birene58e2632022-07-15 23:25:39 +00001230 ::android::base::SetMinimumLogSeverity(::android::base::VERBOSE);
Roshan Piusa63b53f2019-11-18 11:03:13 -08001231 }
Roshan Piusabcf78f2017-10-06 16:30:38 -07001232 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001233}
1234
Gabriel Birene58e2632022-07-15 23:25:39 +00001235ndk::ScopedAStatus WifiChip::forceDumpToDebugRingBufferInternal(const std::string& ring_name) {
1236 ndk::ScopedAStatus status = registerDebugRingBufferCallback();
1237 if (!status.isOk()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001238 return status;
1239 }
1240 legacy_hal::wifi_error legacy_status =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001241 legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), ring_name);
xshu5899e8e2018-01-09 15:36:03 -08001242
Roshan Piusabcf78f2017-10-06 16:30:38 -07001243 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001244}
1245
Gabriel Birene58e2632022-07-15 23:25:39 +00001246ndk::ScopedAStatus WifiChip::flushRingBufferToFileInternal() {
Roger Wangb294c762018-11-02 15:34:39 +08001247 if (!writeRingbufferFilesInternal()) {
1248 LOG(ERROR) << "Error writing files to flash";
1249 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1250 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001251 return ndk::ScopedAStatus::ok();
Roger Wangb294c762018-11-02 15:34:39 +08001252}
1253
Gabriel Birene58e2632022-07-15 23:25:39 +00001254ndk::ScopedAStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001255 legacy_hal::wifi_error legacy_status =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001256 legacy_hal_.lock()->deregisterRingBufferCallbackHandler(getFirstActiveWlanIfaceName());
xshu0a0fe512020-07-22 17:53:37 -07001257 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1258 debug_ring_buffer_cb_registered_ = false;
1259 }
Roshan Piusabcf78f2017-10-06 16:30:38 -07001260 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius8c0c8e92017-02-24 08:07:42 -08001261}
1262
Gabriel Birene58e2632022-07-15 23:25:39 +00001263std::pair<WifiDebugHostWakeReasonStats, ndk::ScopedAStatus>
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001264WifiChip::getDebugHostWakeReasonStatsInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001265 legacy_hal::wifi_error legacy_status;
1266 legacy_hal::WakeReasonStats legacy_stats;
1267 std::tie(legacy_status, legacy_stats) =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001268 legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001269 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001270 return {WifiDebugHostWakeReasonStats{}, createWifiStatusFromLegacyError(legacy_status)};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001271 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001272 WifiDebugHostWakeReasonStats aidl_stats;
1273 if (!aidl_struct_util::convertLegacyWakeReasonStatsToAidl(legacy_stats, &aidl_stats)) {
1274 return {WifiDebugHostWakeReasonStats{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001275 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001276 return {aidl_stats, ndk::ScopedAStatus::ok()};
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001277}
1278
Gabriel Birene58e2632022-07-15 23:25:39 +00001279ndk::ScopedAStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001280 legacy_hal::wifi_error legacy_status;
1281 if (enable) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001282 std::weak_ptr<WifiChip> weak_ptr_this = weak_ptr_this_;
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001283 const auto& on_alert_callback = [weak_ptr_this](int32_t error_code,
1284 std::vector<uint8_t> debug_data) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001285 const auto shared_ptr_this = weak_ptr_this.lock();
Roshan Piusabcf78f2017-10-06 16:30:38 -07001286 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1287 LOG(ERROR) << "Callback invoked on an invalid object";
1288 return;
1289 }
1290 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001291 if (!callback->onDebugErrorAlert(error_code, debug_data).isOk()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001292 LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
1293 }
1294 }
1295 };
1296 legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001297 getFirstActiveWlanIfaceName(), on_alert_callback);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001298 } else {
1299 legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001300 getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001301 }
1302 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius203cb032016-12-14 17:41:20 -08001303}
Roshan Pius2c06a3f2016-12-15 17:51:40 -08001304
Gabriel Birene58e2632022-07-15 23:25:39 +00001305ndk::ScopedAStatus WifiChip::selectTxPowerScenarioInternal(IWifiChip::TxPowerScenario scenario) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001306 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001307 getFirstActiveWlanIfaceName(),
Gabriel Birene58e2632022-07-15 23:25:39 +00001308 aidl_struct_util::convertAidlTxPowerScenarioToLegacy(scenario));
Roshan Piusabcf78f2017-10-06 16:30:38 -07001309 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -07001310}
1311
Gabriel Birene58e2632022-07-15 23:25:39 +00001312ndk::ScopedAStatus WifiChip::resetTxPowerScenarioInternal() {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001313 auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001314 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -07001315}
1316
Gabriel Birene58e2632022-07-15 23:25:39 +00001317ndk::ScopedAStatus WifiChip::setLatencyModeInternal(IWifiChip::LatencyMode mode) {
Ahmed ElArabawyeaf82402018-10-26 09:46:04 -07001318 auto legacy_status = legacy_hal_.lock()->setLatencyMode(
Gabriel Birene58e2632022-07-15 23:25:39 +00001319 getFirstActiveWlanIfaceName(), aidl_struct_util::convertAidlLatencyModeToLegacy(mode));
Ahmed ElArabawyeaf82402018-10-26 09:46:04 -07001320 return createWifiStatusFromLegacyError(legacy_status);
1321}
1322
Gabriel Birene58e2632022-07-15 23:25:39 +00001323ndk::ScopedAStatus WifiChip::setMultiStaPrimaryConnectionInternal(const std::string& ifname) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001324 auto legacy_status = legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname);
Roshan Piuse9d1e7d2020-11-04 11:44:16 -08001325 return createWifiStatusFromLegacyError(legacy_status);
1326}
1327
Gabriel Birene58e2632022-07-15 23:25:39 +00001328ndk::ScopedAStatus WifiChip::setMultiStaUseCaseInternal(IWifiChip::MultiStaUseCase use_case) {
Roshan Piuse9d1e7d2020-11-04 11:44:16 -08001329 auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase(
Gabriel Birene58e2632022-07-15 23:25:39 +00001330 aidl_struct_util::convertAidlMultiStaUseCaseToLegacy(use_case));
Roshan Piuse9d1e7d2020-11-04 11:44:16 -08001331 return createWifiStatusFromLegacyError(legacy_status);
1332}
1333
Gabriel Birene58e2632022-07-15 23:25:39 +00001334ndk::ScopedAStatus WifiChip::setCoexUnsafeChannelsInternal(
1335 std::vector<IWifiChip::CoexUnsafeChannel> unsafe_channels, CoexRestriction restrictions) {
Quang Luong94bcce52020-11-25 17:52:19 -08001336 std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels;
Gabriel Birene58e2632022-07-15 23:25:39 +00001337 if (!aidl_struct_util::convertAidlVectorOfCoexUnsafeChannelToLegacy(unsafe_channels,
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001338 &legacy_unsafe_channels)) {
Quang Luong94bcce52020-11-25 17:52:19 -08001339 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1340 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001341 uint32_t aidl_restrictions = static_cast<uint32_t>(restrictions);
Quang Luongab70a832020-12-14 13:01:32 -08001342 uint32_t legacy_restrictions = 0;
Gabriel Birene58e2632022-07-15 23:25:39 +00001343 if (aidl_restrictions & static_cast<uint32_t>(CoexRestriction::WIFI_DIRECT)) {
Quang Luongab70a832020-12-14 13:01:32 -08001344 legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_DIRECT;
1345 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001346 if (aidl_restrictions & static_cast<uint32_t>(CoexRestriction::SOFTAP)) {
Quang Luongab70a832020-12-14 13:01:32 -08001347 legacy_restrictions |= legacy_hal::wifi_coex_restriction::SOFTAP;
1348 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001349 if (aidl_restrictions & static_cast<uint32_t>(CoexRestriction::WIFI_AWARE)) {
Quang Luongab70a832020-12-14 13:01:32 -08001350 legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE;
1351 }
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001352 auto legacy_status =
1353 legacy_hal_.lock()->setCoexUnsafeChannels(legacy_unsafe_channels, legacy_restrictions);
Quang Luong94bcce52020-11-25 17:52:19 -08001354 return createWifiStatusFromLegacyError(legacy_status);
1355}
1356
Gabriel Birene58e2632022-07-15 23:25:39 +00001357ndk::ScopedAStatus WifiChip::setCountryCodeInternal(const std::array<uint8_t, 2>& code) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001358 auto legacy_status = legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code);
Kumar Anandda62c382020-11-18 17:17:47 -08001359 return createWifiStatusFromLegacyError(legacy_status);
1360}
1361
Gabriel Birene58e2632022-07-15 23:25:39 +00001362std::pair<std::vector<WifiUsableChannel>, ndk::ScopedAStatus> WifiChip::getUsableChannelsInternal(
1363 WifiBand band, WifiIfaceMode ifaceModeMask, UsableChannelFilter filterMask) {
Kumar Anand2a630a32021-01-21 14:09:14 -08001364 legacy_hal::wifi_error legacy_status;
1365 std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels;
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001366 std::tie(legacy_status, legacy_usable_channels) = legacy_hal_.lock()->getUsableChannels(
Gabriel Birene58e2632022-07-15 23:25:39 +00001367 aidl_struct_util::convertAidlWifiBandToLegacyMacBand(band),
1368 aidl_struct_util::convertAidlWifiIfaceModeToLegacy(
1369 static_cast<uint32_t>(ifaceModeMask)),
1370 aidl_struct_util::convertAidlUsableChannelFilterToLegacy(
1371 static_cast<uint32_t>(filterMask)));
Kumar Anandaea86e02021-02-10 16:22:31 -08001372
Kumar Anand2a630a32021-01-21 14:09:14 -08001373 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001374 return {std::vector<WifiUsableChannel>(), createWifiStatusFromLegacyError(legacy_status)};
Kumar Anand2a630a32021-01-21 14:09:14 -08001375 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001376 std::vector<WifiUsableChannel> aidl_usable_channels;
1377 if (!aidl_struct_util::convertLegacyWifiUsableChannelsToAidl(legacy_usable_channels,
1378 &aidl_usable_channels)) {
1379 return {std::vector<WifiUsableChannel>(), createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
Kumar Anand2a630a32021-01-21 14:09:14 -08001380 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001381 return {aidl_usable_channels, ndk::ScopedAStatus::ok()};
Kumar Anand2a630a32021-01-21 14:09:14 -08001382}
1383
Gabriel Birene58e2632022-07-15 23:25:39 +00001384std::pair<WifiRadioCombinationMatrix, ndk::ScopedAStatus>
Sunil Ravief97d232022-01-24 10:39:56 -08001385WifiChip::getSupportedRadioCombinationsMatrixInternal() {
1386 legacy_hal::wifi_error legacy_status;
1387 legacy_hal::wifi_radio_combination_matrix* legacy_matrix;
1388
1389 std::tie(legacy_status, legacy_matrix) =
1390 legacy_hal_.lock()->getSupportedRadioCombinationsMatrix();
1391 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1392 LOG(ERROR) << "Failed to get SupportedRadioCombinations matrix from legacy HAL: "
1393 << legacyErrorToString(legacy_status);
Gabriel Birene58e2632022-07-15 23:25:39 +00001394 return {WifiRadioCombinationMatrix{}, createWifiStatusFromLegacyError(legacy_status)};
Sunil Ravief97d232022-01-24 10:39:56 -08001395 }
1396
Gabriel Birene58e2632022-07-15 23:25:39 +00001397 WifiRadioCombinationMatrix aidl_matrix;
1398 if (!aidl_struct_util::convertLegacyRadioCombinationsMatrixToAidl(legacy_matrix,
1399 &aidl_matrix)) {
1400 LOG(ERROR) << "Failed convertLegacyRadioCombinationsMatrixToAidl() ";
1401 return {WifiRadioCombinationMatrix(), createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS)};
Sunil Ravief97d232022-01-24 10:39:56 -08001402 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001403 return {aidl_matrix, ndk::ScopedAStatus::ok()};
Sunil Ravief97d232022-01-24 10:39:56 -08001404}
1405
Gabriel Birene58e2632022-07-15 23:25:39 +00001406ndk::ScopedAStatus WifiChip::triggerSubsystemRestartInternal() {
1407 auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart();
1408 return createWifiStatusFromLegacyError(legacy_status);
Quang Luong5d8805e2022-01-28 15:46:40 -08001409}
1410
Gabriel Birene58e2632022-07-15 23:25:39 +00001411ndk::ScopedAStatus WifiChip::handleChipConfiguration(
1412 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, int32_t mode_id) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001413 // If the chip is already configured in a different mode, stop
1414 // the legacy HAL and then start it after firmware mode change.
Roshan Piuscc338202017-11-02 13:54:09 -07001415 if (isValidModeId(current_mode_id_)) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001416 LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ << " to mode " << mode_id;
Roshan Piusba38d9c2017-12-08 07:32:08 -08001417 invalidateAndRemoveAllIfaces();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001418 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop(lock, []() {});
Roshan Piusba38d9c2017-12-08 07:32:08 -08001419 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001420 LOG(ERROR) << "Failed to stop legacy HAL: " << legacyErrorToString(legacy_status);
Roshan Piusba38d9c2017-12-08 07:32:08 -08001421 return createWifiStatusFromLegacyError(legacy_status);
1422 }
Roshan Piusabcf78f2017-10-06 16:30:38 -07001423 }
Roshan Piuscc338202017-11-02 13:54:09 -07001424 // Firmware mode change not needed for V2 devices.
1425 bool success = true;
Tomasz Wasilczykb424da72018-11-15 11:52:57 -08001426 if (mode_id == feature_flags::chip_mode_ids::kV1Sta) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001427 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
Tomasz Wasilczykb424da72018-11-15 11:52:57 -08001428 } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001429 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
1430 }
1431 if (!success) {
1432 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1433 }
1434 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
1435 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001436 LOG(ERROR) << "Failed to start legacy HAL: " << legacyErrorToString(legacy_status);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001437 return createWifiStatusFromLegacyError(legacy_status);
1438 }
Roshan Pius85c64412018-01-22 17:58:40 -08001439 // Every time the HAL is restarted, we need to register the
1440 // radio mode change callback.
Gabriel Birene58e2632022-07-15 23:25:39 +00001441 ndk::ScopedAStatus status = registerRadioModeChangeCallback();
1442 if (!status.isOk()) {
1443 // This is probably not a critical failure?
Roshan Pius85c64412018-01-22 17:58:40 -08001444 LOG(ERROR) << "Failed to register radio mode change callback";
1445 }
chenpaulf5eca292019-03-14 11:08:03 +08001446 // Extract and save the version information into property.
Gabriel Birene58e2632022-07-15 23:25:39 +00001447 std::pair<IWifiChip::ChipDebugInfo, ndk::ScopedAStatus> version_info;
chenpaulf5eca292019-03-14 11:08:03 +08001448 version_info = WifiChip::requestChipDebugInfoInternal();
Gabriel Birene58e2632022-07-15 23:25:39 +00001449 if (version_info.second.isOk()) {
chenpaulf5eca292019-03-14 11:08:03 +08001450 property_set("vendor.wlan.firmware.version",
Gabriel Birene58e2632022-07-15 23:25:39 +00001451 version_info.first.firmwareDescription.c_str());
1452 property_set("vendor.wlan.driver.version", version_info.first.driverDescription.c_str());
chenpaulf5eca292019-03-14 11:08:03 +08001453 }
1454
Gabriel Birene58e2632022-07-15 23:25:39 +00001455 return ndk::ScopedAStatus::ok();
Roshan Pius2c06a3f2016-12-15 17:51:40 -08001456}
Roshan Pius48185b22016-12-15 19:10:30 -08001457
Gabriel Birene58e2632022-07-15 23:25:39 +00001458ndk::ScopedAStatus WifiChip::registerDebugRingBufferCallback() {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001459 if (debug_ring_buffer_cb_registered_) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001460 return ndk::ScopedAStatus::ok();
Roshan Pius48185b22016-12-15 19:10:30 -08001461 }
Roshan Pius3797e182017-03-30 18:01:54 -07001462
Gabriel Birene58e2632022-07-15 23:25:39 +00001463 std::weak_ptr<WifiChip> weak_ptr_this = weak_ptr_this_;
Roshan Piusabcf78f2017-10-06 16:30:38 -07001464 const auto& on_ring_buffer_data_callback =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001465 [weak_ptr_this](const std::string& name, const std::vector<uint8_t>& data,
1466 const legacy_hal::wifi_ring_buffer_status& status) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001467 const auto shared_ptr_this = weak_ptr_this.lock();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001468 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1469 LOG(ERROR) << "Callback invoked on an invalid object";
Veerendranath Jakkam25b3a6f2020-04-14 22:04:39 +05301470 return;
1471 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001472 WifiDebugRingBufferStatus aidl_status;
Sunil Ravi07ef1912022-05-17 18:01:06 -07001473 Ringbuffer::AppendStatus appendstatus;
Gabriel Birene58e2632022-07-15 23:25:39 +00001474 if (!aidl_struct_util::convertLegacyDebugRingBufferStatusToAidl(status,
1475 &aidl_status)) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001476 LOG(ERROR) << "Error converting ring buffer status";
1477 return;
1478 }
1479 {
1480 std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t);
1481 const auto& target = shared_ptr_this->ringbuffer_map_.find(name);
1482 if (target != shared_ptr_this->ringbuffer_map_.end()) {
1483 Ringbuffer& cur_buffer = target->second;
Sunil Ravi07ef1912022-05-17 18:01:06 -07001484 appendstatus = cur_buffer.append(data);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001485 } else {
1486 LOG(ERROR) << "Ringname " << name << " not found";
1487 return;
1488 }
1489 // unique_lock unlocked here
1490 }
Sunil Ravi07ef1912022-05-17 18:01:06 -07001491 if (appendstatus == Ringbuffer::AppendStatus::FAIL_RING_BUFFER_CORRUPTED) {
1492 LOG(ERROR) << "Ringname " << name << " is corrupted. Clear the ring buffer";
1493 shared_ptr_this->writeRingbufferFilesInternal();
1494 return;
1495 }
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001496 };
1497 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->registerRingBufferCallbackHandler(
Roshan Pius6036c022019-03-27 10:41:58 -07001498 getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback);
Roshan Pius48185b22016-12-15 19:10:30 -08001499
Roshan Piusabcf78f2017-10-06 16:30:38 -07001500 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1501 debug_ring_buffer_cb_registered_ = true;
1502 }
1503 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius48185b22016-12-15 19:10:30 -08001504}
1505
Gabriel Birene58e2632022-07-15 23:25:39 +00001506ndk::ScopedAStatus WifiChip::registerRadioModeChangeCallback() {
1507 std::weak_ptr<WifiChip> weak_ptr_this = weak_ptr_this_;
Roshan Pius85c64412018-01-22 17:58:40 -08001508 const auto& on_radio_mode_change_callback =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001509 [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001510 const auto shared_ptr_this = weak_ptr_this.lock();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001511 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1512 LOG(ERROR) << "Callback invoked on an invalid object";
1513 return;
Roshan Pius85c64412018-01-22 17:58:40 -08001514 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001515 std::vector<IWifiChipEventCallback::RadioModeInfo> aidl_radio_mode_infos;
1516 if (!aidl_struct_util::convertLegacyWifiMacInfosToAidl(mac_infos,
1517 &aidl_radio_mode_infos)) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001518 LOG(ERROR) << "Error converting wifi mac info";
1519 return;
1520 }
1521 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001522 if (!callback->onRadioModeChange(aidl_radio_mode_infos).isOk()) {
1523 LOG(ERROR) << "Failed to invoke onRadioModeChange callback";
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001524 }
1525 }
1526 };
Roshan Pius85c64412018-01-22 17:58:40 -08001527 legacy_hal::wifi_error legacy_status =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001528 legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
1529 getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
Roshan Pius85c64412018-01-22 17:58:40 -08001530 return createWifiStatusFromLegacyError(legacy_status);
1531}
1532
Gabriel Birene58e2632022-07-15 23:25:39 +00001533std::vector<IWifiChip::ChipConcurrencyCombination>
Quang Luong5d8805e2022-01-28 15:46:40 -08001534WifiChip::getCurrentModeConcurrencyCombinations() {
Roshan Piuscc338202017-11-02 13:54:09 -07001535 if (!isValidModeId(current_mode_id_)) {
1536 LOG(ERROR) << "Chip not configured in a mode yet";
Gabriel Birene58e2632022-07-15 23:25:39 +00001537 return std::vector<IWifiChip::ChipConcurrencyCombination>();
Roshan Piuscc338202017-11-02 13:54:09 -07001538 }
1539 for (const auto& mode : modes_) {
1540 if (mode.id == current_mode_id_) {
1541 return mode.availableCombinations;
1542 }
1543 }
Quang Luong5d8805e2022-01-28 15:46:40 -08001544 CHECK(0) << "Expected to find concurrency combinations for current mode!";
Gabriel Birene58e2632022-07-15 23:25:39 +00001545 return std::vector<IWifiChip::ChipConcurrencyCombination>();
Roshan Piuscc338202017-11-02 13:54:09 -07001546}
1547
Quang Luong5d8805e2022-01-28 15:46:40 -08001548// Returns a map indexed by IfaceConcurrencyType with the number of ifaces currently
1549// created of the corresponding concurrency type.
1550std::map<IfaceConcurrencyType, size_t> WifiChip::getCurrentConcurrencyCombination() {
1551 std::map<IfaceConcurrencyType, size_t> iface_counts;
1552 uint32_t num_ap = 0;
1553 uint32_t num_ap_bridged = 0;
1554 for (const auto& ap_iface : ap_ifaces_) {
1555 std::string ap_iface_name = ap_iface->getName();
1556 if (br_ifaces_ap_instances_.count(ap_iface_name) > 0 &&
1557 br_ifaces_ap_instances_[ap_iface_name].size() > 1) {
1558 num_ap_bridged++;
1559 } else {
1560 num_ap++;
1561 }
1562 }
1563 iface_counts[IfaceConcurrencyType::AP] = num_ap;
1564 iface_counts[IfaceConcurrencyType::AP_BRIDGED] = num_ap_bridged;
Gabriel Birene58e2632022-07-15 23:25:39 +00001565 iface_counts[IfaceConcurrencyType::NAN_IFACE] = nan_ifaces_.size();
Quang Luong5d8805e2022-01-28 15:46:40 -08001566 iface_counts[IfaceConcurrencyType::P2P] = p2p_ifaces_.size();
1567 iface_counts[IfaceConcurrencyType::STA] = sta_ifaces_.size();
Roshan Piuscc338202017-11-02 13:54:09 -07001568 return iface_counts;
1569}
1570
Quang Luong5d8805e2022-01-28 15:46:40 -08001571// This expands the provided concurrency combinations to a more parseable
Roshan Piuscc338202017-11-02 13:54:09 -07001572// form. Returns a vector of available combinations possible with the number
Quang Luong5d8805e2022-01-28 15:46:40 -08001573// of each concurrency type in the combination.
1574// This method is a port of HalDeviceManager.expandConcurrencyCombos() from framework.
1575std::vector<std::map<IfaceConcurrencyType, size_t>> WifiChip::expandConcurrencyCombinations(
Gabriel Birene58e2632022-07-15 23:25:39 +00001576 const IWifiChip::ChipConcurrencyCombination& combination) {
1577 int32_t num_expanded_combos = 1;
Roshan Piuscc338202017-11-02 13:54:09 -07001578 for (const auto& limit : combination.limits) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001579 for (int32_t i = 0; i < limit.maxIfaces; i++) {
Roshan Piuscc338202017-11-02 13:54:09 -07001580 num_expanded_combos *= limit.types.size();
1581 }
1582 }
1583
Quang Luong5d8805e2022-01-28 15:46:40 -08001584 // Allocate the vector of expanded combos and reset all concurrency type counts to 0
Roshan Piuscc338202017-11-02 13:54:09 -07001585 // in each combo.
Quang Luong5d8805e2022-01-28 15:46:40 -08001586 std::vector<std::map<IfaceConcurrencyType, size_t>> expanded_combos;
Roshan Piuscc338202017-11-02 13:54:09 -07001587 expanded_combos.resize(num_expanded_combos);
1588 for (auto& expanded_combo : expanded_combos) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001589 for (const auto type : {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED,
1590 IfaceConcurrencyType::NAN_IFACE, IfaceConcurrencyType::P2P,
1591 IfaceConcurrencyType::STA}) {
Roshan Piuscc338202017-11-02 13:54:09 -07001592 expanded_combo[type] = 0;
1593 }
1594 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001595 int32_t span = num_expanded_combos;
Roshan Piuscc338202017-11-02 13:54:09 -07001596 for (const auto& limit : combination.limits) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001597 for (int32_t i = 0; i < limit.maxIfaces; i++) {
Roshan Piuscc338202017-11-02 13:54:09 -07001598 span /= limit.types.size();
Gabriel Birene58e2632022-07-15 23:25:39 +00001599 for (int32_t k = 0; k < num_expanded_combos; ++k) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001600 const auto iface_type = limit.types[(k / span) % limit.types.size()];
Roshan Piuscc338202017-11-02 13:54:09 -07001601 expanded_combos[k][iface_type]++;
1602 }
1603 }
1604 }
1605 return expanded_combos;
1606}
1607
Quang Luong5d8805e2022-01-28 15:46:40 -08001608bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
1609 const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
1610 IfaceConcurrencyType requested_type) {
1611 const auto current_combo = getCurrentConcurrencyCombination();
Roshan Piuscc338202017-11-02 13:54:09 -07001612
1613 // Check if we have space for 1 more iface of |type| in this combo
Quang Luong5d8805e2022-01-28 15:46:40 -08001614 for (const auto type :
Gabriel Birene58e2632022-07-15 23:25:39 +00001615 {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED,
1616 IfaceConcurrencyType::NAN_IFACE, IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
Roshan Piuscc338202017-11-02 13:54:09 -07001617 size_t num_ifaces_needed = current_combo.at(type);
1618 if (type == requested_type) {
1619 num_ifaces_needed++;
1620 }
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001621 size_t num_ifaces_allowed = expanded_combo.at(type);
Roshan Piuscc338202017-11-02 13:54:09 -07001622 if (num_ifaces_needed > num_ifaces_allowed) {
1623 return false;
1624 }
1625 }
1626 return true;
1627}
1628
1629// This method does the following:
Quang Luong5d8805e2022-01-28 15:46:40 -08001630// a) Enumerate all possible concurrency combos by expanding the current
1631// ChipConcurrencyCombination.
1632// b) Check if the requested concurrency type can be added to the current mode
1633// with the concurrency combination that is already active.
1634bool WifiChip::canCurrentModeSupportConcurrencyTypeWithCurrentTypes(
1635 IfaceConcurrencyType requested_type) {
Roshan Piuscc338202017-11-02 13:54:09 -07001636 if (!isValidModeId(current_mode_id_)) {
1637 LOG(ERROR) << "Chip not configured in a mode yet";
1638 return false;
1639 }
Quang Luong5d8805e2022-01-28 15:46:40 -08001640 const auto combinations = getCurrentModeConcurrencyCombinations();
Roshan Piuscc338202017-11-02 13:54:09 -07001641 for (const auto& combination : combinations) {
Quang Luong5d8805e2022-01-28 15:46:40 -08001642 const auto expanded_combos = expandConcurrencyCombinations(combination);
Roshan Piuscc338202017-11-02 13:54:09 -07001643 for (const auto& expanded_combo : expanded_combos) {
Quang Luong5d8805e2022-01-28 15:46:40 -08001644 if (canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(expanded_combo,
1645 requested_type)) {
Roshan Piuscc338202017-11-02 13:54:09 -07001646 return true;
1647 }
1648 }
1649 }
1650 return false;
1651}
1652
Quang Luong5d8805e2022-01-28 15:46:40 -08001653// Note: This does not consider concurrency types already active. It only checks if the
1654// provided expanded concurrency combination can support the requested combo.
1655bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyCombo(
1656 const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
1657 const std::map<IfaceConcurrencyType, size_t>& req_combo) {
1658 // Check if we have space for 1 more |type| in this combo
1659 for (const auto type :
Gabriel Birene58e2632022-07-15 23:25:39 +00001660 {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED,
1661 IfaceConcurrencyType::NAN_IFACE, IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001662 if (req_combo.count(type) == 0) {
Quang Luong5d8805e2022-01-28 15:46:40 -08001663 // Concurrency type not in the req_combo.
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001664 continue;
1665 }
1666 size_t num_ifaces_needed = req_combo.at(type);
1667 size_t num_ifaces_allowed = expanded_combo.at(type);
1668 if (num_ifaces_needed > num_ifaces_allowed) {
1669 return false;
1670 }
1671 }
1672 return true;
1673}
Gabriel Birene58e2632022-07-15 23:25:39 +00001674
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001675// This method does the following:
Quang Luong5d8805e2022-01-28 15:46:40 -08001676// a) Enumerate all possible concurrency combos by expanding the current
1677// ChipConcurrencyCombination.
1678// b) Check if the requested concurrency combo can be added to the current mode.
1679// Note: This does not consider concurrency types already active. It only checks if the
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001680// current mode can support the requested combo.
Quang Luong5d8805e2022-01-28 15:46:40 -08001681bool WifiChip::canCurrentModeSupportConcurrencyCombo(
1682 const std::map<IfaceConcurrencyType, size_t>& req_combo) {
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001683 if (!isValidModeId(current_mode_id_)) {
1684 LOG(ERROR) << "Chip not configured in a mode yet";
1685 return false;
1686 }
Quang Luong5d8805e2022-01-28 15:46:40 -08001687 const auto combinations = getCurrentModeConcurrencyCombinations();
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001688 for (const auto& combination : combinations) {
Quang Luong5d8805e2022-01-28 15:46:40 -08001689 const auto expanded_combos = expandConcurrencyCombinations(combination);
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001690 for (const auto& expanded_combo : expanded_combos) {
Quang Luong5d8805e2022-01-28 15:46:40 -08001691 if (canExpandedConcurrencyComboSupportConcurrencyCombo(expanded_combo, req_combo)) {
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001692 return true;
1693 }
1694 }
1695 }
1696 return false;
1697}
1698
1699// This method does the following:
Quang Luong5d8805e2022-01-28 15:46:40 -08001700// a) Enumerate all possible concurrency combos by expanding the current
1701// ChipConcurrencyCombination.
1702// b) Check if the requested concurrency type can be added to the current mode.
1703bool WifiChip::canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type) {
1704 // Check if we can support at least 1 of the requested concurrency type.
1705 std::map<IfaceConcurrencyType, size_t> req_iface_combo;
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001706 req_iface_combo[requested_type] = 1;
Quang Luong5d8805e2022-01-28 15:46:40 -08001707 return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001708}
1709
Gabriel Birene58e2632022-07-15 23:25:39 +00001710bool WifiChip::isValidModeId(int32_t mode_id) {
Roshan Piuscc338202017-11-02 13:54:09 -07001711 for (const auto& mode : modes_) {
1712 if (mode.id == mode_id) {
1713 return true;
1714 }
1715 }
1716 return false;
1717}
1718
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001719bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
lesl261818b2020-11-27 12:37:35 +08001720 // Check if we can support at least 1 STA & 1 AP concurrently.
Quang Luong5d8805e2022-01-28 15:46:40 -08001721 std::map<IfaceConcurrencyType, size_t> req_iface_combo;
1722 req_iface_combo[IfaceConcurrencyType::STA] = 1;
1723 req_iface_combo[IfaceConcurrencyType::AP] = 1;
1724 return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001725}
1726
lesl261818b2020-11-27 12:37:35 +08001727bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() {
1728 // Check if we can support at least 2 STA concurrently.
Quang Luong5d8805e2022-01-28 15:46:40 -08001729 std::map<IfaceConcurrencyType, size_t> req_iface_combo;
1730 req_iface_combo[IfaceConcurrencyType::STA] = 2;
1731 return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
James Mattisd2e4c072019-05-22 16:14:48 -07001732}
1733
Roshan Pius6036c022019-03-27 10:41:58 -07001734std::string WifiChip::getFirstActiveWlanIfaceName() {
Roshan Pius444473f2019-04-19 08:41:20 -07001735 if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName();
leslf012b652021-01-08 15:22:49 +08001736 if (ap_ifaces_.size() > 0) {
1737 // If the first active wlan iface is bridged iface.
1738 // Return first instance name.
1739 for (auto const& it : br_ifaces_ap_instances_) {
1740 if (it.first == ap_ifaces_[0]->getName()) {
1741 return it.second[0];
1742 }
1743 }
1744 return ap_ifaces_[0]->getName();
1745 }
Roshan Pius6036c022019-03-27 10:41:58 -07001746 // This could happen if the chip call is made before any STA/AP
1747 // iface is created. Default to wlan0 for such cases.
Roshan Pius444473f2019-04-19 08:41:20 -07001748 LOG(WARNING) << "No active wlan interfaces in use! Using default";
Jimmy Chen2dddd792019-12-23 17:50:39 +02001749 return getWlanIfaceNameWithType(IfaceType::STA, 0);
Roshan Pius6036c022019-03-27 10:41:58 -07001750}
1751
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001752// Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx|
1753// not already in use.
1754// Note: This doesn't check the actual presence of these interfaces.
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001755std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx) {
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001756 for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
Jimmy Chen2dddd792019-12-23 17:50:39 +02001757 const auto ifname = getWlanIfaceNameWithType(type, idx);
lesl94d28242020-11-18 22:17:37 +08001758 if (findUsingNameFromBridgedApInstances(ifname)) continue;
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -08001759 if (findUsingName(ap_ifaces_, ifname)) continue;
1760 if (findUsingName(sta_ifaces_, ifname)) continue;
1761 return ifname;
Roshan Pius8e3c7ef2017-11-03 09:43:08 -07001762 }
1763 // This should never happen. We screwed up somewhere if it did.
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -08001764 CHECK(false) << "All wlan interfaces in use already!";
Roshan Pius8e3c7ef2017-11-03 09:43:08 -07001765 return {};
1766}
1767
lesl261818b2020-11-27 12:37:35 +08001768uint32_t WifiChip::startIdxOfApIface() {
1769 if (isDualStaConcurrencyAllowedInCurrentMode()) {
1770 // When the HAL support dual STAs, AP should start with idx 2.
1771 return 2;
1772 } else if (isStaApConcurrencyAllowedInCurrentMode()) {
1773 // When the HAL support STA + AP but it doesn't support dual STAs.
1774 // AP should start with idx 1.
1775 return 1;
1776 }
1777 // No concurrency support.
1778 return 0;
1779}
1780
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001781// AP iface names start with idx 1 for modes supporting
James Mattisd2e4c072019-05-22 16:14:48 -07001782// concurrent STA and not dual AP, else start with idx 0.
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001783std::string WifiChip::allocateApIfaceName() {
Roshan Pius78cb5992020-04-30 12:39:21 -07001784 // Check if we have a dedicated iface for AP.
Les Lee3ba02e02022-09-07 13:44:06 +08001785 std::vector<std::string> ifnames = getPredefinedApIfaceNames(true);
1786 for (auto const& ifname : ifnames) {
1787 if (findUsingName(ap_ifaces_, ifname)) continue;
1788 return ifname;
Roshan Pius78cb5992020-04-30 12:39:21 -07001789 }
lesl261818b2020-11-27 12:37:35 +08001790 return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
1791}
1792
1793std::vector<std::string> WifiChip::allocateBridgedApInstanceNames() {
1794 // Check if we have a dedicated iface for AP.
1795 std::vector<std::string> instances = getPredefinedApIfaceNames(true);
1796 if (instances.size() == 2) {
1797 return instances;
1798 } else {
1799 int num_ifaces_need_to_allocate = 2 - instances.size();
1800 for (int i = 0; i < num_ifaces_need_to_allocate; i++) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001801 std::string instance_name =
1802 allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface() + i);
lesl261818b2020-11-27 12:37:35 +08001803 if (!instance_name.empty()) {
1804 instances.push_back(instance_name);
1805 }
1806 }
1807 }
1808 return instances;
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001809}
1810
1811// STA iface names start with idx 0.
1812// Primary STA iface will always be 0.
1813std::string WifiChip::allocateStaIfaceName() {
Jimmy Chen2dddd792019-12-23 17:50:39 +02001814 return allocateApOrStaIfaceName(IfaceType::STA, 0);
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001815}
1816
xshu5899e8e2018-01-09 15:36:03 -08001817bool WifiChip::writeRingbufferFilesInternal() {
1818 if (!removeOldFilesInternal()) {
1819 LOG(ERROR) << "Error occurred while deleting old tombstone files";
1820 return false;
1821 }
1822 // write ringbuffers to file
Veerendranath Jakkam25b3a6f2020-04-14 22:04:39 +05301823 {
1824 std::unique_lock<std::mutex> lk(lock_t);
xshuc905ea62021-07-11 19:57:02 -07001825 for (auto& item : ringbuffer_map_) {
1826 Ringbuffer& cur_buffer = item.second;
Veerendranath Jakkam25b3a6f2020-04-14 22:04:39 +05301827 if (cur_buffer.getData().empty()) {
1828 continue;
1829 }
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001830 const std::string file_path_raw = kTombstoneFolderPath + item.first + "XXXXXXXXXX";
Veerendranath Jakkam25b3a6f2020-04-14 22:04:39 +05301831 const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
1832 if (dump_fd == -1) {
1833 PLOG(ERROR) << "create file failed";
1834 return false;
1835 }
1836 unique_fd file_auto_closer(dump_fd);
1837 for (const auto& cur_block : cur_buffer.getData()) {
Sunil Ravi07ef1912022-05-17 18:01:06 -07001838 if (cur_block.size() <= 0 || cur_block.size() > kMaxBufferSizeBytes) {
1839 PLOG(ERROR) << "Ring buffer: " << item.first
1840 << " is corrupted. Invalid block size: " << cur_block.size();
1841 break;
1842 }
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001843 if (write(dump_fd, cur_block.data(), sizeof(cur_block[0]) * cur_block.size()) ==
1844 -1) {
Veerendranath Jakkam25b3a6f2020-04-14 22:04:39 +05301845 PLOG(ERROR) << "Error writing to file";
1846 }
xshu5899e8e2018-01-09 15:36:03 -08001847 }
xshuc905ea62021-07-11 19:57:02 -07001848 cur_buffer.clear();
xshu5899e8e2018-01-09 15:36:03 -08001849 }
xshu0a0fe512020-07-22 17:53:37 -07001850 // unique_lock unlocked here
xshu5899e8e2018-01-09 15:36:03 -08001851 }
1852 return true;
1853}
1854
Jimmy Chen2dddd792019-12-23 17:50:39 +02001855std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) {
1856 std::string ifname;
1857
1858 // let the legacy hal override the interface name
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001859 legacy_hal::wifi_error err = legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname);
Jimmy Chen2dddd792019-12-23 17:50:39 +02001860 if (err == legacy_hal::WIFI_SUCCESS) return ifname;
1861
1862 return getWlanIfaceName(idx);
1863}
1864
lesl94d28242020-11-18 22:17:37 +08001865void WifiChip::invalidateAndClearBridgedApAll() {
1866 for (auto const& it : br_ifaces_ap_instances_) {
1867 for (auto const& iface : it.second) {
Roshan Pius8c1a67b2021-03-02 10:00:23 -08001868 iface_util_->removeIfaceFromBridge(it.first, iface);
lesl94d28242020-11-18 22:17:37 +08001869 legacy_hal_.lock()->deleteVirtualInterface(iface);
1870 }
Roshan Pius8c1a67b2021-03-02 10:00:23 -08001871 iface_util_->deleteBridge(it.first);
lesl94d28242020-11-18 22:17:37 +08001872 }
1873 br_ifaces_ap_instances_.clear();
1874}
1875
Gabriel Birene58e2632022-07-15 23:25:39 +00001876void WifiChip::invalidateAndClearBridgedAp(const std::string& br_name) {
1877 if (br_name.empty()) return;
1878 // delete managed interfaces
lesl94d28242020-11-18 22:17:37 +08001879 for (auto const& it : br_ifaces_ap_instances_) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001880 if (it.first == br_name) {
lesl94d28242020-11-18 22:17:37 +08001881 for (auto const& iface : it.second) {
Gabriel Birene58e2632022-07-15 23:25:39 +00001882 iface_util_->removeIfaceFromBridge(br_name, iface);
lesl94d28242020-11-18 22:17:37 +08001883 legacy_hal_.lock()->deleteVirtualInterface(iface);
1884 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001885 iface_util_->deleteBridge(br_name);
1886 br_ifaces_ap_instances_.erase(br_name);
1887 break;
lesl94d28242020-11-18 22:17:37 +08001888 }
1889 }
Gabriel Birene58e2632022-07-15 23:25:39 +00001890 return;
lesl94d28242020-11-18 22:17:37 +08001891}
1892
1893bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) {
1894 for (auto const& it : br_ifaces_ap_instances_) {
1895 if (it.first == name) {
1896 return true;
1897 }
1898 for (auto const& iface : it.second) {
1899 if (iface == name) {
1900 return true;
1901 }
1902 }
1903 }
1904 return false;
1905}
1906
Roshan Pius3c4e8a32016-10-03 14:53:58 -07001907} // namespace wifi
1908} // namespace hardware
1909} // namespace android
Gabriel Birene58e2632022-07-15 23:25:39 +00001910} // namespace aidl