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