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),
56 ifaces.end());
57 }
58
59 template <typename Iface>
invalidateAndClearAll(std::vector<sp<Iface>> & ifaces)60 void invalidateAndClearAll(std::vector<sp<Iface>>& ifaces) {
61 for (const auto& iface : ifaces) {
62 iface->invalidate();
63 }
64 ifaces.clear();
65 }
66
67 template <typename Iface>
getNames(std::vector<sp<Iface>> & ifaces)68 std::vector<hidl_string> getNames(std::vector<sp<Iface>>& ifaces) {
69 std::vector<hidl_string> names;
70 for (const auto& iface : ifaces) {
71 names.emplace_back(iface->getName());
72 }
73 return names;
74 }
75
76 template <typename Iface>
findUsingName(std::vector<sp<Iface>> & ifaces,const std::string & name)77 sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces,
78 const std::string& name) {
79 std::vector<hidl_string> names;
80 for (const auto& iface : ifaces) {
81 if (name == iface->getName()) {
82 return iface;
83 }
84 }
85 return nullptr;
86 }
87
getWlanIfaceName(unsigned idx)88 std::string getWlanIfaceName(unsigned idx) {
89 if (idx >= kMaxWlanIfaces) {
90 CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
91 return {};
92 }
93
94 std::array<char, PROPERTY_VALUE_MAX> buffer;
95 if (idx == 0 || idx == 1) {
96 const char* altPropName =
97 (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
98 auto res = property_get(altPropName, buffer.data(), nullptr);
99 if (res > 0) return buffer.data();
100 }
101 std::string propName = "wifi.interface." + std::to_string(idx);
102 auto res = property_get(propName.c_str(), buffer.data(), nullptr);
103 if (res > 0) return buffer.data();
104
105 return "wlan" + std::to_string(idx);
106 }
107
108 // Returns the dedicated iface name if defined.
109 // Returns two ifaces in bridged mode.
getPredefinedApIfaceNames(bool is_bridged)110 std::vector<std::string> getPredefinedApIfaceNames(bool is_bridged) {
111 std::vector<std::string> ifnames;
112 std::array<char, PROPERTY_VALUE_MAX> buffer;
113 buffer.fill(0);
114 if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) ==
115 0) {
116 return ifnames;
117 }
118 ifnames.push_back(buffer.data());
119 if (is_bridged) {
120 buffer.fill(0);
121 if (property_get("ro.vendor.wifi.sap.concurrent.iface", buffer.data(),
122 nullptr) == 0) {
123 return ifnames;
124 }
125 ifnames.push_back(buffer.data());
126 }
127 return ifnames;
128 }
129
getPredefinedP2pIfaceName()130 std::string getPredefinedP2pIfaceName() {
131 std::array<char, PROPERTY_VALUE_MAX> primaryIfaceName;
132 char p2pParentIfname[100];
133 std::string p2pDevIfName = "";
134 std::array<char, PROPERTY_VALUE_MAX> buffer;
135 property_get("wifi.direct.interface", buffer.data(), "p2p0");
136 if (strncmp(buffer.data(), P2P_MGMT_DEVICE_PREFIX,
137 strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
138 /* Get the p2p parent interface name from p2p device interface name set
139 * in property */
140 strncpy(p2pParentIfname, buffer.data() + strlen(P2P_MGMT_DEVICE_PREFIX),
141 strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX));
142 if (property_get(kActiveWlanIfaceNameProperty, primaryIfaceName.data(),
143 nullptr) == 0) {
144 return buffer.data();
145 }
146 /* Check if the parent interface derived from p2p device interface name
147 * is active */
148 if (strncmp(p2pParentIfname, primaryIfaceName.data(),
149 strlen(buffer.data()) - strlen(P2P_MGMT_DEVICE_PREFIX)) !=
150 0) {
151 /*
152 * Update the predefined p2p device interface parent interface name
153 * with current active wlan interface
154 */
155 p2pDevIfName += P2P_MGMT_DEVICE_PREFIX;
156 p2pDevIfName += primaryIfaceName.data();
157 LOG(INFO) << "update the p2p device interface name to "
158 << p2pDevIfName.c_str();
159 return p2pDevIfName;
160 }
161 }
162 return buffer.data();
163 }
164
165 // Returns the dedicated iface name if one is defined.
getPredefinedNanIfaceName()166 std::string getPredefinedNanIfaceName() {
167 std::array<char, PROPERTY_VALUE_MAX> buffer;
168 if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) {
169 return {};
170 }
171 return buffer.data();
172 }
173
setActiveWlanIfaceNameProperty(const std::string & ifname)174 void setActiveWlanIfaceNameProperty(const std::string& ifname) {
175 auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data());
176 if (res != 0) {
177 PLOG(ERROR) << "Failed to set active wlan iface name property";
178 }
179 }
180
181 // delete files that meet either conditions:
182 // 1. older than a predefined time in the wifi tombstone dir.
183 // 2. Files in excess to a predefined amount, starting from the oldest ones
removeOldFilesInternal()184 bool removeOldFilesInternal() {
185 time_t now = time(0);
186 const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
187 std::unique_ptr<DIR, decltype(&closedir)> dir_dump(
188 opendir(kTombstoneFolderPath), closedir);
189 if (!dir_dump) {
190 PLOG(ERROR) << "Failed to open directory";
191 return false;
192 }
193 struct dirent* dp;
194 bool success = true;
195 std::list<std::pair<const time_t, std::string>> valid_files;
196 while ((dp = readdir(dir_dump.get()))) {
197 if (dp->d_type != DT_REG) {
198 continue;
199 }
200 std::string cur_file_name(dp->d_name);
201 struct stat cur_file_stat;
202 std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
203 if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) {
204 PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
205 success = false;
206 continue;
207 }
208 const time_t cur_file_time = cur_file_stat.st_mtime;
209 valid_files.push_back(
210 std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
211 }
212 valid_files.sort(); // sort the list of files by last modified time from
213 // small to big.
214 uint32_t cur_file_count = valid_files.size();
215 for (auto cur_file : valid_files) {
216 if (cur_file_count > kMaxRingBufferFileNum ||
217 cur_file.first < delete_files_before) {
218 if (unlink(cur_file.second.c_str()) != 0) {
219 PLOG(ERROR) << "Error deleting file";
220 success = false;
221 }
222 cur_file_count--;
223 } else {
224 break;
225 }
226 }
227 return success;
228 }
229
230 // Helper function for |cpioArchiveFilesInDir|
cpioWriteHeader(int out_fd,struct stat & st,const char * file_name,size_t file_name_len)231 bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name,
232 size_t file_name_len) {
233 std::array<char, 32 * 1024> read_buf;
234 ssize_t llen =
235 sprintf(read_buf.data(),
236 "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
237 kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid,
238 st.st_gid, static_cast<int>(st.st_nlink),
239 static_cast<int>(st.st_mtime), static_cast<int>(st.st_size),
240 major(st.st_dev), minor(st.st_dev), major(st.st_rdev),
241 minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0);
242 if (write(out_fd, read_buf.data(), llen) == -1) {
243 PLOG(ERROR) << "Error writing cpio header to file " << file_name;
244 return false;
245 }
246 if (write(out_fd, file_name, file_name_len) == -1) {
247 PLOG(ERROR) << "Error writing filename to file " << file_name;
248 return false;
249 }
250
251 // NUL Pad header up to 4 multiple bytes.
252 llen = (llen + file_name_len) % 4;
253 if (llen != 0) {
254 const uint32_t zero = 0;
255 if (write(out_fd, &zero, 4 - llen) == -1) {
256 PLOG(ERROR) << "Error padding 0s to file " << file_name;
257 return false;
258 }
259 }
260 return true;
261 }
262
263 // Helper function for |cpioArchiveFilesInDir|
cpioWriteFileContent(int fd_read,int out_fd,struct stat & st)264 size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) {
265 // writing content of file
266 std::array<char, 32 * 1024> read_buf;
267 ssize_t llen = st.st_size;
268 size_t n_error = 0;
269 while (llen > 0) {
270 ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size());
271 if (bytes_read == -1) {
272 PLOG(ERROR) << "Error reading file";
273 return ++n_error;
274 }
275 llen -= bytes_read;
276 if (write(out_fd, read_buf.data(), bytes_read) == -1) {
277 PLOG(ERROR) << "Error writing data to file";
278 return ++n_error;
279 }
280 if (bytes_read == 0) { // this should never happen, but just in case
281 // to unstuck from while loop
282 PLOG(ERROR) << "Unexpected read result";
283 n_error++;
284 break;
285 }
286 }
287 llen = st.st_size % 4;
288 if (llen != 0) {
289 const uint32_t zero = 0;
290 if (write(out_fd, &zero, 4 - llen) == -1) {
291 PLOG(ERROR) << "Error padding 0s to file";
292 return ++n_error;
293 }
294 }
295 return n_error;
296 }
297
298 // Helper function for |cpioArchiveFilesInDir|
cpioWriteFileTrailer(int out_fd)299 bool cpioWriteFileTrailer(int out_fd) {
300 std::array<char, 4096> read_buf;
301 read_buf.fill(0);
302 if (write(out_fd, read_buf.data(),
303 sprintf(read_buf.data(), "070701%040X%056X%08XTRAILER!!!", 1,
304 0x0b, 0) +
305 4) == -1) {
306 PLOG(ERROR) << "Error writing trailing bytes";
307 return false;
308 }
309 return true;
310 }
311
312 // Archives all files in |input_dir| and writes result into |out_fd|
313 // Logic obtained from //external/toybox/toys/posix/cpio.c "Output cpio archive"
314 // portion
cpioArchiveFilesInDir(int out_fd,const char * input_dir)315 size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) {
316 struct dirent* dp;
317 size_t n_error = 0;
318 std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir),
319 closedir);
320 if (!dir_dump) {
321 PLOG(ERROR) << "Failed to open directory";
322 return ++n_error;
323 }
324 while ((dp = readdir(dir_dump.get()))) {
325 if (dp->d_type != DT_REG) {
326 continue;
327 }
328 std::string cur_file_name(dp->d_name);
329 struct stat st;
330 const std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
331 if (stat(cur_file_path.c_str(), &st) == -1) {
332 PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
333 n_error++;
334 continue;
335 }
336 const int fd_read = open(cur_file_path.c_str(), O_RDONLY);
337 if (fd_read == -1) {
338 PLOG(ERROR) << "Failed to open file " << cur_file_path;
339 n_error++;
340 continue;
341 }
342 std::string file_name_with_last_modified_time =
343 cur_file_name + "-" + std::to_string(st.st_mtime);
344 // string.size() does not include the null terminator. The cpio FreeBSD
345 // file header expects the null character to be included in the length.
346 const size_t file_name_len =
347 file_name_with_last_modified_time.size() + 1;
348 unique_fd file_auto_closer(fd_read);
349 if (!cpioWriteHeader(out_fd, st,
350 file_name_with_last_modified_time.c_str(),
351 file_name_len)) {
352 return ++n_error;
353 }
354 size_t write_error = cpioWriteFileContent(fd_read, out_fd, st);
355 if (write_error) {
356 return n_error + write_error;
357 }
358 }
359 if (!cpioWriteFileTrailer(out_fd)) {
360 return ++n_error;
361 }
362 return n_error;
363 }
364
365 // Helper function to create a non-const char*.
makeCharVec(const std::string & str)366 std::vector<char> makeCharVec(const std::string& str) {
367 std::vector<char> vec(str.size() + 1);
368 vec.assign(str.begin(), str.end());
369 vec.push_back('\0');
370 return vec;
371 }
372
373 } // namespace
374
375 namespace android {
376 namespace hardware {
377 namespace wifi {
378 namespace V1_5 {
379 namespace implementation {
380 using hidl_return_util::validateAndCall;
381 using hidl_return_util::validateAndCallWithLock;
382
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)383 WifiChip::WifiChip(
384 ChipId chip_id, bool is_primary,
385 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
386 const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
387 const std::shared_ptr<iface_util::WifiIfaceUtil> iface_util,
388 const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags,
389 const std::function<void(const std::string&)>& handler)
390 : chip_id_(chip_id),
391 legacy_hal_(legacy_hal),
392 mode_controller_(mode_controller),
393 iface_util_(iface_util),
394 is_valid_(true),
395 current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
396 modes_(feature_flags.lock()->getChipModes(is_primary)),
397 debug_ring_buffer_cb_registered_(false),
398 subsystemCallbackHandler_(handler) {
399 setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
400 }
401
invalidate()402 void WifiChip::invalidate() {
403 if (!writeRingbufferFilesInternal()) {
404 LOG(ERROR) << "Error writing files to flash";
405 }
406 invalidateAndRemoveAllIfaces();
407 setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
408 legacy_hal_.reset();
409 event_cb_handler_.invalidate();
410 is_valid_ = false;
411 }
412
isValid()413 bool WifiChip::isValid() { return is_valid_; }
414
getEventCallbacks()415 std::set<sp<V1_4::IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
416 return event_cb_handler_.getCallbacks();
417 }
418
getId(getId_cb hidl_status_cb)419 Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
420 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
421 &WifiChip::getIdInternal, hidl_status_cb);
422 }
423
424 // Deprecated support for this callback
registerEventCallback(const sp<V1_0::IWifiChipEventCallback> & event_callback,registerEventCallback_cb hidl_status_cb)425 Return<void> WifiChip::registerEventCallback(
426 const sp<V1_0::IWifiChipEventCallback>& event_callback,
427 registerEventCallback_cb hidl_status_cb) {
428 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
429 &WifiChip::registerEventCallbackInternal,
430 hidl_status_cb, event_callback);
431 }
432
getCapabilities(getCapabilities_cb hidl_status_cb)433 Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
434 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
435 &WifiChip::getCapabilitiesInternal, hidl_status_cb);
436 }
437
getAvailableModes(getAvailableModes_cb hidl_status_cb)438 Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
439 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
440 &WifiChip::getAvailableModesInternal,
441 hidl_status_cb);
442 }
443
configureChip(ChipModeId mode_id,configureChip_cb hidl_status_cb)444 Return<void> WifiChip::configureChip(ChipModeId mode_id,
445 configureChip_cb hidl_status_cb) {
446 return validateAndCallWithLock(
447 this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
448 &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
449 }
450
getMode(getMode_cb hidl_status_cb)451 Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
452 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
453 &WifiChip::getModeInternal, hidl_status_cb);
454 }
455
requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb)456 Return<void> WifiChip::requestChipDebugInfo(
457 requestChipDebugInfo_cb hidl_status_cb) {
458 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
459 &WifiChip::requestChipDebugInfoInternal,
460 hidl_status_cb);
461 }
462
requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb)463 Return<void> WifiChip::requestDriverDebugDump(
464 requestDriverDebugDump_cb hidl_status_cb) {
465 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
466 &WifiChip::requestDriverDebugDumpInternal,
467 hidl_status_cb);
468 }
469
requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb)470 Return<void> WifiChip::requestFirmwareDebugDump(
471 requestFirmwareDebugDump_cb hidl_status_cb) {
472 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
473 &WifiChip::requestFirmwareDebugDumpInternal,
474 hidl_status_cb);
475 }
476
createApIface(createApIface_cb hidl_status_cb)477 Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
478 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
479 &WifiChip::createApIfaceInternal, hidl_status_cb);
480 }
481
createBridgedApIface(createBridgedApIface_cb hidl_status_cb)482 Return<void> WifiChip::createBridgedApIface(
483 createBridgedApIface_cb hidl_status_cb) {
484 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
485 &WifiChip::createBridgedApIfaceInternal,
486 hidl_status_cb);
487 }
488
getApIfaceNames(getApIfaceNames_cb hidl_status_cb)489 Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
490 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
491 &WifiChip::getApIfaceNamesInternal, hidl_status_cb);
492 }
493
getApIface(const hidl_string & ifname,getApIface_cb hidl_status_cb)494 Return<void> WifiChip::getApIface(const hidl_string& ifname,
495 getApIface_cb hidl_status_cb) {
496 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
497 &WifiChip::getApIfaceInternal, hidl_status_cb,
498 ifname);
499 }
500
removeApIface(const hidl_string & ifname,removeApIface_cb hidl_status_cb)501 Return<void> WifiChip::removeApIface(const hidl_string& ifname,
502 removeApIface_cb hidl_status_cb) {
503 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
504 &WifiChip::removeApIfaceInternal, hidl_status_cb,
505 ifname);
506 }
507
removeIfaceInstanceFromBridgedApIface(const hidl_string & ifname,const hidl_string & ifInstanceName,removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb)508 Return<void> WifiChip::removeIfaceInstanceFromBridgedApIface(
509 const hidl_string& ifname, const hidl_string& ifInstanceName,
510 removeIfaceInstanceFromBridgedApIface_cb hidl_status_cb) {
511 return validateAndCall(
512 this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
513 &WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal,
514 hidl_status_cb, ifname, ifInstanceName);
515 }
516
createNanIface(createNanIface_cb hidl_status_cb)517 Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
518 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
519 &WifiChip::createNanIfaceInternal, hidl_status_cb);
520 }
521
getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb)522 Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
523 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
524 &WifiChip::getNanIfaceNamesInternal, hidl_status_cb);
525 }
526
getNanIface(const hidl_string & ifname,getNanIface_cb hidl_status_cb)527 Return<void> WifiChip::getNanIface(const hidl_string& ifname,
528 getNanIface_cb hidl_status_cb) {
529 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
530 &WifiChip::getNanIfaceInternal, hidl_status_cb,
531 ifname);
532 }
533
removeNanIface(const hidl_string & ifname,removeNanIface_cb hidl_status_cb)534 Return<void> WifiChip::removeNanIface(const hidl_string& ifname,
535 removeNanIface_cb hidl_status_cb) {
536 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
537 &WifiChip::removeNanIfaceInternal, hidl_status_cb,
538 ifname);
539 }
540
createP2pIface(createP2pIface_cb hidl_status_cb)541 Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
542 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
543 &WifiChip::createP2pIfaceInternal, hidl_status_cb);
544 }
545
getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb)546 Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
547 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
548 &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb);
549 }
550
getP2pIface(const hidl_string & ifname,getP2pIface_cb hidl_status_cb)551 Return<void> WifiChip::getP2pIface(const hidl_string& ifname,
552 getP2pIface_cb hidl_status_cb) {
553 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
554 &WifiChip::getP2pIfaceInternal, hidl_status_cb,
555 ifname);
556 }
557
removeP2pIface(const hidl_string & ifname,removeP2pIface_cb hidl_status_cb)558 Return<void> WifiChip::removeP2pIface(const hidl_string& ifname,
559 removeP2pIface_cb hidl_status_cb) {
560 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
561 &WifiChip::removeP2pIfaceInternal, hidl_status_cb,
562 ifname);
563 }
564
createStaIface(createStaIface_cb hidl_status_cb)565 Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
566 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
567 &WifiChip::createStaIfaceInternal, hidl_status_cb);
568 }
569
getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb)570 Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
571 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
572 &WifiChip::getStaIfaceNamesInternal, hidl_status_cb);
573 }
574
getStaIface(const hidl_string & ifname,getStaIface_cb hidl_status_cb)575 Return<void> WifiChip::getStaIface(const hidl_string& ifname,
576 getStaIface_cb hidl_status_cb) {
577 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
578 &WifiChip::getStaIfaceInternal, hidl_status_cb,
579 ifname);
580 }
581
removeStaIface(const hidl_string & ifname,removeStaIface_cb hidl_status_cb)582 Return<void> WifiChip::removeStaIface(const hidl_string& ifname,
583 removeStaIface_cb hidl_status_cb) {
584 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
585 &WifiChip::removeStaIfaceInternal, hidl_status_cb,
586 ifname);
587 }
588
createRttController(const sp<IWifiIface> & bound_iface,createRttController_cb hidl_status_cb)589 Return<void> WifiChip::createRttController(
590 const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) {
591 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
592 &WifiChip::createRttControllerInternal,
593 hidl_status_cb, bound_iface);
594 }
595
getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb)596 Return<void> WifiChip::getDebugRingBuffersStatus(
597 getDebugRingBuffersStatus_cb hidl_status_cb) {
598 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
599 &WifiChip::getDebugRingBuffersStatusInternal,
600 hidl_status_cb);
601 }
602
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)603 Return<void> WifiChip::startLoggingToDebugRingBuffer(
604 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
605 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
606 startLoggingToDebugRingBuffer_cb hidl_status_cb) {
607 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
608 &WifiChip::startLoggingToDebugRingBufferInternal,
609 hidl_status_cb, ring_name, verbose_level,
610 max_interval_in_sec, min_data_size_in_bytes);
611 }
612
forceDumpToDebugRingBuffer(const hidl_string & ring_name,forceDumpToDebugRingBuffer_cb hidl_status_cb)613 Return<void> WifiChip::forceDumpToDebugRingBuffer(
614 const hidl_string& ring_name,
615 forceDumpToDebugRingBuffer_cb hidl_status_cb) {
616 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
617 &WifiChip::forceDumpToDebugRingBufferInternal,
618 hidl_status_cb, ring_name);
619 }
620
flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb)621 Return<void> WifiChip::flushRingBufferToFile(
622 flushRingBufferToFile_cb hidl_status_cb) {
623 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
624 &WifiChip::flushRingBufferToFileInternal,
625 hidl_status_cb);
626 }
627
stopLoggingToDebugRingBuffer(stopLoggingToDebugRingBuffer_cb hidl_status_cb)628 Return<void> WifiChip::stopLoggingToDebugRingBuffer(
629 stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
630 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
631 &WifiChip::stopLoggingToDebugRingBufferInternal,
632 hidl_status_cb);
633 }
634
getDebugHostWakeReasonStats(getDebugHostWakeReasonStats_cb hidl_status_cb)635 Return<void> WifiChip::getDebugHostWakeReasonStats(
636 getDebugHostWakeReasonStats_cb hidl_status_cb) {
637 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
638 &WifiChip::getDebugHostWakeReasonStatsInternal,
639 hidl_status_cb);
640 }
641
enableDebugErrorAlerts(bool enable,enableDebugErrorAlerts_cb hidl_status_cb)642 Return<void> WifiChip::enableDebugErrorAlerts(
643 bool enable, enableDebugErrorAlerts_cb hidl_status_cb) {
644 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
645 &WifiChip::enableDebugErrorAlertsInternal,
646 hidl_status_cb, enable);
647 }
648
selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario,selectTxPowerScenario_cb hidl_status_cb)649 Return<void> WifiChip::selectTxPowerScenario(
650 V1_1::IWifiChip::TxPowerScenario scenario,
651 selectTxPowerScenario_cb hidl_status_cb) {
652 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
653 &WifiChip::selectTxPowerScenarioInternal,
654 hidl_status_cb, scenario);
655 }
656
resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb)657 Return<void> WifiChip::resetTxPowerScenario(
658 resetTxPowerScenario_cb hidl_status_cb) {
659 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
660 &WifiChip::resetTxPowerScenarioInternal,
661 hidl_status_cb);
662 }
663
setLatencyMode(LatencyMode mode,setLatencyMode_cb hidl_status_cb)664 Return<void> WifiChip::setLatencyMode(LatencyMode mode,
665 setLatencyMode_cb hidl_status_cb) {
666 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
667 &WifiChip::setLatencyModeInternal, hidl_status_cb,
668 mode);
669 }
670
registerEventCallback_1_2(const sp<V1_2::IWifiChipEventCallback> & event_callback,registerEventCallback_cb hidl_status_cb)671 Return<void> WifiChip::registerEventCallback_1_2(
672 const sp<V1_2::IWifiChipEventCallback>& event_callback,
673 registerEventCallback_cb hidl_status_cb) {
674 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
675 &WifiChip::registerEventCallbackInternal_1_2,
676 hidl_status_cb, event_callback);
677 }
678
selectTxPowerScenario_1_2(TxPowerScenario scenario,selectTxPowerScenario_cb hidl_status_cb)679 Return<void> WifiChip::selectTxPowerScenario_1_2(
680 TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) {
681 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
682 &WifiChip::selectTxPowerScenarioInternal_1_2,
683 hidl_status_cb, scenario);
684 }
685
getCapabilities_1_3(getCapabilities_cb hidl_status_cb)686 Return<void> WifiChip::getCapabilities_1_3(getCapabilities_cb hidl_status_cb) {
687 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
688 &WifiChip::getCapabilitiesInternal_1_3,
689 hidl_status_cb);
690 }
691
getCapabilities_1_5(getCapabilities_1_5_cb hidl_status_cb)692 Return<void> WifiChip::getCapabilities_1_5(
693 getCapabilities_1_5_cb hidl_status_cb) {
694 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
695 &WifiChip::getCapabilitiesInternal_1_5,
696 hidl_status_cb);
697 }
698
debug(const hidl_handle & handle,const hidl_vec<hidl_string> &)699 Return<void> WifiChip::debug(const hidl_handle& handle,
700 const hidl_vec<hidl_string>&) {
701 if (handle != nullptr && handle->numFds >= 1) {
702 {
703 std::unique_lock<std::mutex> lk(lock_t);
704 for (const auto& item : ringbuffer_map_) {
705 forceDumpToDebugRingBufferInternal(item.first);
706 }
707 // unique_lock unlocked here
708 }
709 usleep(100 * 1000); // sleep for 100 milliseconds to wait for
710 // ringbuffer updates.
711 int fd = handle->data[0];
712 if (!writeRingbufferFilesInternal()) {
713 LOG(ERROR) << "Error writing files to flash";
714 }
715 uint32_t n_error = cpioArchiveFilesInDir(fd, kTombstoneFolderPath);
716 if (n_error != 0) {
717 LOG(ERROR) << n_error << " errors occured in cpio function";
718 }
719 fsync(fd);
720 } else {
721 LOG(ERROR) << "File handle error";
722 }
723 return Void();
724 }
725
createRttController_1_4(const sp<IWifiIface> & bound_iface,createRttController_1_4_cb hidl_status_cb)726 Return<void> WifiChip::createRttController_1_4(
727 const sp<IWifiIface>& bound_iface,
728 createRttController_1_4_cb hidl_status_cb) {
729 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
730 &WifiChip::createRttControllerInternal_1_4,
731 hidl_status_cb, bound_iface);
732 }
733
registerEventCallback_1_4(const sp<V1_4::IWifiChipEventCallback> & event_callback,registerEventCallback_cb hidl_status_cb)734 Return<void> WifiChip::registerEventCallback_1_4(
735 const sp<V1_4::IWifiChipEventCallback>& event_callback,
736 registerEventCallback_cb hidl_status_cb) {
737 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
738 &WifiChip::registerEventCallbackInternal_1_4,
739 hidl_status_cb, event_callback);
740 }
741
setMultiStaPrimaryConnection(const hidl_string & ifname,setMultiStaPrimaryConnection_cb hidl_status_cb)742 Return<void> WifiChip::setMultiStaPrimaryConnection(
743 const hidl_string& ifname, setMultiStaPrimaryConnection_cb hidl_status_cb) {
744 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
745 &WifiChip::setMultiStaPrimaryConnectionInternal,
746 hidl_status_cb, ifname);
747 }
748
setMultiStaUseCase(MultiStaUseCase use_case,setMultiStaUseCase_cb hidl_status_cb)749 Return<void> WifiChip::setMultiStaUseCase(
750 MultiStaUseCase use_case, setMultiStaUseCase_cb hidl_status_cb) {
751 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
752 &WifiChip::setMultiStaUseCaseInternal,
753 hidl_status_cb, use_case);
754 }
755
setCoexUnsafeChannels(const hidl_vec<CoexUnsafeChannel> & unsafeChannels,hidl_bitfield<CoexRestriction> restrictions,setCoexUnsafeChannels_cb hidl_status_cb)756 Return<void> WifiChip::setCoexUnsafeChannels(
757 const hidl_vec<CoexUnsafeChannel>& unsafeChannels,
758 hidl_bitfield<CoexRestriction> restrictions,
759 setCoexUnsafeChannels_cb hidl_status_cb) {
760 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
761 &WifiChip::setCoexUnsafeChannelsInternal,
762 hidl_status_cb, unsafeChannels, restrictions);
763 }
764
setCountryCode(const hidl_array<int8_t,2> & code,setCountryCode_cb hidl_status_cb)765 Return<void> WifiChip::setCountryCode(const hidl_array<int8_t, 2>& code,
766 setCountryCode_cb hidl_status_cb) {
767 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
768 &WifiChip::setCountryCodeInternal, hidl_status_cb,
769 code);
770 }
771
getUsableChannels(WifiBand band,hidl_bitfield<WifiIfaceMode> ifaceModeMask,hidl_bitfield<UsableChannelFilter> filterMask,getUsableChannels_cb _hidl_cb)772 Return<void> WifiChip::getUsableChannels(
773 WifiBand band, hidl_bitfield<WifiIfaceMode> ifaceModeMask,
774 hidl_bitfield<UsableChannelFilter> filterMask,
775 getUsableChannels_cb _hidl_cb) {
776 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
777 &WifiChip::getUsableChannelsInternal, _hidl_cb, band,
778 ifaceModeMask, filterMask);
779 }
780
triggerSubsystemRestart(triggerSubsystemRestart_cb hidl_status_cb)781 Return<void> WifiChip::triggerSubsystemRestart(
782 triggerSubsystemRestart_cb hidl_status_cb) {
783 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
784 &WifiChip::triggerSubsystemRestartInternal,
785 hidl_status_cb);
786 }
787
invalidateAndRemoveAllIfaces()788 void WifiChip::invalidateAndRemoveAllIfaces() {
789 invalidateAndClearBridgedApAll();
790 invalidateAndClearAll(ap_ifaces_);
791 invalidateAndClearAll(nan_ifaces_);
792 invalidateAndClearAll(p2p_ifaces_);
793 invalidateAndClearAll(sta_ifaces_);
794 // Since all the ifaces are invalid now, all RTT controller objects
795 // using those ifaces also need to be invalidated.
796 for (const auto& rtt : rtt_controllers_) {
797 rtt->invalidate();
798 }
799 rtt_controllers_.clear();
800 }
801
invalidateAndRemoveDependencies(const std::string & removed_iface_name)802 void WifiChip::invalidateAndRemoveDependencies(
803 const std::string& removed_iface_name) {
804 for (auto it = nan_ifaces_.begin(); it != nan_ifaces_.end();) {
805 auto nan_iface = *it;
806 if (nan_iface->getName() == removed_iface_name) {
807 nan_iface->invalidate();
808 for (const auto& callback : event_cb_handler_.getCallbacks()) {
809 if (!callback
810 ->onIfaceRemoved(IfaceType::NAN, removed_iface_name)
811 .isOk()) {
812 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
813 }
814 }
815 it = nan_ifaces_.erase(it);
816 } else {
817 ++it;
818 }
819 }
820
821 for (auto it = rtt_controllers_.begin(); it != rtt_controllers_.end();) {
822 auto rtt = *it;
823 if (rtt->getIfaceName() == removed_iface_name) {
824 rtt->invalidate();
825 it = rtt_controllers_.erase(it);
826 } else {
827 ++it;
828 }
829 }
830 }
831
getIdInternal()832 std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
833 return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
834 }
835
registerEventCallbackInternal(const sp<V1_0::IWifiChipEventCallback> &)836 WifiStatus WifiChip::registerEventCallbackInternal(
837 const sp<V1_0::IWifiChipEventCallback>& /* event_callback */) {
838 // Deprecated support for this callback.
839 return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
840 }
841
getCapabilitiesInternal()842 std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
843 // Deprecated support for this callback.
844 return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
845 }
846
847 std::pair<WifiStatus, std::vector<V1_4::IWifiChip::ChipMode>>
getAvailableModesInternal()848 WifiChip::getAvailableModesInternal() {
849 return {createWifiStatus(WifiStatusCode::SUCCESS), modes_};
850 }
851
configureChipInternal(std::unique_lock<std::recursive_mutex> * lock,ChipModeId mode_id)852 WifiStatus WifiChip::configureChipInternal(
853 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
854 ChipModeId mode_id) {
855 if (!isValidModeId(mode_id)) {
856 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
857 }
858 if (mode_id == current_mode_id_) {
859 LOG(DEBUG) << "Already in the specified mode " << mode_id;
860 return createWifiStatus(WifiStatusCode::SUCCESS);
861 }
862 WifiStatus status = handleChipConfiguration(lock, mode_id);
863 if (status.code != WifiStatusCode::SUCCESS) {
864 for (const auto& callback : event_cb_handler_.getCallbacks()) {
865 if (!callback->onChipReconfigureFailure(status).isOk()) {
866 LOG(ERROR)
867 << "Failed to invoke onChipReconfigureFailure callback";
868 }
869 }
870 return status;
871 }
872 for (const auto& callback : event_cb_handler_.getCallbacks()) {
873 if (!callback->onChipReconfigured(mode_id).isOk()) {
874 LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
875 }
876 }
877 current_mode_id_ = mode_id;
878 LOG(INFO) << "Configured chip in mode " << mode_id;
879 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
880
881 legacy_hal_.lock()->registerSubsystemRestartCallbackHandler(
882 subsystemCallbackHandler_);
883
884 return status;
885 }
886
getModeInternal()887 std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
888 if (!isValidModeId(current_mode_id_)) {
889 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE),
890 current_mode_id_};
891 }
892 return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
893 }
894
895 std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo>
requestChipDebugInfoInternal()896 WifiChip::requestChipDebugInfoInternal() {
897 V1_4::IWifiChip::ChipDebugInfo result;
898 legacy_hal::wifi_error legacy_status;
899 std::string driver_desc;
900 const auto ifname = getFirstActiveWlanIfaceName();
901 std::tie(legacy_status, driver_desc) =
902 legacy_hal_.lock()->getDriverVersion(ifname);
903 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
904 LOG(ERROR) << "Failed to get driver version: "
905 << legacyErrorToString(legacy_status);
906 WifiStatus status = createWifiStatusFromLegacyError(
907 legacy_status, "failed to get driver version");
908 return {status, result};
909 }
910 result.driverDescription = driver_desc.c_str();
911
912 std::string firmware_desc;
913 std::tie(legacy_status, firmware_desc) =
914 legacy_hal_.lock()->getFirmwareVersion(ifname);
915 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
916 LOG(ERROR) << "Failed to get firmware version: "
917 << legacyErrorToString(legacy_status);
918 WifiStatus status = createWifiStatusFromLegacyError(
919 legacy_status, "failed to get firmware version");
920 return {status, result};
921 }
922 result.firmwareDescription = firmware_desc.c_str();
923
924 return {createWifiStatus(WifiStatusCode::SUCCESS), result};
925 }
926
927 std::pair<WifiStatus, std::vector<uint8_t>>
requestDriverDebugDumpInternal()928 WifiChip::requestDriverDebugDumpInternal() {
929 legacy_hal::wifi_error legacy_status;
930 std::vector<uint8_t> driver_dump;
931 std::tie(legacy_status, driver_dump) =
932 legacy_hal_.lock()->requestDriverMemoryDump(
933 getFirstActiveWlanIfaceName());
934 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
935 LOG(ERROR) << "Failed to get driver debug dump: "
936 << legacyErrorToString(legacy_status);
937 return {createWifiStatusFromLegacyError(legacy_status),
938 std::vector<uint8_t>()};
939 }
940 return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
941 }
942
943 std::pair<WifiStatus, std::vector<uint8_t>>
requestFirmwareDebugDumpInternal()944 WifiChip::requestFirmwareDebugDumpInternal() {
945 legacy_hal::wifi_error legacy_status;
946 std::vector<uint8_t> firmware_dump;
947 std::tie(legacy_status, firmware_dump) =
948 legacy_hal_.lock()->requestFirmwareMemoryDump(
949 getFirstActiveWlanIfaceName());
950 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
951 LOG(ERROR) << "Failed to get firmware debug dump: "
952 << legacyErrorToString(legacy_status);
953 return {createWifiStatusFromLegacyError(legacy_status), {}};
954 }
955 return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
956 }
957
createVirtualApInterface(const std::string & apVirtIf)958 WifiStatus WifiChip::createVirtualApInterface(const std::string& apVirtIf) {
959 legacy_hal::wifi_error legacy_status;
960 legacy_status = legacy_hal_.lock()->createVirtualInterface(
961 apVirtIf,
962 hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP));
963 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
964 LOG(ERROR) << "Failed to add interface: " << apVirtIf << " "
965 << legacyErrorToString(legacy_status);
966 return createWifiStatusFromLegacyError(legacy_status);
967 }
968 return createWifiStatus(WifiStatusCode::SUCCESS);
969 }
970
newWifiApIface(std::string & ifname)971 sp<WifiApIface> WifiChip::newWifiApIface(std::string& ifname) {
972 std::vector<std::string> ap_instances;
973 for (auto const& it : br_ifaces_ap_instances_) {
974 if (it.first == ifname) {
975 ap_instances = it.second;
976 }
977 }
978 sp<WifiApIface> iface =
979 new WifiApIface(ifname, ap_instances, legacy_hal_, iface_util_);
980 ap_ifaces_.push_back(iface);
981 for (const auto& callback : event_cb_handler_.getCallbacks()) {
982 if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
983 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
984 }
985 }
986 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
987 return iface;
988 }
989
990 std::pair<WifiStatus, sp<V1_5::IWifiApIface>>
createApIfaceInternal()991 WifiChip::createApIfaceInternal() {
992 if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
993 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
994 }
995 std::string ifname = allocateApIfaceName();
996 WifiStatus status = createVirtualApInterface(ifname);
997 if (status.code != WifiStatusCode::SUCCESS) {
998 return {status, {}};
999 }
1000 sp<WifiApIface> iface = newWifiApIface(ifname);
1001 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1002 }
1003
1004 std::pair<WifiStatus, sp<V1_5::IWifiApIface>>
createBridgedApIfaceInternal()1005 WifiChip::createBridgedApIfaceInternal() {
1006 if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
1007 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1008 }
1009 std::vector<std::string> ap_instances = allocateBridgedApInstanceNames();
1010 if (ap_instances.size() < 2) {
1011 LOG(ERROR) << "Fail to allocate two instances";
1012 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1013 }
1014 std::string br_ifname = kApBridgeIfacePrefix + ap_instances[0];
1015 for (int i = 0; i < 2; i++) {
1016 WifiStatus status = createVirtualApInterface(ap_instances[i]);
1017 if (status.code != WifiStatusCode::SUCCESS) {
1018 if (i != 0) { // The failure happened when creating second virtual
1019 // iface.
1020 legacy_hal_.lock()->deleteVirtualInterface(
1021 ap_instances.front()); // Remove the first virtual iface.
1022 }
1023 return {status, {}};
1024 }
1025 }
1026 br_ifaces_ap_instances_[br_ifname] = ap_instances;
1027 if (!iface_util_->createBridge(br_ifname)) {
1028 LOG(ERROR) << "Failed createBridge - br_name=" << br_ifname.c_str();
1029 invalidateAndClearBridgedAp(br_ifname);
1030 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1031 }
1032 for (auto const& instance : ap_instances) {
1033 // Bind ap instance interface to AP bridge
1034 if (!iface_util_->addIfaceToBridge(br_ifname, instance)) {
1035 LOG(ERROR) << "Failed add if to Bridge - if_name="
1036 << instance.c_str();
1037 invalidateAndClearBridgedAp(br_ifname);
1038 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1039 }
1040 }
1041 sp<WifiApIface> iface = newWifiApIface(br_ifname);
1042 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1043 }
1044
1045 std::pair<WifiStatus, std::vector<hidl_string>>
getApIfaceNamesInternal()1046 WifiChip::getApIfaceNamesInternal() {
1047 if (ap_ifaces_.empty()) {
1048 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
1049 }
1050 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)};
1051 }
1052
getApIfaceInternal(const std::string & ifname)1053 std::pair<WifiStatus, sp<V1_5::IWifiApIface>> WifiChip::getApIfaceInternal(
1054 const std::string& ifname) {
1055 const auto iface = findUsingName(ap_ifaces_, ifname);
1056 if (!iface.get()) {
1057 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
1058 }
1059 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1060 }
1061
removeApIfaceInternal(const std::string & ifname)1062 WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
1063 const auto iface = findUsingName(ap_ifaces_, ifname);
1064 if (!iface.get()) {
1065 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1066 }
1067 // Invalidate & remove any dependent objects first.
1068 // Note: This is probably not required because we never create
1069 // nan/rtt objects over AP iface. But, there is no harm to do it
1070 // here and not make that assumption all over the place.
1071 invalidateAndRemoveDependencies(ifname);
1072 // Clear the bridge interface and the iface instance.
1073 invalidateAndClearBridgedAp(ifname);
1074 invalidateAndClear(ap_ifaces_, iface);
1075 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1076 if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
1077 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1078 }
1079 }
1080 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1081 return createWifiStatus(WifiStatusCode::SUCCESS);
1082 }
1083
removeIfaceInstanceFromBridgedApIfaceInternal(const std::string & ifname,const std::string & ifInstanceName)1084 WifiStatus WifiChip::removeIfaceInstanceFromBridgedApIfaceInternal(
1085 const std::string& ifname, const std::string& ifInstanceName) {
1086 const auto iface = findUsingName(ap_ifaces_, ifname);
1087 if (!iface.get() || ifInstanceName.empty()) {
1088 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1089 }
1090 // Requires to remove one of the instance in bridge mode
1091 for (auto const& it : br_ifaces_ap_instances_) {
1092 if (it.first == ifname) {
1093 std::vector<std::string> ap_instances = it.second;
1094 for (auto const& iface : ap_instances) {
1095 if (iface == ifInstanceName) {
1096 if (!iface_util_->removeIfaceFromBridge(it.first, iface)) {
1097 LOG(ERROR)
1098 << "Failed to remove interface: " << ifInstanceName
1099 << " from " << ifname;
1100 return createWifiStatus(
1101 WifiStatusCode::ERROR_NOT_AVAILABLE);
1102 }
1103 legacy_hal::wifi_error legacy_status =
1104 legacy_hal_.lock()->deleteVirtualInterface(iface);
1105 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1106 LOG(ERROR) << "Failed to del interface: " << iface
1107 << " " << legacyErrorToString(legacy_status);
1108 return createWifiStatusFromLegacyError(legacy_status);
1109 }
1110 ap_instances.erase(
1111 std::remove(ap_instances.begin(), ap_instances.end(),
1112 ifInstanceName),
1113 ap_instances.end());
1114 br_ifaces_ap_instances_[ifname] = ap_instances;
1115 break;
1116 }
1117 }
1118 break;
1119 }
1120 }
1121 iface->removeInstance(ifInstanceName);
1122 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1123
1124 return createWifiStatus(WifiStatusCode::SUCCESS);
1125 }
1126
1127 std::pair<WifiStatus, sp<V1_4::IWifiNanIface>>
createNanIfaceInternal()1128 WifiChip::createNanIfaceInternal() {
1129 if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) {
1130 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1131 }
1132 bool is_dedicated_iface = true;
1133 std::string ifname = getPredefinedNanIfaceName();
1134 if (ifname.empty() || !iface_util_->ifNameToIndex(ifname)) {
1135 // Use the first shared STA iface (wlan0) if a dedicated aware iface is
1136 // not defined.
1137 ifname = getFirstActiveWlanIfaceName();
1138 is_dedicated_iface = false;
1139 }
1140 sp<WifiNanIface> iface =
1141 new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
1142 nan_ifaces_.push_back(iface);
1143 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1144 if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
1145 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1146 }
1147 }
1148 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1149 }
1150
1151 std::pair<WifiStatus, std::vector<hidl_string>>
getNanIfaceNamesInternal()1152 WifiChip::getNanIfaceNamesInternal() {
1153 if (nan_ifaces_.empty()) {
1154 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
1155 }
1156 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)};
1157 }
1158
getNanIfaceInternal(const std::string & ifname)1159 std::pair<WifiStatus, sp<V1_4::IWifiNanIface>> WifiChip::getNanIfaceInternal(
1160 const std::string& ifname) {
1161 const auto iface = findUsingName(nan_ifaces_, ifname);
1162 if (!iface.get()) {
1163 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
1164 }
1165 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1166 }
1167
removeNanIfaceInternal(const std::string & ifname)1168 WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
1169 const auto iface = findUsingName(nan_ifaces_, ifname);
1170 if (!iface.get()) {
1171 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1172 }
1173 invalidateAndClear(nan_ifaces_, iface);
1174 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1175 if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
1176 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1177 }
1178 }
1179 return createWifiStatus(WifiStatusCode::SUCCESS);
1180 }
1181
createP2pIfaceInternal()1182 std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
1183 if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::P2P)) {
1184 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1185 }
1186 std::string ifname = getPredefinedP2pIfaceName();
1187 sp<WifiP2pIface> iface = new WifiP2pIface(ifname, legacy_hal_);
1188 p2p_ifaces_.push_back(iface);
1189 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1190 if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
1191 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1192 }
1193 }
1194 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1195 }
1196
1197 std::pair<WifiStatus, std::vector<hidl_string>>
getP2pIfaceNamesInternal()1198 WifiChip::getP2pIfaceNamesInternal() {
1199 if (p2p_ifaces_.empty()) {
1200 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
1201 }
1202 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)};
1203 }
1204
getP2pIfaceInternal(const std::string & ifname)1205 std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(
1206 const std::string& ifname) {
1207 const auto iface = findUsingName(p2p_ifaces_, ifname);
1208 if (!iface.get()) {
1209 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
1210 }
1211 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1212 }
1213
removeP2pIfaceInternal(const std::string & ifname)1214 WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
1215 const auto iface = findUsingName(p2p_ifaces_, ifname);
1216 if (!iface.get()) {
1217 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1218 }
1219 invalidateAndClear(p2p_ifaces_, iface);
1220 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1221 if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
1222 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1223 }
1224 }
1225 return createWifiStatus(WifiStatusCode::SUCCESS);
1226 }
1227
1228 std::pair<WifiStatus, sp<V1_5::IWifiStaIface>>
createStaIfaceInternal()1229 WifiChip::createStaIfaceInternal() {
1230 if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) {
1231 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1232 }
1233 std::string ifname = allocateStaIfaceName();
1234 legacy_hal::wifi_error legacy_status =
1235 legacy_hal_.lock()->createVirtualInterface(
1236 ifname,
1237 hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA));
1238 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1239 LOG(ERROR) << "Failed to add interface: " << ifname << " "
1240 << legacyErrorToString(legacy_status);
1241 return {createWifiStatusFromLegacyError(legacy_status), {}};
1242 }
1243 sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_);
1244 sta_ifaces_.push_back(iface);
1245 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1246 if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
1247 LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1248 }
1249 }
1250 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1251 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1252 }
1253
1254 std::pair<WifiStatus, std::vector<hidl_string>>
getStaIfaceNamesInternal()1255 WifiChip::getStaIfaceNamesInternal() {
1256 if (sta_ifaces_.empty()) {
1257 return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
1258 }
1259 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)};
1260 }
1261
getStaIfaceInternal(const std::string & ifname)1262 std::pair<WifiStatus, sp<V1_5::IWifiStaIface>> WifiChip::getStaIfaceInternal(
1263 const std::string& ifname) {
1264 const auto iface = findUsingName(sta_ifaces_, ifname);
1265 if (!iface.get()) {
1266 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
1267 }
1268 return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1269 }
1270
removeStaIfaceInternal(const std::string & ifname)1271 WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
1272 const auto iface = findUsingName(sta_ifaces_, ifname);
1273 if (!iface.get()) {
1274 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1275 }
1276 // Invalidate & remove any dependent objects first.
1277 invalidateAndRemoveDependencies(ifname);
1278 legacy_hal::wifi_error legacy_status =
1279 legacy_hal_.lock()->deleteVirtualInterface(ifname);
1280 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1281 LOG(ERROR) << "Failed to remove interface: " << ifname << " "
1282 << legacyErrorToString(legacy_status);
1283 }
1284 invalidateAndClear(sta_ifaces_, iface);
1285 for (const auto& callback : event_cb_handler_.getCallbacks()) {
1286 if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
1287 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1288 }
1289 }
1290 setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1291 return createWifiStatus(WifiStatusCode::SUCCESS);
1292 }
1293
1294 std::pair<WifiStatus, sp<V1_0::IWifiRttController>>
createRttControllerInternal(const sp<IWifiIface> &)1295 WifiChip::createRttControllerInternal(const sp<IWifiIface>& /*bound_iface*/) {
1296 LOG(ERROR) << "createRttController is not supported on this HAL";
1297 return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
1298 }
1299
1300 std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
getDebugRingBuffersStatusInternal()1301 WifiChip::getDebugRingBuffersStatusInternal() {
1302 legacy_hal::wifi_error legacy_status;
1303 std::vector<legacy_hal::wifi_ring_buffer_status>
1304 legacy_ring_buffer_status_vec;
1305 std::tie(legacy_status, legacy_ring_buffer_status_vec) =
1306 legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
1307 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1308 return {createWifiStatusFromLegacyError(legacy_status), {}};
1309 }
1310 std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
1311 if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
1312 legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
1313 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
1314 }
1315 return {createWifiStatus(WifiStatusCode::SUCCESS),
1316 hidl_ring_buffer_status_vec};
1317 }
1318
startLoggingToDebugRingBufferInternal(const hidl_string & ring_name,WifiDebugRingBufferVerboseLevel verbose_level,uint32_t max_interval_in_sec,uint32_t min_data_size_in_bytes)1319 WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
1320 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
1321 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
1322 WifiStatus status = registerDebugRingBufferCallback();
1323 if (status.code != WifiStatusCode::SUCCESS) {
1324 return status;
1325 }
1326 legacy_hal::wifi_error legacy_status =
1327 legacy_hal_.lock()->startRingBufferLogging(
1328 getFirstActiveWlanIfaceName(), ring_name,
1329 static_cast<
1330 std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
1331 verbose_level),
1332 max_interval_in_sec, min_data_size_in_bytes);
1333 ringbuffer_map_.insert(std::pair<std::string, Ringbuffer>(
1334 ring_name, Ringbuffer(kMaxBufferSizeBytes)));
1335 // if verbose logging enabled, turn up HAL daemon logging as well.
1336 if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
1337 android::base::SetMinimumLogSeverity(android::base::DEBUG);
1338 } else {
1339 android::base::SetMinimumLogSeverity(android::base::VERBOSE);
1340 }
1341 return createWifiStatusFromLegacyError(legacy_status);
1342 }
1343
forceDumpToDebugRingBufferInternal(const hidl_string & ring_name)1344 WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
1345 const hidl_string& ring_name) {
1346 WifiStatus status = registerDebugRingBufferCallback();
1347 if (status.code != WifiStatusCode::SUCCESS) {
1348 return status;
1349 }
1350 legacy_hal::wifi_error legacy_status =
1351 legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(),
1352 ring_name);
1353
1354 return createWifiStatusFromLegacyError(legacy_status);
1355 }
1356
flushRingBufferToFileInternal()1357 WifiStatus WifiChip::flushRingBufferToFileInternal() {
1358 if (!writeRingbufferFilesInternal()) {
1359 LOG(ERROR) << "Error writing files to flash";
1360 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1361 }
1362 return createWifiStatus(WifiStatusCode::SUCCESS);
1363 }
1364
stopLoggingToDebugRingBufferInternal()1365 WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
1366 legacy_hal::wifi_error legacy_status =
1367 legacy_hal_.lock()->deregisterRingBufferCallbackHandler(
1368 getFirstActiveWlanIfaceName());
1369 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1370 debug_ring_buffer_cb_registered_ = false;
1371 }
1372 return createWifiStatusFromLegacyError(legacy_status);
1373 }
1374
1375 std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
getDebugHostWakeReasonStatsInternal()1376 WifiChip::getDebugHostWakeReasonStatsInternal() {
1377 legacy_hal::wifi_error legacy_status;
1378 legacy_hal::WakeReasonStats legacy_stats;
1379 std::tie(legacy_status, legacy_stats) =
1380 legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
1381 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1382 return {createWifiStatusFromLegacyError(legacy_status), {}};
1383 }
1384 WifiDebugHostWakeReasonStats hidl_stats;
1385 if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats,
1386 &hidl_stats)) {
1387 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
1388 }
1389 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
1390 }
1391
enableDebugErrorAlertsInternal(bool enable)1392 WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
1393 legacy_hal::wifi_error legacy_status;
1394 if (enable) {
1395 android::wp<WifiChip> weak_ptr_this(this);
1396 const auto& on_alert_callback = [weak_ptr_this](
1397 int32_t error_code,
1398 std::vector<uint8_t> debug_data) {
1399 const auto shared_ptr_this = weak_ptr_this.promote();
1400 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1401 LOG(ERROR) << "Callback invoked on an invalid object";
1402 return;
1403 }
1404 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
1405 if (!callback->onDebugErrorAlert(error_code, debug_data)
1406 .isOk()) {
1407 LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
1408 }
1409 }
1410 };
1411 legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
1412 getFirstActiveWlanIfaceName(), on_alert_callback);
1413 } else {
1414 legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
1415 getFirstActiveWlanIfaceName());
1416 }
1417 return createWifiStatusFromLegacyError(legacy_status);
1418 }
1419
selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario)1420 WifiStatus WifiChip::selectTxPowerScenarioInternal(
1421 V1_1::IWifiChip::TxPowerScenario scenario) {
1422 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
1423 getFirstActiveWlanIfaceName(),
1424 hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
1425 return createWifiStatusFromLegacyError(legacy_status);
1426 }
1427
resetTxPowerScenarioInternal()1428 WifiStatus WifiChip::resetTxPowerScenarioInternal() {
1429 auto legacy_status =
1430 legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
1431 return createWifiStatusFromLegacyError(legacy_status);
1432 }
1433
setLatencyModeInternal(LatencyMode mode)1434 WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) {
1435 auto legacy_status = legacy_hal_.lock()->setLatencyMode(
1436 getFirstActiveWlanIfaceName(),
1437 hidl_struct_util::convertHidlLatencyModeToLegacy(mode));
1438 return createWifiStatusFromLegacyError(legacy_status);
1439 }
1440
registerEventCallbackInternal_1_2(const sp<V1_2::IWifiChipEventCallback> &)1441 WifiStatus WifiChip::registerEventCallbackInternal_1_2(
1442 const sp<V1_2::IWifiChipEventCallback>& /* event_callback */) {
1443 // Deprecated support for this callback.
1444 return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
1445 }
1446
selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario)1447 WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(
1448 TxPowerScenario scenario) {
1449 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
1450 getFirstActiveWlanIfaceName(),
1451 hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario));
1452 return createWifiStatusFromLegacyError(legacy_status);
1453 }
1454
getCapabilitiesInternal_1_3()1455 std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_3() {
1456 // Deprecated support for this callback.
1457 return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
1458 }
1459
getCapabilitiesInternal_1_5()1460 std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_5() {
1461 legacy_hal::wifi_error legacy_status;
1462 uint64_t legacy_feature_set;
1463 uint32_t legacy_logger_feature_set;
1464 const auto ifname = getFirstActiveWlanIfaceName();
1465 std::tie(legacy_status, legacy_feature_set) =
1466 legacy_hal_.lock()->getSupportedFeatureSet(ifname);
1467 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1468 return {createWifiStatusFromLegacyError(legacy_status), 0};
1469 }
1470 std::tie(legacy_status, legacy_logger_feature_set) =
1471 legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
1472 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1473 // some devices don't support querying logger feature set
1474 legacy_logger_feature_set = 0;
1475 }
1476 uint32_t hidl_caps;
1477 if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
1478 legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
1479 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
1480 }
1481 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
1482 }
1483
1484 std::pair<WifiStatus, sp<V1_4::IWifiRttController>>
createRttControllerInternal_1_4(const sp<IWifiIface> & bound_iface)1485 WifiChip::createRttControllerInternal_1_4(const sp<IWifiIface>& bound_iface) {
1486 if (sta_ifaces_.size() == 0 &&
1487 !canCurrentModeSupportIfaceOfType(IfaceType::STA)) {
1488 LOG(ERROR)
1489 << "createRttControllerInternal_1_4: Chip cannot support STAs "
1490 "(and RTT by extension)";
1491 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1492 }
1493 sp<WifiRttController> rtt = new WifiRttController(
1494 getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
1495 rtt_controllers_.emplace_back(rtt);
1496 return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
1497 }
1498
registerEventCallbackInternal_1_4(const sp<V1_4::IWifiChipEventCallback> & event_callback)1499 WifiStatus WifiChip::registerEventCallbackInternal_1_4(
1500 const sp<V1_4::IWifiChipEventCallback>& event_callback) {
1501 if (!event_cb_handler_.addCallback(event_callback)) {
1502 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1503 }
1504 return createWifiStatus(WifiStatusCode::SUCCESS);
1505 }
1506
setMultiStaPrimaryConnectionInternal(const std::string & ifname)1507 WifiStatus WifiChip::setMultiStaPrimaryConnectionInternal(
1508 const std::string& ifname) {
1509 auto legacy_status =
1510 legacy_hal_.lock()->multiStaSetPrimaryConnection(ifname);
1511 return createWifiStatusFromLegacyError(legacy_status);
1512 }
1513
setMultiStaUseCaseInternal(MultiStaUseCase use_case)1514 WifiStatus WifiChip::setMultiStaUseCaseInternal(MultiStaUseCase use_case) {
1515 auto legacy_status = legacy_hal_.lock()->multiStaSetUseCase(
1516 hidl_struct_util::convertHidlMultiStaUseCaseToLegacy(use_case));
1517 return createWifiStatusFromLegacyError(legacy_status);
1518 }
1519
setCoexUnsafeChannelsInternal(std::vector<CoexUnsafeChannel> unsafe_channels,uint32_t restrictions)1520 WifiStatus WifiChip::setCoexUnsafeChannelsInternal(
1521 std::vector<CoexUnsafeChannel> unsafe_channels, uint32_t restrictions) {
1522 std::vector<legacy_hal::wifi_coex_unsafe_channel> legacy_unsafe_channels;
1523 if (!hidl_struct_util::convertHidlVectorOfCoexUnsafeChannelToLegacy(
1524 unsafe_channels, &legacy_unsafe_channels)) {
1525 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1526 }
1527 uint32_t legacy_restrictions = 0;
1528 if (restrictions & CoexRestriction::WIFI_DIRECT) {
1529 legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_DIRECT;
1530 }
1531 if (restrictions & CoexRestriction::SOFTAP) {
1532 legacy_restrictions |= legacy_hal::wifi_coex_restriction::SOFTAP;
1533 }
1534 if (restrictions & CoexRestriction::WIFI_AWARE) {
1535 legacy_restrictions |= legacy_hal::wifi_coex_restriction::WIFI_AWARE;
1536 }
1537 auto legacy_status = legacy_hal_.lock()->setCoexUnsafeChannels(
1538 legacy_unsafe_channels, legacy_restrictions);
1539 return createWifiStatusFromLegacyError(legacy_status);
1540 }
1541
setCountryCodeInternal(const std::array<int8_t,2> & code)1542 WifiStatus WifiChip::setCountryCodeInternal(const std::array<int8_t, 2>& code) {
1543 auto legacy_status =
1544 legacy_hal_.lock()->setCountryCode(getFirstActiveWlanIfaceName(), code);
1545 return createWifiStatusFromLegacyError(legacy_status);
1546 }
1547
1548 std::pair<WifiStatus, std::vector<WifiUsableChannel>>
getUsableChannelsInternal(WifiBand band,uint32_t ifaceModeMask,uint32_t filterMask)1549 WifiChip::getUsableChannelsInternal(WifiBand band, uint32_t ifaceModeMask,
1550 uint32_t filterMask) {
1551 legacy_hal::wifi_error legacy_status;
1552 std::vector<legacy_hal::wifi_usable_channel> legacy_usable_channels;
1553 std::tie(legacy_status, legacy_usable_channels) =
1554 legacy_hal_.lock()->getUsableChannels(
1555 hidl_struct_util::convertHidlWifiBandToLegacyMacBand(band),
1556 hidl_struct_util::convertHidlWifiIfaceModeToLegacy(ifaceModeMask),
1557 hidl_struct_util::convertHidlUsableChannelFilterToLegacy(
1558 filterMask));
1559
1560 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1561 return {createWifiStatusFromLegacyError(legacy_status), {}};
1562 }
1563 std::vector<WifiUsableChannel> hidl_usable_channels;
1564 if (!hidl_struct_util::convertLegacyWifiUsableChannelsToHidl(
1565 legacy_usable_channels, &hidl_usable_channels)) {
1566 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
1567 }
1568 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_usable_channels};
1569 }
1570
triggerSubsystemRestartInternal()1571 WifiStatus WifiChip::triggerSubsystemRestartInternal() {
1572 auto legacy_status = legacy_hal_.lock()->triggerSubsystemRestart();
1573 return createWifiStatusFromLegacyError(legacy_status);
1574 }
1575
handleChipConfiguration(std::unique_lock<std::recursive_mutex> * lock,ChipModeId mode_id)1576 WifiStatus WifiChip::handleChipConfiguration(
1577 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
1578 ChipModeId mode_id) {
1579 // If the chip is already configured in a different mode, stop
1580 // the legacy HAL and then start it after firmware mode change.
1581 if (isValidModeId(current_mode_id_)) {
1582 LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_
1583 << " to mode " << mode_id;
1584 invalidateAndRemoveAllIfaces();
1585 legacy_hal::wifi_error legacy_status =
1586 legacy_hal_.lock()->stop(lock, []() {});
1587 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1588 LOG(ERROR) << "Failed to stop legacy HAL: "
1589 << legacyErrorToString(legacy_status);
1590 return createWifiStatusFromLegacyError(legacy_status);
1591 }
1592 }
1593 // Firmware mode change not needed for V2 devices.
1594 bool success = true;
1595 if (mode_id == feature_flags::chip_mode_ids::kV1Sta) {
1596 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
1597 } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) {
1598 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
1599 }
1600 if (!success) {
1601 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1602 }
1603 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
1604 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1605 LOG(ERROR) << "Failed to start legacy HAL: "
1606 << legacyErrorToString(legacy_status);
1607 return createWifiStatusFromLegacyError(legacy_status);
1608 }
1609 // Every time the HAL is restarted, we need to register the
1610 // radio mode change callback.
1611 WifiStatus status = registerRadioModeChangeCallback();
1612 if (status.code != WifiStatusCode::SUCCESS) {
1613 // This probably is not a critical failure?
1614 LOG(ERROR) << "Failed to register radio mode change callback";
1615 }
1616 // Extract and save the version information into property.
1617 std::pair<WifiStatus, V1_4::IWifiChip::ChipDebugInfo> version_info;
1618 version_info = WifiChip::requestChipDebugInfoInternal();
1619 if (WifiStatusCode::SUCCESS == version_info.first.code) {
1620 property_set("vendor.wlan.firmware.version",
1621 version_info.second.firmwareDescription.c_str());
1622 property_set("vendor.wlan.driver.version",
1623 version_info.second.driverDescription.c_str());
1624 }
1625
1626 return createWifiStatus(WifiStatusCode::SUCCESS);
1627 }
1628
registerDebugRingBufferCallback()1629 WifiStatus WifiChip::registerDebugRingBufferCallback() {
1630 if (debug_ring_buffer_cb_registered_) {
1631 return createWifiStatus(WifiStatusCode::SUCCESS);
1632 }
1633
1634 android::wp<WifiChip> weak_ptr_this(this);
1635 const auto& on_ring_buffer_data_callback =
1636 [weak_ptr_this](const std::string& name,
1637 const std::vector<uint8_t>& data,
1638 const legacy_hal::wifi_ring_buffer_status& status) {
1639 const auto shared_ptr_this = weak_ptr_this.promote();
1640 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1641 LOG(ERROR) << "Callback invoked on an invalid object";
1642 return;
1643 }
1644 WifiDebugRingBufferStatus hidl_status;
1645 if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(
1646 status, &hidl_status)) {
1647 LOG(ERROR) << "Error converting ring buffer status";
1648 return;
1649 }
1650 {
1651 std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t);
1652 const auto& target =
1653 shared_ptr_this->ringbuffer_map_.find(name);
1654 if (target != shared_ptr_this->ringbuffer_map_.end()) {
1655 Ringbuffer& cur_buffer = target->second;
1656 cur_buffer.append(data);
1657 } else {
1658 LOG(ERROR) << "Ringname " << name << " not found";
1659 return;
1660 }
1661 // unique_lock unlocked here
1662 }
1663 };
1664 legacy_hal::wifi_error legacy_status =
1665 legacy_hal_.lock()->registerRingBufferCallbackHandler(
1666 getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback);
1667
1668 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1669 debug_ring_buffer_cb_registered_ = true;
1670 }
1671 return createWifiStatusFromLegacyError(legacy_status);
1672 }
1673
registerRadioModeChangeCallback()1674 WifiStatus WifiChip::registerRadioModeChangeCallback() {
1675 android::wp<WifiChip> weak_ptr_this(this);
1676 const auto& on_radio_mode_change_callback =
1677 [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
1678 const auto shared_ptr_this = weak_ptr_this.promote();
1679 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1680 LOG(ERROR) << "Callback invoked on an invalid object";
1681 return;
1682 }
1683 std::vector<V1_4::IWifiChipEventCallback::RadioModeInfo>
1684 hidl_radio_mode_infos;
1685 if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(
1686 mac_infos, &hidl_radio_mode_infos)) {
1687 LOG(ERROR) << "Error converting wifi mac info";
1688 return;
1689 }
1690 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
1691 if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos)
1692 .isOk()) {
1693 LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4"
1694 << " callback on: " << toString(callback);
1695 }
1696 }
1697 };
1698 legacy_hal::wifi_error legacy_status =
1699 legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
1700 getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
1701 return createWifiStatusFromLegacyError(legacy_status);
1702 }
1703
1704 std::vector<V1_4::IWifiChip::ChipIfaceCombination>
getCurrentModeIfaceCombinations()1705 WifiChip::getCurrentModeIfaceCombinations() {
1706 if (!isValidModeId(current_mode_id_)) {
1707 LOG(ERROR) << "Chip not configured in a mode yet";
1708 return {};
1709 }
1710 for (const auto& mode : modes_) {
1711 if (mode.id == current_mode_id_) {
1712 return mode.availableCombinations;
1713 }
1714 }
1715 CHECK(0) << "Expected to find iface combinations for current mode!";
1716 return {};
1717 }
1718
1719 // Returns a map indexed by IfaceType with the number of ifaces currently
1720 // created of the corresponding type.
getCurrentIfaceCombination()1721 std::map<IfaceType, size_t> WifiChip::getCurrentIfaceCombination() {
1722 std::map<IfaceType, size_t> iface_counts;
1723 iface_counts[IfaceType::AP] = ap_ifaces_.size();
1724 iface_counts[IfaceType::NAN] = nan_ifaces_.size();
1725 iface_counts[IfaceType::P2P] = p2p_ifaces_.size();
1726 iface_counts[IfaceType::STA] = sta_ifaces_.size();
1727 return iface_counts;
1728 }
1729
1730 // This expands the provided iface combinations to a more parseable
1731 // form. Returns a vector of available combinations possible with the number
1732 // of ifaces of each type in the combination.
1733 // This method is a port of HalDeviceManager.expandIfaceCombos() from framework.
expandIfaceCombinations(const V1_4::IWifiChip::ChipIfaceCombination & combination)1734 std::vector<std::map<IfaceType, size_t>> WifiChip::expandIfaceCombinations(
1735 const V1_4::IWifiChip::ChipIfaceCombination& combination) {
1736 uint32_t num_expanded_combos = 1;
1737 for (const auto& limit : combination.limits) {
1738 for (uint32_t i = 0; i < limit.maxIfaces; i++) {
1739 num_expanded_combos *= limit.types.size();
1740 }
1741 }
1742
1743 // Allocate the vector of expanded combos and reset all iface counts to 0
1744 // in each combo.
1745 std::vector<std::map<IfaceType, size_t>> expanded_combos;
1746 expanded_combos.resize(num_expanded_combos);
1747 for (auto& expanded_combo : expanded_combos) {
1748 for (const auto type :
1749 {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
1750 expanded_combo[type] = 0;
1751 }
1752 }
1753 uint32_t span = num_expanded_combos;
1754 for (const auto& limit : combination.limits) {
1755 for (uint32_t i = 0; i < limit.maxIfaces; i++) {
1756 span /= limit.types.size();
1757 for (uint32_t k = 0; k < num_expanded_combos; ++k) {
1758 const auto iface_type =
1759 limit.types[(k / span) % limit.types.size()];
1760 expanded_combos[k][iface_type]++;
1761 }
1762 }
1763 }
1764 return expanded_combos;
1765 }
1766
canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(const std::map<IfaceType,size_t> & expanded_combo,IfaceType requested_type)1767 bool WifiChip::canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
1768 const std::map<IfaceType, size_t>& expanded_combo,
1769 IfaceType requested_type) {
1770 const auto current_combo = getCurrentIfaceCombination();
1771
1772 // Check if we have space for 1 more iface of |type| in this combo
1773 for (const auto type :
1774 {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
1775 size_t num_ifaces_needed = current_combo.at(type);
1776 if (type == requested_type) {
1777 num_ifaces_needed++;
1778 }
1779 size_t num_ifaces_allowed = expanded_combo.at(type);
1780 if (num_ifaces_needed > num_ifaces_allowed) {
1781 return false;
1782 }
1783 }
1784 return true;
1785 }
1786
1787 // This method does the following:
1788 // a) Enumerate all possible iface combos by expanding the current
1789 // ChipIfaceCombination.
1790 // b) Check if the requested iface type can be added to the current mode
1791 // with the iface combination that is already active.
canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType requested_type)1792 bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(
1793 IfaceType requested_type) {
1794 if (!isValidModeId(current_mode_id_)) {
1795 LOG(ERROR) << "Chip not configured in a mode yet";
1796 return false;
1797 }
1798 const auto combinations = getCurrentModeIfaceCombinations();
1799 for (const auto& combination : combinations) {
1800 const auto expanded_combos = expandIfaceCombinations(combination);
1801 for (const auto& expanded_combo : expanded_combos) {
1802 if (canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
1803 expanded_combo, requested_type)) {
1804 return true;
1805 }
1806 }
1807 }
1808 return false;
1809 }
1810
1811 // Note: This does not consider ifaces already active. It only checks if the
1812 // provided expanded iface combination can support the requested combo.
canExpandedIfaceComboSupportIfaceCombo(const std::map<IfaceType,size_t> & expanded_combo,const std::map<IfaceType,size_t> & req_combo)1813 bool WifiChip::canExpandedIfaceComboSupportIfaceCombo(
1814 const std::map<IfaceType, size_t>& expanded_combo,
1815 const std::map<IfaceType, size_t>& req_combo) {
1816 // Check if we have space for 1 more iface of |type| in this combo
1817 for (const auto type :
1818 {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
1819 if (req_combo.count(type) == 0) {
1820 // Iface of "type" not in the req_combo.
1821 continue;
1822 }
1823 size_t num_ifaces_needed = req_combo.at(type);
1824 size_t num_ifaces_allowed = expanded_combo.at(type);
1825 if (num_ifaces_needed > num_ifaces_allowed) {
1826 return false;
1827 }
1828 }
1829 return true;
1830 }
1831 // This method does the following:
1832 // a) Enumerate all possible iface combos by expanding the current
1833 // ChipIfaceCombination.
1834 // b) Check if the requested iface combo can be added to the current mode.
1835 // Note: This does not consider ifaces already active. It only checks if the
1836 // current mode can support the requested combo.
canCurrentModeSupportIfaceCombo(const std::map<IfaceType,size_t> & req_combo)1837 bool WifiChip::canCurrentModeSupportIfaceCombo(
1838 const std::map<IfaceType, size_t>& req_combo) {
1839 if (!isValidModeId(current_mode_id_)) {
1840 LOG(ERROR) << "Chip not configured in a mode yet";
1841 return false;
1842 }
1843 const auto combinations = getCurrentModeIfaceCombinations();
1844 for (const auto& combination : combinations) {
1845 const auto expanded_combos = expandIfaceCombinations(combination);
1846 for (const auto& expanded_combo : expanded_combos) {
1847 if (canExpandedIfaceComboSupportIfaceCombo(expanded_combo,
1848 req_combo)) {
1849 return true;
1850 }
1851 }
1852 }
1853 return false;
1854 }
1855
1856 // This method does the following:
1857 // a) Enumerate all possible iface combos by expanding the current
1858 // ChipIfaceCombination.
1859 // b) Check if the requested iface type can be added to the current mode.
canCurrentModeSupportIfaceOfType(IfaceType requested_type)1860 bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType requested_type) {
1861 // Check if we can support at least 1 iface of type.
1862 std::map<IfaceType, size_t> req_iface_combo;
1863 req_iface_combo[requested_type] = 1;
1864 return canCurrentModeSupportIfaceCombo(req_iface_combo);
1865 }
1866
isValidModeId(ChipModeId mode_id)1867 bool WifiChip::isValidModeId(ChipModeId mode_id) {
1868 for (const auto& mode : modes_) {
1869 if (mode.id == mode_id) {
1870 return true;
1871 }
1872 }
1873 return false;
1874 }
1875
isStaApConcurrencyAllowedInCurrentMode()1876 bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
1877 // Check if we can support at least 1 STA & 1 AP concurrently.
1878 std::map<IfaceType, size_t> req_iface_combo;
1879 req_iface_combo[IfaceType::AP] = 1;
1880 req_iface_combo[IfaceType::STA] = 1;
1881 return canCurrentModeSupportIfaceCombo(req_iface_combo);
1882 }
1883
isDualStaConcurrencyAllowedInCurrentMode()1884 bool WifiChip::isDualStaConcurrencyAllowedInCurrentMode() {
1885 // Check if we can support at least 2 STA concurrently.
1886 std::map<IfaceType, size_t> req_iface_combo;
1887 req_iface_combo[IfaceType::STA] = 2;
1888 return canCurrentModeSupportIfaceCombo(req_iface_combo);
1889 }
1890
getFirstActiveWlanIfaceName()1891 std::string WifiChip::getFirstActiveWlanIfaceName() {
1892 if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName();
1893 if (ap_ifaces_.size() > 0) {
1894 // If the first active wlan iface is bridged iface.
1895 // Return first instance name.
1896 for (auto const& it : br_ifaces_ap_instances_) {
1897 if (it.first == ap_ifaces_[0]->getName()) {
1898 return it.second[0];
1899 }
1900 }
1901 return ap_ifaces_[0]->getName();
1902 }
1903 // This could happen if the chip call is made before any STA/AP
1904 // iface is created. Default to wlan0 for such cases.
1905 LOG(WARNING) << "No active wlan interfaces in use! Using default";
1906 return getWlanIfaceNameWithType(IfaceType::STA, 0);
1907 }
1908
1909 // Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx|
1910 // not already in use.
1911 // Note: This doesn't check the actual presence of these interfaces.
allocateApOrStaIfaceName(IfaceType type,uint32_t start_idx)1912 std::string WifiChip::allocateApOrStaIfaceName(IfaceType type,
1913 uint32_t start_idx) {
1914 for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
1915 const auto ifname = getWlanIfaceNameWithType(type, idx);
1916 if (findUsingNameFromBridgedApInstances(ifname)) continue;
1917 if (findUsingName(ap_ifaces_, ifname)) continue;
1918 if (findUsingName(sta_ifaces_, ifname)) continue;
1919 return ifname;
1920 }
1921 // This should never happen. We screwed up somewhere if it did.
1922 CHECK(false) << "All wlan interfaces in use already!";
1923 return {};
1924 }
1925
startIdxOfApIface()1926 uint32_t WifiChip::startIdxOfApIface() {
1927 if (isDualStaConcurrencyAllowedInCurrentMode()) {
1928 // When the HAL support dual STAs, AP should start with idx 2.
1929 return 2;
1930 } else if (isStaApConcurrencyAllowedInCurrentMode()) {
1931 // When the HAL support STA + AP but it doesn't support dual STAs.
1932 // AP should start with idx 1.
1933 return 1;
1934 }
1935 // No concurrency support.
1936 return 0;
1937 }
1938
1939 // AP iface names start with idx 1 for modes supporting
1940 // concurrent STA and not dual AP, else start with idx 0.
allocateApIfaceName()1941 std::string WifiChip::allocateApIfaceName() {
1942 // Check if we have a dedicated iface for AP.
1943 std::vector<std::string> ifnames = getPredefinedApIfaceNames(false);
1944 if (!ifnames.empty()) {
1945 return ifnames[0];
1946 }
1947 return allocateApOrStaIfaceName(IfaceType::AP, startIdxOfApIface());
1948 }
1949
allocateBridgedApInstanceNames()1950 std::vector<std::string> WifiChip::allocateBridgedApInstanceNames() {
1951 // Check if we have a dedicated iface for AP.
1952 std::vector<std::string> instances = getPredefinedApIfaceNames(true);
1953 if (instances.size() == 2) {
1954 return instances;
1955 } else {
1956 int num_ifaces_need_to_allocate = 2 - instances.size();
1957 for (int i = 0; i < num_ifaces_need_to_allocate; i++) {
1958 std::string instance_name = allocateApOrStaIfaceName(
1959 IfaceType::AP, startIdxOfApIface() + i);
1960 if (!instance_name.empty()) {
1961 instances.push_back(instance_name);
1962 }
1963 }
1964 }
1965 return instances;
1966 }
1967
1968 // STA iface names start with idx 0.
1969 // Primary STA iface will always be 0.
allocateStaIfaceName()1970 std::string WifiChip::allocateStaIfaceName() {
1971 return allocateApOrStaIfaceName(IfaceType::STA, 0);
1972 }
1973
writeRingbufferFilesInternal()1974 bool WifiChip::writeRingbufferFilesInternal() {
1975 if (!removeOldFilesInternal()) {
1976 LOG(ERROR) << "Error occurred while deleting old tombstone files";
1977 return false;
1978 }
1979 // write ringbuffers to file
1980 {
1981 std::unique_lock<std::mutex> lk(lock_t);
1982 for (auto& item : ringbuffer_map_) {
1983 Ringbuffer& cur_buffer = item.second;
1984 if (cur_buffer.getData().empty()) {
1985 continue;
1986 }
1987 const std::string file_path_raw =
1988 kTombstoneFolderPath + item.first + "XXXXXXXXXX";
1989 const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
1990 if (dump_fd == -1) {
1991 PLOG(ERROR) << "create file failed";
1992 return false;
1993 }
1994 unique_fd file_auto_closer(dump_fd);
1995 for (const auto& cur_block : cur_buffer.getData()) {
1996 if (write(dump_fd, cur_block.data(),
1997 sizeof(cur_block[0]) * cur_block.size()) == -1) {
1998 PLOG(ERROR) << "Error writing to file";
1999 }
2000 }
2001 cur_buffer.clear();
2002 }
2003 // unique_lock unlocked here
2004 }
2005 return true;
2006 }
2007
getWlanIfaceNameWithType(IfaceType type,unsigned idx)2008 std::string WifiChip::getWlanIfaceNameWithType(IfaceType type, unsigned idx) {
2009 std::string ifname;
2010
2011 // let the legacy hal override the interface name
2012 legacy_hal::wifi_error err =
2013 legacy_hal_.lock()->getSupportedIfaceName((uint32_t)type, ifname);
2014 if (err == legacy_hal::WIFI_SUCCESS) return ifname;
2015
2016 return getWlanIfaceName(idx);
2017 }
2018
invalidateAndClearBridgedApAll()2019 void WifiChip::invalidateAndClearBridgedApAll() {
2020 for (auto const& it : br_ifaces_ap_instances_) {
2021 for (auto const& iface : it.second) {
2022 iface_util_->removeIfaceFromBridge(it.first, iface);
2023 legacy_hal_.lock()->deleteVirtualInterface(iface);
2024 }
2025 iface_util_->deleteBridge(it.first);
2026 }
2027 br_ifaces_ap_instances_.clear();
2028 }
2029
invalidateAndClearBridgedAp(const std::string & br_name)2030 void WifiChip::invalidateAndClearBridgedAp(const std::string& br_name) {
2031 if (br_name.empty()) return;
2032 // delete managed interfaces
2033 for (auto const& it : br_ifaces_ap_instances_) {
2034 if (it.first == br_name) {
2035 for (auto const& iface : it.second) {
2036 iface_util_->removeIfaceFromBridge(br_name, iface);
2037 legacy_hal_.lock()->deleteVirtualInterface(iface);
2038 }
2039 iface_util_->deleteBridge(br_name);
2040 br_ifaces_ap_instances_.erase(br_name);
2041 break;
2042 }
2043 }
2044 return;
2045 }
2046
findUsingNameFromBridgedApInstances(const std::string & name)2047 bool WifiChip::findUsingNameFromBridgedApInstances(const std::string& name) {
2048 for (auto const& it : br_ifaces_ap_instances_) {
2049 if (it.first == name) {
2050 return true;
2051 }
2052 for (auto const& iface : it.second) {
2053 if (iface == name) {
2054 return true;
2055 }
2056 }
2057 }
2058 return false;
2059 }
2060
2061 } // namespace implementation
2062 } // namespace V1_5
2063 } // namespace wifi
2064 } // namespace hardware
2065 } // namespace android
2066