1 /*
2  * Copyright (C) 2019 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 <net/if.h>
18 #include <cstddef>
19 #include <iostream>
20 #include <limits>
21 #include <random>
22 
23 #include <android-base/logging.h>
24 #include <android-base/macros.h>
25 #include <private/android_filesystem_config.h>
26 
27 #undef NAN
28 #include "wifi_iface_util.h"
29 
30 namespace {
31 // Constants to set the local bit & clear the multicast bit.
32 constexpr uint8_t kMacAddressMulticastMask = 0x01;
33 constexpr uint8_t kMacAddressLocallyAssignedMask = 0x02;
34 }  // namespace
35 
36 namespace android {
37 namespace hardware {
38 namespace wifi {
39 namespace V1_5 {
40 namespace implementation {
41 namespace iface_util {
42 
WifiIfaceUtil(const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)43 WifiIfaceUtil::WifiIfaceUtil(
44     const std::weak_ptr<wifi_system::InterfaceTool> iface_tool,
45     const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
46     : iface_tool_(iface_tool),
47       legacy_hal_(legacy_hal),
48       random_mac_address_(nullptr),
49       event_handlers_map_() {}
50 
getFactoryMacAddress(const std::string & iface_name)51 std::array<uint8_t, 6> WifiIfaceUtil::getFactoryMacAddress(
52     const std::string& iface_name) {
53     return iface_tool_.lock()->GetFactoryMacAddress(iface_name.c_str());
54 }
55 
setMacAddress(const std::string & iface_name,const std::array<uint8_t,6> & mac)56 bool WifiIfaceUtil::setMacAddress(const std::string& iface_name,
57                                   const std::array<uint8_t, 6>& mac) {
58 #ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
59     if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), false)) {
60         LOG(ERROR) << "SetUpState(false) failed.";
61         return false;
62     }
63 #endif
64     bool success = iface_tool_.lock()->SetMacAddress(iface_name.c_str(), mac);
65 #ifndef WIFI_AVOID_IFACE_RESET_MAC_CHANGE
66     if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
67         LOG(ERROR) << "SetUpState(true) failed. Wait for driver ready.";
68         // Wait for driver ready and try to set iface UP again
69         if (legacy_hal_.lock()->waitForDriverReady() !=
70             legacy_hal::WIFI_SUCCESS) {
71             LOG(ERROR) << "SetUpState(true) wait for driver ready failed.";
72             return false;
73         }
74         if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), true)) {
75             LOG(ERROR) << "SetUpState(true) failed after retry.";
76             return false;
77         }
78     }
79 #endif
80     IfaceEventHandlers event_handlers = {};
81     const auto it = event_handlers_map_.find(iface_name);
82     if (it != event_handlers_map_.end()) {
83         event_handlers = it->second;
84     }
85     if (event_handlers.on_state_toggle_off_on != nullptr) {
86         event_handlers.on_state_toggle_off_on(iface_name);
87     }
88     if (!success) {
89         LOG(ERROR) << "SetMacAddress failed on " << iface_name;
90     } else {
91         LOG(DEBUG) << "SetMacAddress succeeded on " << iface_name;
92     }
93     return success;
94 }
95 
getOrCreateRandomMacAddress()96 std::array<uint8_t, 6> WifiIfaceUtil::getOrCreateRandomMacAddress() {
97     if (random_mac_address_) {
98         return *random_mac_address_.get();
99     }
100     random_mac_address_ =
101         std::make_unique<std::array<uint8_t, 6>>(createRandomMacAddress());
102     return *random_mac_address_.get();
103 }
104 
registerIfaceEventHandlers(const std::string & iface_name,IfaceEventHandlers handlers)105 void WifiIfaceUtil::registerIfaceEventHandlers(const std::string& iface_name,
106                                                IfaceEventHandlers handlers) {
107     event_handlers_map_[iface_name] = handlers;
108 }
109 
unregisterIfaceEventHandlers(const std::string & iface_name)110 void WifiIfaceUtil::unregisterIfaceEventHandlers(
111     const std::string& iface_name) {
112     event_handlers_map_.erase(iface_name);
113 }
114 
createRandomMacAddress()115 std::array<uint8_t, 6> WifiIfaceUtil::createRandomMacAddress() {
116     std::array<uint8_t, 6> address = {};
117     std::random_device rd;
118     std::default_random_engine engine(rd());
119     std::uniform_int_distribution<uint8_t> dist(
120         std::numeric_limits<uint8_t>::min(),
121         std::numeric_limits<uint8_t>::max());
122     for (size_t i = 0; i < address.size(); i++) {
123         address[i] = dist(engine);
124     }
125     // Set the local bit and clear the multicast bit.
126     address[0] |= kMacAddressLocallyAssignedMask;
127     address[0] &= ~kMacAddressMulticastMask;
128     return address;
129 }
130 
setUpState(const std::string & iface_name,bool request_up)131 bool WifiIfaceUtil::setUpState(const std::string& iface_name, bool request_up) {
132     if (!iface_tool_.lock()->SetUpState(iface_name.c_str(), request_up)) {
133         LOG(ERROR) << "SetUpState to " << request_up << " failed";
134         return false;
135     }
136     return true;
137 }
138 
ifNameToIndex(const std::string & iface_name)139 unsigned WifiIfaceUtil::ifNameToIndex(const std::string& iface_name) {
140     return if_nametoindex(iface_name.c_str());
141 }
142 
createBridge(const std::string & br_name)143 bool WifiIfaceUtil::createBridge(const std::string& br_name) {
144     if (!iface_tool_.lock()->createBridge(br_name)) {
145         return false;
146     }
147 
148     if (!iface_tool_.lock()->SetUpState(br_name.c_str(), true)) {
149         LOG(ERROR) << "bridge SetUpState(true) failed.";
150     }
151     return true;
152 }
153 
deleteBridge(const std::string & br_name)154 bool WifiIfaceUtil::deleteBridge(const std::string& br_name) {
155     if (!iface_tool_.lock()->SetUpState(br_name.c_str(), false)) {
156         LOG(INFO) << "SetUpState(false) failed for bridge=" << br_name.c_str();
157     }
158 
159     return iface_tool_.lock()->deleteBridge(br_name);
160 }
161 
addIfaceToBridge(const std::string & br_name,const std::string & if_name)162 bool WifiIfaceUtil::addIfaceToBridge(const std::string& br_name,
163                                      const std::string& if_name) {
164     return iface_tool_.lock()->addIfaceToBridge(br_name, if_name);
165 }
166 
removeIfaceFromBridge(const std::string & br_name,const std::string & if_name)167 bool WifiIfaceUtil::removeIfaceFromBridge(const std::string& br_name,
168                                           const std::string& if_name) {
169     return iface_tool_.lock()->removeIfaceFromBridge(br_name, if_name);
170 }
171 
172 }  // namespace iface_util
173 }  // namespace implementation
174 }  // namespace V1_5
175 }  // namespace wifi
176 }  // namespace hardware
177 }  // namespace android
178