1 // 2 // Copyright (C) 2016 Google, Inc. 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 #include <rapidjson/document.h> 17 #include <rapidjson/writer.h> 18 #include <rapidjson/stringbuffer.h> 19 #include <net/if.h> 20 #include <sys/ioctl.h> 21 #include <sys/socket.h> 22 23 #include <base.h> 24 #include <base/at_exit.h> 25 #include <base/command_line.h> 26 #include <base/logging.h> 27 #include <base/macros.h> 28 #include <base/strings/string_split.h> 29 #include <base/strings/string_util.h> 30 #include <utils/command_receiver.h> 31 #include <utils/common_utils.h> 32 #include <hardware_legacy/wifi_hal.h> 33 #include <wifi_system/hal_tool.h> 34 #include <wifi_system/interface_tool.h> 35 36 #include "wifi_facade.h" 37 38 const char kWlanInterface[] = "wlan0"; 39 const char kP2pInterface[] = "p2p0"; 40 41 std::tuple<bool, int> WifiFacade::WifiInit() { 42 if (!WifiStartHal()) { 43 return std::make_tuple(false, sl4n_error_codes::kFailInt); 44 } 45 46 if (!WifiGetInterfaces() || wlan0_index == -1) { 47 return std::make_tuple(false, sl4n_error_codes::kFailInt); 48 } 49 50 return std::make_tuple(true, sl4n_error_codes::kPassInt); 51 } 52 53 bool WifiFacade::WifiStartHal() { 54 android::wifi_system::InterfaceTool if_tool; 55 if (wifi_hal_handle == NULL) { 56 android::wifi_system::HalTool hal_tool; 57 if (!hal_tool.InitFunctionTable(&hal_fn)) { 58 return false; 59 } 60 61 if (!if_tool.SetWifiUpState(true)) { 62 return false; 63 } 64 65 res = hal_fn.wifi_initialize(&wifi_hal_handle); 66 return res == WIFI_SUCCESS; 67 } else { 68 return if_tool.SetWifiUpState(true); 69 } 70 } 71 72 bool WifiFacade::WifiGetInterfaces() { 73 int num_ifaces; 74 int result = hal_fn.wifi_get_ifaces(wifi_hal_handle, &num_ifaces, 75 &wifi_iface_handles); 76 if (result < 0) { 77 LOG(ERROR) << sl4n::kTagStr << ": Can not get Wi-Fi interfaces"; 78 return false; 79 } 80 81 if (num_ifaces < 0) { 82 LOG(ERROR) << sl4n::kTagStr << ": Negative number of interfaces"; 83 return false; 84 } 85 86 if (wifi_iface_handles == NULL) { 87 LOG(ERROR) << sl4n::kTagStr 88 << "wifi_get_ifaces returned null interface array"; 89 return false; 90 } 91 92 if (num_ifaces > 8) { 93 LOG(ERROR) << sl4n::kTagStr 94 << "wifi_get_ifaces returned too many interfaces"; 95 return false; 96 } 97 98 char buf[128]; 99 for (int i = 0; i < num_ifaces; ++i) { 100 int result = hal_fn.wifi_get_iface_name(wifi_iface_handles[i], buf, 101 sizeof(buf)); 102 if (result < 0) { 103 LOG(ERROR) << sl4n::kTagStr 104 << "Can't obtain interface name for interface #" << i; 105 continue; 106 } 107 if (!strcmp(buf, kWlanInterface)) { 108 wlan0_index = i; 109 } else if (!strcmp(buf, kP2pInterface)) { 110 p2p0_index = i; 111 } 112 } 113 114 return true; 115 } 116 117 bool WifiFacade::SharedValidator() { 118 if (wifi_hal_handle == NULL) { 119 LOG(ERROR) << sl4n::kTagStr << "HAL handle not initialized"; 120 return false; 121 } 122 123 if (wifi_iface_handles == NULL) { 124 LOG(ERROR) << sl4n::kTagStr << "HAL interfaces not initialized"; 125 return false; 126 } 127 128 if (wlan0_index == -1) { 129 LOG(ERROR) << sl4n::kTagStr << kWlanInterface << " interface not found"; 130 return false; 131 } 132 133 return true; 134 } 135 136 std::tuple<int, int> WifiFacade::WifiGetSupportedFeatureSet() { 137 if (!SharedValidator()) { 138 return std::make_tuple(0, sl4n_error_codes::kFailInt); 139 } 140 141 feature_set set = 0; 142 int result = hal_fn.wifi_get_supported_feature_set( 143 wifi_iface_handles[wlan0_index], &set); 144 if (result == WIFI_SUCCESS) { 145 return std::make_tuple(set, sl4n_error_codes::kPassInt); 146 } else { 147 return std::make_tuple(0, sl4n_error_codes::kFailInt); 148 } 149 } 150 151 ////////////////// 152 // wrappers 153 ///////////////// 154 155 static WifiFacade facade; // triggers registration with CommandReceiver 156 157 void wifi_init_wrapper(rapidjson::Document &doc) { 158 int expected_param_size = 0; 159 if (!CommonUtils::IsParamLengthMatching(doc, expected_param_size)) { 160 return; 161 } 162 bool result; 163 int error_code; 164 std::tie(result, error_code) = facade.WifiInit(); 165 if (error_code == sl4n_error_codes::kFailInt) { 166 doc.AddMember(sl4n::kResultStr, false, doc.GetAllocator()); 167 doc.AddMember(sl4n::kErrorStr, sl4n::kFailStr, doc.GetAllocator()); 168 } else { 169 doc.AddMember(sl4n::kResultStr, result, doc.GetAllocator()); 170 doc.AddMember(sl4n::kErrorStr, NULL, doc.GetAllocator()); 171 } 172 } 173 174 void wifi_get_supported_feature_set_wrapper(rapidjson::Document &doc) { 175 int expected_param_size = 0; 176 if (!CommonUtils::IsParamLengthMatching(doc, expected_param_size)) { 177 return; 178 } 179 int result; 180 int error_code; 181 std::tie(result, error_code) = facade.WifiGetSupportedFeatureSet(); 182 if (error_code == sl4n_error_codes::kFailInt) { 183 doc.AddMember(sl4n::kResultStr, false, doc.GetAllocator()); 184 doc.AddMember(sl4n::kErrorStr, sl4n::kFailStr, doc.GetAllocator()); 185 } else { 186 doc.AddMember(sl4n::kResultStr, result, doc.GetAllocator()); 187 doc.AddMember(sl4n::kErrorStr, NULL, doc.GetAllocator()); 188 } 189 } 190 191 //////////////// 192 // constructor 193 //////////////// 194 195 WifiFacade::WifiFacade() { 196 wifi_hal_handle = NULL; 197 wifi_iface_handles = NULL; 198 num_wifi_iface_handles = 0; 199 wlan0_index = -1; 200 p2p0_index = -1; 201 202 CommandReceiver::RegisterCommand("WifiInit", &wifi_init_wrapper); 203 CommandReceiver::RegisterCommand("WifiGetSupportedFeatureSet", 204 &wifi_get_supported_feature_set_wrapper); 205 } 206