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