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