• 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 <android-base/logging.h>
18 
19 #include "hidl_return_util.h"
20 #include "hidl_struct_util.h"
21 #include "wifi_ap_iface.h"
22 #include "wifi_status_util.h"
23 
24 namespace android {
25 namespace hardware {
26 namespace wifi {
27 namespace V1_6 {
28 namespace implementation {
29 using hidl_return_util::validateAndCall;
30 
WifiApIface(const std::string & ifname,const std::vector<std::string> & instances,const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)31 WifiApIface::WifiApIface(const std::string& ifname, const std::vector<std::string>& instances,
32                          const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
33                          const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
34     : ifname_(ifname),
35       instances_(instances),
36       legacy_hal_(legacy_hal),
37       iface_util_(iface_util),
38       is_valid_(true) {}
39 
invalidate()40 void WifiApIface::invalidate() {
41     legacy_hal_.reset();
42     is_valid_ = false;
43 }
44 
isValid()45 bool WifiApIface::isValid() {
46     return is_valid_;
47 }
48 
getName()49 std::string WifiApIface::getName() {
50     return ifname_;
51 }
52 
removeInstance(std::string instance)53 void WifiApIface::removeInstance(std::string instance) {
54     instances_.erase(std::remove(instances_.begin(), instances_.end(), instance), instances_.end());
55 }
56 
getName(getName_cb hidl_status_cb)57 Return<void> WifiApIface::getName(getName_cb hidl_status_cb) {
58     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
59                            &WifiApIface::getNameInternal, hidl_status_cb);
60 }
61 
getType(getType_cb hidl_status_cb)62 Return<void> WifiApIface::getType(getType_cb hidl_status_cb) {
63     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
64                            &WifiApIface::getTypeInternal, hidl_status_cb);
65 }
66 
setCountryCode(const hidl_array<int8_t,2> & code,setCountryCode_cb hidl_status_cb)67 Return<void> WifiApIface::setCountryCode(const hidl_array<int8_t, 2>& code,
68                                          setCountryCode_cb hidl_status_cb) {
69     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
70                            &WifiApIface::setCountryCodeInternal, hidl_status_cb, code);
71 }
72 
getValidFrequenciesForBand(V1_0::WifiBand band,getValidFrequenciesForBand_cb hidl_status_cb)73 Return<void> WifiApIface::getValidFrequenciesForBand(V1_0::WifiBand band,
74                                                      getValidFrequenciesForBand_cb hidl_status_cb) {
75     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
76                            &WifiApIface::getValidFrequenciesForBandInternal, hidl_status_cb, band);
77 }
78 
setMacAddress(const hidl_array<uint8_t,6> & mac,setMacAddress_cb hidl_status_cb)79 Return<void> WifiApIface::setMacAddress(const hidl_array<uint8_t, 6>& mac,
80                                         setMacAddress_cb hidl_status_cb) {
81     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
82                            &WifiApIface::setMacAddressInternal, hidl_status_cb, mac);
83 }
84 
getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb)85 Return<void> WifiApIface::getFactoryMacAddress(getFactoryMacAddress_cb hidl_status_cb) {
86     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
87                            &WifiApIface::getFactoryMacAddressInternal, hidl_status_cb,
88                            instances_.size() > 0 ? instances_[0] : ifname_);
89 }
90 
resetToFactoryMacAddress(resetToFactoryMacAddress_cb hidl_status_cb)91 Return<void> WifiApIface::resetToFactoryMacAddress(resetToFactoryMacAddress_cb hidl_status_cb) {
92     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
93                            &WifiApIface::resetToFactoryMacAddressInternal, hidl_status_cb);
94 }
95 
getBridgedInstances(getBridgedInstances_cb hidl_status_cb)96 Return<void> WifiApIface::getBridgedInstances(getBridgedInstances_cb hidl_status_cb) {
97     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
98                            &WifiApIface::getBridgedInstancesInternal, hidl_status_cb);
99 }
100 
getNameInternal()101 std::pair<WifiStatus, std::string> WifiApIface::getNameInternal() {
102     return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
103 }
104 
getTypeInternal()105 std::pair<WifiStatus, IfaceType> WifiApIface::getTypeInternal() {
106     return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::AP};
107 }
108 
setCountryCodeInternal(const std::array<int8_t,2> & code)109 WifiStatus WifiApIface::setCountryCodeInternal(const std::array<int8_t, 2>& code) {
110     legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->setCountryCode(
111             instances_.size() > 0 ? instances_[0] : ifname_, code);
112     return createWifiStatusFromLegacyError(legacy_status);
113 }
114 
115 std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
getValidFrequenciesForBandInternal(V1_0::WifiBand band)116 WifiApIface::getValidFrequenciesForBandInternal(V1_0::WifiBand band) {
117     static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), "Size mismatch");
118     legacy_hal::wifi_error legacy_status;
119     std::vector<uint32_t> valid_frequencies;
120     std::tie(legacy_status, valid_frequencies) = legacy_hal_.lock()->getValidFrequenciesForBand(
121             instances_.size() > 0 ? instances_[0] : ifname_,
122             hidl_struct_util::convertHidlWifiBandToLegacy(band));
123     return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
124 }
125 
setMacAddressInternal(const std::array<uint8_t,6> & mac)126 WifiStatus WifiApIface::setMacAddressInternal(const std::array<uint8_t, 6>& mac) {
127     // Support random MAC up to 2 interfaces
128     if (instances_.size() == 2) {
129         int rbyte = 1;
130         for (auto const& intf : instances_) {
131             std::array<uint8_t, 6> rmac = mac;
132             // reverse the bits to avoid collision
133             rmac[rbyte] = 0xff - rmac[rbyte];
134             if (!iface_util_.lock()->setMacAddress(intf, rmac)) {
135                 LOG(INFO) << "Failed to set random mac address on " << intf;
136                 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
137             }
138             rbyte++;
139         }
140     }
141     // It also needs to set mac address for bridged interface, otherwise the mac
142     // address of bridged interface will be changed after one of instance
143     // down.
144     if (!iface_util_.lock()->setMacAddress(ifname_, mac)) {
145         LOG(ERROR) << "Fail to config MAC for interface " << ifname_;
146         return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
147     }
148     return createWifiStatus(WifiStatusCode::SUCCESS);
149 }
150 
getFactoryMacAddressInternal(const std::string & ifaceName)151 std::pair<WifiStatus, std::array<uint8_t, 6>> WifiApIface::getFactoryMacAddressInternal(
152         const std::string& ifaceName) {
153     std::array<uint8_t, 6> mac = iface_util_.lock()->getFactoryMacAddress(ifaceName);
154     if (mac[0] == 0 && mac[1] == 0 && mac[2] == 0 && mac[3] == 0 && mac[4] == 0 && mac[5] == 0) {
155         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), mac};
156     }
157     return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
158 }
159 
resetToFactoryMacAddressInternal()160 WifiStatus WifiApIface::resetToFactoryMacAddressInternal() {
161     std::pair<WifiStatus, std::array<uint8_t, 6>> getMacResult;
162     if (instances_.size() == 2) {
163         for (auto const& intf : instances_) {
164             getMacResult = getFactoryMacAddressInternal(intf);
165             LOG(DEBUG) << "Reset MAC to factory MAC on " << intf;
166             if (getMacResult.first.code != WifiStatusCode::SUCCESS ||
167                 !iface_util_.lock()->setMacAddress(intf, getMacResult.second)) {
168                 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
169             }
170         }
171         // It needs to set mac address for bridged interface, otherwise the mac
172         // address of the bridged interface will be changed after one of the
173         // instance down. Thus we are generating a random MAC address for the
174         // bridged interface even if we got the request to reset the Factory
175         // MAC. Since the bridged interface is an internal interface for the
176         // operation of bpf and others networking operation.
177         if (!iface_util_.lock()->setMacAddress(ifname_,
178                                                iface_util_.lock()->createRandomMacAddress())) {
179             LOG(ERROR) << "Fail to config MAC for bridged interface " << ifname_;
180             return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
181         }
182     } else {
183         getMacResult = getFactoryMacAddressInternal(ifname_);
184         LOG(DEBUG) << "Reset MAC to factory MAC on " << ifname_;
185         if (getMacResult.first.code != WifiStatusCode::SUCCESS ||
186             !iface_util_.lock()->setMacAddress(ifname_, getMacResult.second)) {
187             return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
188         }
189     }
190     return createWifiStatus(WifiStatusCode::SUCCESS);
191 }
192 
getBridgedInstancesInternal()193 std::pair<WifiStatus, std::vector<hidl_string>> WifiApIface::getBridgedInstancesInternal() {
194     std::vector<hidl_string> instances;
195     for (const auto& instance_name : instances_) {
196         instances.push_back(instance_name);
197     }
198     return {createWifiStatus(WifiStatusCode::SUCCESS), instances};
199 }
200 }  // namespace implementation
201 }  // namespace V1_6
202 }  // namespace wifi
203 }  // namespace hardware
204 }  // namespace android
205