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