blob: 920beb8778a2fe87ee553bd6c766c90c3a42577f [file] [log] [blame]
Roshan Pius3c4e8a32016-10-03 14:53:58 -07001/*
Gabriel Biren631a8112022-12-01 22:29:32 +00002 * Copyright (C) 2016 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 Biren631a8112022-12-01 22:29:32 +000017#include <fcntl.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>
lesl94d28242020-11-18 22:17:37 +080022#include <net/if.h>
xshu5899e8e2018-01-09 15:36:03 -080023#include <sys/stat.h>
24#include <sys/sysmacros.h>
Roshan Pius3c4e8a32016-10-03 14:53:58 -070025
Gabriel Biren631a8112022-12-01 22:29:32 +000026#include "hidl_return_util.h"
27#include "hidl_struct_util.h"
28#include "wifi_chip.h"
Roshan Pius5c055462016-10-11 08:27:27 -070029#include "wifi_status_util.h"
Roshan Pius3c4e8a32016-10-03 14:53:58 -070030
Sunil Ravi7f2822a2021-10-15 16:55:53 -070031#define P2P_MGMT_DEVICE_PREFIX "p2p-dev-"
32
Roshan Pius35d958c2016-10-06 16:47:38 -070033namespace {
Gabriel Biren631a8112022-12-01 22:29:32 +000034using android::sp;
xshu5899e8e2018-01-09 15:36:03 -080035using android::base::unique_fd;
Gabriel Biren631a8112022-12-01 22:29:32 +000036using android::hardware::hidl_string;
37using android::hardware::hidl_vec;
38using android::hardware::wifi::V1_0::ChipModeId;
39using android::hardware::wifi::V1_0::IfaceType;
40using android::hardware::wifi::V1_0::IWifiChip;
Roshan Pius52947fb2016-11-18 11:38:07 -080041
xshu5899e8e2018-01-09 15:36:03 -080042constexpr char kCpioMagic[] = "070701";
Roger Wangb294c762018-11-02 15:34:39 +080043constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3;
44constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10;
xshu37126c92018-04-13 16:24:45 -070045constexpr uint32_t kMaxRingBufferFileNum = 20;
xshu5899e8e2018-01-09 15:36:03 -080046constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
Roshan Pius8574e7f2019-04-01 13:30:40 -070047constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface";
48constexpr char kNoActiveWlanIfaceNamePropertyValue[] = "";
49constexpr unsigned kMaxWlanIfaces = 5;
lesl94d28242020-11-18 22:17:37 +080050constexpr char kApBridgeIfacePrefix[] = "ap_br_";
xshu5899e8e2018-01-09 15:36:03 -080051
Roshan Pius35d958c2016-10-06 16:47:38 -070052template <typename Iface>
Gabriel Biren631a8112022-12-01 22:29:32 +000053void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
Roshan Pius675609b2017-10-31 14:24:58 -070054 iface->invalidate();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -080055 ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), ifaces.end());
Roshan Pius675609b2017-10-31 14:24:58 -070056}
57
58template <typename Iface>
Gabriel Biren631a8112022-12-01 22:29:32 +000059void invalidateAndClearAll(std::vector<sp<Iface>>& ifaces) {
Roshan Pius675609b2017-10-31 14:24:58 -070060 for (const auto& iface : ifaces) {
Roshan Piusabcf78f2017-10-06 16:30:38 -070061 iface->invalidate();
Roshan Piusabcf78f2017-10-06 16:30:38 -070062 }
Roshan Pius675609b2017-10-31 14:24:58 -070063 ifaces.clear();
64}
65
66template <typename Iface>
Gabriel Biren631a8112022-12-01 22:29:32 +000067std::vector<hidl_string> getNames(std::vector<sp<Iface>>& ifaces) {
68 std::vector<hidl_string> names;
Roshan Pius675609b2017-10-31 14:24:58 -070069 for (const auto& iface : ifaces) {
70 names.emplace_back(iface->getName());
71 }
72 return names;
73}
74
75template <typename Iface>
Gabriel Biren631a8112022-12-01 22:29:32 +000076sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces, const std::string& name) {
77 std::vector<hidl_string> names;
Roshan Pius675609b2017-10-31 14:24:58 -070078 for (const auto& iface : ifaces) {
79 if (name == iface->getName()) {
80 return iface;
81 }
82 }
83 return nullptr;
Roshan Pius35d958c2016-10-06 16:47:38 -070084}
Roshan Pius9377a0d2017-10-06 13:18:54 -070085
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -080086std::string getWlanIfaceName(unsigned idx) {
87 if (idx >= kMaxWlanIfaces) {
88 CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
89 return {};
90 }
Roshan Pius9377a0d2017-10-06 13:18:54 -070091
Roshan Pius8e3c7ef2017-11-03 09:43:08 -070092 std::array<char, PROPERTY_VALUE_MAX> buffer;
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -080093 if (idx == 0 || idx == 1) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -080094 const char* altPropName = (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
Roshan Pius5b333462019-03-01 14:07:22 -080095 auto res = property_get(altPropName, buffer.data(), nullptr);
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -080096 if (res > 0) return buffer.data();
97 }
Roshan Pius5b333462019-03-01 14:07:22 -080098 std::string propName = "wifi.interface." + std::to_string(idx);
99 auto res = property_get(propName.c_str(), buffer.data(), nullptr);
100 if (res > 0) return buffer.data();
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -0800101
102 return "wlan" + std::to_string(idx);
Roshan Pius9377a0d2017-10-06 13:18:54 -0700103}
Roshan Pius9377a0d2017-10-06 13:18:54 -0700104
lesl261818b2020-11-27 12:37:35 +0800105// Returns the dedicated iface name if defined.
106// Returns two ifaces in bridged mode.
107std::vector<std::string> getPredefinedApIfaceNames(bool is_bridged) {
108 std::vector<std::string> ifnames;
Roshan Pius78cb5992020-04-30 12:39:21 -0700109 std::array<char, PROPERTY_VALUE_MAX> buffer;
lesl261818b2020-11-27 12:37:35 +0800110 buffer.fill(0);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800111 if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == 0) {
lesl261818b2020-11-27 12:37:35 +0800112 return ifnames;
Roshan Pius78cb5992020-04-30 12:39:21 -0700113 }
lesl261818b2020-11-27 12:37:35 +0800114 ifnames.push_back(buffer.data());
115 if (is_bridged) {
116 buffer.fill(0);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800117 if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), nullptr) == 0) {
lesl261818b2020-11-27 12:37:35 +0800118 return ifnames;
119 }
120 ifnames.push_back(buffer.data());
121 }
122 return ifnames;
Roshan Pius78cb5992020-04-30 12:39:21 -0700123}
124
lesl261818b2020-11-27 12:37:35 +0800125std::string getPredefinedP2pIfaceName() {
Sunil Ravi7f2822a2021-10-15 16:55:53 -0700126 std::array<char, PROPERTY_VALUE_MAX> primaryIfaceName;
127 char p2pParentIfname[100];
128 std::string p2pDevIfName = "";
Roshan Piusabcf78f2017-10-06 16:30:38 -0700129 std::array<char, PROPERTY_VALUE_MAX> buffer;
130 property_get("wifi.direct.interface", buffer.data(), "p2p0");
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800131 if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX, strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
Sunil Ravi7f2822a2021-10-15 16:55:53 -0700132 /* Get the p2p parent interface name from p2p device interface name set
133 * in property */
Gabriel Biren11d4ab82022-03-31 00:08:02 +0000134 strlcpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX),
Sunil Ravi7f2822a2021-10-15 16:55:53 -0700135 strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX));
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800136 if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(), nullptr) == 0) {
Sunil Ravi7f2822a2021-10-15 16:55:53 -0700137 return buffer.data();
138 }
139 /* Check if the parent interface derived from p2p device interface name
140 * is active */
141 if (strncmp(p2pParentIfname, primaryIfaceName.data(),
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800142 strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) != 0) {
Sunil Ravi7f2822a2021-10-15 16:55:53 -0700143 /*
144 * Update the predefined p2p device interface parent interface name
145 * with current active wlan interface
146 */
147 p2pDevIfName += P2P_MGMT_DEVICE_PREFIX;
148 p2pDevIfName += primaryIfaceName.data();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800149 LOG(INFO) << "update the p2p device interface name to " << p2pDevIfName.c_str();
Sunil Ravi7f2822a2021-10-15 16:55:53 -0700150 return p2pDevIfName;
151 }
152 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700153 return buffer.data();
Roshan Pius9377a0d2017-10-06 13:18:54 -0700154}
155
Roshan Pius5ba0a902020-04-14 11:55:42 -0700156// Returns the dedicated iface name if one is defined.
lesl261818b2020-11-27 12:37:35 +0800157std::string getPredefinedNanIfaceName() {
Roshan Pius5ba0a902020-04-14 11:55:42 -0700158 std::array<char, PROPERTY_VALUE_MAX> buffer;
159 if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) {
160 return {};
161 }
162 return buffer.data();
163}
164
Roshan Pius8574e7f2019-04-01 13:30:40 -0700165void setActiveWlanIfaceNameProperty(const std::string& ifname) {
166 auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data());
167 if (res != 0) {
168 PLOG(ERROR) << "Failed to set active wlan iface name property";
169 }
170}
171
Gabriel Biren631a8112022-12-01 22:29:32 +0000172// delete files that meet either conditions:
173// 1. older than a predefined time in the wifi tombstone dir.
xshu37126c92018-04-13 16:24:45 -0700174// 2. Files in excess to a predefined amount, starting from the oldest ones
xshu5899e8e2018-01-09 15:36:03 -0800175bool removeOldFilesInternal() {
176 time_t now = time(0);
177 const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800178 std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(kTombstoneFolderPath), closedir);
xshu5899e8e2018-01-09 15:36:03 -0800179 if (!dir_dump) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800180 PLOG(ERROR) << "Failed to open directory";
xshu5899e8e2018-01-09 15:36:03 -0800181 return false;
182 }
xshu5899e8e2018-01-09 15:36:03 -0800183 struct dirent* dp;
184 bool success = true;
xshu37126c92018-04-13 16:24:45 -0700185 std::list<std::pair<const time_t, std::string>> valid_files;
Josh Gaoa568e532018-06-04 18:16:00 -0700186 while ((dp = readdir(dir_dump.get()))) {
xshu5899e8e2018-01-09 15:36:03 -0800187 if (dp->d_type != DT_REG) {
188 continue;
189 }
190 std::string cur_file_name(dp->d_name);
191 struct stat cur_file_stat;
192 std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
xshu4cb33162018-01-24 15:40:06 -0800193 if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800194 PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
xshu5899e8e2018-01-09 15:36:03 -0800195 success = false;
xshu4cb33162018-01-24 15:40:06 -0800196 continue;
197 }
xshu37126c92018-04-13 16:24:45 -0700198 const time_t cur_file_time = cur_file_stat.st_mtime;
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800199 valid_files.push_back(std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
xshu37126c92018-04-13 16:24:45 -0700200 }
201 valid_files.sort(); // sort the list of files by last modified time from
202 // small to big.
203 uint32_t cur_file_count = valid_files.size();
204 for (auto cur_file : valid_files) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800205 if (cur_file_count > kMaxRingBufferFileNum || cur_file.first < delete_files_before) {
xshu37126c92018-04-13 16:24:45 -0700206 if (unlink(cur_file.second.c_str()) != 0) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800207 PLOG(ERROR) << "Error deleting file";
xshu37126c92018-04-13 16:24:45 -0700208 success = false;
209 }
210 cur_file_count--;
211 } else {
212 break;
xshu5899e8e2018-01-09 15:36:03 -0800213 }
214 }
215 return success;
216}
217
xshu4cb33162018-01-24 15:40:06 -0800218// Helper function for |cpioArchiveFilesInDir|
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800219bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, size_t file_name_len) {
Gabriel Biren11d4ab82022-03-31 00:08:02 +0000220 const int buf_size = 32 * 1024;
221 std::array<char, buf_size> read_buf;
222 ssize_t llen = snprintf(
223 read_buf.data(), buf_size, "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
224 kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid, st.st_gid,
225 static_cast<int>(st.st_nlink), static_cast<int>(st.st_mtime),
226 static_cast<int>(st.st_size), major(st.st_dev), minor(st.st_dev), major(st.st_rdev),
227 minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0);
228 if (write(out_fd, read_buf.data(), llen < buf_size ? llen : buf_size - 1) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800229 PLOG(ERROR) << "Error writing cpio header to file " << file_name;
xshu4cb33162018-01-24 15:40:06 -0800230 return false;
231 }
232 if (write(out_fd, file_name, file_name_len) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800233 PLOG(ERROR) << "Error writing filename to file " << file_name;
xshu4cb33162018-01-24 15:40:06 -0800234 return false;
235 }
236
237 // NUL Pad header up to 4 multiple bytes.
238 llen = (llen + file_name_len) % 4;
239 if (llen != 0) {
240 const uint32_t zero = 0;
241 if (write(out_fd, &zero, 4 - llen) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800242 PLOG(ERROR) << "Error padding 0s to file " << file_name;
xshu4cb33162018-01-24 15:40:06 -0800243 return false;
244 }
245 }
246 return true;
247}
248
249// Helper function for |cpioArchiveFilesInDir|
250size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) {
251 // writing content of file
252 std::array<char, 32 * 1024> read_buf;
253 ssize_t llen = st.st_size;
254 size_t n_error = 0;
255 while (llen > 0) {
256 ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size());
257 if (bytes_read == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800258 PLOG(ERROR) << "Error reading file";
xshu4cb33162018-01-24 15:40:06 -0800259 return ++n_error;
260 }
261 llen -= bytes_read;
262 if (write(out_fd, read_buf.data(), bytes_read) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800263 PLOG(ERROR) << "Error writing data to file";
xshu4cb33162018-01-24 15:40:06 -0800264 return ++n_error;
265 }
266 if (bytes_read == 0) { // this should never happen, but just in case
267 // to unstuck from while loop
Elliott Hughes4db4add2019-03-08 12:42:57 -0800268 PLOG(ERROR) << "Unexpected read result";
xshu4cb33162018-01-24 15:40:06 -0800269 n_error++;
270 break;
271 }
272 }
273 llen = st.st_size % 4;
274 if (llen != 0) {
275 const uint32_t zero = 0;
276 if (write(out_fd, &zero, 4 - llen) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800277 PLOG(ERROR) << "Error padding 0s to file";
xshu4cb33162018-01-24 15:40:06 -0800278 return ++n_error;
279 }
280 }
281 return n_error;
282}
283
284// Helper function for |cpioArchiveFilesInDir|
285bool cpioWriteFileTrailer(int out_fd) {
Gabriel Biren11d4ab82022-03-31 00:08:02 +0000286 const int buf_size = 4096;
287 std::array<char, buf_size> read_buf;
xshu4cb33162018-01-24 15:40:06 -0800288 read_buf.fill(0);
Gabriel Biren11d4ab82022-03-31 00:08:02 +0000289 ssize_t llen = snprintf(read_buf.data(), 4096, "070701%040X%056X%08XTRAILER!!!", 1, 0x0b, 0);
290 if (write(out_fd, read_buf.data(), (llen < buf_size ? llen : buf_size - 1) + 4) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800291 PLOG(ERROR) << "Error writing trailing bytes";
xshu4cb33162018-01-24 15:40:06 -0800292 return false;
293 }
294 return true;
295}
296
xshu5899e8e2018-01-09 15:36:03 -0800297// Archives all files in |input_dir| and writes result into |out_fd|
298// Logic obtained from //external/toybox/toys/posix/cpio.c "Output cpio archive"
299// portion
xshu4cb33162018-01-24 15:40:06 -0800300size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) {
xshu5899e8e2018-01-09 15:36:03 -0800301 struct dirent* dp;
302 size_t n_error = 0;
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800303 std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir), closedir);
xshu5899e8e2018-01-09 15:36:03 -0800304 if (!dir_dump) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800305 PLOG(ERROR) << "Failed to open directory";
xshu4cb33162018-01-24 15:40:06 -0800306 return ++n_error;
xshu5899e8e2018-01-09 15:36:03 -0800307 }
Josh Gaoa568e532018-06-04 18:16:00 -0700308 while ((dp = readdir(dir_dump.get()))) {
xshu5899e8e2018-01-09 15:36:03 -0800309 if (dp->d_type != DT_REG) {
310 continue;
311 }
312 std::string cur_file_name(dp->d_name);
xshu5899e8e2018-01-09 15:36:03 -0800313 struct stat st;
xshu5899e8e2018-01-09 15:36:03 -0800314 const std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
xshu4cb33162018-01-24 15:40:06 -0800315 if (stat(cur_file_path.c_str(), &st) == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800316 PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
xshu5899e8e2018-01-09 15:36:03 -0800317 n_error++;
xshu4cb33162018-01-24 15:40:06 -0800318 continue;
319 }
320 const int fd_read = open(cur_file_path.c_str(), O_RDONLY);
321 if (fd_read == -1) {
Elliott Hughes4db4add2019-03-08 12:42:57 -0800322 PLOG(ERROR) << "Failed to open file " << cur_file_path;
xshu4cb33162018-01-24 15:40:06 -0800323 n_error++;
324 continue;
325 }
xshuf392fb42020-08-13 16:57:00 -0700326 std::string file_name_with_last_modified_time =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800327 cur_file_name + "-" + std::to_string(st.st_mtime);
xshuf392fb42020-08-13 16:57:00 -0700328 // string.size() does not include the null terminator. The cpio FreeBSD
329 // file header expects the null character to be included in the length.
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800330 const size_t file_name_len = file_name_with_last_modified_time.size() + 1;
xshu4cb33162018-01-24 15:40:06 -0800331 unique_fd file_auto_closer(fd_read);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800332 if (!cpioWriteHeader(out_fd, st, file_name_with_last_modified_time.c_str(),
xshu4cb33162018-01-24 15:40:06 -0800333 file_name_len)) {
334 return ++n_error;
335 }
336 size_t write_error = cpioWriteFileContent(fd_read, out_fd, st);
337 if (write_error) {
338 return n_error + write_error;
xshu5899e8e2018-01-09 15:36:03 -0800339 }
340 }
xshu4cb33162018-01-24 15:40:06 -0800341 if (!cpioWriteFileTrailer(out_fd)) {
342 return ++n_error;
xshu5899e8e2018-01-09 15:36:03 -0800343 }
344 return n_error;
345}
346
347// Helper function to create a non-const char*.
348std::vector<char> makeCharVec(const std::string& str) {
349 std::vector<char> vec(str.size() + 1);
350 vec.assign(str.begin(), str.end());
351 vec.push_back('\0');
352 return vec;
353}
354
Roshan Piusabcf78f2017-10-06 16:30:38 -0700355} // namespace
Roshan Pius35d958c2016-10-06 16:47:38 -0700356
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700357namespace android {
358namespace hardware {
359namespace wifi {
Gabriel Biren631a8112022-12-01 22:29:32 +0000360namespace V1_6 {
361namespace implementation {
362using hidl_return_util::validateAndCall;
363using hidl_return_util::validateAndCallWithLock;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700364
Gabriel Biren631a8112022-12-01 22:29:32 +0000365WifiChip::WifiChip(ChipId chip_id, bool is_primary,
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800366 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
367 const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
368 const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
369 const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
370 const std::function<void(const std::string&)>& handler)
Roshan Pius52947fb2016-11-18 11:38:07 -0800371 : chip_id_(chip_id),
372 legacy_hal_(legacy_hal),
373 mode_controller_(mode_controller),
Roshan Pius99dab382019-02-14 07:57:10 -0800374 iface_util_(iface_util),
Roshan Pius52947fb2016-11-18 11:38:07 -0800375 is_valid_(true),
Tomasz Wasilczykb424da72018-11-15 11:52:57 -0800376 current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
Jimmy Chen2dddd792019-12-23 17:50:39 +0200377 modes_(feature_flags.lock()->getChipModes(is_primary)),
Ahmed ElArabawy2134bf72020-06-18 15:07:12 -0700378 debug_ring_buffer_cb_registered_(false),
379 subsystemCallbackHandler_(handler) {
Roshan Pius8574e7f2019-04-01 13:30:40 -0700380 setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
381}
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700382
Roshan Piusaabe5752016-09-29 09:03:59 -0700383void WifiChip::invalidate() {
xshu37126c92018-04-13 16:24:45 -0700384 if (!writeRingbufferFilesInternal()) {
385 LOG(ERROR) << "Error writing files to flash";
386 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700387 invalidateAndRemoveAllIfaces();
Roshan Pius8574e7f2019-04-01 13:30:40 -0700388 setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700389 legacy_hal_.reset();
390 event_cb_handler_.invalidate();
391 is_valid_ = false;
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700392}
393
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800394bool WifiChip::isValid() {
395 return is_valid_;
396}
Roshan Pius3c868522016-10-27 12:43:49 -0700397
Gabriel Biren631a8112022-12-01 22:29:32 +0000398std::set<sp<V1_4::IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700399 return event_cb_handler_.getCallbacks();
Roshan Pius203cb032016-12-14 17:41:20 -0800400}
401
Gabriel Biren631a8112022-12-01 22:29:32 +0000402Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800403 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getIdInternal,
Gabriel Biren631a8112022-12-01 22:29:32 +0000404 hidl_status_cb);
Roshan Piuscd566bd2016-10-10 08:03:42 -0700405}
406
Gabriel Biren631a8112022-12-01 22:29:32 +0000407// Deprecated support for this callback
408Return<void> WifiChip::registerEventCallback(const sp<V1_0::IWifiChipEventCallback>& event_callback,
409 registerEventCallback_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700410 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000411 &WifiChip::registerEventCallbackInternal, hidl_status_cb,
412 event_callback);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700413}
414
Gabriel Biren631a8112022-12-01 22:29:32 +0000415Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700416 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000417 &WifiChip::getCapabilitiesInternal, hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700418}
419
Gabriel Biren631a8112022-12-01 22:29:32 +0000420Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700421 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000422 &WifiChip::getAvailableModesInternal, hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700423}
424
Gabriel Biren631a8112022-12-01 22:29:32 +0000425Return<void> WifiChip::configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800426 return validateAndCallWithLock(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000427 &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700428}
429
Gabriel Biren631a8112022-12-01 22:29:32 +0000430Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700431 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000432 &WifiChip::getModeInternal, hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700433}
434
Gabriel Biren631a8112022-12-01 22:29:32 +0000435Return<void> WifiChip::requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700436 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000437 &WifiChip::requestChipDebugInfoInternal, hidl_status_cb);
Roshan Pius5c055462016-10-11 08:27:27 -0700438}
439
Gabriel Biren631a8112022-12-01 22:29:32 +0000440Return<void> WifiChip::requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700441 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000442 &WifiChip::requestDriverDebugDumpInternal, hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700443}
444
Gabriel Biren631a8112022-12-01 22:29:32 +0000445Return<void> WifiChip::requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700446 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000447 &WifiChip::requestFirmwareDebugDumpInternal, hidl_status_cb);
Roshan Pius3c4e8a32016-10-03 14:53:58 -0700448}
449
Gabriel Biren631a8112022-12-01 22:29:32 +0000450Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700451 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000452 &WifiChip::createApIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700453}
454
Gabriel Biren631a8112022-12-01 22:29:32 +0000455Return<void> WifiChip::createBridgedApIface(createBridgedApIface_cb hidl_status_cb) {
lesl94d28242020-11-18 22:17:37 +0800456 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000457 &WifiChip::createBridgedApIfaceInternal, hidl_status_cb);
lesl94d28242020-11-18 22:17:37 +0800458}
459
Gabriel Biren631a8112022-12-01 22:29:32 +0000460Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700461 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000462 &WifiChip::getApIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700463}
464
Gabriel Biren631a8112022-12-01 22:29:32 +0000465Return<void> WifiChip::getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700466 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000467 &WifiChip::getApIfaceInternal, hidl_status_cb, ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700468}
469
Gabriel Biren631a8112022-12-01 22:29:32 +0000470Return<void> WifiChip::removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700471 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000472 &WifiChip::removeApIfaceInternal, hidl_status_cb, ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800473}
474
Gabriel Biren631a8112022-12-01 22:29:32 +0000475Return<void> WifiChip::removeIfaceInstanceFromBridgedApIface(
476 const hidl_string& ifname, const hidl_string& ifInstanceName,
477 removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800478 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000479 &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, hidl_status_cb,
480 ifname, ifInstanceName);
lesl94d28242020-11-18 22:17:37 +0800481}
482
Gabriel Biren631a8112022-12-01 22:29:32 +0000483Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700484 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000485 &WifiChip::createNanIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700486}
487
Gabriel Biren631a8112022-12-01 22:29:32 +0000488Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700489 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000490 &WifiChip::getNanIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700491}
492
Gabriel Biren631a8112022-12-01 22:29:32 +0000493Return<void> WifiChip::getNanIface(const hidl_string& ifname, getNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700494 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000495 &WifiChip::getNanIfaceInternal, hidl_status_cb, ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700496}
497
Gabriel Biren631a8112022-12-01 22:29:32 +0000498Return<void> WifiChip::removeNanIface(const hidl_string& ifname, removeNanIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700499 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000500 &WifiChip::removeNanIfaceInternal, hidl_status_cb, ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800501}
502
Gabriel Biren631a8112022-12-01 22:29:32 +0000503Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700504 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000505 &WifiChip::createP2pIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700506}
507
Gabriel Biren631a8112022-12-01 22:29:32 +0000508Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700509 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000510 &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700511}
512
Gabriel Biren631a8112022-12-01 22:29:32 +0000513Return<void> WifiChip::getP2pIface(const hidl_string& ifname, getP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700514 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000515 &WifiChip::getP2pIfaceInternal, hidl_status_cb, ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700516}
517
Gabriel Biren631a8112022-12-01 22:29:32 +0000518Return<void> WifiChip::removeP2pIface(const hidl_string& ifname, removeP2pIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700519 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000520 &WifiChip::removeP2pIfaceInternal, hidl_status_cb, ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800521}
522
Gabriel Biren631a8112022-12-01 22:29:32 +0000523Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700524 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000525 &WifiChip::createStaIfaceInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700526}
527
Gabriel Biren631a8112022-12-01 22:29:32 +0000528Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700529 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000530 &WifiChip::getStaIfaceNamesInternal, hidl_status_cb);
Roshan Pius35d958c2016-10-06 16:47:38 -0700531}
532
Gabriel Biren631a8112022-12-01 22:29:32 +0000533Return<void> WifiChip::getStaIface(const hidl_string& ifname, getStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700534 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000535 &WifiChip::getStaIfaceInternal, hidl_status_cb, ifname);
Roshan Pius35d958c2016-10-06 16:47:38 -0700536}
537
Gabriel Biren631a8112022-12-01 22:29:32 +0000538Return<void> WifiChip::removeStaIface(const hidl_string& ifname, removeStaIface_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700539 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000540 &WifiChip::removeStaIfaceInternal, hidl_status_cb, ifname);
Roshan Pius8b55e6f2016-12-09 12:05:12 -0800541}
542
Gabriel Biren631a8112022-12-01 22:29:32 +0000543Return<void> WifiChip::createRttController(const sp<IWifiIface>& bound_iface,
544 createRttController_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700545 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000546 &WifiChip::createRttControllerInternal, hidl_status_cb, bound_iface);
Roshan Pius59268282016-10-06 20:23:47 -0700547}
548
Gabriel Biren631a8112022-12-01 22:29:32 +0000549Return<void> WifiChip::getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700550 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000551 &WifiChip::getDebugRingBuffersStatusInternal, hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700552}
553
Gabriel Biren631a8112022-12-01 22:29:32 +0000554Return<void> WifiChip::startLoggingToDebugRingBuffer(
555 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
556 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
557 startLoggingToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700558 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000559 &WifiChip::startLoggingToDebugRingBufferInternal, hidl_status_cb,
560 ring_name, verbose_level, max_interval_in_sec, min_data_size_in_bytes);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700561}
562
Gabriel Biren631a8112022-12-01 22:29:32 +0000563Return<void> WifiChip::forceDumpToDebugRingBuffer(const hidl_string& ring_name,
564 forceDumpToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700565 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000566 &WifiChip::forceDumpToDebugRingBufferInternal, hidl_status_cb,
567 ring_name);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700568}
569
Gabriel Biren631a8112022-12-01 22:29:32 +0000570Return<void> WifiChip::flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb) {
Roger Wangb294c762018-11-02 15:34:39 +0800571 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000572 &WifiChip::flushRingBufferToFileInternal, hidl_status_cb);
Roger Wangb294c762018-11-02 15:34:39 +0800573}
574
Gabriel Biren631a8112022-12-01 22:29:32 +0000575Return<void> WifiChip::stopLoggingToDebugRingBuffer(
576 stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700577 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000578 &WifiChip::stopLoggingToDebugRingBufferInternal, hidl_status_cb);
Roshan Pius8c0c8e92017-02-24 08:07:42 -0800579}
580
Gabriel Biren631a8112022-12-01 22:29:32 +0000581Return<void> WifiChip::getDebugHostWakeReasonStats(getDebugHostWakeReasonStats_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700582 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000583 &WifiChip::getDebugHostWakeReasonStatsInternal, hidl_status_cb);
Roshan Pius7d08d7a2016-10-27 14:35:05 -0700584}
585
Gabriel Biren631a8112022-12-01 22:29:32 +0000586Return<void> WifiChip::enableDebugErrorAlerts(bool enable,
587 enableDebugErrorAlerts_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700588 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000589 &WifiChip::enableDebugErrorAlertsInternal, hidl_status_cb, enable);
Roshan Pius203cb032016-12-14 17:41:20 -0800590}
591
Gabriel Biren631a8112022-12-01 22:29:32 +0000592Return<void> WifiChip::selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario,
593 selectTxPowerScenario_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700594 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000595 &WifiChip::selectTxPowerScenarioInternal, hidl_status_cb, scenario);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700596}
597
Gabriel Biren631a8112022-12-01 22:29:32 +0000598Return<void> WifiChip::resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700599 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000600 &WifiChip::resetTxPowerScenarioInternal, hidl_status_cb);
Roshan Piusdbd83ef2017-06-20 12:05:40 -0700601}
602
Gabriel Biren631a8112022-12-01 22:29:32 +0000603Return<void> WifiChip::setLatencyMode(LatencyMode mode, setLatencyMode_cb hidl_status_cb) {
Ahmed ElArabawyeaf82402018-10-26 09:46:04 -0700604 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000605 &WifiChip::setLatencyModeInternal, hidl_status_cb, mode);
Ahmed ElArabawyeaf82402018-10-26 09:46:04 -0700606}
607
Gabriel Biren631a8112022-12-01 22:29:32 +0000608Return<void> WifiChip::registerEventCallback_1_2(
609 const sp<V1_2::IWifiChipEventCallback>& event_callback,
610 registerEventCallback_cb hidl_status_cb) {
611 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
612 &WifiChip::registerEventCallbackInternal_1_2, hidl_status_cb,
613 event_callback);
614}
615
616Return<void> WifiChip::selectTxPowerScenario_1_2(TxPowerScenario scenario,
617 selectTxPowerScenario_cb hidl_status_cb) {
618 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
619 &WifiChip::selectTxPowerScenarioInternal_1_2, hidl_status_cb, scenario);
620}
621
622Return<void> WifiChip::getCapabilities_1_3(getCapabilities_cb hidl_status_cb) {
623 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
624 &WifiChip::getCapabilitiesInternal_1_3, hidl_status_cb);
625}
626
627Return<void> WifiChip::getCapabilities_1_5(getCapabilities_1_5_cb hidl_status_cb) {
628 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
629 &WifiChip::getCapabilitiesInternal_1_5, hidl_status_cb);
630}
631
632Return<void> WifiChip::debug(const hidl_handle& handle, const hidl_vec<hidl_string>&) {
633 if (handle != nullptr && handle->numFds >= 1) {
634 {
635 std::unique_lock<std::mutex> lk(lock_t);
636 for (const auto& item : ringbuffer_map_) {
637 forceDumpToDebugRingBufferInternal(item.first);
638 }
639 // unique_lock unlocked here
xshu0a0fe512020-07-22 17:53:37 -0700640 }
Gabriel Biren631a8112022-12-01 22:29:32 +0000641 usleep(100 * 1000); // sleep for 100 milliseconds to wait for
642 // ringbuffer updates.
643 int fd = handle->data[0];
644 if (!writeRingbufferFilesInternal()) {
645 LOG(ERROR) << "Error writing files to flash";
646 }
647 uint32_t n_error = cpioArchiveFilesInDir(fd, kTombstoneFolderPath);
648 if (n_error != 0) {
649 LOG(ERROR) << n_error << " errors occured in cpio function";
650 }
651 fsync(fd);
652 } else {
653 LOG(ERROR) << "File handle error";
xshu5899e8e2018-01-09 15:36:03 -0800654 }
Gabriel Biren631a8112022-12-01 22:29:32 +0000655 return Void();
xshu5899e8e2018-01-09 15:36:03 -0800656}
657
Gabriel Biren631a8112022-12-01 22:29:32 +0000658Return<void> WifiChip::createRttController_1_4(const sp<IWifiIface>& bound_iface,
659 createRttController_1_4_cb hidl_status_cb) {
Ahmed ElArabawyeeb53382019-10-10 20:18:31 -0700660 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000661 &WifiChip::createRttControllerInternal_1_4, hidl_status_cb, bound_iface);
Ahmed ElArabawyeeb53382019-10-10 20:18:31 -0700662}
663
Gabriel Biren631a8112022-12-01 22:29:32 +0000664Return<void> WifiChip::registerEventCallback_1_4(
665 const sp<V1_4::IWifiChipEventCallback>& event_callback,
666 registerEventCallback_cb hidl_status_cb) {
Ahmed ElArabawyfd809fc2019-11-15 18:19:15 -0800667 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000668 &WifiChip::registerEventCallbackInternal_1_4, hidl_status_cb,
669 event_callback);
Ahmed ElArabawyfd809fc2019-11-15 18:19:15 -0800670}
671
Gabriel Biren631a8112022-12-01 22:29:32 +0000672Return<void> WifiChip::setMultiStaPrimaryConnection(
673 const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) {
Roshan Piuse9d1e7d2020-11-04 11:44:16 -0800674 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000675 &WifiChip::setMultiStaPrimaryConnectionInternal, hidl_status_cb, ifname);
Roshan Piuse9d1e7d2020-11-04 11:44:16 -0800676}
677
Gabriel Biren631a8112022-12-01 22:29:32 +0000678Return<void> WifiChip::setMultiStaUseCase(MultiStaUseCase use_case,
679 setMultiStaUseCase_cb hidl_status_cb) {
680 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
681 &WifiChip::setMultiStaUseCaseInternal, hidl_status_cb, use_case);
682}
683
684Return<void> WifiChip::setCoexUnsafeChannels(const hidl_vec<CoexUnsafeChannel>& unsafeChannels,
685 hidl_bitfield<CoexRestriction> restrictions,
686 setCoexUnsafeChannels_cb hidl_status_cb) {
687 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
688 &WifiChip::setCoexUnsafeChannelsInternal, hidl_status_cb, unsafeChannels,
689 restrictions);
690}
691
692Return<void> WifiChip::setCountryCode(const hidl_array<int8_t, 2>& code,
693 setCountryCode_cb hidl_status_cb) {
Kumar Anandda62c382020-11-18 17:17:47 -0800694 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000695 &WifiChip::setCountryCodeInternal, hidl_status_cb, code);
Kumar Anandda62c382020-11-18 17:17:47 -0800696}
697
Gabriel Biren631a8112022-12-01 22:29:32 +0000698Return<void> WifiChip::getUsableChannels(
699 WifiBand band, hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,
700 hidl_bitfield<V1_5::IWifiChip::UsableChannelFilter> filterMask,
701 getUsableChannels_cb _hidl_cb) {
Kumar Anand2a630a32021-01-21 14:09:14 -0800702 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000703 &WifiChip::getUsableChannelsInternal, _hidl_cb, band, ifaceModeMask,
704 filterMask);
Kumar Anand2a630a32021-01-21 14:09:14 -0800705}
706
Gabriel Biren631a8112022-12-01 22:29:32 +0000707Return<void> WifiChip::triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb) {
chenpaulc6f57032021-03-05 17:06:50 +0800708 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000709 &WifiChip::triggerSubsystemRestartInternal, hidl_status_cb);
chenpaulc6f57032021-03-05 17:06:50 +0800710}
711
Gabriel Biren631a8112022-12-01 22:29:32 +0000712Return<void> WifiChip::createRttController_1_6(const sp<IWifiIface>& bound_iface,
713 createRttController_1_6_cb hidl_status_cb) {
Ahmed ElArabawy05571e42022-01-19 11:54:11 -0800714 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
Gabriel Biren631a8112022-12-01 22:29:32 +0000715 &WifiChip::createRttControllerInternal_1_6, hidl_status_cb, bound_iface);
716}
717
718Return<void> WifiChip::getUsableChannels_1_6(
719 WifiBand band, hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,
720 hidl_bitfield<V1_6::IWifiChip::UsableChannelFilter> filterMask,
721 getUsableChannels_1_6_cb _hidl_cb) {
722 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
723 &WifiChip::getUsableChannelsInternal_1_6, _hidl_cb, band, ifaceModeMask,
724 filterMask);
725}
726
727Return<void> WifiChip::getSupportedRadioCombinationsMatrix(
728 getSupportedRadioCombinationsMatrix_cb hidl_status_cb) {
729 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
730 &WifiChip::getSupportedRadioCombinationsMatrixInternal, hidl_status_cb);
731}
732
733Return<void> WifiChip::getAvailableModes_1_6(getAvailableModes_1_6_cb hidl_status_cb) {
734 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
735 &WifiChip::getAvailableModesInternal_1_6, hidl_status_cb);
Quang Luong5d8805e2022-01-28 15:46:40 -0800736}
737
Roshan Pius35d958c2016-10-06 16:47:38 -0700738void WifiChip::invalidateAndRemoveAllIfaces() {
lesl94d28242020-11-18 22:17:37 +0800739 invalidateAndClearBridgedApAll();
Roshan Pius675609b2017-10-31 14:24:58 -0700740 invalidateAndClearAll(ap_ifaces_);
741 invalidateAndClearAll(nan_ifaces_);
742 invalidateAndClearAll(p2p_ifaces_);
743 invalidateAndClearAll(sta_ifaces_);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700744 // Since all the ifaces are invalid now, all RTT controller objects
745 // using those ifaces also need to be invalidated.
746 for (const auto& rtt : rtt_controllers_) {
747 rtt->invalidate();
748 }
749 rtt_controllers_.clear();
Roshan Pius35d958c2016-10-06 16:47:38 -0700750}
751
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800752void WifiChip::invalidateAndRemoveDependencies(const std::string& removed_iface_name) {
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200753 for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) {
754 auto nan_iface = *it;
Roshan Pius82368502019-05-16 12:53:02 -0700755 if (nan_iface->getName() == removed_iface_name) {
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200756 nan_iface->invalidate();
Roshan Pius82368502019-05-16 12:53:02 -0700757 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Gabriel Biren631a8112022-12-01 22:29:32 +0000758 if (!callback->onIfaceRemoved(IfaceType::NAN, removed_iface_name).isOk()) {
Roshan Pius82368502019-05-16 12:53:02 -0700759 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
760 }
761 }
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200762 it = nan_ifaces_.erase(it);
763 } else {
764 ++it;
Roshan Pius82368502019-05-16 12:53:02 -0700765 }
766 }
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200767
768 for (auto it = rtt_controllers_.begin(); it != rtt_controllers_.end();) {
769 auto rtt = *it;
Roshan Pius82368502019-05-16 12:53:02 -0700770 if (rtt->getIfaceName() == removed_iface_name) {
Jimmy Chen7a82ad82019-11-29 17:31:22 +0200771 rtt->invalidate();
772 it = rtt_controllers_.erase(it);
773 } else {
774 ++it;
Roshan Pius82368502019-05-16 12:53:02 -0700775 }
776 }
777}
778
Gabriel Biren631a8112022-12-01 22:29:32 +0000779std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
780 return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700781}
782
Gabriel Biren631a8112022-12-01 22:29:32 +0000783WifiStatus WifiChip::registerEventCallbackInternal(
784 const sp<V1_0::IWifiChipEventCallback>& /* event_callback */) {
785 // Deprecated support for this callback.
786 return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
Roshan Pius3c868522016-10-27 12:43:49 -0700787}
788
Gabriel Biren631a8112022-12-01 22:29:32 +0000789std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
790 // Deprecated support for this callback.
791 return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
Gabriel Birene58e2632022-07-15 23:25:39 +0000792}
793
Gabriel Biren631a8112022-12-01 22:29:32 +0000794std::pair<WifiStatus, std::vector<V1_0::IWifiChip::ChipMode>>
Gabriel Birene58e2632022-07-15 23:25:39 +0000795WifiChip::getAvailableModesInternal() {
Gabriel Biren631a8112022-12-01 22:29:32 +0000796 // Deprecated support -- use getAvailableModes_1_6 for more granular concurrency combinations.
797 std::vector<V1_0::IWifiChip::ChipMode> modes_1_0 = {};
798 for (const auto& mode_1_6 : modes_) {
799 std::vector<V1_0::IWifiChip::ChipIfaceCombination> combos_1_0;
800 for (const auto& combo_1_6 : mode_1_6.availableCombinations) {
801 std::vector<V1_0::IWifiChip::ChipIfaceCombinationLimit> limits_1_0;
802 for (const auto& limit_1_6 : combo_1_6.limits) {
803 std::vector<IfaceType> types_1_0;
804 for (IfaceConcurrencyType type_1_6 : limit_1_6.types) {
805 switch (type_1_6) {
806 case IfaceConcurrencyType::STA:
807 types_1_0.push_back(IfaceType::STA);
808 break;
809 case IfaceConcurrencyType::AP:
810 types_1_0.push_back(IfaceType::AP);
811 break;
812 case IfaceConcurrencyType::AP_BRIDGED:
813 // Ignore AP_BRIDGED
814 break;
815 case IfaceConcurrencyType::P2P:
816 types_1_0.push_back(IfaceType::P2P);
817 break;
818 case IfaceConcurrencyType::NAN:
819 types_1_0.push_back(IfaceType::NAN);
820 break;
821 }
822 }
823 if (types_1_0.empty()) {
824 continue;
825 }
826 V1_0::IWifiChip::ChipIfaceCombinationLimit limit_1_0;
827 limit_1_0.types = hidl_vec(types_1_0);
828 limit_1_0.maxIfaces = limit_1_6.maxIfaces;
829 limits_1_0.push_back(limit_1_0);
830 }
831 if (limits_1_0.empty()) {
832 continue;
833 }
834 V1_0::IWifiChip::ChipIfaceCombination combo_1_0;
835 combo_1_0.limits = hidl_vec(limits_1_0);
836 combos_1_0.push_back(combo_1_0);
837 }
838 if (combos_1_0.empty()) {
839 continue;
840 }
841 V1_0::IWifiChip::ChipMode mode_1_0;
842 mode_1_0.id = mode_1_6.id;
843 mode_1_0.availableCombinations = hidl_vec(combos_1_0);
844 modes_1_0.push_back(mode_1_0);
845 }
846 return {createWifiStatus(WifiStatusCode::SUCCESS), modes_1_0};
Gabriel Birene58e2632022-07-15 23:25:39 +0000847}
848
Gabriel Biren631a8112022-12-01 22:29:32 +0000849WifiStatus WifiChip::configureChipInternal(
850 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) {
Roshan Piuscc338202017-11-02 13:54:09 -0700851 if (!isValidModeId(mode_id)) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700852 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
853 }
854 if (mode_id == current_mode_id_) {
855 LOG(DEBUG) << "Already in the specified mode " << mode_id;
Gabriel Biren631a8112022-12-01 22:29:32 +0000856 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700857 }
Gabriel Biren631a8112022-12-01 22:29:32 +0000858 WifiStatus status = handleChipConfiguration(lock, mode_id);
859 if (status.code != WifiStatusCode::SUCCESS) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700860 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Gabriel Biren631a8112022-12-01 22:29:32 +0000861 if (!callback->onChipReconfigureFailure(status).isOk()) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800862 LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback";
Roshan Piusabcf78f2017-10-06 16:30:38 -0700863 }
864 }
865 return status;
866 }
Roshan Piusd37341f2017-01-31 13:13:28 -0800867 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700868 if (!callback->onChipReconfigured(mode_id).isOk()) {
869 LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
870 }
Roshan Pius52947fb2016-11-18 11:38:07 -0800871 }
Roshan Piusabcf78f2017-10-06 16:30:38 -0700872 current_mode_id_ = mode_id;
Roshan Piusba38d9c2017-12-08 07:32:08 -0800873 LOG(INFO) << "Configured chip in mode " << mode_id;
Roshan Pius8574e7f2019-04-01 13:30:40 -0700874 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
Ahmed ElArabawy2134bf72020-06-18 15:07:12 -0700875
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800876 legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(subsystemCallbackHandler_);
Ahmed ElArabawy2134bf72020-06-18 15:07:12 -0700877
Roshan Pius2c06a3f2016-12-15 17:51:40 -0800878 return status;
Roshan Pius3c868522016-10-27 12:43:49 -0700879}
880
Gabriel Biren631a8112022-12-01 22:29:32 +0000881std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
Roshan Piuscc338202017-11-02 13:54:09 -0700882 if (!isValidModeId(current_mode_id_)) {
Gabriel Biren631a8112022-12-01 22:29:32 +0000883 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), current_mode_id_};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700884 }
Gabriel Biren631a8112022-12-01 22:29:32 +0000885 return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
Roshan Pius3c868522016-10-27 12:43:49 -0700886}
887
Gabriel Biren631a8112022-12-01 22:29:32 +0000888std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo> WifiChip::requestChipDebugInfoInternal() {
889 V1_4::IWifiChip::ChipDebugInfo result;
Roshan Piusabcf78f2017-10-06 16:30:38 -0700890 legacy_hal::wifi_error legacy_status;
891 std::string driver_desc;
Roshan Pius6036c022019-03-27 10:41:58 -0700892 const auto ifname = getFirstActiveWlanIfaceName();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800893 std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion(ifname);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700894 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800895 LOG(ERROR) << "Failed to get driver version: " << legacyErrorToString(legacy_status);
Gabriel Biren631a8112022-12-01 22:29:32 +0000896 WifiStatus status =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800897 createWifiStatusFromLegacyError(legacy_status, "failed to get driver version");
Gabriel Biren631a8112022-12-01 22:29:32 +0000898 return {status, result};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700899 }
900 result.driverDescription = driver_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700901
Roshan Piusabcf78f2017-10-06 16:30:38 -0700902 std::string firmware_desc;
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800903 std::tie(legacy_status, firmware_desc) = legacy_hal_.lock()->getFirmwareVersion(ifname);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700904 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800905 LOG(ERROR) << "Failed to get firmware version: " << legacyErrorToString(legacy_status);
Gabriel Biren631a8112022-12-01 22:29:32 +0000906 WifiStatus status =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800907 createWifiStatusFromLegacyError(legacy_status, "failed to get firmware version");
Gabriel Biren631a8112022-12-01 22:29:32 +0000908 return {status, result};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700909 }
910 result.firmwareDescription = firmware_desc.c_str();
Roshan Pius3c868522016-10-27 12:43:49 -0700911
Gabriel Biren631a8112022-12-01 22:29:32 +0000912 return {createWifiStatus(WifiStatusCode::SUCCESS), result};
Roshan Pius3c868522016-10-27 12:43:49 -0700913}
914
Gabriel Biren631a8112022-12-01 22:29:32 +0000915std::pair<WifiStatus, std::vector<uint8_t>> WifiChip::requestDriverDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700916 legacy_hal::wifi_error legacy_status;
917 std::vector<uint8_t> driver_dump;
918 std::tie(legacy_status, driver_dump) =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800919 legacy_hal_.lock()->requestDriverMemoryDump(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -0700920 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800921 LOG(ERROR) << "Failed to get driver debug dump: " << legacyErrorToString(legacy_status);
Gabriel Biren631a8112022-12-01 22:29:32 +0000922 return {createWifiStatusFromLegacyError(legacy_status), std::vector<uint8_t>()};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700923 }
Gabriel Biren631a8112022-12-01 22:29:32 +0000924 return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
Roshan Pius3c868522016-10-27 12:43:49 -0700925}
926
Gabriel Biren631a8112022-12-01 22:29:32 +0000927std::pair<WifiStatus, std::vector<uint8_t>> WifiChip::requestFirmwareDebugDumpInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -0700928 legacy_hal::wifi_error legacy_status;
929 std::vector<uint8_t> firmware_dump;
930 std::tie(legacy_status, firmware_dump) =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800931 legacy_hal_.lock()->requestFirmwareMemoryDump(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -0700932 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800933 LOG(ERROR) << "Failed to get firmware debug dump: " << legacyErrorToString(legacy_status);
Gabriel Biren631a8112022-12-01 22:29:32 +0000934 return {createWifiStatusFromLegacyError(legacy_status), {}};
Roshan Piusabcf78f2017-10-06 16:30:38 -0700935 }
Gabriel Biren631a8112022-12-01 22:29:32 +0000936 return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
Roshan Pius3c868522016-10-27 12:43:49 -0700937}
938
Gabriel Biren631a8112022-12-01 22:29:32 +0000939WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) {
lesl94d28242020-11-18 22:17:37 +0800940 legacy_hal::wifi_error legacy_status;
941 legacy_status = legacy_hal_.lock()->createVirtualInterface(
Gabriel Biren631a8112022-12-01 22:29:32 +0000942 apVirtIf, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP));
Sunil Raviddab4bb2020-02-03 22:45:19 -0800943 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
lesl94d28242020-11-18 22:17:37 +0800944 LOG(ERROR) << "Failed to add interface: " << apVirtIf << " "
Sunil Raviddab4bb2020-02-03 22:45:19 -0800945 << legacyErrorToString(legacy_status);
lesl94d28242020-11-18 22:17:37 +0800946 return createWifiStatusFromLegacyError(legacy_status);
Sunil Raviddab4bb2020-02-03 22:45:19 -0800947 }
Gabriel Biren631a8112022-12-01 22:29:32 +0000948 return createWifiStatus(WifiStatusCode::SUCCESS);
lesl94d28242020-11-18 22:17:37 +0800949}
950
Gabriel Biren631a8112022-12-01 22:29:32 +0000951sp<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) {
lesl420c4fc2020-11-23 19:33:04 +0800952 std::vector<std::string> ap_instances;
953 for (auto const& it : br_ifaces_ap_instances_) {
954 if (it.first == ifname) {
955 ap_instances = it.second;
956 }
957 }
Gabriel Biren631a8112022-12-01 22:29:32 +0000958 sp<WifiApIface> iface = new WifiApIface(ifname, ap_instances, legacy_hal_, iface_util_);
Roshan Pius675609b2017-10-31 14:24:58 -0700959 ap_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -0700960 for (const auto& callback : event_cb_handler_.getCallbacks()) {
961 if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
962 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
963 }
964 }
Roshan Pius8574e7f2019-04-01 13:30:40 -0700965 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
lesl94d28242020-11-18 22:17:37 +0800966 return iface;
967}
968
Gabriel Biren631a8112022-12-01 22:29:32 +0000969std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createApIfaceInternal() {
Quang Luong5d8805e2022-01-28 15:46:40 -0800970 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP)) {
Gabriel Biren631a8112022-12-01 22:29:32 +0000971 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
lesl94d28242020-11-18 22:17:37 +0800972 }
973 std::string ifname = allocateApIfaceName();
Gabriel Biren631a8112022-12-01 22:29:32 +0000974 WifiStatus status = createVirtualApInterface(ifname);
975 if (status.code != WifiStatusCode::SUCCESS) {
976 return {status, {}};
lesl94d28242020-11-18 22:17:37 +0800977 }
Gabriel Biren631a8112022-12-01 22:29:32 +0000978 sp<WifiApIface> iface = newWifiApIface(ifname);
979 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
lesl94d28242020-11-18 22:17:37 +0800980}
981
Gabriel Biren631a8112022-12-01 22:29:32 +0000982std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createBridgedApIfaceInternal() {
Quang Luong5d8805e2022-01-28 15:46:40 -0800983 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP_BRIDGED)) {
Gabriel Biren631a8112022-12-01 22:29:32 +0000984 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
lesl94d28242020-11-18 22:17:37 +0800985 }
lesl261818b2020-11-27 12:37:35 +0800986 std::vector<std::string> ap_instances = allocateBridgedApInstanceNames();
987 if (ap_instances.size() < 2) {
988 LOG(ERROR) << "Fail to allocate two instances";
Gabriel Biren631a8112022-12-01 22:29:32 +0000989 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
lesl261818b2020-11-27 12:37:35 +0800990 }
991 std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0];
lesl94d28242020-11-18 22:17:37 +0800992 for (int i = 0; i < 2; i++) {
Gabriel Biren631a8112022-12-01 22:29:32 +0000993 WifiStatus status = createVirtualApInterface(ap_instances[i]);
994 if (status.code != WifiStatusCode::SUCCESS) {
lesl261818b2020-11-27 12:37:35 +0800995 if (i != 0) { // The failure happened when creating second virtual
996 // iface.
lesl94d28242020-11-18 22:17:37 +0800997 legacy_hal_.lock()->deleteVirtualInterface(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -0800998 ap_instances.front()); // Remove the first virtual iface.
lesl94d28242020-11-18 22:17:37 +0800999 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001000 return {status, {}};
lesl94d28242020-11-18 22:17:37 +08001001 }
lesl94d28242020-11-18 22:17:37 +08001002 }
1003 br_ifaces_ap_instances_[br_ifname] = ap_instances;
Roshan Pius8c1a67b2021-03-02 10:00:23 -08001004 if (!iface_util_->createBridge(br_ifname)) {
lesl94d28242020-11-18 22:17:37 +08001005 LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
Gabriel Biren631a8112022-12-01 22:29:32 +00001006 deleteApIface(br_ifname);
1007 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
lesl94d28242020-11-18 22:17:37 +08001008 }
1009 for (auto const& instance : ap_instances) {
1010 // Bind ap instance interface to AP bridge
Roshan Pius8c1a67b2021-03-02 10:00:23 -08001011 if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001012 LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str();
Gabriel Biren631a8112022-12-01 22:29:32 +00001013 deleteApIface(br_ifname);
1014 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
lesl94d28242020-11-18 22:17:37 +08001015 }
1016 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001017 sp<WifiApIface> iface = newWifiApIface(br_ifname);
1018 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001019}
1020
Gabriel Biren631a8112022-12-01 22:29:32 +00001021std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getApIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -07001022 if (ap_ifaces_.empty()) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001023 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001024 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001025 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -07001026}
1027
Gabriel Biren631a8112022-12-01 22:29:32 +00001028std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::getApIfaceInternal(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001029 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001030 const auto iface = findUsingName(ap_ifaces_, ifname);
1031 if (!iface.get()) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001032 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001033 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001034 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001035}
1036
Gabriel Biren631a8112022-12-01 22:29:32 +00001037WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001038 const auto iface = findUsingName(ap_ifaces_, ifname);
1039 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001040 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -08001041 }
Roshan Pius82368502019-05-16 12:53:02 -07001042 // Invalidate & remove any dependent objects first.
1043 // Note: This is probably not required because we never create
1044 // nan/rtt objects over AP iface. But, there is no harm to do it
1045 // here and not make that assumption all over the place.
1046 invalidateAndRemoveDependencies(ifname);
Gabriel Biren631a8112022-12-01 22:29:32 +00001047 deleteApIface(ifname);
Roshan Pius675609b2017-10-31 14:24:58 -07001048 invalidateAndClear(ap_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001049 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1050 if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
1051 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1052 }
1053 }
Roshan Pius8574e7f2019-04-01 13:30:40 -07001054 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
Gabriel Biren631a8112022-12-01 22:29:32 +00001055 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001056}
1057
Gabriel Biren631a8112022-12-01 22:29:32 +00001058WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001059 const std::string& ifname, const std::string& ifInstanceName) {
lesl94d28242020-11-18 22:17:37 +08001060 const auto iface = findUsingName(ap_ifaces_, ifname);
lesl819e3722021-01-07 09:49:04 +08001061 if (!iface.get() || ifInstanceName.empty()) {
lesl94d28242020-11-18 22:17:37 +08001062 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1063 }
1064 // Requires to remove one of the instance in bridge mode
1065 for (auto const& it : br_ifaces_ap_instances_) {
1066 if (it.first == ifname) {
Les Lee03d642f2021-06-21 21:25:20 +08001067 std::vector<std::string> ap_instances = it.second;
1068 for (auto const& iface : ap_instances) {
lesl94d28242020-11-18 22:17:37 +08001069 if (iface == ifInstanceName) {
Roshan Pius8c1a67b2021-03-02 10:00:23 -08001070 if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001071 LOG(ERROR) << "Failed to remove interface: " << ifInstanceName << " from "
1072 << ifname;
1073 return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE);
lesl94d28242020-11-18 22:17:37 +08001074 }
George Burgess IV2c0a47d2021-01-20 21:14:13 -08001075 legacy_hal::wifi_error legacy_status =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001076 legacy_hal_.lock()->deleteVirtualInterface(iface);
lesl94d28242020-11-18 22:17:37 +08001077 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001078 LOG(ERROR) << "Failed to del interface: " << iface << " "
1079 << legacyErrorToString(legacy_status);
lesl94d28242020-11-18 22:17:37 +08001080 return createWifiStatusFromLegacyError(legacy_status);
1081 }
Les Lee03d642f2021-06-21 21:25:20 +08001082 ap_instances.erase(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001083 std::remove(ap_instances.begin(), ap_instances.end(), ifInstanceName),
1084 ap_instances.end());
Les Lee03d642f2021-06-21 21:25:20 +08001085 br_ifaces_ap_instances_[ifname] = ap_instances;
1086 break;
lesl94d28242020-11-18 22:17:37 +08001087 }
1088 }
1089 break;
1090 }
1091 }
lesl669c9062021-01-22 19:37:47 +08001092 iface->removeInstance(ifInstanceName);
Les Lee03d642f2021-06-21 21:25:20 +08001093 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1094
Gabriel Biren631a8112022-12-01 22:29:32 +00001095 return createWifiStatus(WifiStatusCode::SUCCESS);
lesl94d28242020-11-18 22:17:37 +08001096}
1097
Gabriel Biren631a8112022-12-01 22:29:32 +00001098std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::createNanIfaceInternal() {
1099 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::NAN)) {
1100 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Etan Cohenc5700402017-03-08 16:43:38 -08001101 }
Roshan Pius5ba0a902020-04-14 11:55:42 -07001102 bool is_dedicated_iface = true;
lesl261818b2020-11-27 12:37:35 +08001103 std::string ifname = getPredefinedNanIfaceName();
Roshan Pius8c1a67b2021-03-02 10:00:23 -08001104 if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) {
Roshan Pius5ba0a902020-04-14 11:55:42 -07001105 // Use the first shared STA iface (wlan0) if a dedicated aware iface is
1106 // not defined.
1107 ifname = getFirstActiveWlanIfaceName();
1108 is_dedicated_iface = false;
1109 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001110 sp<WifiNanIface> iface = new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
Roshan Piuscc338202017-11-02 13:54:09 -07001111 nan_ifaces_.push_back(iface);
1112 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001113 if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
Roshan Piuscc338202017-11-02 13:54:09 -07001114 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1115 }
1116 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001117 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001118}
1119
Gabriel Biren631a8112022-12-01 22:29:32 +00001120std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getNanIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -07001121 if (nan_ifaces_.empty()) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001122 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001123 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001124 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -07001125}
1126
Gabriel Biren631a8112022-12-01 22:29:32 +00001127std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::getNanIfaceInternal(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001128 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001129 const auto iface = findUsingName(nan_ifaces_, ifname);
1130 if (!iface.get()) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001131 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001132 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001133 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001134}
1135
Gabriel Biren631a8112022-12-01 22:29:32 +00001136WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001137 const auto iface = findUsingName(nan_ifaces_, ifname);
1138 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001139 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -08001140 }
Roshan Pius675609b2017-10-31 14:24:58 -07001141 invalidateAndClear(nan_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001142 for (const auto& callback : event_cb_handler_.getCallbacks()) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001143 if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001144 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1145 }
1146 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001147 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001148}
1149
Gabriel Biren631a8112022-12-01 22:29:32 +00001150std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
Quang Luong5d8805e2022-01-28 15:46:40 -08001151 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::P2P)) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001152 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -08001153 }
lesl261818b2020-11-27 12:37:35 +08001154 std::string ifname = getPredefinedP2pIfaceName();
Gabriel Biren631a8112022-12-01 22:29:32 +00001155 sp<WifiP2pIface> iface = new WifiP2pIface(ifname, legacy_hal_);
Roshan Pius675609b2017-10-31 14:24:58 -07001156 p2p_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001157 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1158 if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
1159 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1160 }
1161 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001162 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001163}
1164
Gabriel Biren631a8112022-12-01 22:29:32 +00001165std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getP2pIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -07001166 if (p2p_ifaces_.empty()) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001167 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001168 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001169 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -07001170}
1171
Gabriel Biren631a8112022-12-01 22:29:32 +00001172std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001173 const auto iface = findUsingName(p2p_ifaces_, ifname);
1174 if (!iface.get()) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001175 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001176 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001177 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001178}
1179
Gabriel Biren631a8112022-12-01 22:29:32 +00001180WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001181 const auto iface = findUsingName(p2p_ifaces_, ifname);
1182 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001183 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -08001184 }
Roshan Pius675609b2017-10-31 14:24:58 -07001185 invalidateAndClear(p2p_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001186 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1187 if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
1188 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1189 }
1190 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001191 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001192}
1193
Gabriel Biren631a8112022-12-01 22:29:32 +00001194std::pair<WifiStatus, sp<V1_6::IWifiStaIface>> WifiChip::createStaIfaceInternal() {
Quang Luong5d8805e2022-01-28 15:46:40 -08001195 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001196 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
Roshan Piusbc662202017-01-30 17:07:42 -08001197 }
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001198 std::string ifname = allocateStaIfaceName();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001199 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->createVirtualInterface(
Gabriel Biren631a8112022-12-01 22:29:32 +00001200 ifname, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA));
Sunil Raviddab4bb2020-02-03 22:45:19 -08001201 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1202 LOG(ERROR) << "Failed to add interface: " << ifname << " "
1203 << legacyErrorToString(legacy_status);
Gabriel Biren631a8112022-12-01 22:29:32 +00001204 return {createWifiStatusFromLegacyError(legacy_status), {}};
Sunil Raviddab4bb2020-02-03 22:45:19 -08001205 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001206 sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_);
Roshan Pius675609b2017-10-31 14:24:58 -07001207 sta_ifaces_.push_back(iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001208 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1209 if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
1210 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1211 }
1212 }
Roshan Pius8574e7f2019-04-01 13:30:40 -07001213 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
Gabriel Biren631a8112022-12-01 22:29:32 +00001214 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001215}
1216
Gabriel Biren631a8112022-12-01 22:29:32 +00001217std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getStaIfaceNamesInternal() {
Roshan Pius675609b2017-10-31 14:24:58 -07001218 if (sta_ifaces_.empty()) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001219 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001220 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001221 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)};
Roshan Pius3c868522016-10-27 12:43:49 -07001222}
1223
Gabriel Biren631a8112022-12-01 22:29:32 +00001224std::pair<WifiStatus, sp<V1_6::IWifiStaIface>> WifiChip::getStaIfaceInternal(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001225 const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001226 const auto iface = findUsingName(sta_ifaces_, ifname);
1227 if (!iface.get()) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001228 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001229 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001230 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
Roshan Pius3c868522016-10-27 12:43:49 -07001231}
1232
Gabriel Biren631a8112022-12-01 22:29:32 +00001233WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
Roshan Pius675609b2017-10-31 14:24:58 -07001234 const auto iface = findUsingName(sta_ifaces_, ifname);
1235 if (!iface.get()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001236 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
Roshan Piusbc662202017-01-30 17:07:42 -08001237 }
Roshan Pius82368502019-05-16 12:53:02 -07001238 // Invalidate & remove any dependent objects first.
1239 invalidateAndRemoveDependencies(ifname);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001240 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(ifname);
Sunil Raviddab4bb2020-02-03 22:45:19 -08001241 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1242 LOG(ERROR) << "Failed to remove interface: " << ifname << " "
1243 << legacyErrorToString(legacy_status);
1244 }
Roshan Pius675609b2017-10-31 14:24:58 -07001245 invalidateAndClear(sta_ifaces_, iface);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001246 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1247 if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
1248 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1249 }
1250 }
Roshan Pius8574e7f2019-04-01 13:30:40 -07001251 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
Gabriel Biren631a8112022-12-01 22:29:32 +00001252 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius8b55e6f2016-12-09 12:05:12 -08001253}
1254
Gabriel Biren631a8112022-12-01 22:29:32 +00001255std::pair<WifiStatus, sp<V1_0::IWifiRttController>> WifiChip::createRttControllerInternal(
1256 const sp<IWifiIface>& /*bound_iface*/) {
1257 LOG(ERROR) << "createRttController is not supported on this HAL";
1258 return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
Roshan Pius3c868522016-10-27 12:43:49 -07001259}
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001260
Gabriel Biren631a8112022-12-01 22:29:32 +00001261std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001262WifiChip::getDebugRingBuffersStatusInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001263 legacy_hal::wifi_error legacy_status;
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001264 std::vector<legacy_hal::wifi_ring_buffer_status> legacy_ring_buffer_status_vec;
Roshan Piusabcf78f2017-10-06 16:30:38 -07001265 std::tie(legacy_status, legacy_ring_buffer_status_vec) =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001266 legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001267 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001268 return {createWifiStatusFromLegacyError(legacy_status), {}};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001269 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001270 std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
1271 if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
1272 legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
1273 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001274 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001275 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_ring_buffer_status_vec};
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001276}
1277
Gabriel Biren631a8112022-12-01 22:29:32 +00001278WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
1279 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001280 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001281 WifiStatus status = registerDebugRingBufferCallback();
1282 if (status.code != WifiStatusCode::SUCCESS) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001283 return status;
1284 }
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001285 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRingBufferLogging(
Roshan Pius6036c022019-03-27 10:41:58 -07001286 getFirstActiveWlanIfaceName(), ring_name,
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001287 static_cast<std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(verbose_level),
Roshan Piusabcf78f2017-10-06 16:30:38 -07001288 max_interval_in_sec, min_data_size_in_bytes);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001289 ringbuffer_map_.insert(
1290 std::pair<std::string, Ringbuffer>(ring_name, Ringbuffer(kMaxBufferSizeBytes)));
Roshan Piusa63b53f2019-11-18 11:03:13 -08001291 // if verbose logging enabled, turn up HAL daemon logging as well.
1292 if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001293 android::base::SetMinimumLogSeverity(android::base::DEBUG);
Roshan Piusa63b53f2019-11-18 11:03:13 -08001294 } else {
Gabriel Biren631a8112022-12-01 22:29:32 +00001295 android::base::SetMinimumLogSeverity(android::base::VERBOSE);
Roshan Piusa63b53f2019-11-18 11:03:13 -08001296 }
Roshan Piusabcf78f2017-10-06 16:30:38 -07001297 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001298}
1299
Gabriel Biren631a8112022-12-01 22:29:32 +00001300WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(const hidl_string& ring_name) {
1301 WifiStatus status = registerDebugRingBufferCallback();
1302 if (status.code != WifiStatusCode::SUCCESS) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001303 return status;
1304 }
1305 legacy_hal::wifi_error legacy_status =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001306 legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), ring_name);
xshu5899e8e2018-01-09 15:36:03 -08001307
Roshan Piusabcf78f2017-10-06 16:30:38 -07001308 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001309}
1310
Gabriel Biren631a8112022-12-01 22:29:32 +00001311WifiStatus WifiChip::flushRingBufferToFileInternal() {
Roger Wangb294c762018-11-02 15:34:39 +08001312 if (!writeRingbufferFilesInternal()) {
1313 LOG(ERROR) << "Error writing files to flash";
1314 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1315 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001316 return createWifiStatus(WifiStatusCode::SUCCESS);
Roger Wangb294c762018-11-02 15:34:39 +08001317}
1318
Gabriel Biren631a8112022-12-01 22:29:32 +00001319WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001320 legacy_hal::wifi_error legacy_status =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001321 legacy_hal_.lock()->deregisterRingBufferCallbackHandler(getFirstActiveWlanIfaceName());
xshu0a0fe512020-07-22 17:53:37 -07001322 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1323 debug_ring_buffer_cb_registered_ = false;
1324 }
Roshan Piusabcf78f2017-10-06 16:30:38 -07001325 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius8c0c8e92017-02-24 08:07:42 -08001326}
1327
Gabriel Biren631a8112022-12-01 22:29:32 +00001328std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001329WifiChip::getDebugHostWakeReasonStatsInternal() {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001330 legacy_hal::wifi_error legacy_status;
1331 legacy_hal::WakeReasonStats legacy_stats;
1332 std::tie(legacy_status, legacy_stats) =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001333 legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001334 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001335 return {createWifiStatusFromLegacyError(legacy_status), {}};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001336 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001337 WifiDebugHostWakeReasonStats hidl_stats;
1338 if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats, &hidl_stats)) {
1339 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
Roshan Piusabcf78f2017-10-06 16:30:38 -07001340 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001341 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
Roshan Pius7d08d7a2016-10-27 14:35:05 -07001342}
1343
Gabriel Biren631a8112022-12-01 22:29:32 +00001344WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001345 legacy_hal::wifi_error legacy_status;
1346 if (enable) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001347 android::wp<WifiChip> weak_ptr_this(this);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001348 const auto& on_alert_callback = [weak_ptr_this](int32_t error_code,
1349 std::vector<uint8_t> debug_data) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001350 const auto shared_ptr_this = weak_ptr_this.promote();
Roshan Piusabcf78f2017-10-06 16:30:38 -07001351 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1352 LOG(ERROR) << "Callback invoked on an invalid object";
1353 return;
1354 }
1355 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001356 if (!callback->onDebugErrorAlert(error_code, debug_data).isOk()) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001357 LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
1358 }
1359 }
1360 };
1361 legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001362 getFirstActiveWlanIfaceName(), on_alert_callback);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001363 } else {
1364 legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001365 getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001366 }
1367 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius203cb032016-12-14 17:41:20 -08001368}
Roshan Pius2c06a3f2016-12-15 17:51:40 -08001369
Gabriel Biren631a8112022-12-01 22:29:32 +00001370WifiStatus WifiChip::selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001371 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001372 getFirstActiveWlanIfaceName(),
Gabriel Biren631a8112022-12-01 22:29:32 +00001373 hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
Roshan Piusabcf78f2017-10-06 16:30:38 -07001374 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -07001375}
1376
Gabriel Biren631a8112022-12-01 22:29:32 +00001377WifiStatus WifiChip::resetTxPowerScenarioInternal() {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001378 auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
Roshan Piusabcf78f2017-10-06 16:30:38 -07001379 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusdbd83ef2017-06-20 12:05:40 -07001380}
1381
Gabriel Biren631a8112022-12-01 22:29:32 +00001382WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) {
Ahmed ElArabawyeaf82402018-10-26 09:46:04 -07001383 auto legacy_status = legacy_hal_.lock()->setLatencyMode(
Gabriel Biren631a8112022-12-01 22:29:32 +00001384 getFirstActiveWlanIfaceName(), hidl_struct_util::convertHidlLatencyModeToLegacy(mode));
Ahmed ElArabawyeaf82402018-10-26 09:46:04 -07001385 return createWifiStatusFromLegacyError(legacy_status);
1386}
1387
Gabriel Biren631a8112022-12-01 22:29:32 +00001388WifiStatus WifiChip::registerEventCallbackInternal_1_2(
1389 const sp<V1_2::IWifiChipEventCallback>& /* event_callback */) {
1390 // Deprecated support for this callback.
1391 return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
1392}
1393
1394WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario) {
1395 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
1396 getFirstActiveWlanIfaceName(),
1397 hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario));
1398 return createWifiStatusFromLegacyError(legacy_status);
1399}
1400
1401std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_3() {
1402 // Deprecated support for this callback.
1403 return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
1404}
1405
1406std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_5() {
1407 legacy_hal::wifi_error legacy_status;
1408 uint64_t legacy_feature_set;
1409 uint32_t legacy_logger_feature_set;
1410 const auto ifname = getFirstActiveWlanIfaceName();
1411 std::tie(legacy_status, legacy_feature_set) =
1412 legacy_hal_.lock()->getSupportedFeatureSet(ifname);
1413 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1414 return {createWifiStatusFromLegacyError(legacy_status), 0};
1415 }
1416 std::tie(legacy_status, legacy_logger_feature_set) =
1417 legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
1418 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1419 // some devices don't support querying logger feature set
1420 legacy_logger_feature_set = 0;
1421 }
1422 uint32_t hidl_caps;
1423 if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
1424 legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
1425 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
1426 }
1427 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
1428}
1429
1430std::pair<WifiStatus, sp<V1_4::IWifiRttController>> WifiChip::createRttControllerInternal_1_4(
1431 const sp<IWifiIface>& /*bound_iface*/) {
1432 LOG(ERROR) << "createRttController_1_4 is not supported on this HAL";
1433 return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
1434}
1435
1436WifiStatus WifiChip::registerEventCallbackInternal_1_4(
1437 const sp<V1_4::IWifiChipEventCallback>& event_callback) {
1438 if (!event_cb_handler_.addCallback(event_callback)) {
1439 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1440 }
1441 return createWifiStatus(WifiStatusCode::SUCCESS);
1442}
1443
1444WifiStatus WifiChip::setMultiStaPrimaryConnectionInternal(const std::string& ifname) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001445 auto legacy_status = legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname);
Roshan Piuse9d1e7d2020-11-04 11:44:16 -08001446 return createWifiStatusFromLegacyError(legacy_status);
1447}
1448
Gabriel Biren631a8112022-12-01 22:29:32 +00001449WifiStatus WifiChip::setMultiStaUseCaseInternal(MultiStaUseCase use_case) {
Roshan Piuse9d1e7d2020-11-04 11:44:16 -08001450 auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase(
Gabriel Biren631a8112022-12-01 22:29:32 +00001451 hidl_struct_util::convertHidlMultiStaUseCaseToLegacy(use_case));
Roshan Piuse9d1e7d2020-11-04 11:44:16 -08001452 return createWifiStatusFromLegacyError(legacy_status);
1453}
1454
Gabriel Biren631a8112022-12-01 22:29:32 +00001455WifiStatus WifiChip::setCoexUnsafeChannelsInternal(std::vector<CoexUnsafeChannel> unsafe_channels,
1456 uint32_t restrictions) {
Quang Luong94bcce52020-11-25 17:52:19 -08001457 std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels;
Gabriel Biren631a8112022-12-01 22:29:32 +00001458 if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy(unsafe_channels,
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001459 &legacy_unsafe_channels)) {
Quang Luong94bcce52020-11-25 17:52:19 -08001460 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1461 }
Quang Luongab70a832020-12-14 13:01:32 -08001462 uint32_t legacy_restrictions = 0;
Gabriel Biren631a8112022-12-01 22:29:32 +00001463 if (restrictions & CoexRestriction::WIFI_DIRECT) {
Quang Luongab70a832020-12-14 13:01:32 -08001464 legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_DIRECT;
1465 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001466 if (restrictions & CoexRestriction::SOFTAP) {
Quang Luongab70a832020-12-14 13:01:32 -08001467 legacy_restrictions |= legacy_hal::wifi_coex_restriction::SOFTAP;
1468 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001469 if (restrictions & CoexRestriction::WIFI_AWARE) {
Quang Luongab70a832020-12-14 13:01:32 -08001470 legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE;
1471 }
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001472 auto legacy_status =
1473 legacy_hal_.lock()->setCoexUnsafeChannels(legacy_unsafe_channels, legacy_restrictions);
Quang Luong94bcce52020-11-25 17:52:19 -08001474 return createWifiStatusFromLegacyError(legacy_status);
1475}
1476
Gabriel Biren631a8112022-12-01 22:29:32 +00001477WifiStatus WifiChip::setCountryCodeInternal(const std::array<int8_t, 2>& code) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001478 auto legacy_status = legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code);
Kumar Anandda62c382020-11-18 17:17:47 -08001479 return createWifiStatusFromLegacyError(legacy_status);
1480}
1481
Gabriel Biren631a8112022-12-01 22:29:32 +00001482std::pair<WifiStatus, std::vector<V1_5::WifiUsableChannel>> WifiChip::getUsableChannelsInternal(
1483 WifiBand /*band*/, uint32_t /*ifaceModeMask*/, uint32_t /*filterMask*/) {
1484 LOG(ERROR) << "getUsableChannels is not supported on this HAL";
1485 return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
1486}
1487
1488WifiStatus WifiChip::triggerSubsystemRestartInternal() {
1489 auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart();
1490 return createWifiStatusFromLegacyError(legacy_status);
1491}
1492
1493std::pair<WifiStatus, sp<V1_6::IWifiRttController>> WifiChip::createRttControllerInternal_1_6(
1494 const sp<IWifiIface>& bound_iface) {
1495 if (sta_ifaces_.size() == 0 &&
1496 !canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
1497 LOG(ERROR) << "createRttControllerInternal_1_6: Chip cannot support STAs "
1498 "(and RTT by extension)";
1499 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1500 }
1501 sp<WifiRttController> rtt =
1502 new WifiRttController(getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
1503 rtt_controllers_.emplace_back(rtt);
1504 return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
1505}
1506
1507std::pair<WifiStatus, std::vector<V1_6::WifiUsableChannel>> WifiChip::getUsableChannelsInternal_1_6(
1508 WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask) {
Kumar Anand2a630a32021-01-21 14:09:14 -08001509 legacy_hal::wifi_error legacy_status;
1510 std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels;
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001511 std::tie(legacy_status, legacy_usable_channels) = legacy_hal_.lock()->getUsableChannels(
Gabriel Biren631a8112022-12-01 22:29:32 +00001512 hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band),
1513 hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask),
1514 hidl_struct_util::convertHidlUsableChannelFilterToLegacy(filterMask));
Kumar Anandaea86e02021-02-10 16:22:31 -08001515
Kumar Anand2a630a32021-01-21 14:09:14 -08001516 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001517 return {createWifiStatusFromLegacyError(legacy_status), {}};
Kumar Anand2a630a32021-01-21 14:09:14 -08001518 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001519 std::vector<V1_6::WifiUsableChannel> hidl_usable_channels;
1520 if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl(legacy_usable_channels,
1521 &hidl_usable_channels)) {
1522 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
Kumar Anand2a630a32021-01-21 14:09:14 -08001523 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001524 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels};
Kumar Anand2a630a32021-01-21 14:09:14 -08001525}
1526
Gabriel Biren631a8112022-12-01 22:29:32 +00001527std::pair<WifiStatus, V1_6::WifiRadioCombinationMatrix>
Sunil Ravief97d232022-01-24 10:39:56 -08001528WifiChip::getSupportedRadioCombinationsMatrixInternal() {
1529 legacy_hal::wifi_error legacy_status;
1530 legacy_hal::wifi_radio_combination_matrix* legacy_matrix;
1531
1532 std::tie(legacy_status, legacy_matrix) =
1533 legacy_hal_.lock()->getSupportedRadioCombinationsMatrix();
1534 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1535 LOG(ERROR) << "Failed to get SupportedRadioCombinations matrix from legacy HAL: "
1536 << legacyErrorToString(legacy_status);
Gabriel Biren631a8112022-12-01 22:29:32 +00001537 return {createWifiStatusFromLegacyError(legacy_status), {}};
Sunil Ravief97d232022-01-24 10:39:56 -08001538 }
1539
Gabriel Biren631a8112022-12-01 22:29:32 +00001540 V1_6::WifiRadioCombinationMatrix hidl_matrix;
1541 if (!hidl_struct_util::convertLegacyRadioCombinationsMatrixToHidl(legacy_matrix,
1542 &hidl_matrix)) {
1543 LOG(ERROR) << "Failed convertLegacyRadioCombinationsMatrixToHidl() ";
1544 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), {}};
Sunil Ravief97d232022-01-24 10:39:56 -08001545 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001546 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_matrix};
Sunil Ravief97d232022-01-24 10:39:56 -08001547}
1548
Gabriel Biren631a8112022-12-01 22:29:32 +00001549std::pair<WifiStatus, std::vector<V1_6::IWifiChip::ChipMode>>
1550WifiChip::getAvailableModesInternal_1_6() {
1551 return {createWifiStatus(WifiStatusCode::SUCCESS), modes_};
Quang Luong5d8805e2022-01-28 15:46:40 -08001552}
1553
Gabriel Biren631a8112022-12-01 22:29:32 +00001554WifiStatus WifiChip::handleChipConfiguration(
1555 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001556 // If the chip is already configured in a different mode, stop
1557 // the legacy HAL and then start it after firmware mode change.
Roshan Piuscc338202017-11-02 13:54:09 -07001558 if (isValidModeId(current_mode_id_)) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001559 LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ << " to mode " << mode_id;
Roshan Piusba38d9c2017-12-08 07:32:08 -08001560 invalidateAndRemoveAllIfaces();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001561 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop(lock, []() {});
Roshan Piusba38d9c2017-12-08 07:32:08 -08001562 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001563 LOG(ERROR) << "Failed to stop legacy HAL: " << legacyErrorToString(legacy_status);
Roshan Piusba38d9c2017-12-08 07:32:08 -08001564 return createWifiStatusFromLegacyError(legacy_status);
1565 }
Roshan Piusabcf78f2017-10-06 16:30:38 -07001566 }
Roshan Piuscc338202017-11-02 13:54:09 -07001567 // Firmware mode change not needed for V2 devices.
1568 bool success = true;
Tomasz Wasilczykb424da72018-11-15 11:52:57 -08001569 if (mode_id == feature_flags::chip_mode_ids::kV1Sta) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001570 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
Tomasz Wasilczykb424da72018-11-15 11:52:57 -08001571 } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001572 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
1573 }
1574 if (!success) {
1575 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1576 }
1577 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
1578 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001579 LOG(ERROR) << "Failed to start legacy HAL: " << legacyErrorToString(legacy_status);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001580 return createWifiStatusFromLegacyError(legacy_status);
1581 }
Roshan Pius85c64412018-01-22 17:58:40 -08001582 // Every time the HAL is restarted, we need to register the
1583 // radio mode change callback.
Gabriel Biren631a8112022-12-01 22:29:32 +00001584 WifiStatus status = registerRadioModeChangeCallback();
1585 if (status.code != WifiStatusCode::SUCCESS) {
1586 // This probably is not a critical failure?
Roshan Pius85c64412018-01-22 17:58:40 -08001587 LOG(ERROR) << "Failed to register radio mode change callback";
1588 }
chenpaulf5eca292019-03-14 11:08:03 +08001589 // Extract and save the version information into property.
Gabriel Biren631a8112022-12-01 22:29:32 +00001590 std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo> version_info;
chenpaulf5eca292019-03-14 11:08:03 +08001591 version_info = WifiChip::requestChipDebugInfoInternal();
Gabriel Biren631a8112022-12-01 22:29:32 +00001592 if (WifiStatusCode::SUCCESS == version_info.first.code) {
chenpaulf5eca292019-03-14 11:08:03 +08001593 property_set("vendor.wlan.firmware.version",
Gabriel Biren631a8112022-12-01 22:29:32 +00001594 version_info.second.firmwareDescription.c_str());
1595 property_set("vendor.wlan.driver.version", version_info.second.driverDescription.c_str());
chenpaulf5eca292019-03-14 11:08:03 +08001596 }
1597
Gabriel Biren631a8112022-12-01 22:29:32 +00001598 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius2c06a3f2016-12-15 17:51:40 -08001599}
Roshan Pius48185b22016-12-15 19:10:30 -08001600
Gabriel Biren631a8112022-12-01 22:29:32 +00001601WifiStatus WifiChip::registerDebugRingBufferCallback() {
Roshan Piusabcf78f2017-10-06 16:30:38 -07001602 if (debug_ring_buffer_cb_registered_) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001603 return createWifiStatus(WifiStatusCode::SUCCESS);
Roshan Pius48185b22016-12-15 19:10:30 -08001604 }
Roshan Pius3797e182017-03-30 18:01:54 -07001605
Gabriel Biren631a8112022-12-01 22:29:32 +00001606 android::wp<WifiChip> weak_ptr_this(this);
Roshan Piusabcf78f2017-10-06 16:30:38 -07001607 const auto& on_ring_buffer_data_callback =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001608 [weak_ptr_this](const std::string& name, const std::vector<uint8_t>& data,
1609 const legacy_hal::wifi_ring_buffer_status& status) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001610 const auto shared_ptr_this = weak_ptr_this.promote();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001611 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1612 LOG(ERROR) << "Callback invoked on an invalid object";
Veerendranath Jakkam25b3a6f2020-04-14 22:04:39 +05301613 return;
1614 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001615 WifiDebugRingBufferStatus hidl_status;
Sunil Ravi07ef1912022-05-17 18:01:06 -07001616 Ringbuffer::AppendStatus appendstatus;
Gabriel Biren631a8112022-12-01 22:29:32 +00001617 if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(status,
1618 &hidl_status)) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001619 LOG(ERROR) << "Error converting ring buffer status";
1620 return;
1621 }
1622 {
1623 std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t);
1624 const auto& target = shared_ptr_this->ringbuffer_map_.find(name);
1625 if (target != shared_ptr_this->ringbuffer_map_.end()) {
1626 Ringbuffer& cur_buffer = target->second;
Sunil Ravi07ef1912022-05-17 18:01:06 -07001627 appendstatus = cur_buffer.append(data);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001628 } else {
1629 LOG(ERROR) << "Ringname " << name << " not found";
1630 return;
1631 }
1632 // unique_lock unlocked here
1633 }
Sunil Ravi07ef1912022-05-17 18:01:06 -07001634 if (appendstatus == Ringbuffer::AppendStatus::FAIL_RING_BUFFER_CORRUPTED) {
1635 LOG(ERROR) << "Ringname " << name << " is corrupted. Clear the ring buffer";
1636 shared_ptr_this->writeRingbufferFilesInternal();
1637 return;
1638 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001639
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001640 };
1641 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->registerRingBufferCallbackHandler(
Roshan Pius6036c022019-03-27 10:41:58 -07001642 getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback);
Roshan Pius48185b22016-12-15 19:10:30 -08001643
Roshan Piusabcf78f2017-10-06 16:30:38 -07001644 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1645 debug_ring_buffer_cb_registered_ = true;
1646 }
1647 return createWifiStatusFromLegacyError(legacy_status);
Roshan Pius48185b22016-12-15 19:10:30 -08001648}
1649
Gabriel Biren631a8112022-12-01 22:29:32 +00001650WifiStatus WifiChip::registerRadioModeChangeCallback() {
1651 android::wp<WifiChip> weak_ptr_this(this);
Roshan Pius85c64412018-01-22 17:58:40 -08001652 const auto& on_radio_mode_change_callback =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001653 [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001654 const auto shared_ptr_this = weak_ptr_this.promote();
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001655 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1656 LOG(ERROR) << "Callback invoked on an invalid object";
1657 return;
Roshan Pius85c64412018-01-22 17:58:40 -08001658 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001659 std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
1660 if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(mac_infos,
1661 &hidl_radio_mode_infos)) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001662 LOG(ERROR) << "Error converting wifi mac info";
1663 return;
1664 }
1665 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001666 if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos).isOk()) {
1667 LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4"
1668 << " callback on: " << toString(callback);
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001669 }
1670 }
1671 };
Roshan Pius85c64412018-01-22 17:58:40 -08001672 legacy_hal::wifi_error legacy_status =
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001673 legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
1674 getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
Roshan Pius85c64412018-01-22 17:58:40 -08001675 return createWifiStatusFromLegacyError(legacy_status);
1676}
1677
Gabriel Biren631a8112022-12-01 22:29:32 +00001678std::vector<V1_6::IWifiChip::ChipConcurrencyCombination>
Quang Luong5d8805e2022-01-28 15:46:40 -08001679WifiChip::getCurrentModeConcurrencyCombinations() {
Roshan Piuscc338202017-11-02 13:54:09 -07001680 if (!isValidModeId(current_mode_id_)) {
1681 LOG(ERROR) << "Chip not configured in a mode yet";
Gabriel Biren631a8112022-12-01 22:29:32 +00001682 return {};
Roshan Piuscc338202017-11-02 13:54:09 -07001683 }
1684 for (const auto& mode : modes_) {
1685 if (mode.id == current_mode_id_) {
1686 return mode.availableCombinations;
1687 }
1688 }
Quang Luong5d8805e2022-01-28 15:46:40 -08001689 CHECK(0) << "Expected to find concurrency combinations for current mode!";
Gabriel Biren631a8112022-12-01 22:29:32 +00001690 return {};
Roshan Piuscc338202017-11-02 13:54:09 -07001691}
1692
Quang Luong5d8805e2022-01-28 15:46:40 -08001693// Returns a map indexed by IfaceConcurrencyType with the number of ifaces currently
1694// created of the corresponding concurrency type.
1695std::map<IfaceConcurrencyType, size_t> WifiChip::getCurrentConcurrencyCombination() {
1696 std::map<IfaceConcurrencyType, size_t> iface_counts;
1697 uint32_t num_ap = 0;
1698 uint32_t num_ap_bridged = 0;
1699 for (const auto& ap_iface : ap_ifaces_) {
1700 std::string ap_iface_name = ap_iface->getName();
1701 if (br_ifaces_ap_instances_.count(ap_iface_name) > 0 &&
1702 br_ifaces_ap_instances_[ap_iface_name].size() > 1) {
1703 num_ap_bridged++;
1704 } else {
1705 num_ap++;
1706 }
1707 }
1708 iface_counts[IfaceConcurrencyType::AP] = num_ap;
1709 iface_counts[IfaceConcurrencyType::AP_BRIDGED] = num_ap_bridged;
Gabriel Biren631a8112022-12-01 22:29:32 +00001710 iface_counts[IfaceConcurrencyType::NAN] = nan_ifaces_.size();
Quang Luong5d8805e2022-01-28 15:46:40 -08001711 iface_counts[IfaceConcurrencyType::P2P] = p2p_ifaces_.size();
1712 iface_counts[IfaceConcurrencyType::STA] = sta_ifaces_.size();
Roshan Piuscc338202017-11-02 13:54:09 -07001713 return iface_counts;
1714}
1715
Quang Luong5d8805e2022-01-28 15:46:40 -08001716// This expands the provided concurrency combinations to a more parseable
Roshan Piuscc338202017-11-02 13:54:09 -07001717// form. Returns a vector of available combinations possible with the number
Quang Luong5d8805e2022-01-28 15:46:40 -08001718// of each concurrency type in the combination.
1719// This method is a port of HalDeviceManager.expandConcurrencyCombos() from framework.
1720std::vector<std::map<IfaceConcurrencyType, size_t>> WifiChip::expandConcurrencyCombinations(
Gabriel Biren631a8112022-12-01 22:29:32 +00001721 const V1_6::IWifiChip::ChipConcurrencyCombination& combination) {
1722 uint32_t num_expanded_combos = 1;
Roshan Piuscc338202017-11-02 13:54:09 -07001723 for (const auto& limit : combination.limits) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001724 for (uint32_t i = 0; i < limit.maxIfaces; i++) {
Roshan Piuscc338202017-11-02 13:54:09 -07001725 num_expanded_combos *= limit.types.size();
1726 }
1727 }
1728
Quang Luong5d8805e2022-01-28 15:46:40 -08001729 // Allocate the vector of expanded combos and reset all concurrency type counts to 0
Roshan Piuscc338202017-11-02 13:54:09 -07001730 // in each combo.
Quang Luong5d8805e2022-01-28 15:46:40 -08001731 std::vector<std::map<IfaceConcurrencyType, size_t>> expanded_combos;
Roshan Piuscc338202017-11-02 13:54:09 -07001732 expanded_combos.resize(num_expanded_combos);
1733 for (auto& expanded_combo : expanded_combos) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001734 for (const auto type :
1735 {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
1736 IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
Roshan Piuscc338202017-11-02 13:54:09 -07001737 expanded_combo[type] = 0;
1738 }
1739 }
Gabriel Biren631a8112022-12-01 22:29:32 +00001740 uint32_t span = num_expanded_combos;
Roshan Piuscc338202017-11-02 13:54:09 -07001741 for (const auto& limit : combination.limits) {
Gabriel Biren631a8112022-12-01 22:29:32 +00001742 for (uint32_t i = 0; i < limit.maxIfaces; i++) {
Roshan Piuscc338202017-11-02 13:54:09 -07001743 span /= limit.types.size();
Gabriel Biren631a8112022-12-01 22:29:32 +00001744 for (uint32_t k = 0; k < num_expanded_combos; ++k) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001745 const auto iface_type = limit.types[(k / span) % limit.types.size()];
Roshan Piuscc338202017-11-02 13:54:09 -07001746 expanded_combos[k][iface_type]++;
1747 }
1748 }
1749 }
1750 return expanded_combos;
1751}
1752
Quang Luong5d8805e2022-01-28 15:46:40 -08001753bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
1754 const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
1755 IfaceConcurrencyType requested_type) {
1756 const auto current_combo = getCurrentConcurrencyCombination();
Roshan Piuscc338202017-11-02 13:54:09 -07001757
1758 // Check if we have space for 1 more iface of |type| in this combo
Quang Luong5d8805e2022-01-28 15:46:40 -08001759 for (const auto type :
Gabriel Biren631a8112022-12-01 22:29:32 +00001760 {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
1761 IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
Roshan Piuscc338202017-11-02 13:54:09 -07001762 size_t num_ifaces_needed = current_combo.at(type);
1763 if (type == requested_type) {
1764 num_ifaces_needed++;
1765 }
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001766 size_t num_ifaces_allowed = expanded_combo.at(type);
Roshan Piuscc338202017-11-02 13:54:09 -07001767 if (num_ifaces_needed > num_ifaces_allowed) {
1768 return false;
1769 }
1770 }
1771 return true;
1772}
1773
1774// This method does the following:
Quang Luong5d8805e2022-01-28 15:46:40 -08001775// a) Enumerate all possible concurrency combos by expanding the current
1776// ChipConcurrencyCombination.
1777// b) Check if the requested concurrency type can be added to the current mode
1778// with the concurrency combination that is already active.
1779bool WifiChip::canCurrentModeSupportConcurrencyTypeWithCurrentTypes(
1780 IfaceConcurrencyType requested_type) {
Roshan Piuscc338202017-11-02 13:54:09 -07001781 if (!isValidModeId(current_mode_id_)) {
1782 LOG(ERROR) << "Chip not configured in a mode yet";
1783 return false;
1784 }
Quang Luong5d8805e2022-01-28 15:46:40 -08001785 const auto combinations = getCurrentModeConcurrencyCombinations();
Roshan Piuscc338202017-11-02 13:54:09 -07001786 for (const auto& combination : combinations) {
Quang Luong5d8805e2022-01-28 15:46:40 -08001787 const auto expanded_combos = expandConcurrencyCombinations(combination);
Roshan Piuscc338202017-11-02 13:54:09 -07001788 for (const auto& expanded_combo : expanded_combos) {
Quang Luong5d8805e2022-01-28 15:46:40 -08001789 if (canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(expanded_combo,
1790 requested_type)) {
Roshan Piuscc338202017-11-02 13:54:09 -07001791 return true;
1792 }
1793 }
1794 }
1795 return false;
1796}
1797
Quang Luong5d8805e2022-01-28 15:46:40 -08001798// Note: This does not consider concurrency types already active. It only checks if the
1799// provided expanded concurrency combination can support the requested combo.
1800bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyCombo(
1801 const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
1802 const std::map<IfaceConcurrencyType, size_t>& req_combo) {
1803 // Check if we have space for 1 more |type| in this combo
1804 for (const auto type :
Gabriel Biren631a8112022-12-01 22:29:32 +00001805 {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
1806 IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001807 if (req_combo.count(type) == 0) {
Quang Luong5d8805e2022-01-28 15:46:40 -08001808 // Concurrency type not in the req_combo.
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001809 continue;
1810 }
1811 size_t num_ifaces_needed = req_combo.at(type);
1812 size_t num_ifaces_allowed = expanded_combo.at(type);
1813 if (num_ifaces_needed > num_ifaces_allowed) {
1814 return false;
1815 }
1816 }
1817 return true;
1818}
1819// This method does the following:
Quang Luong5d8805e2022-01-28 15:46:40 -08001820// a) Enumerate all possible concurrency combos by expanding the current
1821// ChipConcurrencyCombination.
1822// b) Check if the requested concurrency combo can be added to the current mode.
1823// Note: This does not consider concurrency types already active. It only checks if the
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001824// current mode can support the requested combo.
Quang Luong5d8805e2022-01-28 15:46:40 -08001825bool WifiChip::canCurrentModeSupportConcurrencyCombo(
1826 const std::map<IfaceConcurrencyType, size_t>& req_combo) {
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001827 if (!isValidModeId(current_mode_id_)) {
1828 LOG(ERROR) << "Chip not configured in a mode yet";
1829 return false;
1830 }
Quang Luong5d8805e2022-01-28 15:46:40 -08001831 const auto combinations = getCurrentModeConcurrencyCombinations();
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001832 for (const auto& combination : combinations) {
Quang Luong5d8805e2022-01-28 15:46:40 -08001833 const auto expanded_combos = expandConcurrencyCombinations(combination);
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001834 for (const auto& expanded_combo : expanded_combos) {
Quang Luong5d8805e2022-01-28 15:46:40 -08001835 if (canExpandedConcurrencyComboSupportConcurrencyCombo(expanded_combo, req_combo)) {
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001836 return true;
1837 }
1838 }
1839 }
1840 return false;
1841}
1842
1843// This method does the following:
Quang Luong5d8805e2022-01-28 15:46:40 -08001844// a) Enumerate all possible concurrency combos by expanding the current
1845// ChipConcurrencyCombination.
1846// b) Check if the requested concurrency type can be added to the current mode.
1847bool WifiChip::canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type) {
1848 // Check if we can support at least 1 of the requested concurrency type.
1849 std::map<IfaceConcurrencyType, size_t> req_iface_combo;
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001850 req_iface_combo[requested_type] = 1;
Quang Luong5d8805e2022-01-28 15:46:40 -08001851 return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001852}
1853
Gabriel Biren631a8112022-12-01 22:29:32 +00001854bool WifiChip::isValidModeId(ChipModeId mode_id) {
Roshan Piuscc338202017-11-02 13:54:09 -07001855 for (const auto& mode : modes_) {
1856 if (mode.id == mode_id) {
1857 return true;
1858 }
1859 }
1860 return false;
1861}
1862
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001863bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
lesl261818b2020-11-27 12:37:35 +08001864 // Check if we can support at least 1 STA & 1 AP concurrently.
Quang Luong5d8805e2022-01-28 15:46:40 -08001865 std::map<IfaceConcurrencyType, size_t> req_iface_combo;
1866 req_iface_combo[IfaceConcurrencyType::STA] = 1;
1867 req_iface_combo[IfaceConcurrencyType::AP] = 1;
1868 return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001869}
1870
lesl261818b2020-11-27 12:37:35 +08001871bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() {
1872 // Check if we can support at least 2 STA concurrently.
Quang Luong5d8805e2022-01-28 15:46:40 -08001873 std::map<IfaceConcurrencyType, size_t> req_iface_combo;
1874 req_iface_combo[IfaceConcurrencyType::STA] = 2;
1875 return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
James Mattisd2e4c072019-05-22 16:14:48 -07001876}
1877
Roshan Pius6036c022019-03-27 10:41:58 -07001878std::string WifiChip::getFirstActiveWlanIfaceName() {
Roshan Pius444473f2019-04-19 08:41:20 -07001879 if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName();
leslf012b652021-01-08 15:22:49 +08001880 if (ap_ifaces_.size() > 0) {
1881 // If the first active wlan iface is bridged iface.
1882 // Return first instance name.
1883 for (auto const& it : br_ifaces_ap_instances_) {
1884 if (it.first == ap_ifaces_[0]->getName()) {
1885 return it.second[0];
1886 }
1887 }
1888 return ap_ifaces_[0]->getName();
1889 }
Roshan Pius6036c022019-03-27 10:41:58 -07001890 // This could happen if the chip call is made before any STA/AP
1891 // iface is created. Default to wlan0 for such cases.
Roshan Pius444473f2019-04-19 08:41:20 -07001892 LOG(WARNING) << "No active wlan interfaces in use! Using default";
Jimmy Chen2dddd792019-12-23 17:50:39 +02001893 return getWlanIfaceNameWithType(IfaceType::STA, 0);
Roshan Pius6036c022019-03-27 10:41:58 -07001894}
1895
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001896// Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx|
1897// not already in use.
1898// Note: This doesn't check the actual presence of these interfaces.
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001899std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx) {
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001900 for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
Jimmy Chen2dddd792019-12-23 17:50:39 +02001901 const auto ifname = getWlanIfaceNameWithType(type, idx);
lesl94d28242020-11-18 22:17:37 +08001902 if (findUsingNameFromBridgedApInstances(ifname)) continue;
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -08001903 if (findUsingName(ap_ifaces_, ifname)) continue;
1904 if (findUsingName(sta_ifaces_, ifname)) continue;
1905 return ifname;
Roshan Pius8e3c7ef2017-11-03 09:43:08 -07001906 }
1907 // This should never happen. We screwed up somewhere if it did.
Tomasz Wasilczyk77401d32018-12-20 12:42:54 -08001908 CHECK(false) << "All wlan interfaces in use already!";
Roshan Pius8e3c7ef2017-11-03 09:43:08 -07001909 return {};
1910}
1911
lesl261818b2020-11-27 12:37:35 +08001912uint32_t WifiChip::startIdxOfApIface() {
1913 if (isDualStaConcurrencyAllowedInCurrentMode()) {
1914 // When the HAL support dual STAs, AP should start with idx 2.
1915 return 2;
1916 } else if (isStaApConcurrencyAllowedInCurrentMode()) {
1917 // When the HAL support STA + AP but it doesn't support dual STAs.
1918 // AP should start with idx 1.
1919 return 1;
1920 }
1921 // No concurrency support.
1922 return 0;
1923}
1924
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001925// AP iface names start with idx 1 for modes supporting
James Mattisd2e4c072019-05-22 16:14:48 -07001926// concurrent STA and not dual AP, else start with idx 0.
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001927std::string WifiChip::allocateApIfaceName() {
Roshan Pius78cb5992020-04-30 12:39:21 -07001928 // Check if we have a dedicated iface for AP.
Les Lee3ba02e02022-09-07 13:44:06 +08001929 std::vector<std::string> ifnames = getPredefinedApIfaceNames(true);
1930 for (auto const& ifname : ifnames) {
1931 if (findUsingName(ap_ifaces_, ifname)) continue;
1932 return ifname;
Roshan Pius78cb5992020-04-30 12:39:21 -07001933 }
lesl261818b2020-11-27 12:37:35 +08001934 return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
1935}
1936
1937std::vector<std::string> WifiChip::allocateBridgedApInstanceNames() {
1938 // Check if we have a dedicated iface for AP.
1939 std::vector<std::string> instances = getPredefinedApIfaceNames(true);
1940 if (instances.size() == 2) {
1941 return instances;
1942 } else {
1943 int num_ifaces_need_to_allocate = 2 - instances.size();
1944 for (int i = 0; i < num_ifaces_need_to_allocate; i++) {
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001945 std::string instance_name =
1946 allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface() + i);
lesl261818b2020-11-27 12:37:35 +08001947 if (!instance_name.empty()) {
1948 instances.push_back(instance_name);
1949 }
1950 }
1951 }
1952 return instances;
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001953}
1954
1955// STA iface names start with idx 0.
1956// Primary STA iface will always be 0.
1957std::string WifiChip::allocateStaIfaceName() {
Jimmy Chen2dddd792019-12-23 17:50:39 +02001958 return allocateApOrStaIfaceName(IfaceType::STA, 0);
Roshan Piusa3e5b7f2019-03-25 13:52:45 -07001959}
1960
xshu5899e8e2018-01-09 15:36:03 -08001961bool WifiChip::writeRingbufferFilesInternal() {
1962 if (!removeOldFilesInternal()) {
1963 LOG(ERROR) << "Error occurred while deleting old tombstone files";
1964 return false;
1965 }
1966 // write ringbuffers to file
Veerendranath Jakkam25b3a6f2020-04-14 22:04:39 +05301967 {
1968 std::unique_lock<std::mutex> lk(lock_t);
xshuc905ea62021-07-11 19:57:02 -07001969 for (auto& item : ringbuffer_map_) {
1970 Ringbuffer& cur_buffer = item.second;
Veerendranath Jakkam25b3a6f2020-04-14 22:04:39 +05301971 if (cur_buffer.getData().empty()) {
1972 continue;
1973 }
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001974 const std::string file_path_raw = kTombstoneFolderPath + item.first + "XXXXXXXXXX";
Veerendranath Jakkam25b3a6f2020-04-14 22:04:39 +05301975 const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
1976 if (dump_fd == -1) {
1977 PLOG(ERROR) << "create file failed";
1978 return false;
1979 }
1980 unique_fd file_auto_closer(dump_fd);
1981 for (const auto& cur_block : cur_buffer.getData()) {
Sunil Ravi07ef1912022-05-17 18:01:06 -07001982 if (cur_block.size() <= 0 || cur_block.size() > kMaxBufferSizeBytes) {
1983 PLOG(ERROR) << "Ring buffer: " << item.first
1984 << " is corrupted. Invalid block size: " << cur_block.size();
1985 break;
1986 }
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08001987 if (write(dump_fd, cur_block.data(), sizeof(cur_block[0]) * cur_block.size()) ==
1988 -1) {
Veerendranath Jakkam25b3a6f2020-04-14 22:04:39 +05301989 PLOG(ERROR) << "Error writing to file";
1990 }
xshu5899e8e2018-01-09 15:36:03 -08001991 }
xshuc905ea62021-07-11 19:57:02 -07001992 cur_buffer.clear();
xshu5899e8e2018-01-09 15:36:03 -08001993 }
xshu0a0fe512020-07-22 17:53:37 -07001994 // unique_lock unlocked here
xshu5899e8e2018-01-09 15:36:03 -08001995 }
1996 return true;
1997}
1998
Jimmy Chen2dddd792019-12-23 17:50:39 +02001999std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) {
2000 std::string ifname;
2001
2002 // let the legacy hal override the interface name
Ahmed ElArabawy687ce132022-01-11 16:42:48 -08002003 legacy_hal::wifi_error err = legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname);
Jimmy Chen2dddd792019-12-23 17:50:39 +02002004 if (err == legacy_hal::WIFI_SUCCESS) return ifname;
2005
2006 return getWlanIfaceName(idx);
2007}
2008
lesl94d28242020-11-18 22:17:37 +08002009void WifiChip::invalidateAndClearBridgedApAll() {
2010 for (auto const& it : br_ifaces_ap_instances_) {
2011 for (auto const& iface : it.second) {
Roshan Pius8c1a67b2021-03-02 10:00:23 -08002012 iface_util_->removeIfaceFromBridge(it.first, iface);
lesl94d28242020-11-18 22:17:37 +08002013 legacy_hal_.lock()->deleteVirtualInterface(iface);
2014 }
Roshan Pius8c1a67b2021-03-02 10:00:23 -08002015 iface_util_->deleteBridge(it.first);
lesl94d28242020-11-18 22:17:37 +08002016 }
2017 br_ifaces_ap_instances_.clear();
2018}
2019
Gabriel Biren631a8112022-12-01 22:29:32 +00002020void WifiChip::deleteApIface(const std::string& if_name) {
2021 if (if_name.empty()) return;
2022 // delete bridged interfaces if have
lesl94d28242020-11-18 22:17:37 +08002023 for (auto const& it : br_ifaces_ap_instances_) {
Gabriel Biren631a8112022-12-01 22:29:32 +00002024 if (it.first == if_name) {
lesl94d28242020-11-18 22:17:37 +08002025 for (auto const& iface : it.second) {
Gabriel Biren631a8112022-12-01 22:29:32 +00002026 iface_util_->removeIfaceFromBridge(if_name, iface);
lesl94d28242020-11-18 22:17:37 +08002027 legacy_hal_.lock()->deleteVirtualInterface(iface);
2028 }
Gabriel Biren631a8112022-12-01 22:29:32 +00002029 iface_util_->deleteBridge(if_name);
2030 br_ifaces_ap_instances_.erase(if_name);
2031 // ifname is bridged AP, return here.
2032 return;
lesl94d28242020-11-18 22:17:37 +08002033 }
2034 }
Gabriel Biren631a8112022-12-01 22:29:32 +00002035
2036 // No bridged AP case, delete AP iface
2037 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(if_name);
2038 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
2039 LOG(ERROR) << "Failed to remove interface: " << if_name << " "
2040 << legacyErrorToString(legacy_status);
2041 }
lesl94d28242020-11-18 22:17:37 +08002042}
2043
2044bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) {
2045 for (auto const& it : br_ifaces_ap_instances_) {
2046 if (it.first == name) {
2047 return true;
2048 }
2049 for (auto const& iface : it.second) {
2050 if (iface == name) {
2051 return true;
2052 }
2053 }
2054 }
2055 return false;
2056}
2057
Gabriel Biren631a8112022-12-01 22:29:32 +00002058} // namespace implementation
2059} // namespace V1_6
Roshan Pius3c4e8a32016-10-03 14:53:58 -07002060} // namespace wifi
2061} // namespace hardware
2062} // namespace android