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