1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <fcntl.h>
18
19 #include <android-base/logging.h>
20 #include <android-base/unique_fd.h>
21 #include <cutils/properties.h>
22 #include <net/if.h>
23 #include <sys/stat.h>
24 #include <sys/sysmacros.h>
25
26 #include "hidl_return_util.h"
27 #include "hidl_struct_util.h"
28 #include "wifi_chip.h"
29 #include "wifi_status_util.h"
30
31 #define P2P_MGMT_DEVICE_PREFIX "p2p-dev-"
32
33 namespace {
34 using android::sp;
35 using android::base::unique_fd;
36 using android::hardware::hidl_string;
37 using android::hardware::hidl_vec;
38 using android::hardware::wifi::V1_0::ChipModeId;
39 using android::hardware::wifi::V1_0::IfaceType;
40 using android::hardware::wifi::V1_0::IWifiChip;
41
42 constexpr char kCpioMagic[] = "070701";
43 constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3;
44 constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10;
45 constexpr uint32_t kMaxRingBufferFileNum = 20;
46 constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
47 constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface";
48 constexpr char kNoActiveWlanIfaceNamePropertyValue[] = "";
49 constexpr unsigned kMaxWlanIfaces = 5;
50 constexpr char kApBridgeIfacePrefix[] = "ap_br_";
51
52 template <typename Iface>
invalidateAndClear(std::vector<sp<Iface>> & ifaces,sp<Iface> iface)53 void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
54 iface->invalidate();
55 ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), ifaces.end());
56 }
57
58 template <typename Iface>
invalidateAndClearAll(std::vector<sp<Iface>> & ifaces)59 void invalidateAndClearAll(std::vector<sp<Iface>>& ifaces) {
60 for (const auto& iface : ifaces) {
61 iface->invalidate();
62 }
63 ifaces.clear();
64 }
65
66 template <typename Iface>
getNames(std::vector<sp<Iface>> & ifaces)67 std::vector<hidl_string> getNames(std::vector<sp<Iface>>& ifaces) {
68 std::vector<hidl_string> names;
69 for (const auto& iface : ifaces) {
70 names.emplace_back(iface->getName());
71 }
72 return names;
73 }
74
75 template <typename Iface>
findUsingName(std::vector<sp<Iface>> & ifaces,const std::string & name)76 sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces, const std::string& name) {
77 std::vector<hidl_string> names;
78 for (const auto& iface : ifaces) {
79 if (name == iface->getName()) {
80 return iface;
81 }
82 }
83 return nullptr;
84 }
85
getWlanIfaceName(unsigned idx)86 std::string getWlanIfaceName(unsigned idx) {
87 if (idx >= kMaxWlanIfaces) {
88 CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
89 return {};
90 }
91
92 std::array<char, PROPERTY_VALUE_MAX> buffer;
93 if (idx == 0 || idx == 1) {
94 const char* altPropName = (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
95 auto res = property_get(altPropName, buffer.data(), nullptr);
96 if (res > 0) return buffer.data();
97 }
98 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();
101
102 return "wlan" + std::to_string(idx);
103 }
104
105 // Returns the dedicated iface name if defined.
106 // Returns two ifaces in bridged mode.
getPredefinedApIfaceNames(bool is_bridged)107 std::vector<std::string> getPredefinedApIfaceNames(bool is_bridged) {
108 std::vector<std::string> ifnames;
109 std::array<char, PROPERTY_VALUE_MAX> buffer;
110 buffer.fill(0);
111 if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) == 0) {
112 return ifnames;
113 }
114 ifnames.push_back(buffer.data());
115 if (is_bridged) {
116 buffer.fill(0);
117 if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(), nullptr) == 0) {
118 return ifnames;
119 }
120 ifnames.push_back(buffer.data());
121 }
122 return ifnames;
123 }
124
getPredefinedP2pIfaceName()125 std::string getPredefinedP2pIfaceName() {
126 std::array<char, PROPERTY_VALUE_MAX> primaryIfaceName;
127 char p2pParentIfname[100];
128 std::string p2pDevIfName = "";
129 std::array<char, PROPERTY_VALUE_MAX> buffer;
130 property_get("wifi.direct.interface", buffer.data(), "p2p0");
131 if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX, strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
132 /* Get the p2p parent interface name from p2p device interface name set
133 * in property */
134 strlcpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX),
135 strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX));
136 if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(), nullptr) == 0) {
137 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(),
142 strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) != 0) {
143 /*
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();
149 LOG(INFO) << "update the p2p device interface name to " << p2pDevIfName.c_str();
150 return p2pDevIfName;
151 }
152 }
153 return buffer.data();
154 }
155
156 // Returns the dedicated iface name if one is defined.
getPredefinedNanIfaceName()157 std::string getPredefinedNanIfaceName() {
158 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
setActiveWlanIfaceNameProperty(const std::string & ifname)165 void 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
172 // delete files that meet either conditions:
173 // 1. older than a predefined time in the wifi tombstone dir.
174 // 2. Files in excess to a predefined amount, starting from the oldest ones
removeOldFilesInternal()175 bool removeOldFilesInternal() {
176 time_t now = time(0);
177 const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
178 std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(kTombstoneFolderPath), closedir);
179 if (!dir_dump) {
180 PLOG(ERROR) << "Failed to open directory";
181 return false;
182 }
183 struct dirent* dp;
184 bool success = true;
185 std::list<std::pair<const time_t, std::string>> valid_files;
186 while ((dp = readdir(dir_dump.get()))) {
187 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;
193 if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) {
194 PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
195 success = false;
196 continue;
197 }
198 const time_t cur_file_time = cur_file_stat.st_mtime;
199 valid_files.push_back(std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
200 }
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) {
205 if (cur_file_count > kMaxRingBufferFileNum || cur_file.first < delete_files_before) {
206 if (unlink(cur_file.second.c_str()) != 0) {
207 PLOG(ERROR) << "Error deleting file";
208 success = false;
209 }
210 cur_file_count--;
211 } else {
212 break;
213 }
214 }
215 return success;
216 }
217
218 // Helper function for |cpioArchiveFilesInDir|
cpioWriteHeader(int out_fd,struct stat & st,const char * file_name,size_t file_name_len)219 bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, size_t file_name_len) {
220 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) {
229 PLOG(ERROR) << "Error writing cpio header to file " << file_name;
230 return false;
231 }
232 if (write(out_fd, file_name, file_name_len) == -1) {
233 PLOG(ERROR) << "Error writing filename to file " << file_name;
234 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) {
242 PLOG(ERROR) << "Error padding 0s to file " << file_name;
243 return false;
244 }
245 }
246 return true;
247 }
248
249 // Helper function for |cpioArchiveFilesInDir|
cpioWriteFileContent(int fd_read,int out_fd,struct stat & st)250 size_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) {
258 PLOG(ERROR) << "Error reading file";
259 return ++n_error;
260 }
261 llen -= bytes_read;
262 if (write(out_fd, read_buf.data(), bytes_read) == -1) {
263 PLOG(ERROR) << "Error writing data to file";
264 return ++n_error;
265 }
266 if (bytes_read == 0) { // this should never happen, but just in case
267 // to unstuck from while loop
268 PLOG(ERROR) << "Unexpected read result";
269 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) {
277 PLOG(ERROR) << "Error padding 0s to file";
278 return ++n_error;
279 }
280 }
281 return n_error;
282 }
283
284 // Helper function for |cpioArchiveFilesInDir|
cpioWriteFileTrailer(int out_fd)285 bool cpioWriteFileTrailer(int out_fd) {
286 const int buf_size = 4096;
287 std::array<char, buf_size> read_buf;
288 read_buf.fill(0);
289 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) {
291 PLOG(ERROR) << "Error writing trailing bytes";
292 return false;
293 }
294 return true;
295 }
296
297 // 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
cpioArchiveFilesInDir(int out_fd,const char * input_dir)300 size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) {
301 struct dirent* dp;
302 size_t n_error = 0;
303 std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir), closedir);
304 if (!dir_dump) {
305 PLOG(ERROR) << "Failed to open directory";
306 return ++n_error;
307 }
308 while ((dp = readdir(dir_dump.get()))) {
309 if (dp->d_type != DT_REG) {
310 continue;
311 }
312 std::string cur_file_name(dp->d_name);
313 struct stat st;
314 const std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
315 if (stat(cur_file_path.c_str(), &st) == -1) {
316 PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
317 n_error++;
318 continue;
319 }
320 const int fd_read = open(cur_file_path.c_str(), O_RDONLY);
321 if (fd_read == -1) {
322 PLOG(ERROR) << "Failed to open file " << cur_file_path;
323 n_error++;
324 continue;
325 }
326 std::string file_name_with_last_modified_time =
327 cur_file_name + "-" + std::to_string(st.st_mtime);
328 // string.size() does not include the null terminator. The cpio FreeBSD
329 // file header expects the null character to be included in the length.
330 const size_t file_name_len = file_name_with_last_modified_time.size() + 1;
331 unique_fd file_auto_closer(fd_read);
332 if (!cpioWriteHeader(out_fd, st, file_name_with_last_modified_time.c_str(),
333 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;
339 }
340 }
341 if (!cpioWriteFileTrailer(out_fd)) {
342 return ++n_error;
343 }
344 return n_error;
345 }
346
347 // Helper function to create a non-const char*.
makeCharVec(const std::string & str)348 std::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
355 } // namespace
356
357 namespace android {
358 namespace hardware {
359 namespace wifi {
360 namespace V1_6 {
361 namespace implementation {
362 using hidl_return_util::validateAndCall;
363 using hidl_return_util::validateAndCallWithLock;
364
WifiChip(ChipId chip_id,bool is_primary,const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,const std::weak_ptr<mode_controller::WifiModeController> mode_controller,const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,const std::function<void (const std::string &)> & handler)365 WifiChip::WifiChip(ChipId chip_id, bool is_primary,
366 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)
371 : chip_id_(chip_id),
372 legacy_hal_(legacy_hal),
373 mode_controller_(mode_controller),
374 iface_util_(iface_util),
375 is_valid_(true),
376 current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
377 modes_(feature_flags.lock()->getChipModes(is_primary)),
378 debug_ring_buffer_cb_registered_(false),
379 subsystemCallbackHandler_(handler) {
380 setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
381 }
382
invalidate()383 void WifiChip::invalidate() {
384 if (!writeRingbufferFilesInternal()) {
385 LOG(ERROR) << "Error writing files to flash";
386 }
387 invalidateAndRemoveAllIfaces();
388 setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
389 legacy_hal_.reset();
390 event_cb_handler_.invalidate();
391 is_valid_ = false;
392 }
393
isValid()394 bool WifiChip::isValid() {
395 return is_valid_;
396 }
397
getEventCallbacks()398 std::set<sp<V1_4::IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
399 return event_cb_handler_.getCallbacks();
400 }
401
getId(getId_cb hidl_status_cb)402 Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
403 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, &WifiChip::getIdInternal,
404 hidl_status_cb);
405 }
406
407 // Deprecated support for this callback
registerEventCallback(const sp<V1_0::IWifiChipEventCallback> & event_callback,registerEventCallback_cb hidl_status_cb)408 Return<void> WifiChip::registerEventCallback(const sp<V1_0::IWifiChipEventCallback>& event_callback,
409 registerEventCallback_cb hidl_status_cb) {
410 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
411 &WifiChip::registerEventCallbackInternal, hidl_status_cb,
412 event_callback);
413 }
414
getCapabilities(getCapabilities_cb hidl_status_cb)415 Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
416 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
417 &WifiChip::getCapabilitiesInternal, hidl_status_cb);
418 }
419
getAvailableModes(getAvailableModes_cb hidl_status_cb)420 Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
421 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
422 &WifiChip::getAvailableModesInternal, hidl_status_cb);
423 }
424
configureChip(ChipModeId mode_id,configureChip_cb hidl_status_cb)425 Return<void> WifiChip::configureChip(ChipModeId mode_id, configureChip_cb hidl_status_cb) {
426 return validateAndCallWithLock(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
427 &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
428 }
429
getMode(getMode_cb hidl_status_cb)430 Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
431 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
432 &WifiChip::getModeInternal, hidl_status_cb);
433 }
434
requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb)435 Return<void> WifiChip::requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb) {
436 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
437 &WifiChip::requestChipDebugInfoInternal, hidl_status_cb);
438 }
439
requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb)440 Return<void> WifiChip::requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb) {
441 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
442 &WifiChip::requestDriverDebugDumpInternal, hidl_status_cb);
443 }
444
requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb)445 Return<void> WifiChip::requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb) {
446 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
447 &WifiChip::requestFirmwareDebugDumpInternal, hidl_status_cb);
448 }
449
createApIface(createApIface_cb hidl_status_cb)450 Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
451 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
452 &WifiChip::createApIfaceInternal, hidl_status_cb);
453 }
454
createBridgedApIface(createBridgedApIface_cb hidl_status_cb)455 Return<void> WifiChip::createBridgedApIface(createBridgedApIface_cb hidl_status_cb) {
456 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
457 &WifiChip::createBridgedApIfaceInternal, hidl_status_cb);
458 }
459
getApIfaceNames(getApIfaceNames_cb hidl_status_cb)460 Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
461 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
462 &WifiChip::getApIfaceNamesInternal, hidl_status_cb);
463 }
464
getApIface(const hidl_string & ifname,getApIface_cb hidl_status_cb)465 Return<void> WifiChip::getApIface(const hidl_string& ifname, getApIface_cb hidl_status_cb) {
466 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
467 &WifiChip::getApIfaceInternal, hidl_status_cb, ifname);
468 }
469
removeApIface(const hidl_string & ifname,removeApIface_cb hidl_status_cb)470 Return<void> WifiChip::removeApIface(const hidl_string& ifname, removeApIface_cb hidl_status_cb) {
471 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
472 &WifiChip::removeApIfaceInternal, hidl_status_cb, ifname);
473 }
474
removeIfaceInstanceFromBridgedApIface(const hidl_string & ifname,const hidl_string & ifInstanceName,removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb)475 Return<void> WifiChip::removeIfaceInstanceFromBridgedApIface(
476 const hidl_string& ifname, const hidl_string& ifInstanceName,
477 removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) {
478 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
479 &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal, hidl_status_cb,
480 ifname, ifInstanceName);
481 }
482
createNanIface(createNanIface_cb hidl_status_cb)483 Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
484 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
485 &WifiChip::createNanIfaceInternal, hidl_status_cb);
486 }
487
getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb)488 Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
489 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
490 &WifiChip::getNanIfaceNamesInternal, hidl_status_cb);
491 }
492
getNanIface(const hidl_string & ifname,getNanIface_cb hidl_status_cb)493 Return<void> WifiChip::getNanIface(const hidl_string& ifname, getNanIface_cb hidl_status_cb) {
494 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
495 &WifiChip::getNanIfaceInternal, hidl_status_cb, ifname);
496 }
497
removeNanIface(const hidl_string & ifname,removeNanIface_cb hidl_status_cb)498 Return<void> WifiChip::removeNanIface(const hidl_string& ifname, removeNanIface_cb hidl_status_cb) {
499 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
500 &WifiChip::removeNanIfaceInternal, hidl_status_cb, ifname);
501 }
502
createP2pIface(createP2pIface_cb hidl_status_cb)503 Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
504 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
505 &WifiChip::createP2pIfaceInternal, hidl_status_cb);
506 }
507
getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb)508 Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
509 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
510 &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb);
511 }
512
getP2pIface(const hidl_string & ifname,getP2pIface_cb hidl_status_cb)513 Return<void> WifiChip::getP2pIface(const hidl_string& ifname, getP2pIface_cb hidl_status_cb) {
514 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
515 &WifiChip::getP2pIfaceInternal, hidl_status_cb, ifname);
516 }
517
removeP2pIface(const hidl_string & ifname,removeP2pIface_cb hidl_status_cb)518 Return<void> WifiChip::removeP2pIface(const hidl_string& ifname, removeP2pIface_cb hidl_status_cb) {
519 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
520 &WifiChip::removeP2pIfaceInternal, hidl_status_cb, ifname);
521 }
522
createStaIface(createStaIface_cb hidl_status_cb)523 Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
524 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
525 &WifiChip::createStaIfaceInternal, hidl_status_cb);
526 }
527
getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb)528 Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
529 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
530 &WifiChip::getStaIfaceNamesInternal, hidl_status_cb);
531 }
532
getStaIface(const hidl_string & ifname,getStaIface_cb hidl_status_cb)533 Return<void> WifiChip::getStaIface(const hidl_string& ifname, getStaIface_cb hidl_status_cb) {
534 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
535 &WifiChip::getStaIfaceInternal, hidl_status_cb, ifname);
536 }
537
removeStaIface(const hidl_string & ifname,removeStaIface_cb hidl_status_cb)538 Return<void> WifiChip::removeStaIface(const hidl_string& ifname, removeStaIface_cb hidl_status_cb) {
539 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
540 &WifiChip::removeStaIfaceInternal, hidl_status_cb, ifname);
541 }
542
createRttController(const sp<IWifiIface> & bound_iface,createRttController_cb hidl_status_cb)543 Return<void> WifiChip::createRttController(const sp<IWifiIface>& bound_iface,
544 createRttController_cb hidl_status_cb) {
545 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
546 &WifiChip::createRttControllerInternal, hidl_status_cb, bound_iface);
547 }
548
getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb)549 Return<void> WifiChip::getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb) {
550 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
551 &WifiChip::getDebugRingBuffersStatusInternal, hidl_status_cb);
552 }
553
startLoggingToDebugRingBuffer(const hidl_string & ring_name,WifiDebugRingBufferVerboseLevel verbose_level,uint32_t max_interval_in_sec,uint32_t min_data_size_in_bytes,startLoggingToDebugRingBuffer_cb hidl_status_cb)554 Return<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) {
558 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
559 &WifiChip::startLoggingToDebugRingBufferInternal, hidl_status_cb,
560 ring_name, verbose_level, max_interval_in_sec, min_data_size_in_bytes);
561 }
562
forceDumpToDebugRingBuffer(const hidl_string & ring_name,forceDumpToDebugRingBuffer_cb hidl_status_cb)563 Return<void> WifiChip::forceDumpToDebugRingBuffer(const hidl_string& ring_name,
564 forceDumpToDebugRingBuffer_cb hidl_status_cb) {
565 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
566 &WifiChip::forceDumpToDebugRingBufferInternal, hidl_status_cb,
567 ring_name);
568 }
569
flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb)570 Return<void> WifiChip::flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb) {
571 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
572 &WifiChip::flushRingBufferToFileInternal, hidl_status_cb);
573 }
574
stopLoggingToDebugRingBuffer(stopLoggingToDebugRingBuffer_cb hidl_status_cb)575 Return<void> WifiChip::stopLoggingToDebugRingBuffer(
576 stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
577 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
578 &WifiChip::stopLoggingToDebugRingBufferInternal, hidl_status_cb);
579 }
580
getDebugHostWakeReasonStats(getDebugHostWakeReasonStats_cb hidl_status_cb)581 Return<void> WifiChip::getDebugHostWakeReasonStats(getDebugHostWakeReasonStats_cb hidl_status_cb) {
582 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
583 &WifiChip::getDebugHostWakeReasonStatsInternal, hidl_status_cb);
584 }
585
enableDebugErrorAlerts(bool enable,enableDebugErrorAlerts_cb hidl_status_cb)586 Return<void> WifiChip::enableDebugErrorAlerts(bool enable,
587 enableDebugErrorAlerts_cb hidl_status_cb) {
588 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
589 &WifiChip::enableDebugErrorAlertsInternal, hidl_status_cb, enable);
590 }
591
selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario,selectTxPowerScenario_cb hidl_status_cb)592 Return<void> WifiChip::selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario,
593 selectTxPowerScenario_cb hidl_status_cb) {
594 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
595 &WifiChip::selectTxPowerScenarioInternal, hidl_status_cb, scenario);
596 }
597
resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb)598 Return<void> WifiChip::resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb) {
599 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
600 &WifiChip::resetTxPowerScenarioInternal, hidl_status_cb);
601 }
602
setLatencyMode(LatencyMode mode,setLatencyMode_cb hidl_status_cb)603 Return<void> WifiChip::setLatencyMode(LatencyMode mode, setLatencyMode_cb hidl_status_cb) {
604 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
605 &WifiChip::setLatencyModeInternal, hidl_status_cb, mode);
606 }
607
registerEventCallback_1_2(const sp<V1_2::IWifiChipEventCallback> & event_callback,registerEventCallback_cb hidl_status_cb)608 Return<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
selectTxPowerScenario_1_2(TxPowerScenario scenario,selectTxPowerScenario_cb hidl_status_cb)616 Return<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
getCapabilities_1_3(getCapabilities_cb hidl_status_cb)622 Return<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
getCapabilities_1_5(getCapabilities_1_5_cb hidl_status_cb)627 Return<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
debug(const hidl_handle & handle,const hidl_vec<hidl_string> &)632 Return<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
640 }
641 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";
654 }
655 return Void();
656 }
657
createRttController_1_4(const sp<IWifiIface> & bound_iface,createRttController_1_4_cb hidl_status_cb)658 Return<void> WifiChip::createRttController_1_4(const sp<IWifiIface>& bound_iface,
659 createRttController_1_4_cb hidl_status_cb) {
660 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
661 &WifiChip::createRttControllerInternal_1_4, hidl_status_cb, bound_iface);
662 }
663
registerEventCallback_1_4(const sp<V1_4::IWifiChipEventCallback> & event_callback,registerEventCallback_cb hidl_status_cb)664 Return<void> WifiChip::registerEventCallback_1_4(
665 const sp<V1_4::IWifiChipEventCallback>& event_callback,
666 registerEventCallback_cb hidl_status_cb) {
667 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
668 &WifiChip::registerEventCallbackInternal_1_4, hidl_status_cb,
669 event_callback);
670 }
671
setMultiStaPrimaryConnection(const hidl_string & ifname,setMultiStaPrimaryConnection_cb hidl_status_cb)672 Return<void> WifiChip::setMultiStaPrimaryConnection(
673 const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) {
674 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
675 &WifiChip::setMultiStaPrimaryConnectionInternal, hidl_status_cb, ifname);
676 }
677
setMultiStaUseCase(MultiStaUseCase use_case,setMultiStaUseCase_cb hidl_status_cb)678 Return<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
setCoexUnsafeChannels(const hidl_vec<CoexUnsafeChannel> & unsafeChannels,hidl_bitfield<CoexRestriction> restrictions,setCoexUnsafeChannels_cb hidl_status_cb)684 Return<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
setCountryCode(const hidl_array<int8_t,2> & code,setCountryCode_cb hidl_status_cb)692 Return<void> WifiChip::setCountryCode(const hidl_array<int8_t, 2>& code,
693 setCountryCode_cb hidl_status_cb) {
694 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
695 &WifiChip::setCountryCodeInternal, hidl_status_cb, code);
696 }
697
getUsableChannels(WifiBand band,hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,hidl_bitfield<V1_5::IWifiChip::UsableChannelFilter> filterMask,getUsableChannels_cb _hidl_cb)698 Return<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) {
702 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
703 &WifiChip::getUsableChannelsInternal, _hidl_cb, band, ifaceModeMask,
704 filterMask);
705 }
706
triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb)707 Return<void> WifiChip::triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb) {
708 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
709 &WifiChip::triggerSubsystemRestartInternal, hidl_status_cb);
710 }
711
createRttController_1_6(const sp<IWifiIface> & bound_iface,createRttController_1_6_cb hidl_status_cb)712 Return<void> WifiChip::createRttController_1_6(const sp<IWifiIface>& bound_iface,
713 createRttController_1_6_cb hidl_status_cb) {
714 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
715 &WifiChip::createRttControllerInternal_1_6, hidl_status_cb, bound_iface);
716 }
717
getUsableChannels_1_6(WifiBand band,hidl_bitfield<V1_5::WifiIfaceMode> ifaceModeMask,hidl_bitfield<V1_6::IWifiChip::UsableChannelFilter> filterMask,getUsableChannels_1_6_cb _hidl_cb)718 Return<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
getSupportedRadioCombinationsMatrix(getSupportedRadioCombinationsMatrix_cb hidl_status_cb)727 Return<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
getAvailableModes_1_6(getAvailableModes_1_6_cb hidl_status_cb)733 Return<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);
736 }
737
invalidateAndRemoveAllIfaces()738 void WifiChip::invalidateAndRemoveAllIfaces() {
739 invalidateAndClearBridgedApAll();
740 invalidateAndClearAll(ap_ifaces_);
741 invalidateAndClearAll(nan_ifaces_);
742 invalidateAndClearAll(p2p_ifaces_);
743 invalidateAndClearAll(sta_ifaces_);
744 // 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();
750 }
751
invalidateAndRemoveDependencies(const std::string & removed_iface_name)752 void WifiChip::invalidateAndRemoveDependencies(const std::string& removed_iface_name) {
753 for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) {
754 auto nan_iface = *it;
755 if (nan_iface->getName() == removed_iface_name) {
756 nan_iface->invalidate();
757 for (const auto& callback : event_cb_handler_.getCallbacks()) {
758 if (!callback->onIfaceRemoved(IfaceType::NAN, removed_iface_name).isOk()) {
759 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
760 }
761 }
762 it = nan_ifaces_.erase(it);
763 } else {
764 ++it;
765 }
766 }
767
768 for (auto it = rtt_controllers_.begin(); it != rtt_controllers_.end();) {
769 auto rtt = *it;
770 if (rtt->getIfaceName() == removed_iface_name) {
771 rtt->invalidate();
772 it = rtt_controllers_.erase(it);
773 } else {
774 ++it;
775 }
776 }
777 }
778
getIdInternal()779 std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
780 return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
781 }
782
registerEventCallbackInternal(const sp<V1_0::IWifiChipEventCallback> &)783 WifiStatus WifiChip::registerEventCallbackInternal(
784 const sp<V1_0::IWifiChipEventCallback>& /* event_callback */) {
785 // Deprecated support for this callback.
786 return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
787 }
788
getCapabilitiesInternal()789 std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
790 // Deprecated support for this callback.
791 return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
792 }
793
794 std::pair<WifiStatus, std::vector<V1_0::IWifiChip::ChipMode>>
getAvailableModesInternal()795 WifiChip::getAvailableModesInternal() {
796 // 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};
847 }
848
configureChipInternal(std::unique_lock<std::recursive_mutex> * lock,ChipModeId mode_id)849 WifiStatus WifiChip::configureChipInternal(
850 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) {
851 if (!isValidModeId(mode_id)) {
852 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
853 }
854 if (mode_id == current_mode_id_) {
855 LOG(DEBUG) << "Already in the specified mode " << mode_id;
856 return createWifiStatus(WifiStatusCode::SUCCESS);
857 }
858 WifiStatus status = handleChipConfiguration(lock, mode_id);
859 if (status.code != WifiStatusCode::SUCCESS) {
860 for (const auto& callback : event_cb_handler_.getCallbacks()) {
861 if (!callback->onChipReconfigureFailure(status).isOk()) {
862 LOG(ERROR) << "Failed to invoke onChipReconfigureFailure callback";
863 }
864 }
865 return status;
866 }
867 for (const auto& callback : event_cb_handler_.getCallbacks()) {
868 if (!callback->onChipReconfigured(mode_id).isOk()) {
869 LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
870 }
871 }
872 current_mode_id_ = mode_id;
873 LOG(INFO) << "Configured chip in mode " << mode_id;
874 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
875
876 legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(subsystemCallbackHandler_);
877
878 return status;
879 }
880
getModeInternal()881 std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
882 if (!isValidModeId(current_mode_id_)) {
883 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), current_mode_id_};
884 }
885 return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
886 }
887
requestChipDebugInfoInternal()888 std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo> WifiChip::requestChipDebugInfoInternal() {
889 V1_4::IWifiChip::ChipDebugInfo result;
890 legacy_hal::wifi_error legacy_status;
891 std::string driver_desc;
892 const auto ifname = getFirstActiveWlanIfaceName();
893 std::tie(legacy_status, driver_desc) = legacy_hal_.lock()->getDriverVersion(ifname);
894 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
895 LOG(ERROR) << "Failed to get driver version: " << legacyErrorToString(legacy_status);
896 WifiStatus status =
897 createWifiStatusFromLegacyError(legacy_status, "failed to get driver version");
898 return {status, result};
899 }
900 result.driverDescription = driver_desc.c_str();
901
902 std::string firmware_desc;
903 std::tie(legacy_status, firmware_desc) = legacy_hal_.lock()->getFirmwareVersion(ifname);
904 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
905 LOG(ERROR) << "Failed to get firmware version: " << legacyErrorToString(legacy_status);
906 WifiStatus status =
907 createWifiStatusFromLegacyError(legacy_status, "failed to get firmware version");
908 return {status, result};
909 }
910 result.firmwareDescription = firmware_desc.c_str();
911
912 return {createWifiStatus(WifiStatusCode::SUCCESS), result};
913 }
914
requestDriverDebugDumpInternal()915 std::pair<WifiStatus, std::vector<uint8_t>> WifiChip::requestDriverDebugDumpInternal() {
916 legacy_hal::wifi_error legacy_status;
917 std::vector<uint8_t> driver_dump;
918 std::tie(legacy_status, driver_dump) =
919 legacy_hal_.lock()->requestDriverMemoryDump(getFirstActiveWlanIfaceName());
920 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
921 LOG(ERROR) << "Failed to get driver debug dump: " << legacyErrorToString(legacy_status);
922 return {createWifiStatusFromLegacyError(legacy_status), std::vector<uint8_t>()};
923 }
924 return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
925 }
926
requestFirmwareDebugDumpInternal()927 std::pair<WifiStatus, std::vector<uint8_t>> WifiChip::requestFirmwareDebugDumpInternal() {
928 legacy_hal::wifi_error legacy_status;
929 std::vector<uint8_t> firmware_dump;
930 std::tie(legacy_status, firmware_dump) =
931 legacy_hal_.lock()->requestFirmwareMemoryDump(getFirstActiveWlanIfaceName());
932 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
933 LOG(ERROR) << "Failed to get firmware debug dump: " << legacyErrorToString(legacy_status);
934 return {createWifiStatusFromLegacyError(legacy_status), {}};
935 }
936 return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
937 }
938
createVirtualApInterface(const std::string & apVirtIf)939 WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) {
940 legacy_hal::wifi_error legacy_status;
941 legacy_status = legacy_hal_.lock()->createVirtualInterface(
942 apVirtIf, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP));
943 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
944 LOG(ERROR) << "Failed to add interface: " << apVirtIf << " "
945 << legacyErrorToString(legacy_status);
946 return createWifiStatusFromLegacyError(legacy_status);
947 }
948 return createWifiStatus(WifiStatusCode::SUCCESS);
949 }
950
newWifiApIface(std::string & ifname)951 sp<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) {
952 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 }
958 sp<WifiApIface> iface = new WifiApIface(ifname, ap_instances, legacy_hal_, iface_util_);
959 ap_ifaces_.push_back(iface);
960 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 }
965 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
966 return iface;
967 }
968
createApIfaceInternal()969 std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createApIfaceInternal() {
970 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP)) {
971 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
972 }
973 std::string ifname = allocateApIfaceName();
974 WifiStatus status = createVirtualApInterface(ifname);
975 if (status.code != WifiStatusCode::SUCCESS) {
976 return {status, {}};
977 }
978 sp<WifiApIface> iface = newWifiApIface(ifname);
979 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
980 }
981
createBridgedApIfaceInternal()982 std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::createBridgedApIfaceInternal() {
983 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::AP_BRIDGED)) {
984 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
985 }
986 std::vector<std::string> ap_instances = allocateBridgedApInstanceNames();
987 if (ap_instances.size() < 2) {
988 LOG(ERROR) << "Fail to allocate two instances";
989 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
990 }
991 std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0];
992 for (int i = 0; i < 2; i++) {
993 WifiStatus status = createVirtualApInterface(ap_instances[i]);
994 if (status.code != WifiStatusCode::SUCCESS) {
995 if (i != 0) { // The failure happened when creating second virtual
996 // iface.
997 legacy_hal_.lock()->deleteVirtualInterface(
998 ap_instances.front()); // Remove the first virtual iface.
999 }
1000 return {status, {}};
1001 }
1002 }
1003 br_ifaces_ap_instances_[br_ifname] = ap_instances;
1004 if (!iface_util_->createBridge(br_ifname)) {
1005 LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
1006 deleteApIface(br_ifname);
1007 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1008 }
1009 for (auto const& instance : ap_instances) {
1010 // Bind ap instance interface to AP bridge
1011 if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
1012 LOG(ERROR) << "Failed add if to Bridge - if_name=" << instance.c_str();
1013 deleteApIface(br_ifname);
1014 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1015 }
1016 }
1017 sp<WifiApIface> iface = newWifiApIface(br_ifname);
1018 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1019 }
1020
getApIfaceNamesInternal()1021 std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getApIfaceNamesInternal() {
1022 if (ap_ifaces_.empty()) {
1023 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
1024 }
1025 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)};
1026 }
1027
getApIfaceInternal(const std::string & ifname)1028 std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::getApIfaceInternal(
1029 const std::string& ifname) {
1030 const auto iface = findUsingName(ap_ifaces_, ifname);
1031 if (!iface.get()) {
1032 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
1033 }
1034 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1035 }
1036
removeApIfaceInternal(const std::string & ifname)1037 WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
1038 const auto iface = findUsingName(ap_ifaces_, ifname);
1039 if (!iface.get()) {
1040 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1041 }
1042 // 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);
1047 deleteApIface(ifname);
1048 invalidateAndClear(ap_ifaces_, iface);
1049 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 }
1054 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1055 return createWifiStatus(WifiStatusCode::SUCCESS);
1056 }
1057
removeIfaceInstanceFromBridgedApIfaceInternal(const std::string & ifname,const std::string & ifInstanceName)1058 WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
1059 const std::string& ifname, const std::string& ifInstanceName) {
1060 const auto iface = findUsingName(ap_ifaces_, ifname);
1061 if (!iface.get() || ifInstanceName.empty()) {
1062 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) {
1067 std::vector<std::string> ap_instances = it.second;
1068 for (auto const& iface : ap_instances) {
1069 if (iface == ifInstanceName) {
1070 if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
1071 LOG(ERROR) << "Failed to remove interface: " << ifInstanceName << " from "
1072 << ifname;
1073 return createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE);
1074 }
1075 legacy_hal::wifi_error legacy_status =
1076 legacy_hal_.lock()->deleteVirtualInterface(iface);
1077 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1078 LOG(ERROR) << "Failed to del interface: " << iface << " "
1079 << legacyErrorToString(legacy_status);
1080 return createWifiStatusFromLegacyError(legacy_status);
1081 }
1082 ap_instances.erase(
1083 std::remove(ap_instances.begin(), ap_instances.end(), ifInstanceName),
1084 ap_instances.end());
1085 br_ifaces_ap_instances_[ifname] = ap_instances;
1086 break;
1087 }
1088 }
1089 break;
1090 }
1091 }
1092 iface->removeInstance(ifInstanceName);
1093 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1094
1095 return createWifiStatus(WifiStatusCode::SUCCESS);
1096 }
1097
createNanIfaceInternal()1098 std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::createNanIfaceInternal() {
1099 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::NAN)) {
1100 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1101 }
1102 bool is_dedicated_iface = true;
1103 std::string ifname = getPredefinedNanIfaceName();
1104 if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) {
1105 // 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 }
1110 sp<WifiNanIface> iface = new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
1111 nan_ifaces_.push_back(iface);
1112 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1113 if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
1114 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1115 }
1116 }
1117 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1118 }
1119
getNanIfaceNamesInternal()1120 std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getNanIfaceNamesInternal() {
1121 if (nan_ifaces_.empty()) {
1122 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
1123 }
1124 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)};
1125 }
1126
getNanIfaceInternal(const std::string & ifname)1127 std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::getNanIfaceInternal(
1128 const std::string& ifname) {
1129 const auto iface = findUsingName(nan_ifaces_, ifname);
1130 if (!iface.get()) {
1131 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
1132 }
1133 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1134 }
1135
removeNanIfaceInternal(const std::string & ifname)1136 WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
1137 const auto iface = findUsingName(nan_ifaces_, ifname);
1138 if (!iface.get()) {
1139 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1140 }
1141 invalidateAndClear(nan_ifaces_, iface);
1142 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1143 if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
1144 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1145 }
1146 }
1147 return createWifiStatus(WifiStatusCode::SUCCESS);
1148 }
1149
createP2pIfaceInternal()1150 std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
1151 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::P2P)) {
1152 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1153 }
1154 std::string ifname = getPredefinedP2pIfaceName();
1155 sp<WifiP2pIface> iface = new WifiP2pIface(ifname, legacy_hal_);
1156 p2p_ifaces_.push_back(iface);
1157 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 }
1162 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1163 }
1164
getP2pIfaceNamesInternal()1165 std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getP2pIfaceNamesInternal() {
1166 if (p2p_ifaces_.empty()) {
1167 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
1168 }
1169 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)};
1170 }
1171
getP2pIfaceInternal(const std::string & ifname)1172 std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(const std::string& ifname) {
1173 const auto iface = findUsingName(p2p_ifaces_, ifname);
1174 if (!iface.get()) {
1175 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
1176 }
1177 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1178 }
1179
removeP2pIfaceInternal(const std::string & ifname)1180 WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
1181 const auto iface = findUsingName(p2p_ifaces_, ifname);
1182 if (!iface.get()) {
1183 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1184 }
1185 invalidateAndClear(p2p_ifaces_, iface);
1186 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 }
1191 return createWifiStatus(WifiStatusCode::SUCCESS);
1192 }
1193
createStaIfaceInternal()1194 std::pair<WifiStatus, sp<V1_6::IWifiStaIface>> WifiChip::createStaIfaceInternal() {
1195 if (!canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType::STA)) {
1196 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1197 }
1198 std::string ifname = allocateStaIfaceName();
1199 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->createVirtualInterface(
1200 ifname, hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA));
1201 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1202 LOG(ERROR) << "Failed to add interface: " << ifname << " "
1203 << legacyErrorToString(legacy_status);
1204 return {createWifiStatusFromLegacyError(legacy_status), {}};
1205 }
1206 sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_);
1207 sta_ifaces_.push_back(iface);
1208 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 }
1213 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1214 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1215 }
1216
getStaIfaceNamesInternal()1217 std::pair<WifiStatus, std::vector<hidl_string>> WifiChip::getStaIfaceNamesInternal() {
1218 if (sta_ifaces_.empty()) {
1219 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
1220 }
1221 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)};
1222 }
1223
getStaIfaceInternal(const std::string & ifname)1224 std::pair<WifiStatus, sp<V1_6::IWifiStaIface>> WifiChip::getStaIfaceInternal(
1225 const std::string& ifname) {
1226 const auto iface = findUsingName(sta_ifaces_, ifname);
1227 if (!iface.get()) {
1228 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
1229 }
1230 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1231 }
1232
removeStaIfaceInternal(const std::string & ifname)1233 WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
1234 const auto iface = findUsingName(sta_ifaces_, ifname);
1235 if (!iface.get()) {
1236 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1237 }
1238 // Invalidate & remove any dependent objects first.
1239 invalidateAndRemoveDependencies(ifname);
1240 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(ifname);
1241 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1242 LOG(ERROR) << "Failed to remove interface: " << ifname << " "
1243 << legacyErrorToString(legacy_status);
1244 }
1245 invalidateAndClear(sta_ifaces_, iface);
1246 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 }
1251 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1252 return createWifiStatus(WifiStatusCode::SUCCESS);
1253 }
1254
createRttControllerInternal(const sp<IWifiIface> &)1255 std::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), {}};
1259 }
1260
1261 std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
getDebugRingBuffersStatusInternal()1262 WifiChip::getDebugRingBuffersStatusInternal() {
1263 legacy_hal::wifi_error legacy_status;
1264 std::vector<legacy_hal::wifi_ring_buffer_status> legacy_ring_buffer_status_vec;
1265 std::tie(legacy_status, legacy_ring_buffer_status_vec) =
1266 legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
1267 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1268 return {createWifiStatusFromLegacyError(legacy_status), {}};
1269 }
1270 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), {}};
1274 }
1275 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_ring_buffer_status_vec};
1276 }
1277
startLoggingToDebugRingBufferInternal(const hidl_string & ring_name,WifiDebugRingBufferVerboseLevel verbose_level,uint32_t max_interval_in_sec,uint32_t min_data_size_in_bytes)1278 WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
1279 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
1280 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
1281 WifiStatus status = registerDebugRingBufferCallback();
1282 if (status.code != WifiStatusCode::SUCCESS) {
1283 return status;
1284 }
1285 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRingBufferLogging(
1286 getFirstActiveWlanIfaceName(), ring_name,
1287 static_cast<std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(verbose_level),
1288 max_interval_in_sec, min_data_size_in_bytes);
1289 ringbuffer_map_.insert(
1290 std::pair<std::string, Ringbuffer>(ring_name, Ringbuffer(kMaxBufferSizeBytes)));
1291 // if verbose logging enabled, turn up HAL daemon logging as well.
1292 if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
1293 android::base::SetMinimumLogSeverity(android::base::DEBUG);
1294 } else {
1295 android::base::SetMinimumLogSeverity(android::base::VERBOSE);
1296 }
1297 return createWifiStatusFromLegacyError(legacy_status);
1298 }
1299
forceDumpToDebugRingBufferInternal(const hidl_string & ring_name)1300 WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(const hidl_string& ring_name) {
1301 WifiStatus status = registerDebugRingBufferCallback();
1302 if (status.code != WifiStatusCode::SUCCESS) {
1303 return status;
1304 }
1305 legacy_hal::wifi_error legacy_status =
1306 legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(), ring_name);
1307
1308 return createWifiStatusFromLegacyError(legacy_status);
1309 }
1310
flushRingBufferToFileInternal()1311 WifiStatus WifiChip::flushRingBufferToFileInternal() {
1312 if (!writeRingbufferFilesInternal()) {
1313 LOG(ERROR) << "Error writing files to flash";
1314 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1315 }
1316 return createWifiStatus(WifiStatusCode::SUCCESS);
1317 }
1318
stopLoggingToDebugRingBufferInternal()1319 WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
1320 legacy_hal::wifi_error legacy_status =
1321 legacy_hal_.lock()->deregisterRingBufferCallbackHandler(getFirstActiveWlanIfaceName());
1322 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1323 debug_ring_buffer_cb_registered_ = false;
1324 }
1325 return createWifiStatusFromLegacyError(legacy_status);
1326 }
1327
1328 std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
getDebugHostWakeReasonStatsInternal()1329 WifiChip::getDebugHostWakeReasonStatsInternal() {
1330 legacy_hal::wifi_error legacy_status;
1331 legacy_hal::WakeReasonStats legacy_stats;
1332 std::tie(legacy_status, legacy_stats) =
1333 legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
1334 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1335 return {createWifiStatusFromLegacyError(legacy_status), {}};
1336 }
1337 WifiDebugHostWakeReasonStats hidl_stats;
1338 if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats, &hidl_stats)) {
1339 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
1340 }
1341 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
1342 }
1343
enableDebugErrorAlertsInternal(bool enable)1344 WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
1345 legacy_hal::wifi_error legacy_status;
1346 if (enable) {
1347 android::wp<WifiChip> weak_ptr_this(this);
1348 const auto& on_alert_callback = [weak_ptr_this](int32_t error_code,
1349 std::vector<uint8_t> debug_data) {
1350 const auto shared_ptr_this = weak_ptr_this.promote();
1351 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()) {
1356 if (!callback->onDebugErrorAlert(error_code, debug_data).isOk()) {
1357 LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
1358 }
1359 }
1360 };
1361 legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
1362 getFirstActiveWlanIfaceName(), on_alert_callback);
1363 } else {
1364 legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
1365 getFirstActiveWlanIfaceName());
1366 }
1367 return createWifiStatusFromLegacyError(legacy_status);
1368 }
1369
selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario)1370 WifiStatus WifiChip::selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario) {
1371 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
1372 getFirstActiveWlanIfaceName(),
1373 hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
1374 return createWifiStatusFromLegacyError(legacy_status);
1375 }
1376
resetTxPowerScenarioInternal()1377 WifiStatus WifiChip::resetTxPowerScenarioInternal() {
1378 auto legacy_status = legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
1379 return createWifiStatusFromLegacyError(legacy_status);
1380 }
1381
setLatencyModeInternal(LatencyMode mode)1382 WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) {
1383 auto legacy_status = legacy_hal_.lock()->setLatencyMode(
1384 getFirstActiveWlanIfaceName(), hidl_struct_util::convertHidlLatencyModeToLegacy(mode));
1385 return createWifiStatusFromLegacyError(legacy_status);
1386 }
1387
registerEventCallbackInternal_1_2(const sp<V1_2::IWifiChipEventCallback> &)1388 WifiStatus 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
selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario)1394 WifiStatus 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
getCapabilitiesInternal_1_3()1401 std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_3() {
1402 // Deprecated support for this callback.
1403 return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
1404 }
1405
getCapabilitiesInternal_1_5()1406 std::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
createRttControllerInternal_1_4(const sp<IWifiIface> &)1430 std::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
registerEventCallbackInternal_1_4(const sp<V1_4::IWifiChipEventCallback> & event_callback)1436 WifiStatus 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
setMultiStaPrimaryConnectionInternal(const std::string & ifname)1444 WifiStatus WifiChip::setMultiStaPrimaryConnectionInternal(const std::string& ifname) {
1445 auto legacy_status = legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname);
1446 return createWifiStatusFromLegacyError(legacy_status);
1447 }
1448
setMultiStaUseCaseInternal(MultiStaUseCase use_case)1449 WifiStatus WifiChip::setMultiStaUseCaseInternal(MultiStaUseCase use_case) {
1450 auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase(
1451 hidl_struct_util::convertHidlMultiStaUseCaseToLegacy(use_case));
1452 return createWifiStatusFromLegacyError(legacy_status);
1453 }
1454
setCoexUnsafeChannelsInternal(std::vector<CoexUnsafeChannel> unsafe_channels,uint32_t restrictions)1455 WifiStatus WifiChip::setCoexUnsafeChannelsInternal(std::vector<CoexUnsafeChannel> unsafe_channels,
1456 uint32_t restrictions) {
1457 std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels;
1458 if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy(unsafe_channels,
1459 &legacy_unsafe_channels)) {
1460 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1461 }
1462 uint32_t legacy_restrictions = 0;
1463 if (restrictions & CoexRestriction::WIFI_DIRECT) {
1464 legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_DIRECT;
1465 }
1466 if (restrictions & CoexRestriction::SOFTAP) {
1467 legacy_restrictions |= legacy_hal::wifi_coex_restriction::SOFTAP;
1468 }
1469 if (restrictions & CoexRestriction::WIFI_AWARE) {
1470 legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE;
1471 }
1472 auto legacy_status =
1473 legacy_hal_.lock()->setCoexUnsafeChannels(legacy_unsafe_channels, legacy_restrictions);
1474 return createWifiStatusFromLegacyError(legacy_status);
1475 }
1476
setCountryCodeInternal(const std::array<int8_t,2> & code)1477 WifiStatus WifiChip::setCountryCodeInternal(const std::array<int8_t, 2>& code) {
1478 auto legacy_status = legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code);
1479 return createWifiStatusFromLegacyError(legacy_status);
1480 }
1481
getUsableChannelsInternal(WifiBand,uint32_t,uint32_t)1482 std::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
triggerSubsystemRestartInternal()1488 WifiStatus WifiChip::triggerSubsystemRestartInternal() {
1489 auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart();
1490 return createWifiStatusFromLegacyError(legacy_status);
1491 }
1492
createRttControllerInternal_1_6(const sp<IWifiIface> & bound_iface)1493 std::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
getUsableChannelsInternal_1_6(WifiBand band,uint32_t ifaceModeMask,uint32_t filterMask)1507 std::pair<WifiStatus, std::vector<V1_6::WifiUsableChannel>> WifiChip::getUsableChannelsInternal_1_6(
1508 WifiBand band, uint32_t ifaceModeMask, uint32_t filterMask) {
1509 legacy_hal::wifi_error legacy_status;
1510 std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels;
1511 std::tie(legacy_status, legacy_usable_channels) = legacy_hal_.lock()->getUsableChannels(
1512 hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band),
1513 hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask),
1514 hidl_struct_util::convertHidlUsableChannelFilterToLegacy(filterMask));
1515
1516 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1517 return {createWifiStatusFromLegacyError(legacy_status), {}};
1518 }
1519 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), {}};
1523 }
1524 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels};
1525 }
1526
1527 std::pair<WifiStatus, V1_6::WifiRadioCombinationMatrix>
getSupportedRadioCombinationsMatrixInternal()1528 WifiChip::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);
1537 return {createWifiStatusFromLegacyError(legacy_status), {}};
1538 }
1539
1540 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), {}};
1545 }
1546 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_matrix};
1547 }
1548
1549 std::pair<WifiStatus, std::vector<V1_6::IWifiChip::ChipMode>>
getAvailableModesInternal_1_6()1550 WifiChip::getAvailableModesInternal_1_6() {
1551 return {createWifiStatus(WifiStatusCode::SUCCESS), modes_};
1552 }
1553
handleChipConfiguration(std::unique_lock<std::recursive_mutex> * lock,ChipModeId mode_id)1554 WifiStatus WifiChip::handleChipConfiguration(
1555 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id) {
1556 // If the chip is already configured in a different mode, stop
1557 // the legacy HAL and then start it after firmware mode change.
1558 if (isValidModeId(current_mode_id_)) {
1559 LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ << " to mode " << mode_id;
1560 invalidateAndRemoveAllIfaces();
1561 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stop(lock, []() {});
1562 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1563 LOG(ERROR) << "Failed to stop legacy HAL: " << legacyErrorToString(legacy_status);
1564 return createWifiStatusFromLegacyError(legacy_status);
1565 }
1566 }
1567 // Firmware mode change not needed for V2 devices.
1568 bool success = true;
1569 if (mode_id == feature_flags::chip_mode_ids::kV1Sta) {
1570 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
1571 } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) {
1572 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) {
1579 LOG(ERROR) << "Failed to start legacy HAL: " << legacyErrorToString(legacy_status);
1580 return createWifiStatusFromLegacyError(legacy_status);
1581 }
1582 // Every time the HAL is restarted, we need to register the
1583 // radio mode change callback.
1584 WifiStatus status = registerRadioModeChangeCallback();
1585 if (status.code != WifiStatusCode::SUCCESS) {
1586 // This probably is not a critical failure?
1587 LOG(ERROR) << "Failed to register radio mode change callback";
1588 }
1589 // Extract and save the version information into property.
1590 std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo> version_info;
1591 version_info = WifiChip::requestChipDebugInfoInternal();
1592 if (WifiStatusCode::SUCCESS == version_info.first.code) {
1593 property_set("vendor.wlan.firmware.version",
1594 version_info.second.firmwareDescription.c_str());
1595 property_set("vendor.wlan.driver.version", version_info.second.driverDescription.c_str());
1596 }
1597
1598 return createWifiStatus(WifiStatusCode::SUCCESS);
1599 }
1600
registerDebugRingBufferCallback()1601 WifiStatus WifiChip::registerDebugRingBufferCallback() {
1602 if (debug_ring_buffer_cb_registered_) {
1603 return createWifiStatus(WifiStatusCode::SUCCESS);
1604 }
1605
1606 android::wp<WifiChip> weak_ptr_this(this);
1607 const auto& on_ring_buffer_data_callback =
1608 [weak_ptr_this](const std::string& name, const std::vector<uint8_t>& data,
1609 const legacy_hal::wifi_ring_buffer_status& status) {
1610 const auto shared_ptr_this = weak_ptr_this.promote();
1611 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1612 LOG(ERROR) << "Callback invoked on an invalid object";
1613 return;
1614 }
1615 WifiDebugRingBufferStatus hidl_status;
1616 Ringbuffer::AppendStatus appendstatus;
1617 if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(status,
1618 &hidl_status)) {
1619 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;
1627 appendstatus = cur_buffer.append(data);
1628 } else {
1629 LOG(ERROR) << "Ringname " << name << " not found";
1630 return;
1631 }
1632 // unique_lock unlocked here
1633 }
1634 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 }
1639
1640 };
1641 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->registerRingBufferCallbackHandler(
1642 getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback);
1643
1644 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1645 debug_ring_buffer_cb_registered_ = true;
1646 }
1647 return createWifiStatusFromLegacyError(legacy_status);
1648 }
1649
registerRadioModeChangeCallback()1650 WifiStatus WifiChip::registerRadioModeChangeCallback() {
1651 android::wp<WifiChip> weak_ptr_this(this);
1652 const auto& on_radio_mode_change_callback =
1653 [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
1654 const auto shared_ptr_this = weak_ptr_this.promote();
1655 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1656 LOG(ERROR) << "Callback invoked on an invalid object";
1657 return;
1658 }
1659 std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo> hidl_radio_mode_infos;
1660 if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(mac_infos,
1661 &hidl_radio_mode_infos)) {
1662 LOG(ERROR) << "Error converting wifi mac info";
1663 return;
1664 }
1665 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
1666 if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos).isOk()) {
1667 LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4"
1668 << " callback on: " << toString(callback);
1669 }
1670 }
1671 };
1672 legacy_hal::wifi_error legacy_status =
1673 legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
1674 getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
1675 return createWifiStatusFromLegacyError(legacy_status);
1676 }
1677
1678 std::vector<V1_6::IWifiChip::ChipConcurrencyCombination>
getCurrentModeConcurrencyCombinations()1679 WifiChip::getCurrentModeConcurrencyCombinations() {
1680 if (!isValidModeId(current_mode_id_)) {
1681 LOG(ERROR) << "Chip not configured in a mode yet";
1682 return {};
1683 }
1684 for (const auto& mode : modes_) {
1685 if (mode.id == current_mode_id_) {
1686 return mode.availableCombinations;
1687 }
1688 }
1689 CHECK(0) << "Expected to find concurrency combinations for current mode!";
1690 return {};
1691 }
1692
1693 // Returns a map indexed by IfaceConcurrencyType with the number of ifaces currently
1694 // created of the corresponding concurrency type.
getCurrentConcurrencyCombination()1695 std::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;
1710 iface_counts[IfaceConcurrencyType::NAN] = nan_ifaces_.size();
1711 iface_counts[IfaceConcurrencyType::P2P] = p2p_ifaces_.size();
1712 iface_counts[IfaceConcurrencyType::STA] = sta_ifaces_.size();
1713 return iface_counts;
1714 }
1715
1716 // This expands the provided concurrency combinations to a more parseable
1717 // form. Returns a vector of available combinations possible with the number
1718 // of each concurrency type in the combination.
1719 // This method is a port of HalDeviceManager.expandConcurrencyCombos() from framework.
expandConcurrencyCombinations(const V1_6::IWifiChip::ChipConcurrencyCombination & combination)1720 std::vector<std::map<IfaceConcurrencyType, size_t>> WifiChip::expandConcurrencyCombinations(
1721 const V1_6::IWifiChip::ChipConcurrencyCombination& combination) {
1722 uint32_t num_expanded_combos = 1;
1723 for (const auto& limit : combination.limits) {
1724 for (uint32_t i = 0; i < limit.maxIfaces; i++) {
1725 num_expanded_combos *= limit.types.size();
1726 }
1727 }
1728
1729 // Allocate the vector of expanded combos and reset all concurrency type counts to 0
1730 // in each combo.
1731 std::vector<std::map<IfaceConcurrencyType, size_t>> expanded_combos;
1732 expanded_combos.resize(num_expanded_combos);
1733 for (auto& expanded_combo : expanded_combos) {
1734 for (const auto type :
1735 {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
1736 IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
1737 expanded_combo[type] = 0;
1738 }
1739 }
1740 uint32_t span = num_expanded_combos;
1741 for (const auto& limit : combination.limits) {
1742 for (uint32_t i = 0; i < limit.maxIfaces; i++) {
1743 span /= limit.types.size();
1744 for (uint32_t k = 0; k < num_expanded_combos; ++k) {
1745 const auto iface_type = limit.types[(k / span) % limit.types.size()];
1746 expanded_combos[k][iface_type]++;
1747 }
1748 }
1749 }
1750 return expanded_combos;
1751 }
1752
canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(const std::map<IfaceConcurrencyType,size_t> & expanded_combo,IfaceConcurrencyType requested_type)1753 bool WifiChip::canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(
1754 const std::map<IfaceConcurrencyType, size_t>& expanded_combo,
1755 IfaceConcurrencyType requested_type) {
1756 const auto current_combo = getCurrentConcurrencyCombination();
1757
1758 // Check if we have space for 1 more iface of |type| in this combo
1759 for (const auto type :
1760 {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
1761 IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
1762 size_t num_ifaces_needed = current_combo.at(type);
1763 if (type == requested_type) {
1764 num_ifaces_needed++;
1765 }
1766 size_t num_ifaces_allowed = expanded_combo.at(type);
1767 if (num_ifaces_needed > num_ifaces_allowed) {
1768 return false;
1769 }
1770 }
1771 return true;
1772 }
1773
1774 // This method does the following:
1775 // 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.
canCurrentModeSupportConcurrencyTypeWithCurrentTypes(IfaceConcurrencyType requested_type)1779 bool WifiChip::canCurrentModeSupportConcurrencyTypeWithCurrentTypes(
1780 IfaceConcurrencyType requested_type) {
1781 if (!isValidModeId(current_mode_id_)) {
1782 LOG(ERROR) << "Chip not configured in a mode yet";
1783 return false;
1784 }
1785 const auto combinations = getCurrentModeConcurrencyCombinations();
1786 for (const auto& combination : combinations) {
1787 const auto expanded_combos = expandConcurrencyCombinations(combination);
1788 for (const auto& expanded_combo : expanded_combos) {
1789 if (canExpandedConcurrencyComboSupportConcurrencyTypeWithCurrentTypes(expanded_combo,
1790 requested_type)) {
1791 return true;
1792 }
1793 }
1794 }
1795 return false;
1796 }
1797
1798 // Note: This does not consider concurrency types already active. It only checks if the
1799 // provided expanded concurrency combination can support the requested combo.
canExpandedConcurrencyComboSupportConcurrencyCombo(const std::map<IfaceConcurrencyType,size_t> & expanded_combo,const std::map<IfaceConcurrencyType,size_t> & req_combo)1800 bool 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 :
1805 {IfaceConcurrencyType::AP, IfaceConcurrencyType::AP_BRIDGED, IfaceConcurrencyType::NAN,
1806 IfaceConcurrencyType::P2P, IfaceConcurrencyType::STA}) {
1807 if (req_combo.count(type) == 0) {
1808 // Concurrency type not in the req_combo.
1809 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:
1820 // 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
1824 // current mode can support the requested combo.
canCurrentModeSupportConcurrencyCombo(const std::map<IfaceConcurrencyType,size_t> & req_combo)1825 bool WifiChip::canCurrentModeSupportConcurrencyCombo(
1826 const std::map<IfaceConcurrencyType, size_t>& req_combo) {
1827 if (!isValidModeId(current_mode_id_)) {
1828 LOG(ERROR) << "Chip not configured in a mode yet";
1829 return false;
1830 }
1831 const auto combinations = getCurrentModeConcurrencyCombinations();
1832 for (const auto& combination : combinations) {
1833 const auto expanded_combos = expandConcurrencyCombinations(combination);
1834 for (const auto& expanded_combo : expanded_combos) {
1835 if (canExpandedConcurrencyComboSupportConcurrencyCombo(expanded_combo, req_combo)) {
1836 return true;
1837 }
1838 }
1839 }
1840 return false;
1841 }
1842
1843 // This method does the following:
1844 // 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.
canCurrentModeSupportConcurrencyType(IfaceConcurrencyType requested_type)1847 bool 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;
1850 req_iface_combo[requested_type] = 1;
1851 return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
1852 }
1853
isValidModeId(ChipModeId mode_id)1854 bool WifiChip::isValidModeId(ChipModeId mode_id) {
1855 for (const auto& mode : modes_) {
1856 if (mode.id == mode_id) {
1857 return true;
1858 }
1859 }
1860 return false;
1861 }
1862
isStaApConcurrencyAllowedInCurrentMode()1863 bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
1864 // Check if we can support at least 1 STA & 1 AP concurrently.
1865 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);
1869 }
1870
isDualStaConcurrencyAllowedInCurrentMode()1871 bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() {
1872 // Check if we can support at least 2 STA concurrently.
1873 std::map<IfaceConcurrencyType, size_t> req_iface_combo;
1874 req_iface_combo[IfaceConcurrencyType::STA] = 2;
1875 return canCurrentModeSupportConcurrencyCombo(req_iface_combo);
1876 }
1877
getFirstActiveWlanIfaceName()1878 std::string WifiChip::getFirstActiveWlanIfaceName() {
1879 if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName();
1880 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 }
1890 // This could happen if the chip call is made before any STA/AP
1891 // iface is created. Default to wlan0 for such cases.
1892 LOG(WARNING) << "No active wlan interfaces in use! Using default";
1893 return getWlanIfaceNameWithType(IfaceType::STA, 0);
1894 }
1895
1896 // 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.
allocateApOrStaIfaceName(IfaceType type,uint32_t start_idx)1899 std::string WifiChip::allocateApOrStaIfaceName(IfaceType type, uint32_t start_idx) {
1900 for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
1901 const auto ifname = getWlanIfaceNameWithType(type, idx);
1902 if (findUsingNameFromBridgedApInstances(ifname)) continue;
1903 if (findUsingName(ap_ifaces_, ifname)) continue;
1904 if (findUsingName(sta_ifaces_, ifname)) continue;
1905 return ifname;
1906 }
1907 // This should never happen. We screwed up somewhere if it did.
1908 CHECK(false) << "All wlan interfaces in use already!";
1909 return {};
1910 }
1911
startIdxOfApIface()1912 uint32_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
1925 // AP iface names start with idx 1 for modes supporting
1926 // concurrent STA and not dual AP, else start with idx 0.
allocateApIfaceName()1927 std::string WifiChip::allocateApIfaceName() {
1928 // Check if we have a dedicated iface for AP.
1929 std::vector<std::string> ifnames = getPredefinedApIfaceNames(false);
1930 if (!ifnames.empty()) {
1931 return ifnames[0];
1932 }
1933 return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
1934 }
1935
allocateBridgedApInstanceNames()1936 std::vector<std::string> WifiChip::allocateBridgedApInstanceNames() {
1937 // Check if we have a dedicated iface for AP.
1938 std::vector<std::string> instances = getPredefinedApIfaceNames(true);
1939 if (instances.size() == 2) {
1940 return instances;
1941 } else {
1942 int num_ifaces_need_to_allocate = 2 - instances.size();
1943 for (int i = 0; i < num_ifaces_need_to_allocate; i++) {
1944 std::string instance_name =
1945 allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface() + i);
1946 if (!instance_name.empty()) {
1947 instances.push_back(instance_name);
1948 }
1949 }
1950 }
1951 return instances;
1952 }
1953
1954 // STA iface names start with idx 0.
1955 // Primary STA iface will always be 0.
allocateStaIfaceName()1956 std::string WifiChip::allocateStaIfaceName() {
1957 return allocateApOrStaIfaceName(IfaceType::STA, 0);
1958 }
1959
writeRingbufferFilesInternal()1960 bool WifiChip::writeRingbufferFilesInternal() {
1961 if (!removeOldFilesInternal()) {
1962 LOG(ERROR) << "Error occurred while deleting old tombstone files";
1963 return false;
1964 }
1965 // write ringbuffers to file
1966 {
1967 std::unique_lock<std::mutex> lk(lock_t);
1968 for (auto& item : ringbuffer_map_) {
1969 Ringbuffer& cur_buffer = item.second;
1970 if (cur_buffer.getData().empty()) {
1971 continue;
1972 }
1973 const std::string file_path_raw = kTombstoneFolderPath + item.first + "XXXXXXXXXX";
1974 const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
1975 if (dump_fd == -1) {
1976 PLOG(ERROR) << "create file failed";
1977 return false;
1978 }
1979 unique_fd file_auto_closer(dump_fd);
1980 for (const auto& cur_block : cur_buffer.getData()) {
1981 if (cur_block.size() <= 0 || cur_block.size() > kMaxBufferSizeBytes) {
1982 PLOG(ERROR) << "Ring buffer: " << item.first
1983 << " is corrupted. Invalid block size: " << cur_block.size();
1984 break;
1985 }
1986 if (write(dump_fd, cur_block.data(), sizeof(cur_block[0]) * cur_block.size()) ==
1987 -1) {
1988 PLOG(ERROR) << "Error writing to file";
1989 }
1990 }
1991 cur_buffer.clear();
1992 }
1993 // unique_lock unlocked here
1994 }
1995 return true;
1996 }
1997
getWlanIfaceNameWithType(IfaceType type,unsigned idx)1998 std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) {
1999 std::string ifname;
2000
2001 // let the legacy hal override the interface name
2002 legacy_hal::wifi_error err = legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname);
2003 if (err == legacy_hal::WIFI_SUCCESS) return ifname;
2004
2005 return getWlanIfaceName(idx);
2006 }
2007
invalidateAndClearBridgedApAll()2008 void WifiChip::invalidateAndClearBridgedApAll() {
2009 for (auto const& it : br_ifaces_ap_instances_) {
2010 for (auto const& iface : it.second) {
2011 iface_util_->removeIfaceFromBridge(it.first, iface);
2012 legacy_hal_.lock()->deleteVirtualInterface(iface);
2013 }
2014 iface_util_->deleteBridge(it.first);
2015 }
2016 br_ifaces_ap_instances_.clear();
2017 }
2018
deleteApIface(const std::string & if_name)2019 void WifiChip::deleteApIface(const std::string& if_name) {
2020 if (if_name.empty()) return;
2021 // delete bridged interfaces if have
2022 for (auto const& it : br_ifaces_ap_instances_) {
2023 if (it.first == if_name) {
2024 for (auto const& iface : it.second) {
2025 iface_util_->removeIfaceFromBridge(if_name, iface);
2026 legacy_hal_.lock()->deleteVirtualInterface(iface);
2027 }
2028 iface_util_->deleteBridge(if_name);
2029 br_ifaces_ap_instances_.erase(if_name);
2030 // ifname is bridged AP, return here.
2031 return;
2032 }
2033 }
2034
2035 // No bridged AP case, delete AP iface
2036 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->deleteVirtualInterface(if_name);
2037 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
2038 LOG(ERROR) << "Failed to remove interface: " << if_name << " "
2039 << legacyErrorToString(legacy_status);
2040 }
2041 }
2042
findUsingNameFromBridgedApInstances(const std::string & name)2043 bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) {
2044 for (auto const& it : br_ifaces_ap_instances_) {
2045 if (it.first == name) {
2046 return true;
2047 }
2048 for (auto const& iface : it.second) {
2049 if (iface == name) {
2050 return true;
2051 }
2052 }
2053 }
2054 return false;
2055 }
2056
2057 } // namespace implementation
2058 } // namespace V1_6
2059 } // namespace wifi
2060 } // namespace hardware
2061 } // namespace android
2062