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