• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <fcntl.h>
18 
19 #include <android-base/logging.h>
20 #include <android-base/unique_fd.h>
21 #include <cutils/properties.h>
22 #include <sys/stat.h>
23 #include <sys/sysmacros.h>
24 
25 #include "hidl_return_util.h"
26 #include "hidl_struct_util.h"
27 #include "wifi_chip.h"
28 #include "wifi_status_util.h"
29 
30 namespace {
31 using android::sp;
32 using android::base::unique_fd;
33 using android::hardware::hidl_string;
34 using android::hardware::hidl_vec;
35 using android::hardware::wifi::V1_0::ChipModeId;
36 using android::hardware::wifi::V1_0::IfaceType;
37 using android::hardware::wifi::V1_0::IWifiChip;
38 
39 constexpr char kCpioMagic[] = "070701";
40 constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3;
41 constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10;
42 constexpr uint32_t kMaxRingBufferFileNum = 20;
43 constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
44 constexpr char kActiveWlanIfaceNameProperty[] = "wifi.active.interface";
45 constexpr char kNoActiveWlanIfaceNamePropertyValue[] = "";
46 constexpr unsigned kMaxWlanIfaces = 5;
47 
48 template <typename Iface>
invalidateAndClear(std::vector<sp<Iface>> & ifaces,sp<Iface> iface)49 void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
50     iface->invalidate();
51     ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface),
52                  ifaces.end());
53 }
54 
55 template <typename Iface>
invalidateAndClearAll(std::vector<sp<Iface>> & ifaces)56 void invalidateAndClearAll(std::vector<sp<Iface>>& ifaces) {
57     for (const auto& iface : ifaces) {
58         iface->invalidate();
59     }
60     ifaces.clear();
61 }
62 
63 template <typename Iface>
getNames(std::vector<sp<Iface>> & ifaces)64 std::vector<hidl_string> getNames(std::vector<sp<Iface>>& ifaces) {
65     std::vector<hidl_string> names;
66     for (const auto& iface : ifaces) {
67         names.emplace_back(iface->getName());
68     }
69     return names;
70 }
71 
72 template <typename Iface>
findUsingName(std::vector<sp<Iface>> & ifaces,const std::string & name)73 sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces,
74                         const std::string& name) {
75     std::vector<hidl_string> names;
76     for (const auto& iface : ifaces) {
77         if (name == iface->getName()) {
78             return iface;
79         }
80     }
81     return nullptr;
82 }
83 
getWlanIfaceName(unsigned idx)84 std::string getWlanIfaceName(unsigned idx) {
85     if (idx >= kMaxWlanIfaces) {
86         CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
87         return {};
88     }
89 
90     std::array<char, PROPERTY_VALUE_MAX> buffer;
91     if (idx == 0 || idx == 1) {
92         const char* altPropName =
93             (idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
94         auto res = property_get(altPropName, buffer.data(), nullptr);
95         if (res > 0) return buffer.data();
96     }
97     std::string propName = "wifi.interface." + std::to_string(idx);
98     auto res = property_get(propName.c_str(), buffer.data(), nullptr);
99     if (res > 0) return buffer.data();
100 
101     return "wlan" + std::to_string(idx);
102 }
103 
104 // Returns the dedicated iface name if one is defined.
getApIfaceName()105 std::string getApIfaceName() {
106     std::array<char, PROPERTY_VALUE_MAX> buffer;
107     if (property_get("ro.vendor.wifi.sap.interface", buffer.data(), nullptr) ==
108         0) {
109         return {};
110     }
111     return buffer.data();
112 }
113 
getP2pIfaceName()114 std::string getP2pIfaceName() {
115     std::array<char, PROPERTY_VALUE_MAX> buffer;
116     property_get("wifi.direct.interface", buffer.data(), "p2p0");
117     return buffer.data();
118 }
119 
120 // Returns the dedicated iface name if one is defined.
getNanIfaceName()121 std::string getNanIfaceName() {
122     std::array<char, PROPERTY_VALUE_MAX> buffer;
123     if (property_get("wifi.aware.interface", buffer.data(), nullptr) == 0) {
124         return {};
125     }
126     return buffer.data();
127 }
128 
setActiveWlanIfaceNameProperty(const std::string & ifname)129 void setActiveWlanIfaceNameProperty(const std::string& ifname) {
130     auto res = property_set(kActiveWlanIfaceNameProperty, ifname.data());
131     if (res != 0) {
132         PLOG(ERROR) << "Failed to set active wlan iface name property";
133     }
134 }
135 
136 // delete files that meet either conditions:
137 // 1. older than a predefined time in the wifi tombstone dir.
138 // 2. Files in excess to a predefined amount, starting from the oldest ones
removeOldFilesInternal()139 bool removeOldFilesInternal() {
140     time_t now = time(0);
141     const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds;
142     std::unique_ptr<DIR, decltype(&closedir)> dir_dump(
143         opendir(kTombstoneFolderPath), closedir);
144     if (!dir_dump) {
145         PLOG(ERROR) << "Failed to open directory";
146         return false;
147     }
148     struct dirent* dp;
149     bool success = true;
150     std::list<std::pair<const time_t, std::string>> valid_files;
151     while ((dp = readdir(dir_dump.get()))) {
152         if (dp->d_type != DT_REG) {
153             continue;
154         }
155         std::string cur_file_name(dp->d_name);
156         struct stat cur_file_stat;
157         std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
158         if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) {
159             PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
160             success = false;
161             continue;
162         }
163         const time_t cur_file_time = cur_file_stat.st_mtime;
164         valid_files.push_back(
165             std::pair<const time_t, std::string>(cur_file_time, cur_file_path));
166     }
167     valid_files.sort();  // sort the list of files by last modified time from
168                          // small to big.
169     uint32_t cur_file_count = valid_files.size();
170     for (auto cur_file : valid_files) {
171         if (cur_file_count > kMaxRingBufferFileNum ||
172             cur_file.first < delete_files_before) {
173             if (unlink(cur_file.second.c_str()) != 0) {
174                 PLOG(ERROR) << "Error deleting file";
175                 success = false;
176             }
177             cur_file_count--;
178         } else {
179             break;
180         }
181     }
182     return success;
183 }
184 
185 // Helper function for |cpioArchiveFilesInDir|
cpioWriteHeader(int out_fd,struct stat & st,const char * file_name,size_t file_name_len)186 bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name,
187                      size_t file_name_len) {
188     std::array<char, 32 * 1024> read_buf;
189     ssize_t llen =
190         sprintf(read_buf.data(),
191                 "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X",
192                 kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid,
193                 st.st_gid, static_cast<int>(st.st_nlink),
194                 static_cast<int>(st.st_mtime), static_cast<int>(st.st_size),
195                 major(st.st_dev), minor(st.st_dev), major(st.st_rdev),
196                 minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0);
197     if (write(out_fd, read_buf.data(), llen) == -1) {
198         PLOG(ERROR) << "Error writing cpio header to file " << file_name;
199         return false;
200     }
201     if (write(out_fd, file_name, file_name_len) == -1) {
202         PLOG(ERROR) << "Error writing filename to file " << file_name;
203         return false;
204     }
205 
206     // NUL Pad header up to 4 multiple bytes.
207     llen = (llen + file_name_len) % 4;
208     if (llen != 0) {
209         const uint32_t zero = 0;
210         if (write(out_fd, &zero, 4 - llen) == -1) {
211             PLOG(ERROR) << "Error padding 0s to file " << file_name;
212             return false;
213         }
214     }
215     return true;
216 }
217 
218 // Helper function for |cpioArchiveFilesInDir|
cpioWriteFileContent(int fd_read,int out_fd,struct stat & st)219 size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) {
220     // writing content of file
221     std::array<char, 32 * 1024> read_buf;
222     ssize_t llen = st.st_size;
223     size_t n_error = 0;
224     while (llen > 0) {
225         ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size());
226         if (bytes_read == -1) {
227             PLOG(ERROR) << "Error reading file";
228             return ++n_error;
229         }
230         llen -= bytes_read;
231         if (write(out_fd, read_buf.data(), bytes_read) == -1) {
232             PLOG(ERROR) << "Error writing data to file";
233             return ++n_error;
234         }
235         if (bytes_read == 0) {  // this should never happen, but just in case
236                                 // to unstuck from while loop
237             PLOG(ERROR) << "Unexpected read result";
238             n_error++;
239             break;
240         }
241     }
242     llen = st.st_size % 4;
243     if (llen != 0) {
244         const uint32_t zero = 0;
245         if (write(out_fd, &zero, 4 - llen) == -1) {
246             PLOG(ERROR) << "Error padding 0s to file";
247             return ++n_error;
248         }
249     }
250     return n_error;
251 }
252 
253 // Helper function for |cpioArchiveFilesInDir|
cpioWriteFileTrailer(int out_fd)254 bool cpioWriteFileTrailer(int out_fd) {
255     std::array<char, 4096> read_buf;
256     read_buf.fill(0);
257     if (write(out_fd, read_buf.data(),
258               sprintf(read_buf.data(), "070701%040X%056X%08XTRAILER!!!", 1,
259                       0x0b, 0) +
260                   4) == -1) {
261         PLOG(ERROR) << "Error writing trailing bytes";
262         return false;
263     }
264     return true;
265 }
266 
267 // Archives all files in |input_dir| and writes result into |out_fd|
268 // Logic obtained from //external/toybox/toys/posix/cpio.c "Output cpio archive"
269 // portion
cpioArchiveFilesInDir(int out_fd,const char * input_dir)270 size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) {
271     struct dirent* dp;
272     size_t n_error = 0;
273     std::unique_ptr<DIR, decltype(&closedir)> dir_dump(opendir(input_dir),
274                                                        closedir);
275     if (!dir_dump) {
276         PLOG(ERROR) << "Failed to open directory";
277         return ++n_error;
278     }
279     while ((dp = readdir(dir_dump.get()))) {
280         if (dp->d_type != DT_REG) {
281             continue;
282         }
283         std::string cur_file_name(dp->d_name);
284         // string.size() does not include the null terminator. The cpio FreeBSD
285         // file header expects the null character to be included in the length.
286         const size_t file_name_len = cur_file_name.size() + 1;
287         struct stat st;
288         const std::string cur_file_path = kTombstoneFolderPath + cur_file_name;
289         if (stat(cur_file_path.c_str(), &st) == -1) {
290             PLOG(ERROR) << "Failed to get file stat for " << cur_file_path;
291             n_error++;
292             continue;
293         }
294         const int fd_read = open(cur_file_path.c_str(), O_RDONLY);
295         if (fd_read == -1) {
296             PLOG(ERROR) << "Failed to open file " << cur_file_path;
297             n_error++;
298             continue;
299         }
300         unique_fd file_auto_closer(fd_read);
301         if (!cpioWriteHeader(out_fd, st, cur_file_name.c_str(),
302                              file_name_len)) {
303             return ++n_error;
304         }
305         size_t write_error = cpioWriteFileContent(fd_read, out_fd, st);
306         if (write_error) {
307             return n_error + write_error;
308         }
309     }
310     if (!cpioWriteFileTrailer(out_fd)) {
311         return ++n_error;
312     }
313     return n_error;
314 }
315 
316 // Helper function to create a non-const char*.
makeCharVec(const std::string & str)317 std::vector<char> makeCharVec(const std::string& str) {
318     std::vector<char> vec(str.size() + 1);
319     vec.assign(str.begin(), str.end());
320     vec.push_back('\0');
321     return vec;
322 }
323 
324 }  // namespace
325 
326 namespace android {
327 namespace hardware {
328 namespace wifi {
329 namespace V1_4 {
330 namespace implementation {
331 using hidl_return_util::validateAndCall;
332 using hidl_return_util::validateAndCallWithLock;
333 
WifiChip(ChipId chip_id,const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,const std::weak_ptr<mode_controller::WifiModeController> mode_controller,const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util,const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags)334 WifiChip::WifiChip(
335     ChipId chip_id, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
336     const std::weak_ptr<mode_controller::WifiModeController> mode_controller,
337     const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util,
338     const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags)
339     : chip_id_(chip_id),
340       legacy_hal_(legacy_hal),
341       mode_controller_(mode_controller),
342       iface_util_(iface_util),
343       is_valid_(true),
344       current_mode_id_(feature_flags::chip_mode_ids::kInvalid),
345       modes_(feature_flags.lock()->getChipModes()),
346       debug_ring_buffer_cb_registered_(false) {
347     setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
348 }
349 
invalidate()350 void WifiChip::invalidate() {
351     if (!writeRingbufferFilesInternal()) {
352         LOG(ERROR) << "Error writing files to flash";
353     }
354     invalidateAndRemoveAllIfaces();
355     setActiveWlanIfaceNameProperty(kNoActiveWlanIfaceNamePropertyValue);
356     legacy_hal_.reset();
357     event_cb_handler_.invalidate();
358     is_valid_ = false;
359 }
360 
isValid()361 bool WifiChip::isValid() { return is_valid_; }
362 
getEventCallbacks()363 std::set<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() {
364     return event_cb_handler_.getCallbacks();
365 }
366 
getId(getId_cb hidl_status_cb)367 Return<void> WifiChip::getId(getId_cb hidl_status_cb) {
368     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
369                            &WifiChip::getIdInternal, hidl_status_cb);
370 }
371 
372 // Deprecated support for this callback
registerEventCallback(const sp<V1_0::IWifiChipEventCallback> & event_callback,registerEventCallback_cb hidl_status_cb)373 Return<void> WifiChip::registerEventCallback(
374     const sp<V1_0::IWifiChipEventCallback>& event_callback,
375     registerEventCallback_cb hidl_status_cb) {
376     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
377                            &WifiChip::registerEventCallbackInternal,
378                            hidl_status_cb, event_callback);
379 }
380 
getCapabilities(getCapabilities_cb hidl_status_cb)381 Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) {
382     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
383                            &WifiChip::getCapabilitiesInternal, hidl_status_cb);
384 }
385 
getAvailableModes(getAvailableModes_cb hidl_status_cb)386 Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) {
387     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
388                            &WifiChip::getAvailableModesInternal,
389                            hidl_status_cb);
390 }
391 
configureChip(ChipModeId mode_id,configureChip_cb hidl_status_cb)392 Return<void> WifiChip::configureChip(ChipModeId mode_id,
393                                      configureChip_cb hidl_status_cb) {
394     return validateAndCallWithLock(
395         this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
396         &WifiChip::configureChipInternal, hidl_status_cb, mode_id);
397 }
398 
getMode(getMode_cb hidl_status_cb)399 Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) {
400     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
401                            &WifiChip::getModeInternal, hidl_status_cb);
402 }
403 
requestChipDebugInfo(requestChipDebugInfo_cb hidl_status_cb)404 Return<void> WifiChip::requestChipDebugInfo(
405     requestChipDebugInfo_cb hidl_status_cb) {
406     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
407                            &WifiChip::requestChipDebugInfoInternal,
408                            hidl_status_cb);
409 }
410 
requestDriverDebugDump(requestDriverDebugDump_cb hidl_status_cb)411 Return<void> WifiChip::requestDriverDebugDump(
412     requestDriverDebugDump_cb hidl_status_cb) {
413     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
414                            &WifiChip::requestDriverDebugDumpInternal,
415                            hidl_status_cb);
416 }
417 
requestFirmwareDebugDump(requestFirmwareDebugDump_cb hidl_status_cb)418 Return<void> WifiChip::requestFirmwareDebugDump(
419     requestFirmwareDebugDump_cb hidl_status_cb) {
420     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
421                            &WifiChip::requestFirmwareDebugDumpInternal,
422                            hidl_status_cb);
423 }
424 
createApIface(createApIface_cb hidl_status_cb)425 Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) {
426     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
427                            &WifiChip::createApIfaceInternal, hidl_status_cb);
428 }
429 
getApIfaceNames(getApIfaceNames_cb hidl_status_cb)430 Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) {
431     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
432                            &WifiChip::getApIfaceNamesInternal, hidl_status_cb);
433 }
434 
getApIface(const hidl_string & ifname,getApIface_cb hidl_status_cb)435 Return<void> WifiChip::getApIface(const hidl_string& ifname,
436                                   getApIface_cb hidl_status_cb) {
437     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
438                            &WifiChip::getApIfaceInternal, hidl_status_cb,
439                            ifname);
440 }
441 
removeApIface(const hidl_string & ifname,removeApIface_cb hidl_status_cb)442 Return<void> WifiChip::removeApIface(const hidl_string& ifname,
443                                      removeApIface_cb hidl_status_cb) {
444     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
445                            &WifiChip::removeApIfaceInternal, hidl_status_cb,
446                            ifname);
447 }
448 
createNanIface(createNanIface_cb hidl_status_cb)449 Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) {
450     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
451                            &WifiChip::createNanIfaceInternal, hidl_status_cb);
452 }
453 
getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb)454 Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) {
455     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
456                            &WifiChip::getNanIfaceNamesInternal, hidl_status_cb);
457 }
458 
getNanIface(const hidl_string & ifname,getNanIface_cb hidl_status_cb)459 Return<void> WifiChip::getNanIface(const hidl_string& ifname,
460                                    getNanIface_cb hidl_status_cb) {
461     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
462                            &WifiChip::getNanIfaceInternal, hidl_status_cb,
463                            ifname);
464 }
465 
removeNanIface(const hidl_string & ifname,removeNanIface_cb hidl_status_cb)466 Return<void> WifiChip::removeNanIface(const hidl_string& ifname,
467                                       removeNanIface_cb hidl_status_cb) {
468     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
469                            &WifiChip::removeNanIfaceInternal, hidl_status_cb,
470                            ifname);
471 }
472 
createP2pIface(createP2pIface_cb hidl_status_cb)473 Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) {
474     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
475                            &WifiChip::createP2pIfaceInternal, hidl_status_cb);
476 }
477 
getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb)478 Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) {
479     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
480                            &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb);
481 }
482 
getP2pIface(const hidl_string & ifname,getP2pIface_cb hidl_status_cb)483 Return<void> WifiChip::getP2pIface(const hidl_string& ifname,
484                                    getP2pIface_cb hidl_status_cb) {
485     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
486                            &WifiChip::getP2pIfaceInternal, hidl_status_cb,
487                            ifname);
488 }
489 
removeP2pIface(const hidl_string & ifname,removeP2pIface_cb hidl_status_cb)490 Return<void> WifiChip::removeP2pIface(const hidl_string& ifname,
491                                       removeP2pIface_cb hidl_status_cb) {
492     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
493                            &WifiChip::removeP2pIfaceInternal, hidl_status_cb,
494                            ifname);
495 }
496 
createStaIface(createStaIface_cb hidl_status_cb)497 Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) {
498     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
499                            &WifiChip::createStaIfaceInternal, hidl_status_cb);
500 }
501 
getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb)502 Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) {
503     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
504                            &WifiChip::getStaIfaceNamesInternal, hidl_status_cb);
505 }
506 
getStaIface(const hidl_string & ifname,getStaIface_cb hidl_status_cb)507 Return<void> WifiChip::getStaIface(const hidl_string& ifname,
508                                    getStaIface_cb hidl_status_cb) {
509     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
510                            &WifiChip::getStaIfaceInternal, hidl_status_cb,
511                            ifname);
512 }
513 
removeStaIface(const hidl_string & ifname,removeStaIface_cb hidl_status_cb)514 Return<void> WifiChip::removeStaIface(const hidl_string& ifname,
515                                       removeStaIface_cb hidl_status_cb) {
516     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
517                            &WifiChip::removeStaIfaceInternal, hidl_status_cb,
518                            ifname);
519 }
520 
createRttController(const sp<IWifiIface> & bound_iface,createRttController_cb hidl_status_cb)521 Return<void> WifiChip::createRttController(
522     const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) {
523     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
524                            &WifiChip::createRttControllerInternal,
525                            hidl_status_cb, bound_iface);
526 }
527 
getDebugRingBuffersStatus(getDebugRingBuffersStatus_cb hidl_status_cb)528 Return<void> WifiChip::getDebugRingBuffersStatus(
529     getDebugRingBuffersStatus_cb hidl_status_cb) {
530     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
531                            &WifiChip::getDebugRingBuffersStatusInternal,
532                            hidl_status_cb);
533 }
534 
startLoggingToDebugRingBuffer(const hidl_string & ring_name,WifiDebugRingBufferVerboseLevel verbose_level,uint32_t max_interval_in_sec,uint32_t min_data_size_in_bytes,startLoggingToDebugRingBuffer_cb hidl_status_cb)535 Return<void> WifiChip::startLoggingToDebugRingBuffer(
536     const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
537     uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes,
538     startLoggingToDebugRingBuffer_cb hidl_status_cb) {
539     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
540                            &WifiChip::startLoggingToDebugRingBufferInternal,
541                            hidl_status_cb, ring_name, verbose_level,
542                            max_interval_in_sec, min_data_size_in_bytes);
543 }
544 
forceDumpToDebugRingBuffer(const hidl_string & ring_name,forceDumpToDebugRingBuffer_cb hidl_status_cb)545 Return<void> WifiChip::forceDumpToDebugRingBuffer(
546     const hidl_string& ring_name,
547     forceDumpToDebugRingBuffer_cb hidl_status_cb) {
548     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
549                            &WifiChip::forceDumpToDebugRingBufferInternal,
550                            hidl_status_cb, ring_name);
551 }
552 
flushRingBufferToFile(flushRingBufferToFile_cb hidl_status_cb)553 Return<void> WifiChip::flushRingBufferToFile(
554     flushRingBufferToFile_cb hidl_status_cb) {
555     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
556                            &WifiChip::flushRingBufferToFileInternal,
557                            hidl_status_cb);
558 }
559 
stopLoggingToDebugRingBuffer(stopLoggingToDebugRingBuffer_cb hidl_status_cb)560 Return<void> WifiChip::stopLoggingToDebugRingBuffer(
561     stopLoggingToDebugRingBuffer_cb hidl_status_cb) {
562     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
563                            &WifiChip::stopLoggingToDebugRingBufferInternal,
564                            hidl_status_cb);
565 }
566 
getDebugHostWakeReasonStats(getDebugHostWakeReasonStats_cb hidl_status_cb)567 Return<void> WifiChip::getDebugHostWakeReasonStats(
568     getDebugHostWakeReasonStats_cb hidl_status_cb) {
569     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
570                            &WifiChip::getDebugHostWakeReasonStatsInternal,
571                            hidl_status_cb);
572 }
573 
enableDebugErrorAlerts(bool enable,enableDebugErrorAlerts_cb hidl_status_cb)574 Return<void> WifiChip::enableDebugErrorAlerts(
575     bool enable, enableDebugErrorAlerts_cb hidl_status_cb) {
576     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
577                            &WifiChip::enableDebugErrorAlertsInternal,
578                            hidl_status_cb, enable);
579 }
580 
selectTxPowerScenario(V1_1::IWifiChip::TxPowerScenario scenario,selectTxPowerScenario_cb hidl_status_cb)581 Return<void> WifiChip::selectTxPowerScenario(
582     V1_1::IWifiChip::TxPowerScenario scenario,
583     selectTxPowerScenario_cb hidl_status_cb) {
584     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
585                            &WifiChip::selectTxPowerScenarioInternal,
586                            hidl_status_cb, scenario);
587 }
588 
resetTxPowerScenario(resetTxPowerScenario_cb hidl_status_cb)589 Return<void> WifiChip::resetTxPowerScenario(
590     resetTxPowerScenario_cb hidl_status_cb) {
591     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
592                            &WifiChip::resetTxPowerScenarioInternal,
593                            hidl_status_cb);
594 }
595 
setLatencyMode(LatencyMode mode,setLatencyMode_cb hidl_status_cb)596 Return<void> WifiChip::setLatencyMode(LatencyMode mode,
597                                       setLatencyMode_cb hidl_status_cb) {
598     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
599                            &WifiChip::setLatencyModeInternal, hidl_status_cb,
600                            mode);
601 }
602 
registerEventCallback_1_2(const sp<V1_2::IWifiChipEventCallback> & event_callback,registerEventCallback_cb hidl_status_cb)603 Return<void> WifiChip::registerEventCallback_1_2(
604     const sp<V1_2::IWifiChipEventCallback>& event_callback,
605     registerEventCallback_cb hidl_status_cb) {
606     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
607                            &WifiChip::registerEventCallbackInternal_1_2,
608                            hidl_status_cb, event_callback);
609 }
610 
selectTxPowerScenario_1_2(TxPowerScenario scenario,selectTxPowerScenario_cb hidl_status_cb)611 Return<void> WifiChip::selectTxPowerScenario_1_2(
612     TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) {
613     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
614                            &WifiChip::selectTxPowerScenarioInternal_1_2,
615                            hidl_status_cb, scenario);
616 }
617 
getCapabilities_1_3(getCapabilities_cb hidl_status_cb)618 Return<void> WifiChip::getCapabilities_1_3(getCapabilities_cb hidl_status_cb) {
619     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
620                            &WifiChip::getCapabilitiesInternal_1_3,
621                            hidl_status_cb);
622 }
623 
debug(const hidl_handle & handle,const hidl_vec<hidl_string> &)624 Return<void> WifiChip::debug(const hidl_handle& handle,
625                              const hidl_vec<hidl_string>&) {
626     if (handle != nullptr && handle->numFds >= 1) {
627         {
628             std::unique_lock<std::mutex> lk(lock_t);
629             for (const auto& item : ringbuffer_map_) {
630                 forceDumpToDebugRingBufferInternal(item.first);
631             }
632             // unique_lock unlocked here
633         }
634         usleep(100 * 1000);  // sleep for 100 milliseconds to wait for
635                              // ringbuffer updates.
636         int fd = handle->data[0];
637         if (!writeRingbufferFilesInternal()) {
638             LOG(ERROR) << "Error writing files to flash";
639         }
640         uint32_t n_error = cpioArchiveFilesInDir(fd, kTombstoneFolderPath);
641         if (n_error != 0) {
642             LOG(ERROR) << n_error << " errors occured in cpio function";
643         }
644         fsync(fd);
645     } else {
646         LOG(ERROR) << "File handle error";
647     }
648     return Void();
649 }
650 
createRttController_1_4(const sp<IWifiIface> & bound_iface,createRttController_1_4_cb hidl_status_cb)651 Return<void> WifiChip::createRttController_1_4(
652     const sp<IWifiIface>& bound_iface,
653     createRttController_1_4_cb hidl_status_cb) {
654     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
655                            &WifiChip::createRttControllerInternal_1_4,
656                            hidl_status_cb, bound_iface);
657 }
658 
registerEventCallback_1_4(const sp<IWifiChipEventCallback> & event_callback,registerEventCallback_cb hidl_status_cb)659 Return<void> WifiChip::registerEventCallback_1_4(
660     const sp<IWifiChipEventCallback>& event_callback,
661     registerEventCallback_cb hidl_status_cb) {
662     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID,
663                            &WifiChip::registerEventCallbackInternal_1_4,
664                            hidl_status_cb, event_callback);
665 }
666 
invalidateAndRemoveAllIfaces()667 void WifiChip::invalidateAndRemoveAllIfaces() {
668     invalidateAndClearAll(ap_ifaces_);
669     invalidateAndClearAll(nan_ifaces_);
670     invalidateAndClearAll(p2p_ifaces_);
671     invalidateAndClearAll(sta_ifaces_);
672     // Since all the ifaces are invalid now, all RTT controller objects
673     // using those ifaces also need to be invalidated.
674     for (const auto& rtt : rtt_controllers_) {
675         rtt->invalidate();
676     }
677     rtt_controllers_.clear();
678 }
679 
invalidateAndRemoveDependencies(const std::string & removed_iface_name)680 void WifiChip::invalidateAndRemoveDependencies(
681     const std::string& removed_iface_name) {
682     for (const auto& nan_iface : nan_ifaces_) {
683         if (nan_iface->getName() == removed_iface_name) {
684             invalidateAndClear(nan_ifaces_, nan_iface);
685             for (const auto& callback : event_cb_handler_.getCallbacks()) {
686                 if (!callback
687                          ->onIfaceRemoved(IfaceType::NAN, removed_iface_name)
688                          .isOk()) {
689                     LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
690                 }
691             }
692         }
693     }
694     for (const auto& rtt : rtt_controllers_) {
695         if (rtt->getIfaceName() == removed_iface_name) {
696             invalidateAndClear(rtt_controllers_, rtt);
697         }
698     }
699 }
700 
getIdInternal()701 std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() {
702     return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_};
703 }
704 
registerEventCallbackInternal(const sp<V1_0::IWifiChipEventCallback> &)705 WifiStatus WifiChip::registerEventCallbackInternal(
706     const sp<V1_0::IWifiChipEventCallback>& /* event_callback */) {
707     // Deprecated support for this callback.
708     return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
709 }
710 
getCapabilitiesInternal()711 std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() {
712     // Deprecated support for this callback.
713     return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), 0};
714 }
715 
716 std::pair<WifiStatus, std::vector<IWifiChip::ChipMode>>
getAvailableModesInternal()717 WifiChip::getAvailableModesInternal() {
718     return {createWifiStatus(WifiStatusCode::SUCCESS), modes_};
719 }
720 
configureChipInternal(std::unique_lock<std::recursive_mutex> * lock,ChipModeId mode_id)721 WifiStatus WifiChip::configureChipInternal(
722     /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
723     ChipModeId mode_id) {
724     if (!isValidModeId(mode_id)) {
725         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
726     }
727     if (mode_id == current_mode_id_) {
728         LOG(DEBUG) << "Already in the specified mode " << mode_id;
729         return createWifiStatus(WifiStatusCode::SUCCESS);
730     }
731     WifiStatus status = handleChipConfiguration(lock, mode_id);
732     if (status.code != WifiStatusCode::SUCCESS) {
733         for (const auto& callback : event_cb_handler_.getCallbacks()) {
734             if (!callback->onChipReconfigureFailure(status).isOk()) {
735                 LOG(ERROR)
736                     << "Failed to invoke onChipReconfigureFailure callback";
737             }
738         }
739         return status;
740     }
741     for (const auto& callback : event_cb_handler_.getCallbacks()) {
742         if (!callback->onChipReconfigured(mode_id).isOk()) {
743             LOG(ERROR) << "Failed to invoke onChipReconfigured callback";
744         }
745     }
746     current_mode_id_ = mode_id;
747     LOG(INFO) << "Configured chip in mode " << mode_id;
748     setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
749     return status;
750 }
751 
getModeInternal()752 std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() {
753     if (!isValidModeId(current_mode_id_)) {
754         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE),
755                 current_mode_id_};
756     }
757     return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_};
758 }
759 
760 std::pair<WifiStatus, IWifiChip::ChipDebugInfo>
requestChipDebugInfoInternal()761 WifiChip::requestChipDebugInfoInternal() {
762     IWifiChip::ChipDebugInfo result;
763     legacy_hal::wifi_error legacy_status;
764     std::string driver_desc;
765     const auto ifname = getFirstActiveWlanIfaceName();
766     std::tie(legacy_status, driver_desc) =
767         legacy_hal_.lock()->getDriverVersion(ifname);
768     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
769         LOG(ERROR) << "Failed to get driver version: "
770                    << legacyErrorToString(legacy_status);
771         WifiStatus status = createWifiStatusFromLegacyError(
772             legacy_status, "failed to get driver version");
773         return {status, result};
774     }
775     result.driverDescription = driver_desc.c_str();
776 
777     std::string firmware_desc;
778     std::tie(legacy_status, firmware_desc) =
779         legacy_hal_.lock()->getFirmwareVersion(ifname);
780     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
781         LOG(ERROR) << "Failed to get firmware version: "
782                    << legacyErrorToString(legacy_status);
783         WifiStatus status = createWifiStatusFromLegacyError(
784             legacy_status, "failed to get firmware version");
785         return {status, result};
786     }
787     result.firmwareDescription = firmware_desc.c_str();
788 
789     return {createWifiStatus(WifiStatusCode::SUCCESS), result};
790 }
791 
792 std::pair<WifiStatus, std::vector<uint8_t>>
requestDriverDebugDumpInternal()793 WifiChip::requestDriverDebugDumpInternal() {
794     legacy_hal::wifi_error legacy_status;
795     std::vector<uint8_t> driver_dump;
796     std::tie(legacy_status, driver_dump) =
797         legacy_hal_.lock()->requestDriverMemoryDump(
798             getFirstActiveWlanIfaceName());
799     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
800         LOG(ERROR) << "Failed to get driver debug dump: "
801                    << legacyErrorToString(legacy_status);
802         return {createWifiStatusFromLegacyError(legacy_status),
803                 std::vector<uint8_t>()};
804     }
805     return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump};
806 }
807 
808 std::pair<WifiStatus, std::vector<uint8_t>>
requestFirmwareDebugDumpInternal()809 WifiChip::requestFirmwareDebugDumpInternal() {
810     legacy_hal::wifi_error legacy_status;
811     std::vector<uint8_t> firmware_dump;
812     std::tie(legacy_status, firmware_dump) =
813         legacy_hal_.lock()->requestFirmwareMemoryDump(
814             getFirstActiveWlanIfaceName());
815     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
816         LOG(ERROR) << "Failed to get firmware debug dump: "
817                    << legacyErrorToString(legacy_status);
818         return {createWifiStatusFromLegacyError(legacy_status), {}};
819     }
820     return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump};
821 }
822 
createApIfaceInternal()823 std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() {
824     if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::AP)) {
825         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
826     }
827     std::string ifname = allocateApIfaceName();
828     legacy_hal::wifi_error legacy_status =
829         legacy_hal_.lock()->createVirtualInterface(
830             ifname,
831             hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::AP));
832     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
833         LOG(ERROR) << "Failed to add interface: " << ifname << " "
834                    << legacyErrorToString(legacy_status);
835         return {createWifiStatusFromLegacyError(legacy_status), {}};
836     }
837     sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_, iface_util_);
838     ap_ifaces_.push_back(iface);
839     for (const auto& callback : event_cb_handler_.getCallbacks()) {
840         if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) {
841             LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
842         }
843     }
844     setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
845     return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
846 }
847 
848 std::pair<WifiStatus, std::vector<hidl_string>>
getApIfaceNamesInternal()849 WifiChip::getApIfaceNamesInternal() {
850     if (ap_ifaces_.empty()) {
851         return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
852     }
853     return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)};
854 }
855 
getApIfaceInternal(const std::string & ifname)856 std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::getApIfaceInternal(
857     const std::string& ifname) {
858     const auto iface = findUsingName(ap_ifaces_, ifname);
859     if (!iface.get()) {
860         return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
861     }
862     return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
863 }
864 
removeApIfaceInternal(const std::string & ifname)865 WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) {
866     const auto iface = findUsingName(ap_ifaces_, ifname);
867     if (!iface.get()) {
868         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
869     }
870     // Invalidate & remove any dependent objects first.
871     // Note: This is probably not required because we never create
872     // nan/rtt objects over AP iface. But, there is no harm to do it
873     // here and not make that assumption all over the place.
874     invalidateAndRemoveDependencies(ifname);
875     legacy_hal::wifi_error legacy_status =
876         legacy_hal_.lock()->deleteVirtualInterface(ifname);
877     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
878         LOG(ERROR) << "Failed to remove interface: " << ifname << " "
879                    << legacyErrorToString(legacy_status);
880     }
881     invalidateAndClear(ap_ifaces_, iface);
882     for (const auto& callback : event_cb_handler_.getCallbacks()) {
883         if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) {
884             LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
885         }
886     }
887     setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
888     return createWifiStatus(WifiStatusCode::SUCCESS);
889 }
890 
createNanIfaceInternal()891 std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
892     if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::NAN)) {
893         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
894     }
895     bool is_dedicated_iface = true;
896     std::string ifname = getNanIfaceName();
897     if (ifname.empty() || !iface_util_.lock()->ifNameToIndex(ifname)) {
898         // Use the first shared STA iface (wlan0) if a dedicated aware iface is
899         // not defined.
900         ifname = getFirstActiveWlanIfaceName();
901         is_dedicated_iface = false;
902     }
903     sp<WifiNanIface> iface =
904         new WifiNanIface(ifname, is_dedicated_iface, legacy_hal_, iface_util_);
905     nan_ifaces_.push_back(iface);
906     for (const auto& callback : event_cb_handler_.getCallbacks()) {
907         if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) {
908             LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
909         }
910     }
911     return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
912 }
913 
914 std::pair<WifiStatus, std::vector<hidl_string>>
getNanIfaceNamesInternal()915 WifiChip::getNanIfaceNamesInternal() {
916     if (nan_ifaces_.empty()) {
917         return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
918     }
919     return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)};
920 }
921 
getNanIfaceInternal(const std::string & ifname)922 std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::getNanIfaceInternal(
923     const std::string& ifname) {
924     const auto iface = findUsingName(nan_ifaces_, ifname);
925     if (!iface.get()) {
926         return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
927     }
928     return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
929 }
930 
removeNanIfaceInternal(const std::string & ifname)931 WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) {
932     const auto iface = findUsingName(nan_ifaces_, ifname);
933     if (!iface.get()) {
934         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
935     }
936     invalidateAndClear(nan_ifaces_, iface);
937     for (const auto& callback : event_cb_handler_.getCallbacks()) {
938         if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) {
939             LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
940         }
941     }
942     return createWifiStatus(WifiStatusCode::SUCCESS);
943 }
944 
createP2pIfaceInternal()945 std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() {
946     if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::P2P)) {
947         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
948     }
949     std::string ifname = getP2pIfaceName();
950     sp<WifiP2pIface> iface = new WifiP2pIface(ifname, legacy_hal_);
951     p2p_ifaces_.push_back(iface);
952     for (const auto& callback : event_cb_handler_.getCallbacks()) {
953         if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) {
954             LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
955         }
956     }
957     return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
958 }
959 
960 std::pair<WifiStatus, std::vector<hidl_string>>
getP2pIfaceNamesInternal()961 WifiChip::getP2pIfaceNamesInternal() {
962     if (p2p_ifaces_.empty()) {
963         return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
964     }
965     return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)};
966 }
967 
getP2pIfaceInternal(const std::string & ifname)968 std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal(
969     const std::string& ifname) {
970     const auto iface = findUsingName(p2p_ifaces_, ifname);
971     if (!iface.get()) {
972         return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
973     }
974     return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
975 }
976 
removeP2pIfaceInternal(const std::string & ifname)977 WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) {
978     const auto iface = findUsingName(p2p_ifaces_, ifname);
979     if (!iface.get()) {
980         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
981     }
982     invalidateAndClear(p2p_ifaces_, iface);
983     for (const auto& callback : event_cb_handler_.getCallbacks()) {
984         if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) {
985             LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
986         }
987     }
988     return createWifiStatus(WifiStatusCode::SUCCESS);
989 }
990 
991 std::pair<WifiStatus, sp<V1_3::IWifiStaIface>>
createStaIfaceInternal()992 WifiChip::createStaIfaceInternal() {
993     if (!canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType::STA)) {
994         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
995     }
996     std::string ifname = allocateStaIfaceName();
997     legacy_hal::wifi_error legacy_status =
998         legacy_hal_.lock()->createVirtualInterface(
999             ifname,
1000             hidl_struct_util::convertHidlIfaceTypeToLegacy(IfaceType::STA));
1001     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1002         LOG(ERROR) << "Failed to add interface: " << ifname << " "
1003                    << legacyErrorToString(legacy_status);
1004         return {createWifiStatusFromLegacyError(legacy_status), {}};
1005     }
1006     sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_, iface_util_);
1007     sta_ifaces_.push_back(iface);
1008     for (const auto& callback : event_cb_handler_.getCallbacks()) {
1009         if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) {
1010             LOG(ERROR) << "Failed to invoke onIfaceAdded callback";
1011         }
1012     }
1013     setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1014     return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1015 }
1016 
1017 std::pair<WifiStatus, std::vector<hidl_string>>
getStaIfaceNamesInternal()1018 WifiChip::getStaIfaceNamesInternal() {
1019     if (sta_ifaces_.empty()) {
1020         return {createWifiStatus(WifiStatusCode::SUCCESS), {}};
1021     }
1022     return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)};
1023 }
1024 
getStaIfaceInternal(const std::string & ifname)1025 std::pair<WifiStatus, sp<V1_3::IWifiStaIface>> WifiChip::getStaIfaceInternal(
1026     const std::string& ifname) {
1027     const auto iface = findUsingName(sta_ifaces_, ifname);
1028     if (!iface.get()) {
1029         return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr};
1030     }
1031     return {createWifiStatus(WifiStatusCode::SUCCESS), iface};
1032 }
1033 
removeStaIfaceInternal(const std::string & ifname)1034 WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) {
1035     const auto iface = findUsingName(sta_ifaces_, ifname);
1036     if (!iface.get()) {
1037         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
1038     }
1039     // Invalidate & remove any dependent objects first.
1040     invalidateAndRemoveDependencies(ifname);
1041     legacy_hal::wifi_error legacy_status =
1042         legacy_hal_.lock()->deleteVirtualInterface(ifname);
1043     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1044         LOG(ERROR) << "Failed to remove interface: " << ifname << " "
1045                    << legacyErrorToString(legacy_status);
1046     }
1047     invalidateAndClear(sta_ifaces_, iface);
1048     for (const auto& callback : event_cb_handler_.getCallbacks()) {
1049         if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) {
1050             LOG(ERROR) << "Failed to invoke onIfaceRemoved callback";
1051         }
1052     }
1053     setActiveWlanIfaceNameProperty(getFirstActiveWlanIfaceName());
1054     return createWifiStatus(WifiStatusCode::SUCCESS);
1055 }
1056 
1057 std::pair<WifiStatus, sp<V1_0::IWifiRttController>>
createRttControllerInternal(const sp<IWifiIface> &)1058 WifiChip::createRttControllerInternal(const sp<IWifiIface>& /*bound_iface*/) {
1059     LOG(ERROR) << "createRttController is not supported on this HAL";
1060     return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
1061 }
1062 
1063 std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>>
getDebugRingBuffersStatusInternal()1064 WifiChip::getDebugRingBuffersStatusInternal() {
1065     legacy_hal::wifi_error legacy_status;
1066     std::vector<legacy_hal::wifi_ring_buffer_status>
1067         legacy_ring_buffer_status_vec;
1068     std::tie(legacy_status, legacy_ring_buffer_status_vec) =
1069         legacy_hal_.lock()->getRingBuffersStatus(getFirstActiveWlanIfaceName());
1070     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1071         return {createWifiStatusFromLegacyError(legacy_status), {}};
1072     }
1073     std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec;
1074     if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl(
1075             legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) {
1076         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
1077     }
1078     return {createWifiStatus(WifiStatusCode::SUCCESS),
1079             hidl_ring_buffer_status_vec};
1080 }
1081 
startLoggingToDebugRingBufferInternal(const hidl_string & ring_name,WifiDebugRingBufferVerboseLevel verbose_level,uint32_t max_interval_in_sec,uint32_t min_data_size_in_bytes)1082 WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
1083     const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level,
1084     uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) {
1085     WifiStatus status = registerDebugRingBufferCallback();
1086     if (status.code != WifiStatusCode::SUCCESS) {
1087         return status;
1088     }
1089     legacy_hal::wifi_error legacy_status =
1090         legacy_hal_.lock()->startRingBufferLogging(
1091             getFirstActiveWlanIfaceName(), ring_name,
1092             static_cast<
1093                 std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
1094                 verbose_level),
1095             max_interval_in_sec, min_data_size_in_bytes);
1096     ringbuffer_map_.insert(std::pair<std::string, Ringbuffer>(
1097         ring_name, Ringbuffer(kMaxBufferSizeBytes)));
1098     // if verbose logging enabled, turn up HAL daemon logging as well.
1099     if (verbose_level < WifiDebugRingBufferVerboseLevel::VERBOSE) {
1100         android::base::SetMinimumLogSeverity(android::base::DEBUG);
1101     } else {
1102         android::base::SetMinimumLogSeverity(android::base::VERBOSE);
1103     }
1104     return createWifiStatusFromLegacyError(legacy_status);
1105 }
1106 
forceDumpToDebugRingBufferInternal(const hidl_string & ring_name)1107 WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
1108     const hidl_string& ring_name) {
1109     WifiStatus status = registerDebugRingBufferCallback();
1110     if (status.code != WifiStatusCode::SUCCESS) {
1111         return status;
1112     }
1113     legacy_hal::wifi_error legacy_status =
1114         legacy_hal_.lock()->getRingBufferData(getFirstActiveWlanIfaceName(),
1115                                               ring_name);
1116 
1117     return createWifiStatusFromLegacyError(legacy_status);
1118 }
1119 
flushRingBufferToFileInternal()1120 WifiStatus WifiChip::flushRingBufferToFileInternal() {
1121     if (!writeRingbufferFilesInternal()) {
1122         LOG(ERROR) << "Error writing files to flash";
1123         return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1124     }
1125     return createWifiStatus(WifiStatusCode::SUCCESS);
1126 }
1127 
stopLoggingToDebugRingBufferInternal()1128 WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
1129     legacy_hal::wifi_error legacy_status =
1130         legacy_hal_.lock()->deregisterRingBufferCallbackHandler(
1131             getFirstActiveWlanIfaceName());
1132     if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1133         debug_ring_buffer_cb_registered_ = false;
1134     }
1135     return createWifiStatusFromLegacyError(legacy_status);
1136 }
1137 
1138 std::pair<WifiStatus, WifiDebugHostWakeReasonStats>
getDebugHostWakeReasonStatsInternal()1139 WifiChip::getDebugHostWakeReasonStatsInternal() {
1140     legacy_hal::wifi_error legacy_status;
1141     legacy_hal::WakeReasonStats legacy_stats;
1142     std::tie(legacy_status, legacy_stats) =
1143         legacy_hal_.lock()->getWakeReasonStats(getFirstActiveWlanIfaceName());
1144     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1145         return {createWifiStatusFromLegacyError(legacy_status), {}};
1146     }
1147     WifiDebugHostWakeReasonStats hidl_stats;
1148     if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats,
1149                                                               &hidl_stats)) {
1150         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
1151     }
1152     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
1153 }
1154 
enableDebugErrorAlertsInternal(bool enable)1155 WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
1156     legacy_hal::wifi_error legacy_status;
1157     if (enable) {
1158         android::wp<WifiChip> weak_ptr_this(this);
1159         const auto& on_alert_callback = [weak_ptr_this](
1160                                             int32_t error_code,
1161                                             std::vector<uint8_t> debug_data) {
1162             const auto shared_ptr_this = weak_ptr_this.promote();
1163             if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1164                 LOG(ERROR) << "Callback invoked on an invalid object";
1165                 return;
1166             }
1167             for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
1168                 if (!callback->onDebugErrorAlert(error_code, debug_data)
1169                          .isOk()) {
1170                     LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback";
1171                 }
1172             }
1173         };
1174         legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
1175             getFirstActiveWlanIfaceName(), on_alert_callback);
1176     } else {
1177         legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
1178             getFirstActiveWlanIfaceName());
1179     }
1180     return createWifiStatusFromLegacyError(legacy_status);
1181 }
1182 
selectTxPowerScenarioInternal(V1_1::IWifiChip::TxPowerScenario scenario)1183 WifiStatus WifiChip::selectTxPowerScenarioInternal(
1184     V1_1::IWifiChip::TxPowerScenario scenario) {
1185     auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
1186         getFirstActiveWlanIfaceName(),
1187         hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
1188     return createWifiStatusFromLegacyError(legacy_status);
1189 }
1190 
resetTxPowerScenarioInternal()1191 WifiStatus WifiChip::resetTxPowerScenarioInternal() {
1192     auto legacy_status =
1193         legacy_hal_.lock()->resetTxPowerScenario(getFirstActiveWlanIfaceName());
1194     return createWifiStatusFromLegacyError(legacy_status);
1195 }
1196 
setLatencyModeInternal(LatencyMode mode)1197 WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) {
1198     auto legacy_status = legacy_hal_.lock()->setLatencyMode(
1199         getFirstActiveWlanIfaceName(),
1200         hidl_struct_util::convertHidlLatencyModeToLegacy(mode));
1201     return createWifiStatusFromLegacyError(legacy_status);
1202 }
1203 
registerEventCallbackInternal_1_2(const sp<V1_2::IWifiChipEventCallback> &)1204 WifiStatus WifiChip::registerEventCallbackInternal_1_2(
1205     const sp<V1_2::IWifiChipEventCallback>& /* event_callback */) {
1206     // Deprecated support for this callback.
1207     return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
1208 }
1209 
selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario)1210 WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(
1211     TxPowerScenario scenario) {
1212     auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
1213         getFirstActiveWlanIfaceName(),
1214         hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario));
1215     return createWifiStatusFromLegacyError(legacy_status);
1216 }
1217 
getCapabilitiesInternal_1_3()1218 std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_3() {
1219     legacy_hal::wifi_error legacy_status;
1220     uint32_t legacy_feature_set;
1221     uint32_t legacy_logger_feature_set;
1222     const auto ifname = getFirstActiveWlanIfaceName();
1223     std::tie(legacy_status, legacy_feature_set) =
1224         legacy_hal_.lock()->getSupportedFeatureSet(ifname);
1225     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1226         return {createWifiStatusFromLegacyError(legacy_status), 0};
1227     }
1228     std::tie(legacy_status, legacy_logger_feature_set) =
1229         legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
1230     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1231         // some devices don't support querying logger feature set
1232         legacy_logger_feature_set = 0;
1233     }
1234     uint32_t hidl_caps;
1235     if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities(
1236             legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
1237         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
1238     }
1239     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
1240 }
1241 
1242 std::pair<WifiStatus, sp<IWifiRttController>>
createRttControllerInternal_1_4(const sp<IWifiIface> & bound_iface)1243 WifiChip::createRttControllerInternal_1_4(const sp<IWifiIface>& bound_iface) {
1244     if (sta_ifaces_.size() == 0 &&
1245         !canCurrentModeSupportIfaceOfType(IfaceType::STA)) {
1246         LOG(ERROR)
1247             << "createRttControllerInternal_1_4: Chip cannot support STAs "
1248                "(and RTT by extension)";
1249         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
1250     }
1251     sp<WifiRttController> rtt = new WifiRttController(
1252         getFirstActiveWlanIfaceName(), bound_iface, legacy_hal_);
1253     rtt_controllers_.emplace_back(rtt);
1254     return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
1255 }
1256 
registerEventCallbackInternal_1_4(const sp<IWifiChipEventCallback> & event_callback)1257 WifiStatus WifiChip::registerEventCallbackInternal_1_4(
1258     const sp<IWifiChipEventCallback>& event_callback) {
1259     if (!event_cb_handler_.addCallback(event_callback)) {
1260         return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1261     }
1262     return createWifiStatus(WifiStatusCode::SUCCESS);
1263 }
1264 
handleChipConfiguration(std::unique_lock<std::recursive_mutex> * lock,ChipModeId mode_id)1265 WifiStatus WifiChip::handleChipConfiguration(
1266     /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
1267     ChipModeId mode_id) {
1268     // If the chip is already configured in a different mode, stop
1269     // the legacy HAL and then start it after firmware mode change.
1270     if (isValidModeId(current_mode_id_)) {
1271         LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_
1272                   << " to mode " << mode_id;
1273         invalidateAndRemoveAllIfaces();
1274         legacy_hal::wifi_error legacy_status =
1275             legacy_hal_.lock()->stop(lock, []() {});
1276         if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1277             LOG(ERROR) << "Failed to stop legacy HAL: "
1278                        << legacyErrorToString(legacy_status);
1279             return createWifiStatusFromLegacyError(legacy_status);
1280         }
1281     }
1282     // Firmware mode change not needed for V2 devices.
1283     bool success = true;
1284     if (mode_id == feature_flags::chip_mode_ids::kV1Sta) {
1285         success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA);
1286     } else if (mode_id == feature_flags::chip_mode_ids::kV1Ap) {
1287         success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP);
1288     }
1289     if (!success) {
1290         return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
1291     }
1292     legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start();
1293     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
1294         LOG(ERROR) << "Failed to start legacy HAL: "
1295                    << legacyErrorToString(legacy_status);
1296         return createWifiStatusFromLegacyError(legacy_status);
1297     }
1298     // Every time the HAL is restarted, we need to register the
1299     // radio mode change callback.
1300     WifiStatus status = registerRadioModeChangeCallback();
1301     if (status.code != WifiStatusCode::SUCCESS) {
1302         // This probably is not a critical failure?
1303         LOG(ERROR) << "Failed to register radio mode change callback";
1304     }
1305     // Extract and save the version information into property.
1306     std::pair<WifiStatus, IWifiChip::ChipDebugInfo> version_info;
1307     version_info = WifiChip::requestChipDebugInfoInternal();
1308     if (WifiStatusCode::SUCCESS == version_info.first.code) {
1309         property_set("vendor.wlan.firmware.version",
1310                      version_info.second.firmwareDescription.c_str());
1311         property_set("vendor.wlan.driver.version",
1312                      version_info.second.driverDescription.c_str());
1313     }
1314 
1315     return createWifiStatus(WifiStatusCode::SUCCESS);
1316 }
1317 
registerDebugRingBufferCallback()1318 WifiStatus WifiChip::registerDebugRingBufferCallback() {
1319     if (debug_ring_buffer_cb_registered_) {
1320         return createWifiStatus(WifiStatusCode::SUCCESS);
1321     }
1322 
1323     android::wp<WifiChip> weak_ptr_this(this);
1324     const auto& on_ring_buffer_data_callback =
1325         [weak_ptr_this](const std::string& name,
1326                         const std::vector<uint8_t>& data,
1327                         const legacy_hal::wifi_ring_buffer_status& status) {
1328             const auto shared_ptr_this = weak_ptr_this.promote();
1329             if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1330                 LOG(ERROR) << "Callback invoked on an invalid object";
1331                 return;
1332             }
1333             WifiDebugRingBufferStatus hidl_status;
1334             if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl(
1335                     status, &hidl_status)) {
1336                 LOG(ERROR) << "Error converting ring buffer status";
1337                 return;
1338             }
1339             {
1340                 std::unique_lock<std::mutex> lk(shared_ptr_this->lock_t);
1341                 const auto& target =
1342                     shared_ptr_this->ringbuffer_map_.find(name);
1343                 if (target != shared_ptr_this->ringbuffer_map_.end()) {
1344                     Ringbuffer& cur_buffer = target->second;
1345                     cur_buffer.append(data);
1346                 } else {
1347                     LOG(ERROR) << "Ringname " << name << " not found";
1348                     return;
1349                 }
1350                 // unique_lock unlocked here
1351             }
1352         };
1353     legacy_hal::wifi_error legacy_status =
1354         legacy_hal_.lock()->registerRingBufferCallbackHandler(
1355             getFirstActiveWlanIfaceName(), on_ring_buffer_data_callback);
1356 
1357     if (legacy_status == legacy_hal::WIFI_SUCCESS) {
1358         debug_ring_buffer_cb_registered_ = true;
1359     }
1360     return createWifiStatusFromLegacyError(legacy_status);
1361 }
1362 
registerRadioModeChangeCallback()1363 WifiStatus WifiChip::registerRadioModeChangeCallback() {
1364     android::wp<WifiChip> weak_ptr_this(this);
1365     const auto& on_radio_mode_change_callback =
1366         [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) {
1367             const auto shared_ptr_this = weak_ptr_this.promote();
1368             if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
1369                 LOG(ERROR) << "Callback invoked on an invalid object";
1370                 return;
1371             }
1372             std::vector<IWifiChipEventCallback::RadioModeInfo>
1373                 hidl_radio_mode_infos;
1374             if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl(
1375                     mac_infos, &hidl_radio_mode_infos)) {
1376                 LOG(ERROR) << "Error converting wifi mac info";
1377                 return;
1378             }
1379             for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
1380                 if (!callback->onRadioModeChange_1_4(hidl_radio_mode_infos)
1381                          .isOk()) {
1382                     LOG(ERROR) << "Failed to invoke onRadioModeChange_1_4"
1383                                << " callback on: " << toString(callback);
1384                 }
1385             }
1386         };
1387     legacy_hal::wifi_error legacy_status =
1388         legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
1389             getFirstActiveWlanIfaceName(), on_radio_mode_change_callback);
1390     return createWifiStatusFromLegacyError(legacy_status);
1391 }
1392 
1393 std::vector<IWifiChip::ChipIfaceCombination>
getCurrentModeIfaceCombinations()1394 WifiChip::getCurrentModeIfaceCombinations() {
1395     if (!isValidModeId(current_mode_id_)) {
1396         LOG(ERROR) << "Chip not configured in a mode yet";
1397         return {};
1398     }
1399     for (const auto& mode : modes_) {
1400         if (mode.id == current_mode_id_) {
1401             return mode.availableCombinations;
1402         }
1403     }
1404     CHECK(0) << "Expected to find iface combinations for current mode!";
1405     return {};
1406 }
1407 
1408 // Returns a map indexed by IfaceType with the number of ifaces currently
1409 // created of the corresponding type.
getCurrentIfaceCombination()1410 std::map<IfaceType, size_t> WifiChip::getCurrentIfaceCombination() {
1411     std::map<IfaceType, size_t> iface_counts;
1412     iface_counts[IfaceType::AP] = ap_ifaces_.size();
1413     iface_counts[IfaceType::NAN] = nan_ifaces_.size();
1414     iface_counts[IfaceType::P2P] = p2p_ifaces_.size();
1415     iface_counts[IfaceType::STA] = sta_ifaces_.size();
1416     return iface_counts;
1417 }
1418 
1419 // This expands the provided iface combinations to a more parseable
1420 // form. Returns a vector of available combinations possible with the number
1421 // of ifaces of each type in the combination.
1422 // This method is a port of HalDeviceManager.expandIfaceCombos() from framework.
expandIfaceCombinations(const IWifiChip::ChipIfaceCombination & combination)1423 std::vector<std::map<IfaceType, size_t>> WifiChip::expandIfaceCombinations(
1424     const IWifiChip::ChipIfaceCombination& combination) {
1425     uint32_t num_expanded_combos = 1;
1426     for (const auto& limit : combination.limits) {
1427         for (uint32_t i = 0; i < limit.maxIfaces; i++) {
1428             num_expanded_combos *= limit.types.size();
1429         }
1430     }
1431 
1432     // Allocate the vector of expanded combos and reset all iface counts to 0
1433     // in each combo.
1434     std::vector<std::map<IfaceType, size_t>> expanded_combos;
1435     expanded_combos.resize(num_expanded_combos);
1436     for (auto& expanded_combo : expanded_combos) {
1437         for (const auto type :
1438              {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
1439             expanded_combo[type] = 0;
1440         }
1441     }
1442     uint32_t span = num_expanded_combos;
1443     for (const auto& limit : combination.limits) {
1444         for (uint32_t i = 0; i < limit.maxIfaces; i++) {
1445             span /= limit.types.size();
1446             for (uint32_t k = 0; k < num_expanded_combos; ++k) {
1447                 const auto iface_type =
1448                     limit.types[(k / span) % limit.types.size()];
1449                 expanded_combos[k][iface_type]++;
1450             }
1451         }
1452     }
1453     return expanded_combos;
1454 }
1455 
canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(const std::map<IfaceType,size_t> & expanded_combo,IfaceType requested_type)1456 bool WifiChip::canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
1457     const std::map<IfaceType, size_t>& expanded_combo,
1458     IfaceType requested_type) {
1459     const auto current_combo = getCurrentIfaceCombination();
1460 
1461     // Check if we have space for 1 more iface of |type| in this combo
1462     for (const auto type :
1463          {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
1464         size_t num_ifaces_needed = current_combo.at(type);
1465         if (type == requested_type) {
1466             num_ifaces_needed++;
1467         }
1468         size_t num_ifaces_allowed = expanded_combo.at(type);
1469         if (num_ifaces_needed > num_ifaces_allowed) {
1470             return false;
1471         }
1472     }
1473     return true;
1474 }
1475 
1476 // This method does the following:
1477 // a) Enumerate all possible iface combos by expanding the current
1478 //    ChipIfaceCombination.
1479 // b) Check if the requested iface type can be added to the current mode
1480 //    with the iface combination that is already active.
canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(IfaceType requested_type)1481 bool WifiChip::canCurrentModeSupportIfaceOfTypeWithCurrentIfaces(
1482     IfaceType requested_type) {
1483     if (!isValidModeId(current_mode_id_)) {
1484         LOG(ERROR) << "Chip not configured in a mode yet";
1485         return false;
1486     }
1487     const auto combinations = getCurrentModeIfaceCombinations();
1488     for (const auto& combination : combinations) {
1489         const auto expanded_combos = expandIfaceCombinations(combination);
1490         for (const auto& expanded_combo : expanded_combos) {
1491             if (canExpandedIfaceComboSupportIfaceOfTypeWithCurrentIfaces(
1492                     expanded_combo, requested_type)) {
1493                 return true;
1494             }
1495         }
1496     }
1497     return false;
1498 }
1499 
1500 // Note: This does not consider ifaces already active. It only checks if the
1501 // provided expanded iface combination can support the requested combo.
canExpandedIfaceComboSupportIfaceCombo(const std::map<IfaceType,size_t> & expanded_combo,const std::map<IfaceType,size_t> & req_combo)1502 bool WifiChip::canExpandedIfaceComboSupportIfaceCombo(
1503     const std::map<IfaceType, size_t>& expanded_combo,
1504     const std::map<IfaceType, size_t>& req_combo) {
1505     // Check if we have space for 1 more iface of |type| in this combo
1506     for (const auto type :
1507          {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) {
1508         if (req_combo.count(type) == 0) {
1509             // Iface of "type" not in the req_combo.
1510             continue;
1511         }
1512         size_t num_ifaces_needed = req_combo.at(type);
1513         size_t num_ifaces_allowed = expanded_combo.at(type);
1514         if (num_ifaces_needed > num_ifaces_allowed) {
1515             return false;
1516         }
1517     }
1518     return true;
1519 }
1520 // This method does the following:
1521 // a) Enumerate all possible iface combos by expanding the current
1522 //    ChipIfaceCombination.
1523 // b) Check if the requested iface combo can be added to the current mode.
1524 // Note: This does not consider ifaces already active. It only checks if the
1525 // current mode can support the requested combo.
canCurrentModeSupportIfaceCombo(const std::map<IfaceType,size_t> & req_combo)1526 bool WifiChip::canCurrentModeSupportIfaceCombo(
1527     const std::map<IfaceType, size_t>& req_combo) {
1528     if (!isValidModeId(current_mode_id_)) {
1529         LOG(ERROR) << "Chip not configured in a mode yet";
1530         return false;
1531     }
1532     const auto combinations = getCurrentModeIfaceCombinations();
1533     for (const auto& combination : combinations) {
1534         const auto expanded_combos = expandIfaceCombinations(combination);
1535         for (const auto& expanded_combo : expanded_combos) {
1536             if (canExpandedIfaceComboSupportIfaceCombo(expanded_combo,
1537                                                        req_combo)) {
1538                 return true;
1539             }
1540         }
1541     }
1542     return false;
1543 }
1544 
1545 // This method does the following:
1546 // a) Enumerate all possible iface combos by expanding the current
1547 //    ChipIfaceCombination.
1548 // b) Check if the requested iface type can be added to the current mode.
canCurrentModeSupportIfaceOfType(IfaceType requested_type)1549 bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType requested_type) {
1550     // Check if we can support atleast 1 iface of type.
1551     std::map<IfaceType, size_t> req_iface_combo;
1552     req_iface_combo[requested_type] = 1;
1553     return canCurrentModeSupportIfaceCombo(req_iface_combo);
1554 }
1555 
isValidModeId(ChipModeId mode_id)1556 bool WifiChip::isValidModeId(ChipModeId mode_id) {
1557     for (const auto& mode : modes_) {
1558         if (mode.id == mode_id) {
1559             return true;
1560         }
1561     }
1562     return false;
1563 }
1564 
isStaApConcurrencyAllowedInCurrentMode()1565 bool WifiChip::isStaApConcurrencyAllowedInCurrentMode() {
1566     // Check if we can support atleast 1 STA & 1 AP concurrently.
1567     std::map<IfaceType, size_t> req_iface_combo;
1568     req_iface_combo[IfaceType::AP] = 1;
1569     req_iface_combo[IfaceType::STA] = 1;
1570     return canCurrentModeSupportIfaceCombo(req_iface_combo);
1571 }
1572 
isDualApAllowedInCurrentMode()1573 bool WifiChip::isDualApAllowedInCurrentMode() {
1574     // Check if we can support atleast 1 STA & 1 AP concurrently.
1575     std::map<IfaceType, size_t> req_iface_combo;
1576     req_iface_combo[IfaceType::AP] = 2;
1577     return canCurrentModeSupportIfaceCombo(req_iface_combo);
1578 }
1579 
getFirstActiveWlanIfaceName()1580 std::string WifiChip::getFirstActiveWlanIfaceName() {
1581     if (sta_ifaces_.size() > 0) return sta_ifaces_[0]->getName();
1582     if (ap_ifaces_.size() > 0) return ap_ifaces_[0]->getName();
1583     // This could happen if the chip call is made before any STA/AP
1584     // iface is created. Default to wlan0 for such cases.
1585     LOG(WARNING) << "No active wlan interfaces in use! Using default";
1586     return getWlanIfaceName(0);
1587 }
1588 
1589 // Return the first wlan (wlan0, wlan1 etc.) starting from |start_idx|
1590 // not already in use.
1591 // Note: This doesn't check the actual presence of these interfaces.
allocateApOrStaIfaceName(uint32_t start_idx)1592 std::string WifiChip::allocateApOrStaIfaceName(uint32_t start_idx) {
1593     for (unsigned idx = start_idx; idx < kMaxWlanIfaces; idx++) {
1594         const auto ifname = getWlanIfaceName(idx);
1595         if (findUsingName(ap_ifaces_, ifname)) continue;
1596         if (findUsingName(sta_ifaces_, ifname)) continue;
1597         return ifname;
1598     }
1599     // This should never happen. We screwed up somewhere if it did.
1600     CHECK(false) << "All wlan interfaces in use already!";
1601     return {};
1602 }
1603 
1604 // AP iface names start with idx 1 for modes supporting
1605 // concurrent STA and not dual AP, else start with idx 0.
allocateApIfaceName()1606 std::string WifiChip::allocateApIfaceName() {
1607     // Check if we have a dedicated iface for AP.
1608     std::string ifname = getApIfaceName();
1609     if (!ifname.empty()) {
1610         return ifname;
1611     }
1612     return allocateApOrStaIfaceName((isStaApConcurrencyAllowedInCurrentMode() &&
1613                                      !isDualApAllowedInCurrentMode())
1614                                         ? 1
1615                                         : 0);
1616 }
1617 
1618 // STA iface names start with idx 0.
1619 // Primary STA iface will always be 0.
allocateStaIfaceName()1620 std::string WifiChip::allocateStaIfaceName() {
1621     return allocateApOrStaIfaceName(0);
1622 }
1623 
writeRingbufferFilesInternal()1624 bool WifiChip::writeRingbufferFilesInternal() {
1625     if (!removeOldFilesInternal()) {
1626         LOG(ERROR) << "Error occurred while deleting old tombstone files";
1627         return false;
1628     }
1629     // write ringbuffers to file
1630     {
1631         std::unique_lock<std::mutex> lk(lock_t);
1632         for (const auto& item : ringbuffer_map_) {
1633             const Ringbuffer& cur_buffer = item.second;
1634             if (cur_buffer.getData().empty()) {
1635                 continue;
1636             }
1637             const std::string file_path_raw =
1638                 kTombstoneFolderPath + item.first + "XXXXXXXXXX";
1639             const int dump_fd = mkstemp(makeCharVec(file_path_raw).data());
1640             if (dump_fd == -1) {
1641                 PLOG(ERROR) << "create file failed";
1642                 return false;
1643             }
1644             unique_fd file_auto_closer(dump_fd);
1645             for (const auto& cur_block : cur_buffer.getData()) {
1646                 if (write(dump_fd, cur_block.data(),
1647                           sizeof(cur_block[0]) * cur_block.size()) == -1) {
1648                     PLOG(ERROR) << "Error writing to file";
1649                 }
1650             }
1651         }
1652         // unique_lock unlocked here
1653     }
1654     return true;
1655 }
1656 
1657 }  // namespace implementation
1658 }  // namespace V1_4
1659 }  // namespace wifi
1660 }  // namespace hardware
1661 }  // namespace android
1662