summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEtan Cohen <etancohen@google.com>2016-02-05 22:03:47 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-02-05 22:03:47 +0000
commita4c9b2f59fa6932a1fe25c073abcd668179d84db (patch)
tree12bacf29ac544f70e7c5f1353009fc30068b5838
parentc583100be95f4238b12270353c16f266adaa6ba6 (diff)
parentfb4f4178cada2fabb3354f69009dc8a9bc2676a5 (diff)
downloadconnectivity-a4c9b2f59fa6932a1fe25c073abcd668179d84db.tar.gz
Merge "Add Wi-Fi HAL facade to sl4n testing." into mm-wireless-dev
am: fb4f4178ca * commit 'fb4f4178cada2fabb3354f69009dc8a9bc2676a5': Add Wi-Fi HAL facade to sl4n testing.
-rw-r--r--sl4n/Android.mk25
-rw-r--r--sl4n/facades/wifi/wifi_facade.cpp257
-rw-r--r--sl4n/facades/wifi/wifi_facade.h50
-rw-r--r--sl4n/utils/command_receiver.cpp34
-rw-r--r--sl4n/utils/command_receiver.h4
5 files changed, 358 insertions, 12 deletions
diff --git a/sl4n/Android.mk b/sl4n/Android.mk
index 6d2a239..c7c0e7f 100644
--- a/sl4n/Android.mk
+++ b/sl4n/Android.mk
@@ -22,12 +22,15 @@ LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := sl4n
LOCAL_C_INCLUDES += \
+ frameworks/opt/net/wifi/service/jni \
+ hardware/libhardware_legacy/include/hardware_legacy \
system/bt \
$(LOCAL_PATH)/rapidjson/include \
$(LOCAL_PATH)/facades
LOCAL_SRC_FILES := \
facades/bluetooth/bluetooth_binder_facade.cpp \
+ facades/wifi/wifi_facade.cpp \
main.cpp \
utils/command_receiver.cpp \
utils/common_utils.cpp
@@ -46,6 +49,28 @@ LOCAL_STATIC_LIBRARIES += \
libosi \
libbluetooth-client
+# set correct Wi-Fi HAL library path and add Wi-Fi related libraries
+# ============================================================
+LIB_WIFI_HAL := libwifi-hal
+
+ifeq ($(BOARD_WLAN_DEVICE), bcmdhd)
+ LIB_WIFI_HAL := libwifi-hal-bcm
+else ifeq ($(BOARD_WLAN_DEVICE), qcwcn)
+ LIB_WIFI_HAL := libwifi-hal-qcom
+else ifeq ($(BOARD_WLAN_DEVICE), mrvl)
+ # this is commented because none of the nexus devices
+ # that sport Marvell's wifi have support for HAL
+ # LIB_WIFI_HAL := libwifi-hal-mrvl
+else ifeq ($(BOARD_WLAN_DEVICE), MediaTek)
+ # support MTK WIFI HAL
+ LIB_WIFI_HAL := libwifi-hal-mt66xx
+endif
+
+LOCAL_STATIC_LIBRARIES += \
+ $(LIB_WIFI_HAL) \
+ libnl \
+ libwifi-hal-stub
+
LOCAL_CFLAGS += -std=c++11 -Wall -Wno-unused-parameter -Wno-missing-field-initializers
diff --git a/sl4n/facades/wifi/wifi_facade.cpp b/sl4n/facades/wifi/wifi_facade.cpp
new file mode 100644
index 0000000..80a3b8f
--- /dev/null
+++ b/sl4n/facades/wifi/wifi_facade.cpp
@@ -0,0 +1,257 @@
+//
+// Copyright (C) 2016 Google, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+#include <rapidjson/document.h>
+#include <rapidjson/writer.h>
+#include <rapidjson/stringbuffer.h>
+#include <net/if.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+
+#include <base.h>
+#include <base/at_exit.h>
+#include <base/command_line.h>
+#include <base/logging.h>
+#include <base/macros.h>
+#include <base/strings/string_split.h>
+#include <base/strings/string_util.h>
+#include <utils/command_receiver.h>
+#include <utils/common_utils.h>
+#include <wifi_hal.h>
+#include <wifi_hal_stub.h>
+
+#include "wifi_facade.h"
+
+const char kWlanInterface[] = "wlan0";
+const char kP2pInterface[] = "p2p0";
+
+std::tuple<bool, int> WifiFacade::WifiInit() {
+ if (!WifiStartHal()) {
+ return std::make_tuple(false, sl4n_error_codes::kFailInt);
+ }
+
+ if (!WifiGetInterfaces() || wlan0_index == -1) {
+ return std::make_tuple(false, sl4n_error_codes::kFailInt);
+ }
+
+ return std::make_tuple(true, sl4n_error_codes::kPassInt);
+}
+
+bool WifiFacade::WifiStartHal() {
+ if (wifi_hal_handle == NULL) {
+ if (init_wifi_stub_hal_func_table(&hal_fn) != 0) {
+ LOG(ERROR) << sl4n::kTagStr
+ << ": Can not initialize the basic function pointer table";
+ return false;
+ }
+
+ wifi_error res = init_wifi_vendor_hal_func_table(&hal_fn);
+ if (res != WIFI_SUCCESS) {
+ LOG(ERROR) << sl4n::kTagStr
+ << ": Can not initialize the vendor function pointer table";
+ return false;
+ }
+
+ int ret = BringInterfaceUpDown(kWlanInterface, 1);
+ if (ret != 0) {
+ return false;
+ }
+
+ res = hal_fn.wifi_initialize(&wifi_hal_handle);
+ return res == WIFI_SUCCESS;
+ } else {
+ return BringInterfaceUpDown(kWlanInterface, 1) == 0;
+ }
+}
+
+bool WifiFacade::WifiGetInterfaces() {
+ int num_ifaces;
+ int result = hal_fn.wifi_get_ifaces(wifi_hal_handle, &num_ifaces,
+ &wifi_iface_handles);
+ if (result < 0) {
+ LOG(ERROR) << sl4n::kTagStr << ": Can not get Wi-Fi interfaces";
+ return false;
+ }
+
+ if (num_ifaces < 0) {
+ LOG(ERROR) << sl4n::kTagStr << ": Negative number of interfaces";
+ return false;
+ }
+
+ if (wifi_iface_handles == NULL) {
+ LOG(ERROR) << sl4n::kTagStr
+ << "wifi_get_ifaces returned null interface array";
+ return false;
+ }
+
+ if (num_ifaces > 8) {
+ LOG(ERROR) << sl4n::kTagStr
+ << "wifi_get_ifaces returned too many interfaces";
+ return false;
+ }
+
+ char buf[128];
+ for (int i = 0; i < num_ifaces; ++i) {
+ int result = hal_fn.wifi_get_iface_name(wifi_iface_handles[i], buf,
+ sizeof(buf));
+ if (result < 0) {
+ LOG(ERROR) << sl4n::kTagStr
+ << "Can't obtain interface name for interface #" << i;
+ continue;
+ }
+ if (!strcmp(buf, kWlanInterface)) {
+ wlan0_index = i;
+ } else if (!strcmp(buf, kP2pInterface)) {
+ p2p0_index = i;
+ }
+ }
+
+ return true;
+}
+
+bool WifiFacade::SharedValidator() {
+ if (wifi_hal_handle == NULL) {
+ LOG(ERROR) << sl4n::kTagStr << "HAL handle not initialized";
+ return false;
+ }
+
+ if (wifi_iface_handles == NULL) {
+ LOG(ERROR) << sl4n::kTagStr << "HAL interfaces not initialized";
+ return false;
+ }
+
+ if (wlan0_index == -1) {
+ LOG(ERROR) << sl4n::kTagStr << kWlanInterface << " interface not found";
+ return false;
+ }
+
+ return true;
+}
+
+std::tuple<int, int> WifiFacade::WifiGetSupportedFeatureSet() {
+ if (!SharedValidator()) {
+ return std::make_tuple(0, sl4n_error_codes::kFailInt);
+ }
+
+ feature_set set = 0;
+ int result = hal_fn.wifi_get_supported_feature_set(
+ wifi_iface_handles[wlan0_index], &set);
+ if (result == WIFI_SUCCESS) {
+ return std::make_tuple(set, sl4n_error_codes::kPassInt);
+ } else {
+ return std::make_tuple(0, sl4n_error_codes::kFailInt);
+ }
+}
+
+// TODO: copy of set_iface_flags from Wi-Fi JNI. Consolidate into a support
+// library.
+int WifiFacade::BringInterfaceUpDown(const char *ifname, int dev_up) {
+ struct ifreq ifr;
+ int ret;
+ int sock = socket(PF_INET, SOCK_DGRAM, 0);
+ if (sock < 0) {
+ LOG(ERROR) << "Bad socket: " << sock;
+ return -errno;
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
+
+ if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
+ ret = errno ? -errno : -999;
+ LOG(ERROR) << "Could not read interface " << ifname << " flags: " << errno;
+ close(sock);
+ return ret;
+ }
+
+ if (dev_up) {
+ if (ifr.ifr_flags & IFF_UP) {
+ close(sock);
+ return 0;
+ }
+ ifr.ifr_flags |= IFF_UP;
+ } else {
+ if (!(ifr.ifr_flags & IFF_UP)) {
+ close(sock);
+ return 0;
+ }
+ ifr.ifr_flags &= ~IFF_UP;
+ }
+
+ if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
+ LOG(ERROR) << "Could not set interface " << ifname << " flags: " << errno;
+ ret = errno ? -errno : -999;
+ close(sock);
+ return ret;
+ }
+ close(sock);
+ return 0;
+}
+
+//////////////////
+// wrappers
+/////////////////
+
+static WifiFacade facade; // triggers registration with CommandReceiver
+
+void wifi_init_wrapper(rapidjson::Document &doc) {
+ int expected_param_size = 0;
+ if (!CommonUtils::IsParamLengthMatching(doc, expected_param_size)) {
+ return;
+ }
+ bool result;
+ int error_code;
+ std::tie(result, error_code) = facade.WifiInit();
+ if (error_code == sl4n_error_codes::kFailInt) {
+ doc.AddMember(sl4n::kResultStr, false, doc.GetAllocator());
+ doc.AddMember(sl4n::kErrorStr, sl4n::kFailStr, doc.GetAllocator());
+ } else {
+ doc.AddMember(sl4n::kResultStr, result, doc.GetAllocator());
+ doc.AddMember(sl4n::kErrorStr, NULL, doc.GetAllocator());
+ }
+}
+
+void wifi_get_supported_feature_set_wrapper(rapidjson::Document &doc) {
+ int expected_param_size = 0;
+ if (!CommonUtils::IsParamLengthMatching(doc, expected_param_size)) {
+ return;
+ }
+ int result;
+ int error_code;
+ std::tie(result, error_code) = facade.WifiGetSupportedFeatureSet();
+ if (error_code == sl4n_error_codes::kFailInt) {
+ doc.AddMember(sl4n::kResultStr, false, doc.GetAllocator());
+ doc.AddMember(sl4n::kErrorStr, sl4n::kFailStr, doc.GetAllocator());
+ } else {
+ doc.AddMember(sl4n::kResultStr, result, doc.GetAllocator());
+ doc.AddMember(sl4n::kErrorStr, NULL, doc.GetAllocator());
+ }
+}
+
+////////////////
+// constructor
+////////////////
+
+WifiFacade::WifiFacade() {
+ wifi_hal_handle = NULL;
+ wifi_iface_handles = NULL;
+ num_wifi_iface_handles = 0;
+ wlan0_index = -1;
+ p2p0_index = -1;
+
+ CommandReceiver::RegisterCommand("WifiInit", &wifi_init_wrapper);
+ CommandReceiver::RegisterCommand("WifiGetSupportedFeatureSet",
+ &wifi_get_supported_feature_set_wrapper);
+}
diff --git a/sl4n/facades/wifi/wifi_facade.h b/sl4n/facades/wifi/wifi_facade.h
new file mode 100644
index 0000000..d78ab66
--- /dev/null
+++ b/sl4n/facades/wifi/wifi_facade.h
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2016 Google, Inc.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at:
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+
+#pragma once
+
+#include <rapidjson/document.h>
+#include <tuple>
+
+// WifiFacade provides simple wrappers to call Wi-Fi HAL APIs.
+//
+// Each public function returns a tuple: <result, code>, where:
+// result: result of HAL API or a dummy value (of the correct type)
+// on failure.
+// code: sl4n_error_codes::kPassInt or sl4n_error_codes::kFailInt on
+// success or failure respectively.
+//
+// The wrapper must check whether or not it is possible to call the API.
+// Note the function "SharedValidator()" should be used by wrapper to check
+// whether or not the HAL is configured correctly.
+class WifiFacade {
+ public:
+ WifiFacade();
+ std::tuple<bool, int> WifiInit();
+ std::tuple<int, int> WifiGetSupportedFeatureSet();
+ private:
+ wifi_hal_fn hal_fn;
+ wifi_handle wifi_hal_handle;
+ wifi_interface_handle* wifi_iface_handles;
+ int num_wifi_iface_handles;
+ int wlan0_index;
+ int p2p0_index;
+
+ bool SharedValidator();
+ bool WifiStartHal();
+ bool WifiGetInterfaces();
+ int BringInterfaceUpDown(const char *ifname, int dev_up);
+};
diff --git a/sl4n/utils/command_receiver.cpp b/sl4n/utils/command_receiver.cpp
index 31493bf..a57c764 100644
--- a/sl4n/utils/command_receiver.cpp
+++ b/sl4n/utils/command_receiver.cpp
@@ -31,9 +31,8 @@
using android::sp;
using ipc::binder::IBluetooth;
-typedef void (*MFP)(rapidjson::Document&);
typedef std::map<std::string, MFP> function_map;
-function_map _funcMap;
+function_map* _funcMap = NULL;
BluetoothBinderFacade bt_binder;
void _clean_result(rapidjson::Document &doc) {
@@ -228,20 +227,23 @@ void bluetooth_binder_set_adv_settings_wrapper(rapidjson::Document &doc) {
// End Wrappers ... I'm not a large water dwelling mammal...
CommandReceiver::CommandReceiver() {
- _funcMap.insert(std::make_pair("initiate", &initiate));
- _funcMap.insert(std::make_pair("BluetoothBinderInitInterface",
+ if (_funcMap == NULL) {
+ _funcMap = new function_map();
+ }
+ _funcMap->insert(std::make_pair("initiate", &initiate));
+ _funcMap->insert(std::make_pair("BluetoothBinderInitInterface",
&bluetooth_binder_init_interface_wapper));
- _funcMap.insert(std::make_pair("BluetoothBinderGetName",
+ _funcMap->insert(std::make_pair("BluetoothBinderGetName",
&bluetooth_binder_get_local_name_wrapper));
- _funcMap.insert(std::make_pair("BluetoothBinderSetName",
+ _funcMap->insert(std::make_pair("BluetoothBinderSetName",
&bluetooth_binder_set_local_name_wrapper));
- _funcMap.insert(std::make_pair("BluetoothBinderGetAddress",
+ _funcMap->insert(std::make_pair("BluetoothBinderGetAddress",
&bluetooth_binder_get_local_address_wrapper));
- _funcMap.insert(std::make_pair("BluetoothBinderEnable",
+ _funcMap->insert(std::make_pair("BluetoothBinderEnable",
&bluetooth_binder_enable_wrapper));
- _funcMap.insert(std::make_pair("BluetoothBinderRegisterBLE",
+ _funcMap->insert(std::make_pair("BluetoothBinderRegisterBLE",
&bluetooth_binder_register_ble_wrapper));
- _funcMap.insert(std::make_pair("BluetoothBinderSetAdvSettings",
+ _funcMap->insert(std::make_pair("BluetoothBinderSetAdvSettings",
&bluetooth_binder_set_adv_settings_wrapper));
}
@@ -253,9 +255,17 @@ void CommandReceiver::Call(rapidjson::Document& doc) {
cmd = doc[sl4n::kMethodStr].GetString();
}
- function_map::const_iterator iter = _funcMap.find(cmd);
- if (iter != _funcMap.end()) {
+ function_map::const_iterator iter = _funcMap->find(cmd);
+ if (iter != _funcMap->end()) {
iter->second(doc);
}
_clean_result(doc);
}
+
+void CommandReceiver::RegisterCommand(std::string name, MFP command) {
+ if (_funcMap == NULL) {
+ _funcMap = new function_map();
+ }
+
+ _funcMap->insert(std::make_pair(name, command));
+}
diff --git a/sl4n/utils/command_receiver.h b/sl4n/utils/command_receiver.h
index b2e9531..c2af543 100644
--- a/sl4n/utils/command_receiver.h
+++ b/sl4n/utils/command_receiver.h
@@ -18,6 +18,8 @@
#include <rapidjson/document.h>
+typedef void (*MFP)(rapidjson::Document&);
+
// This class defines the functions that interact with the input JSON and
// correspondingly calls the facade associated with the input JSON doc. This
// class also contains wrapper functions to the actual SL4N Facades and does
@@ -30,6 +32,8 @@ class CommandReceiver {
CommandReceiver();
~CommandReceiver();
+ static void RegisterCommand(std::string name, MFP command);
+
// Function that extracts the method/cmd parameter from the JSON doc and
// passes the document to the corresponding wrapper function.
void Call(rapidjson::Document& doc);