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
WifiInit()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
WifiStartHal()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
WifiGetInterfaces()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
SharedValidator()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
WifiGetSupportedFeatureSet()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
wifi_init_wrapper(rapidjson::Document & doc)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
wifi_get_supported_feature_set_wrapper(rapidjson::Document & doc)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
WifiFacade()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