Home | History | Annotate | Download | only in wifi
      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