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 38const char kWlanInterface[] = "wlan0"; 39const char kP2pInterface[] = "p2p0"; 40 41std::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 53bool 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 72bool 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 117bool 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 136std::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 155static WifiFacade facade; // triggers registration with CommandReceiver 156 157void 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 174void 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 195WifiFacade::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