upload android base code part4
This commit is contained in:
parent
b9e30e05b1
commit
78ea2404cd
23455 changed files with 5250148 additions and 0 deletions
3
android/hardware/realtek/wlan/Android.mk
Normal file
3
android/hardware/realtek/wlan/Android.mk
Normal file
|
@ -0,0 +1,3 @@
|
|||
ifeq ($(BOARD_WIFI_VENDOR), realtek)
|
||||
include $(call all-subdir-makefiles)
|
||||
endif
|
39
android/hardware/realtek/wlan/config/Android.mk
Normal file
39
android/hardware/realtek/wlan/config/Android.mk
Normal file
|
@ -0,0 +1,39 @@
|
|||
#
|
||||
# Copyright (C) 2008 The Android Open Source Project
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
########################
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := dhcpcd.conf
|
||||
LOCAL_MODULE_CLASS := ETC
|
||||
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/dhcpcd
|
||||
LOCAL_SRC_FILES := android_dhcpcd.conf
|
||||
include $(BUILD_PREBUILT)
|
||||
|
||||
#########################
|
||||
|
||||
WIFI_DRIVER_SOCKET_IFACE := wlan0
|
||||
ifeq ($(strip $(WPA_SUPPLICANT_VERSION)),VER_0_8_X)
|
||||
include external/wpa_supplicant_8/wpa_supplicant/wpa_supplicant_conf.mk
|
||||
else
|
||||
ifeq ($(strip $(WPA_SUPPLICANT_VERSION)),VER_0_6_X)
|
||||
include external/wpa_supplicant_6/wpa_supplicant/wpa_supplicant_conf.mk
|
||||
else
|
||||
include external/wpa_supplicant/wpa_supplicant_conf.mk
|
||||
endif
|
||||
endif
|
||||
#######################
|
9
android/hardware/realtek/wlan/config/android_dhcpcd.conf
Normal file
9
android/hardware/realtek/wlan/config/android_dhcpcd.conf
Normal file
|
@ -0,0 +1,9 @@
|
|||
# dhcpcd configuration for Android Wi-Fi interface
|
||||
# See dhcpcd.conf(5) for details.
|
||||
|
||||
# Disable solicitation of IPv6 Router Advertisements
|
||||
noipv6rs
|
||||
|
||||
interface wlan0
|
||||
# dhcpcd-run-hooks uses these options.
|
||||
option subnet_mask, routers, domain_name_servers, interface_mtu
|
27
android/hardware/realtek/wlan/config/config.mk
Normal file
27
android/hardware/realtek/wlan/config/config.mk
Normal file
|
@ -0,0 +1,27 @@
|
|||
#
|
||||
# Copyright (C) 2008 The Android Open Source Project
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
hardware/realtek/wlan/config/wpa_supplicant_overlay.conf:$(TARGET_COPY_OUT_VENDOR)/etc/wifi/wpa_supplicant_overlay.conf \
|
||||
hardware/realtek/wlan/config/p2p_supplicant_overlay.conf:$(TARGET_COPY_OUT_VENDOR)/etc/wifi/p2p_supplicant_overlay.conf \
|
||||
hardware/realtek/wlan/config/macprog.sh:$(TARGET_COPY_OUT_VENDOR)/xbin/macprog.sh \
|
||||
device/softwinner/common/init.wireless.realtek.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.wireless.realtek.rc
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(TOP_DIR)device/softwinner/$(basename $(TARGET_DEVICE))/configs/init.wireless.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.wireless.rc
|
||||
|
||||
PRODUCT_COPY_FILES += \
|
||||
$(call find-copy-subdir-files,"wifi_efuse_*.map",$(TOP_DIR)device/softwinner/$(basename $(TARGET_DEVICE))/configs/,$(TARGET_COPY_OUT_VENDOR)/etc/wifi)
|
72
android/hardware/realtek/wlan/config/macprog.sh
Executable file
72
android/hardware/realtek/wlan/config/macprog.sh
Executable file
|
@ -0,0 +1,72 @@
|
|||
#!/vendor/bin/sh
|
||||
|
||||
macaddr=$(getprop ro.boot.mac)
|
||||
macaddr=$(echo $macaddr | tr [a-z] [A-Z])
|
||||
|
||||
function verify()
|
||||
{
|
||||
local mac=$1
|
||||
local ret=0
|
||||
if [ -z "$mac" ]; then
|
||||
ret=1
|
||||
elif [ "$(echo $mac | wc -c)" -ne 18 ]; then
|
||||
ret=1
|
||||
elif [ "$mac" = "00:00:00:00:00:00" ]; then
|
||||
ret=1
|
||||
elif [ "$mac" = "FF:FF:FF:FF:FF:FF" ]; then
|
||||
ret=1
|
||||
elif [ "${mac:4:13}" = "7:13:36:E4:4B" ]; then
|
||||
ret=1
|
||||
elif [ "${mac:4:13}" = "9:CB:C9:A4:EC" ]; then
|
||||
ret=1
|
||||
fi
|
||||
return $ret
|
||||
}
|
||||
|
||||
verify $macaddr
|
||||
|
||||
if [ $? -ne "0" ]; then
|
||||
macaddr="FC"
|
||||
macaddr="$macaddr:$(printf "%02X" $((RANDOM/128)))"
|
||||
macaddr="$macaddr:$(printf "%02X" $((RANDOM/128)))"
|
||||
macaddr="$macaddr:$(printf "%02X" $((RANDOM/128)))"
|
||||
macaddr="$macaddr:$(printf "%02X" $((RANDOM/128)))"
|
||||
macaddr="$macaddr:$(printf "%02X" $((RANDOM/128)))"
|
||||
fi
|
||||
|
||||
if [ -n "$macaddr" ]; then
|
||||
base=0x${macaddr:0:2}
|
||||
let "val=base&0xFC"
|
||||
val=$(printf "%02X" $val)
|
||||
macaddr=${val}${macaddr:2:15}
|
||||
|
||||
base=0x${macaddr:3:2}
|
||||
|
||||
wifi_file=/data/misc/wifi/wifimac.txt
|
||||
bt_file=$(getprop ro.bt.bdaddr_path)
|
||||
|
||||
if [ -z "$bt_file" ]; then
|
||||
bt_file=/data/misc/bluetooth/bdaddr
|
||||
fi
|
||||
|
||||
if [ ! -f "$wifi_file" ]; then
|
||||
let "val=base&0x0F|0x00"
|
||||
|
||||
val=$(printf "%02X" $val)
|
||||
|
||||
wlan_mac=${macaddr:0:3}${val}${macaddr:5:12}
|
||||
|
||||
echo $wlan_mac > $wifi_file
|
||||
chmod 644 $wifi_file
|
||||
fi
|
||||
|
||||
if [ ! -f "$bt_file" ]; then
|
||||
let "val=base&0x0F|0x20"
|
||||
val=$(printf "%02X" $val)
|
||||
|
||||
bt_mac=${macaddr:0:3}${val}${macaddr:5:12}
|
||||
|
||||
echo $bt_mac > $bt_file
|
||||
chmod 644 $bt_file
|
||||
fi
|
||||
fi
|
|
@ -0,0 +1 @@
|
|||
wowlan_triggers=any
|
|
@ -0,0 +1 @@
|
|||
wowlan_triggers=any
|
56
android/hardware/realtek/wlan/wifi_hal/Android.mk
Normal file
56
android/hardware/realtek/wlan/wifi_hal/Android.mk
Normal file
|
@ -0,0 +1,56 @@
|
|||
# Copyright (C) 2011 The Android Open Source Project
|
||||
#
|
||||
# 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.
|
||||
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
# Make the HAL library
|
||||
# ============================================================
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
LOCAL_CFLAGS := \
|
||||
-Wall \
|
||||
-Werror \
|
||||
-Wno-format \
|
||||
-Wno-reorder \
|
||||
-Wno-unused-function \
|
||||
-Wno-unused-parameter \
|
||||
-Wno-unused-private-field \
|
||||
-Wno-unused-variable \
|
||||
|
||||
LOCAL_C_INCLUDES += \
|
||||
external/libnl/include \
|
||||
$(call include-path-for, libhardware_legacy)/hardware_legacy \
|
||||
external/wpa_supplicant_8/src/drivers
|
||||
|
||||
LOCAL_SRC_FILES := \
|
||||
wifi_hal.cpp \
|
||||
rtt.cpp \
|
||||
common.cpp \
|
||||
cpp_bindings.cpp \
|
||||
gscan.cpp \
|
||||
link_layer_stats.cpp \
|
||||
wifi_logger.cpp \
|
||||
wifi_offload.cpp
|
||||
|
||||
LOCAL_SHARED_LIBRARIES := \
|
||||
libnl \
|
||||
libutils \
|
||||
liblog
|
||||
|
||||
LOCAL_MODULE := libwifi-hal-rtk
|
||||
LOCAL_PROPRIETARY_MODULE := true
|
||||
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
261
android/hardware/realtek/wlan/wifi_hal/common.cpp
Normal file
261
android/hardware/realtek/wlan/wifi_hal/common.cpp
Normal file
|
@ -0,0 +1,261 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/family.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/errqueue.h>
|
||||
|
||||
#include <linux/pkt_sched.h>
|
||||
#include <netlink/object-api.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/socket.h>
|
||||
#include <netlink/handlers.h>
|
||||
|
||||
#include "wifi_hal.h"
|
||||
#include "common.h"
|
||||
#include "cpp_bindings.h"
|
||||
|
||||
interface_info *getIfaceInfo(wifi_interface_handle handle)
|
||||
{
|
||||
return (interface_info *)handle;
|
||||
}
|
||||
|
||||
wifi_handle getWifiHandle(wifi_interface_handle handle)
|
||||
{
|
||||
return getIfaceInfo(handle)->handle;
|
||||
}
|
||||
|
||||
hal_info *getHalInfo(wifi_handle handle)
|
||||
{
|
||||
return (hal_info *)handle;
|
||||
}
|
||||
|
||||
hal_info *getHalInfo(wifi_interface_handle handle)
|
||||
{
|
||||
return getHalInfo(getWifiHandle(handle));
|
||||
}
|
||||
|
||||
wifi_handle getWifiHandle(hal_info *info)
|
||||
{
|
||||
return (wifi_handle)info;
|
||||
}
|
||||
|
||||
wifi_interface_handle getIfaceHandle(interface_info *info)
|
||||
{
|
||||
return (wifi_interface_handle)info;
|
||||
}
|
||||
|
||||
wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg)
|
||||
{
|
||||
hal_info *info = (hal_info *)handle;
|
||||
|
||||
/* TODO: check for multiple handlers? */
|
||||
pthread_mutex_lock(&info->cb_lock);
|
||||
|
||||
wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (info->num_event_cb < info->alloc_event_cb) {
|
||||
info->event_cb[info->num_event_cb].nl_cmd = cmd;
|
||||
info->event_cb[info->num_event_cb].vendor_id = 0;
|
||||
info->event_cb[info->num_event_cb].vendor_subcmd = 0;
|
||||
info->event_cb[info->num_event_cb].cb_func = func;
|
||||
info->event_cb[info->num_event_cb].cb_arg = arg;
|
||||
ALOGV("Successfully added event handler %p:%p for command %d at %d",
|
||||
arg, func, cmd, info->num_event_cb);
|
||||
info->num_event_cb++;
|
||||
result = WIFI_SUCCESS;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&info->cb_lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
wifi_error wifi_register_vendor_handler(wifi_handle handle,
|
||||
uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg)
|
||||
{
|
||||
hal_info *info = (hal_info *)handle;
|
||||
|
||||
/* TODO: check for multiple handlers? */
|
||||
pthread_mutex_lock(&info->cb_lock);
|
||||
|
||||
wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (info->num_event_cb < info->alloc_event_cb) {
|
||||
info->event_cb[info->num_event_cb].nl_cmd = NL80211_CMD_VENDOR;
|
||||
info->event_cb[info->num_event_cb].vendor_id = id;
|
||||
info->event_cb[info->num_event_cb].vendor_subcmd = subcmd;
|
||||
info->event_cb[info->num_event_cb].cb_func = func;
|
||||
info->event_cb[info->num_event_cb].cb_arg = arg;
|
||||
ALOGV("Added event handler %p:%p for vendor 0x%0x and subcmd 0x%0x at %d",
|
||||
arg, func, id, subcmd, info->num_event_cb);
|
||||
info->num_event_cb++;
|
||||
result = WIFI_SUCCESS;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&info->cb_lock);
|
||||
return result;
|
||||
}
|
||||
|
||||
void wifi_unregister_handler(wifi_handle handle, int cmd)
|
||||
{
|
||||
hal_info *info = (hal_info *)handle;
|
||||
|
||||
if (cmd == NL80211_CMD_VENDOR) {
|
||||
ALOGV("Must use wifi_unregister_vendor_handler to remove vendor handlers");
|
||||
return;
|
||||
}
|
||||
|
||||
pthread_mutex_lock(&info->cb_lock);
|
||||
|
||||
for (int i = 0; i < info->num_event_cb; i++) {
|
||||
if (info->event_cb[i].nl_cmd == cmd) {
|
||||
ALOGV("Successfully removed event handler %p:%p for cmd = 0x%0x from %d",
|
||||
info->event_cb[i].cb_arg, info->event_cb[i].cb_func, cmd, i);
|
||||
|
||||
memmove(&info->event_cb[i], &info->event_cb[i+1],
|
||||
(info->num_event_cb - i - 1) * sizeof(cb_info));
|
||||
info->num_event_cb--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&info->cb_lock);
|
||||
}
|
||||
|
||||
void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd)
|
||||
{
|
||||
hal_info *info = (hal_info *)handle;
|
||||
|
||||
pthread_mutex_lock(&info->cb_lock);
|
||||
|
||||
for (int i = 0; i < info->num_event_cb; i++) {
|
||||
|
||||
if (info->event_cb[i].nl_cmd == NL80211_CMD_VENDOR
|
||||
&& info->event_cb[i].vendor_id == id
|
||||
&& info->event_cb[i].vendor_subcmd == subcmd) {
|
||||
ALOGV("Successfully removed event handler %p:%p for vendor 0x%0x, subcmd 0x%0x from %d",
|
||||
info->event_cb[i].cb_arg, info->event_cb[i].cb_func, id, subcmd, i);
|
||||
memmove(&info->event_cb[i], &info->event_cb[i+1],
|
||||
(info->num_event_cb - i - 1) * sizeof(cb_info));
|
||||
info->num_event_cb--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&info->cb_lock);
|
||||
}
|
||||
|
||||
|
||||
wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd)
|
||||
{
|
||||
hal_info *info = (hal_info *)handle;
|
||||
|
||||
ALOGV("registering command %d", id);
|
||||
|
||||
wifi_error result = WIFI_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (info->num_cmd < info->alloc_cmd) {
|
||||
info->cmd[info->num_cmd].id = id;
|
||||
info->cmd[info->num_cmd].cmd = cmd;
|
||||
ALOGV("Successfully added command %d: %p at %d", id, cmd, info->num_cmd);
|
||||
info->num_cmd++;
|
||||
result = WIFI_SUCCESS;
|
||||
} else {
|
||||
ALOGV("Failed to add command %d: %p at %d, reached max limit %d",
|
||||
id, cmd, info->num_cmd, info->alloc_cmd);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
WifiCommand *wifi_unregister_cmd(wifi_handle handle, int id)
|
||||
{
|
||||
hal_info *info = (hal_info *)handle;
|
||||
|
||||
ALOGV("un-registering command %d", id);
|
||||
|
||||
WifiCommand *cmd = NULL;
|
||||
|
||||
for (int i = 0; i < info->num_cmd; i++) {
|
||||
if (info->cmd[i].id == id) {
|
||||
cmd = info->cmd[i].cmd;
|
||||
memmove(&info->cmd[i], &info->cmd[i+1], (info->num_cmd - i - 1) * sizeof(cmd_info));
|
||||
info->num_cmd--;
|
||||
ALOGV("Successfully removed command %d: %p from %d", id, cmd, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!cmd) {
|
||||
ALOGI("Failed to remove command %d: %p", id, cmd);
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
WifiCommand *wifi_get_cmd(wifi_handle handle, int id)
|
||||
{
|
||||
hal_info *info = (hal_info *)handle;
|
||||
|
||||
WifiCommand *cmd = NULL;
|
||||
|
||||
for (int i = 0; i < info->num_cmd; i++) {
|
||||
if (info->cmd[i].id == id) {
|
||||
cmd = info->cmd[i].cmd;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return cmd;
|
||||
}
|
||||
|
||||
void wifi_unregister_cmd(wifi_handle handle, WifiCommand *cmd)
|
||||
{
|
||||
hal_info *info = (hal_info *)handle;
|
||||
|
||||
for (int i = 0; i < info->num_cmd; i++) {
|
||||
if (info->cmd[i].cmd == cmd) {
|
||||
int id = info->cmd[i].id;
|
||||
memmove(&info->cmd[i], &info->cmd[i+1], (info->num_cmd - i - 1) * sizeof(cmd_info));
|
||||
info->num_cmd--;
|
||||
ALOGV("Successfully removed command %d: %p from %d", id, cmd, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wifi_error wifi_cancel_cmd(wifi_request_id id, wifi_interface_handle iface)
|
||||
{
|
||||
wifi_handle handle = getWifiHandle(iface);
|
||||
|
||||
WifiCommand *cmd = wifi_unregister_cmd(handle, id);
|
||||
ALOGV("Cancel WifiCommand = %p", cmd);
|
||||
if (cmd) {
|
||||
cmd->cancel();
|
||||
cmd->releaseRef();
|
||||
return WIFI_SUCCESS;
|
||||
}
|
||||
|
||||
return WIFI_ERROR_INVALID_ARGS;
|
||||
}
|
||||
|
274
android/hardware/realtek/wlan/wifi_hal/common.h
Normal file
274
android/hardware/realtek/wlan/wifi_hal/common.h
Normal file
|
@ -0,0 +1,274 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* 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 "wifi_hal.h"
|
||||
|
||||
#ifndef __WIFI_HAL_COMMON_H__
|
||||
#define __WIFI_HAL_COMMON_H__
|
||||
|
||||
#define LOG_TAG "WifiHAL"
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include "nl80211_copy.h"
|
||||
#include "sync.h"
|
||||
|
||||
#define SOCKET_BUFFER_SIZE (32768U)
|
||||
#define RECV_BUF_SIZE (4096)
|
||||
#define DEFAULT_EVENT_CB_SIZE (64)
|
||||
#define DEFAULT_CMD_SIZE (64)
|
||||
#define DOT11_OUI_LEN 3
|
||||
#define DOT11_MAX_SSID_LEN 32
|
||||
|
||||
#define MAX_PROBE_RESP_IE_LEN 2048
|
||||
/*
|
||||
Vendor OUI - This is a unique identifier that identifies organization. Lets
|
||||
code Android specific functions with Google OUI; although vendors can do more
|
||||
with their own OUI's as well.
|
||||
*/
|
||||
|
||||
const uint32_t GOOGLE_OUI = 0x001A11;
|
||||
/* TODO: define vendor OUI here */
|
||||
|
||||
|
||||
/*
|
||||
This enum defines ranges for various commands; commands themselves
|
||||
can be defined in respective feature headers; i.e. find gscan command
|
||||
definitions in gscan.cpp
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
/* don't use 0 as a valid subcommand */
|
||||
VENDOR_NL80211_SUBCMD_UNSPECIFIED,
|
||||
|
||||
/* define all vendor startup commands between 0x0 and 0x0FFF */
|
||||
VENDOR_NL80211_SUBCMD_RANGE_START = 0x0001,
|
||||
VENDOR_NL80211_SUBCMD_RANGE_END = 0x0FFF,
|
||||
|
||||
/* define all GScan related commands between 0x1000 and 0x10FF */
|
||||
ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START = 0x1000,
|
||||
ANDROID_NL80211_SUBCMD_GSCAN_RANGE_END = 0x10FF,
|
||||
|
||||
/* define all NearbyDiscovery related commands between 0x1100 and 0x11FF */
|
||||
ANDROID_NL80211_SUBCMD_NBD_RANGE_START = 0x1100,
|
||||
ANDROID_NL80211_SUBCMD_NBD_RANGE_END = 0x11FF,
|
||||
|
||||
/* define all RTT related commands between 0x1100 and 0x11FF */
|
||||
ANDROID_NL80211_SUBCMD_RTT_RANGE_START = 0x1100,
|
||||
ANDROID_NL80211_SUBCMD_RTT_RANGE_END = 0x11FF,
|
||||
|
||||
ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START = 0x1200,
|
||||
ANDROID_NL80211_SUBCMD_LSTATS_RANGE_END = 0x12FF,
|
||||
|
||||
/* define all Logger related commands between 0x1400 and 0x14FF */
|
||||
ANDROID_NL80211_SUBCMD_DEBUG_RANGE_START = 0x1400,
|
||||
ANDROID_NL80211_SUBCMD_DEBUG_RANGE_END = 0x14FF,
|
||||
|
||||
/* define all wifi offload related commands between 0x1600 and 0x16FF */
|
||||
ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START = 0x1600,
|
||||
ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_END = 0x16FF,
|
||||
|
||||
/* define all NAN related commands between 0x1700 and 0x17FF */
|
||||
ANDROID_NL80211_SUBCMD_NAN_RANGE_START = 0x1700,
|
||||
ANDROID_NL80211_SUBCMD_NAN_RANGE_END = 0x17FF,
|
||||
|
||||
/* define all Android Packet Filter related commands between 0x1800 and 0x18FF */
|
||||
ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START = 0x1800,
|
||||
ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_END = 0x18FF,
|
||||
|
||||
/* This is reserved for future usage */
|
||||
|
||||
} ANDROID_VENDOR_SUB_COMMAND;
|
||||
|
||||
typedef enum {
|
||||
|
||||
GSCAN_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_GSCAN_RANGE_START,
|
||||
|
||||
GSCAN_SUBCMD_SET_CONFIG, /* 0x1001 */
|
||||
|
||||
GSCAN_SUBCMD_SET_SCAN_CONFIG, /* 0x1002 */
|
||||
GSCAN_SUBCMD_ENABLE_GSCAN, /* 0x1003 */
|
||||
GSCAN_SUBCMD_GET_SCAN_RESULTS, /* 0x1004 */
|
||||
GSCAN_SUBCMD_SCAN_RESULTS, /* 0x1005 */
|
||||
|
||||
GSCAN_SUBCMD_SET_HOTLIST, /* 0x1006 */
|
||||
|
||||
GSCAN_SUBCMD_SET_SIGNIFICANT_CHANGE_CONFIG, /* 0x1007 */
|
||||
GSCAN_SUBCMD_ENABLE_FULL_SCAN_RESULTS, /* 0x1008 */
|
||||
GSCAN_SUBCMD_GET_CHANNEL_LIST, /* 0x1009 */
|
||||
|
||||
WIFI_SUBCMD_GET_FEATURE_SET, /* 0x100A */
|
||||
WIFI_SUBCMD_GET_FEATURE_SET_MATRIX, /* 0x100B */
|
||||
WIFI_SUBCMD_SET_PNO_RANDOM_MAC_OUI, /* 0x100C */
|
||||
WIFI_SUBCMD_NODFS_SET, /* 0x100D */
|
||||
WIFI_SUBCMD_SET_COUNTRY_CODE, /* 0x100E */
|
||||
/* Add more sub commands here */
|
||||
GSCAN_SUBCMD_SET_EPNO_SSID, /* 0x100F */
|
||||
|
||||
WIFI_SUBCMD_SET_SSID_WHITE_LIST, /* 0x1010 */
|
||||
WIFI_SUBCMD_SET_ROAM_PARAMS, /* 0x1011 */
|
||||
WIFI_SUBCMD_ENABLE_LAZY_ROAM, /* 0x1012 */
|
||||
WIFI_SUBCMD_SET_BSSID_PREF, /* 0x1013 */
|
||||
WIFI_SUBCMD_SET_BSSID_BLACKLIST, /* 0x1014 */
|
||||
|
||||
GSCAN_SUBCMD_ANQPO_CONFIG, /* 0x1015 */
|
||||
WIFI_SUBCMD_SET_RSSI_MONITOR, /* 0x1016 */
|
||||
WIFI_SUBCMD_CONFIG_ND_OFFLOAD, /* 0x1017 */
|
||||
/* Add more sub commands here */
|
||||
|
||||
GSCAN_SUBCMD_MAX,
|
||||
|
||||
APF_SUBCMD_GET_CAPABILITIES = ANDROID_NL80211_SUBCMD_PKT_FILTER_RANGE_START,
|
||||
APF_SUBCMD_SET_FILTER,
|
||||
} WIFI_SUB_COMMAND;
|
||||
|
||||
typedef enum {
|
||||
RTK_RESERVED1,
|
||||
RTK_RESERVED2,
|
||||
GSCAN_EVENT_SIGNIFICANT_CHANGE_RESULTS ,
|
||||
GSCAN_EVENT_HOTLIST_RESULTS_FOUND,
|
||||
GSCAN_EVENT_SCAN_RESULTS_AVAILABLE,
|
||||
GSCAN_EVENT_FULL_SCAN_RESULTS,
|
||||
RTT_EVENT_COMPLETE,
|
||||
GSCAN_EVENT_COMPLETE_SCAN,
|
||||
GSCAN_EVENT_HOTLIST_RESULTS_LOST,
|
||||
GSCAN_EVENT_EPNO_EVENT,
|
||||
GOOGLE_DEBUG_RING_EVENT,
|
||||
GOOGLE_DEBUG_MEM_DUMP_EVENT,
|
||||
GSCAN_EVENT_ANQPO_HOTSPOT_MATCH,
|
||||
GOOGLE_RSSI_MONITOR_EVENT
|
||||
} WIFI_EVENT;
|
||||
|
||||
typedef void (*wifi_internal_event_handler) (wifi_handle handle, int events);
|
||||
|
||||
class WifiCommand;
|
||||
|
||||
typedef struct {
|
||||
int nl_cmd;
|
||||
uint32_t vendor_id;
|
||||
int vendor_subcmd;
|
||||
nl_recvmsg_msg_cb_t cb_func;
|
||||
void *cb_arg;
|
||||
} cb_info;
|
||||
|
||||
typedef struct {
|
||||
wifi_request_id id;
|
||||
WifiCommand *cmd;
|
||||
} cmd_info;
|
||||
|
||||
typedef struct {
|
||||
wifi_handle handle; // handle to wifi data
|
||||
char name[IFNAMSIZ+1]; // interface name + trailing null
|
||||
int id; // id to use when talking to driver
|
||||
} interface_info;
|
||||
|
||||
typedef struct {
|
||||
|
||||
struct nl_sock *cmd_sock; // command socket object
|
||||
struct nl_sock *event_sock; // event socket object
|
||||
int nl80211_family_id; // family id for 80211 driver
|
||||
int cleanup_socks[2]; // sockets used to implement wifi_cleanup
|
||||
|
||||
bool in_event_loop; // Indicates that event loop is active
|
||||
bool clean_up; // Indication to exit since cleanup has started
|
||||
|
||||
wifi_internal_event_handler event_handler; // default event handler
|
||||
wifi_cleaned_up_handler cleaned_up_handler; // socket cleaned up handler
|
||||
|
||||
cb_info *event_cb; // event callbacks
|
||||
int num_event_cb; // number of event callbacks
|
||||
int alloc_event_cb; // number of allocated callback objects
|
||||
pthread_mutex_t cb_lock; // mutex for the event_cb access
|
||||
|
||||
cmd_info *cmd; // Outstanding commands
|
||||
int num_cmd; // number of commands
|
||||
int alloc_cmd; // number of commands allocated
|
||||
|
||||
interface_info **interfaces; // array of interfaces
|
||||
int num_interfaces; // number of interfaces
|
||||
|
||||
|
||||
// add other details
|
||||
} hal_info;
|
||||
|
||||
#define PNO_SSID_FOUND 0x1
|
||||
#define PNO_SSID_LOST 0x2
|
||||
|
||||
typedef struct wifi_pno_result {
|
||||
unsigned char ssid[DOT11_MAX_SSID_LEN];
|
||||
unsigned char ssid_len;
|
||||
signed char rssi;
|
||||
u16 channel;
|
||||
u16 flags;
|
||||
mac_addr bssid;
|
||||
} wifi_pno_result_t;
|
||||
|
||||
typedef struct wifi_gscan_result {
|
||||
u64 ts; // Time of discovery
|
||||
u8 ssid[DOT11_MAX_SSID_LEN+1]; // null terminated
|
||||
mac_addr bssid; // BSSID
|
||||
u32 channel; // channel frequency in MHz
|
||||
s32 rssi; // in db
|
||||
u64 rtt; // in nanoseconds
|
||||
u64 rtt_sd; // standard deviation in rtt
|
||||
u16 beacon_period; // units are Kusec
|
||||
u16 capability; // Capability information
|
||||
u32 pad;
|
||||
} wifi_gscan_result_t;
|
||||
|
||||
typedef struct wifi_gscan_full_result {
|
||||
wifi_gscan_result_t fixed;
|
||||
u32 scan_ch_bucket; // scan chbucket bitmask
|
||||
u32 ie_length; // byte length of Information Elements
|
||||
u8 ie_data[1]; // IE data to follow
|
||||
} wifi_gscan_full_result_t;
|
||||
|
||||
wifi_error wifi_register_handler(wifi_handle handle, int cmd, nl_recvmsg_msg_cb_t func, void *arg);
|
||||
wifi_error wifi_register_vendor_handler(wifi_handle handle,
|
||||
uint32_t id, int subcmd, nl_recvmsg_msg_cb_t func, void *arg);
|
||||
|
||||
void wifi_unregister_handler(wifi_handle handle, int cmd);
|
||||
void wifi_unregister_vendor_handler(wifi_handle handle, uint32_t id, int subcmd);
|
||||
|
||||
wifi_error wifi_register_cmd(wifi_handle handle, int id, WifiCommand *cmd);
|
||||
WifiCommand *wifi_unregister_cmd(wifi_handle handle, int id);
|
||||
WifiCommand *wifi_get_cmd(wifi_handle handle, int id);
|
||||
void wifi_unregister_cmd(wifi_handle handle, WifiCommand *cmd);
|
||||
|
||||
interface_info *getIfaceInfo(wifi_interface_handle);
|
||||
wifi_handle getWifiHandle(wifi_interface_handle handle);
|
||||
hal_info *getHalInfo(wifi_handle handle);
|
||||
hal_info *getHalInfo(wifi_interface_handle handle);
|
||||
wifi_handle getWifiHandle(hal_info *info);
|
||||
wifi_interface_handle getIfaceHandle(interface_info *info);
|
||||
wifi_error wifi_cancel_cmd(wifi_request_id id, wifi_interface_handle iface);
|
||||
|
||||
// some common macros
|
||||
|
||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
#define max(x, y) ((x) > (y) ? (x) : (y))
|
||||
|
||||
#define LOG_NDEBUG 1
|
||||
|
||||
#define NULL_CHECK_RETURN(ptr, str, ret) \
|
||||
do { \
|
||||
if (!(ptr)) { \
|
||||
ALOGV("%s(): null pointer - #ptr (%s)\n", __FUNCTION__, str); \
|
||||
return ret; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
748
android/hardware/realtek/wlan/wifi_hal/cpp_bindings.cpp
Normal file
748
android/hardware/realtek/wlan/wifi_hal/cpp_bindings.cpp
Normal file
|
@ -0,0 +1,748 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/family.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/errqueue.h>
|
||||
|
||||
#include <linux/pkt_sched.h>
|
||||
#include <netlink/object-api.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/socket.h>
|
||||
#include <netlink/handlers.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "wifi_hal.h"
|
||||
#include "common.h"
|
||||
#include "cpp_bindings.h"
|
||||
|
||||
void appendFmt(char *buf, int &offset, const char *fmt, ...)
|
||||
{
|
||||
va_list params;
|
||||
va_start(params, fmt);
|
||||
offset += vsprintf(buf + offset, fmt, params);
|
||||
va_end(params);
|
||||
}
|
||||
|
||||
#define C2S(x) case x: return #x;
|
||||
|
||||
static const char *cmdToString(int cmd)
|
||||
{
|
||||
switch (cmd) {
|
||||
C2S(NL80211_CMD_UNSPEC)
|
||||
C2S(NL80211_CMD_GET_WIPHY)
|
||||
C2S(NL80211_CMD_SET_WIPHY)
|
||||
C2S(NL80211_CMD_NEW_WIPHY)
|
||||
C2S(NL80211_CMD_DEL_WIPHY)
|
||||
C2S(NL80211_CMD_GET_INTERFACE)
|
||||
C2S(NL80211_CMD_SET_INTERFACE)
|
||||
C2S(NL80211_CMD_NEW_INTERFACE)
|
||||
C2S(NL80211_CMD_DEL_INTERFACE)
|
||||
C2S(NL80211_CMD_GET_KEY)
|
||||
C2S(NL80211_CMD_SET_KEY)
|
||||
C2S(NL80211_CMD_NEW_KEY)
|
||||
C2S(NL80211_CMD_DEL_KEY)
|
||||
C2S(NL80211_CMD_GET_BEACON)
|
||||
C2S(NL80211_CMD_SET_BEACON)
|
||||
C2S(NL80211_CMD_START_AP)
|
||||
C2S(NL80211_CMD_STOP_AP)
|
||||
C2S(NL80211_CMD_GET_STATION)
|
||||
C2S(NL80211_CMD_SET_STATION)
|
||||
C2S(NL80211_CMD_NEW_STATION)
|
||||
C2S(NL80211_CMD_DEL_STATION)
|
||||
C2S(NL80211_CMD_GET_MPATH)
|
||||
C2S(NL80211_CMD_SET_MPATH)
|
||||
C2S(NL80211_CMD_NEW_MPATH)
|
||||
C2S(NL80211_CMD_DEL_MPATH)
|
||||
C2S(NL80211_CMD_SET_BSS)
|
||||
C2S(NL80211_CMD_SET_REG)
|
||||
C2S(NL80211_CMD_REQ_SET_REG)
|
||||
C2S(NL80211_CMD_GET_MESH_CONFIG)
|
||||
C2S(NL80211_CMD_SET_MESH_CONFIG)
|
||||
C2S(NL80211_CMD_SET_MGMT_EXTRA_IE)
|
||||
C2S(NL80211_CMD_GET_REG)
|
||||
C2S(NL80211_CMD_GET_SCAN)
|
||||
C2S(NL80211_CMD_TRIGGER_SCAN)
|
||||
C2S(NL80211_CMD_NEW_SCAN_RESULTS)
|
||||
C2S(NL80211_CMD_SCAN_ABORTED)
|
||||
C2S(NL80211_CMD_REG_CHANGE)
|
||||
C2S(NL80211_CMD_AUTHENTICATE)
|
||||
C2S(NL80211_CMD_ASSOCIATE)
|
||||
C2S(NL80211_CMD_DEAUTHENTICATE)
|
||||
C2S(NL80211_CMD_DISASSOCIATE)
|
||||
C2S(NL80211_CMD_MICHAEL_MIC_FAILURE)
|
||||
C2S(NL80211_CMD_REG_BEACON_HINT)
|
||||
C2S(NL80211_CMD_JOIN_IBSS)
|
||||
C2S(NL80211_CMD_LEAVE_IBSS)
|
||||
C2S(NL80211_CMD_TESTMODE)
|
||||
C2S(NL80211_CMD_CONNECT)
|
||||
C2S(NL80211_CMD_ROAM)
|
||||
C2S(NL80211_CMD_DISCONNECT)
|
||||
C2S(NL80211_CMD_SET_WIPHY_NETNS)
|
||||
C2S(NL80211_CMD_GET_SURVEY)
|
||||
C2S(NL80211_CMD_NEW_SURVEY_RESULTS)
|
||||
C2S(NL80211_CMD_SET_PMKSA)
|
||||
C2S(NL80211_CMD_DEL_PMKSA)
|
||||
C2S(NL80211_CMD_FLUSH_PMKSA)
|
||||
C2S(NL80211_CMD_REMAIN_ON_CHANNEL)
|
||||
C2S(NL80211_CMD_CANCEL_REMAIN_ON_CHANNEL)
|
||||
C2S(NL80211_CMD_SET_TX_BITRATE_MASK)
|
||||
C2S(NL80211_CMD_REGISTER_FRAME)
|
||||
C2S(NL80211_CMD_FRAME)
|
||||
C2S(NL80211_CMD_FRAME_TX_STATUS)
|
||||
C2S(NL80211_CMD_SET_POWER_SAVE)
|
||||
C2S(NL80211_CMD_GET_POWER_SAVE)
|
||||
C2S(NL80211_CMD_SET_CQM)
|
||||
C2S(NL80211_CMD_NOTIFY_CQM)
|
||||
C2S(NL80211_CMD_SET_CHANNEL)
|
||||
C2S(NL80211_CMD_SET_WDS_PEER)
|
||||
C2S(NL80211_CMD_FRAME_WAIT_CANCEL)
|
||||
C2S(NL80211_CMD_JOIN_MESH)
|
||||
C2S(NL80211_CMD_LEAVE_MESH)
|
||||
C2S(NL80211_CMD_UNPROT_DEAUTHENTICATE)
|
||||
C2S(NL80211_CMD_UNPROT_DISASSOCIATE)
|
||||
C2S(NL80211_CMD_NEW_PEER_CANDIDATE)
|
||||
C2S(NL80211_CMD_GET_WOWLAN)
|
||||
C2S(NL80211_CMD_SET_WOWLAN)
|
||||
C2S(NL80211_CMD_START_SCHED_SCAN)
|
||||
C2S(NL80211_CMD_STOP_SCHED_SCAN)
|
||||
C2S(NL80211_CMD_SCHED_SCAN_RESULTS)
|
||||
C2S(NL80211_CMD_SCHED_SCAN_STOPPED)
|
||||
C2S(NL80211_CMD_SET_REKEY_OFFLOAD)
|
||||
C2S(NL80211_CMD_PMKSA_CANDIDATE)
|
||||
C2S(NL80211_CMD_TDLS_OPER)
|
||||
C2S(NL80211_CMD_TDLS_MGMT)
|
||||
C2S(NL80211_CMD_UNEXPECTED_FRAME)
|
||||
C2S(NL80211_CMD_PROBE_CLIENT)
|
||||
C2S(NL80211_CMD_REGISTER_BEACONS)
|
||||
C2S(NL80211_CMD_UNEXPECTED_4ADDR_FRAME)
|
||||
C2S(NL80211_CMD_SET_NOACK_MAP)
|
||||
C2S(NL80211_CMD_CH_SWITCH_NOTIFY)
|
||||
C2S(NL80211_CMD_START_P2P_DEVICE)
|
||||
C2S(NL80211_CMD_STOP_P2P_DEVICE)
|
||||
C2S(NL80211_CMD_CONN_FAILED)
|
||||
C2S(NL80211_CMD_SET_MCAST_RATE)
|
||||
C2S(NL80211_CMD_SET_MAC_ACL)
|
||||
C2S(NL80211_CMD_RADAR_DETECT)
|
||||
C2S(NL80211_CMD_GET_PROTOCOL_FEATURES)
|
||||
C2S(NL80211_CMD_UPDATE_FT_IES)
|
||||
C2S(NL80211_CMD_FT_EVENT)
|
||||
C2S(NL80211_CMD_CRIT_PROTOCOL_START)
|
||||
C2S(NL80211_CMD_CRIT_PROTOCOL_STOP)
|
||||
C2S(NL80211_CMD_GET_COALESCE)
|
||||
C2S(NL80211_CMD_SET_COALESCE)
|
||||
C2S(NL80211_CMD_CHANNEL_SWITCH)
|
||||
C2S(NL80211_CMD_VENDOR)
|
||||
C2S(NL80211_CMD_SET_QOS_MAP)
|
||||
default:
|
||||
return "NL80211_CMD_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
const char *attributeToString(int attribute)
|
||||
{
|
||||
switch (attribute) {
|
||||
C2S(NL80211_ATTR_UNSPEC)
|
||||
|
||||
C2S(NL80211_ATTR_WIPHY)
|
||||
C2S(NL80211_ATTR_WIPHY_NAME)
|
||||
|
||||
C2S(NL80211_ATTR_IFINDEX)
|
||||
C2S(NL80211_ATTR_IFNAME)
|
||||
C2S(NL80211_ATTR_IFTYPE)
|
||||
|
||||
C2S(NL80211_ATTR_MAC)
|
||||
|
||||
C2S(NL80211_ATTR_KEY_DATA)
|
||||
C2S(NL80211_ATTR_KEY_IDX)
|
||||
C2S(NL80211_ATTR_KEY_CIPHER)
|
||||
C2S(NL80211_ATTR_KEY_SEQ)
|
||||
C2S(NL80211_ATTR_KEY_DEFAULT)
|
||||
|
||||
C2S(NL80211_ATTR_BEACON_INTERVAL)
|
||||
C2S(NL80211_ATTR_DTIM_PERIOD)
|
||||
C2S(NL80211_ATTR_BEACON_HEAD)
|
||||
C2S(NL80211_ATTR_BEACON_TAIL)
|
||||
|
||||
C2S(NL80211_ATTR_STA_AID)
|
||||
C2S(NL80211_ATTR_STA_FLAGS)
|
||||
C2S(NL80211_ATTR_STA_LISTEN_INTERVAL)
|
||||
C2S(NL80211_ATTR_STA_SUPPORTED_RATES)
|
||||
C2S(NL80211_ATTR_STA_VLAN)
|
||||
C2S(NL80211_ATTR_STA_INFO)
|
||||
|
||||
C2S(NL80211_ATTR_WIPHY_BANDS)
|
||||
|
||||
C2S(NL80211_ATTR_MNTR_FLAGS)
|
||||
|
||||
C2S(NL80211_ATTR_MESH_ID)
|
||||
C2S(NL80211_ATTR_STA_PLINK_ACTION)
|
||||
C2S(NL80211_ATTR_MPATH_NEXT_HOP)
|
||||
C2S(NL80211_ATTR_MPATH_INFO)
|
||||
|
||||
C2S(NL80211_ATTR_BSS_CTS_PROT)
|
||||
C2S(NL80211_ATTR_BSS_SHORT_PREAMBLE)
|
||||
C2S(NL80211_ATTR_BSS_SHORT_SLOT_TIME)
|
||||
|
||||
C2S(NL80211_ATTR_HT_CAPABILITY)
|
||||
|
||||
C2S(NL80211_ATTR_SUPPORTED_IFTYPES)
|
||||
|
||||
C2S(NL80211_ATTR_REG_ALPHA2)
|
||||
C2S(NL80211_ATTR_REG_RULES)
|
||||
|
||||
C2S(NL80211_ATTR_MESH_CONFIG)
|
||||
|
||||
C2S(NL80211_ATTR_BSS_BASIC_RATES)
|
||||
|
||||
C2S(NL80211_ATTR_WIPHY_TXQ_PARAMS)
|
||||
C2S(NL80211_ATTR_WIPHY_FREQ)
|
||||
C2S(NL80211_ATTR_WIPHY_CHANNEL_TYPE)
|
||||
|
||||
C2S(NL80211_ATTR_KEY_DEFAULT_MGMT)
|
||||
|
||||
C2S(NL80211_ATTR_MGMT_SUBTYPE)
|
||||
C2S(NL80211_ATTR_IE)
|
||||
|
||||
C2S(NL80211_ATTR_MAX_NUM_SCAN_SSIDS)
|
||||
|
||||
C2S(NL80211_ATTR_SCAN_FREQUENCIES)
|
||||
C2S(NL80211_ATTR_SCAN_SSIDS)
|
||||
C2S(NL80211_ATTR_GENERATION) /* replaces old SCAN_GENERATION */
|
||||
C2S(NL80211_ATTR_BSS)
|
||||
|
||||
C2S(NL80211_ATTR_REG_INITIATOR)
|
||||
C2S(NL80211_ATTR_REG_TYPE)
|
||||
|
||||
C2S(NL80211_ATTR_SUPPORTED_COMMANDS)
|
||||
|
||||
C2S(NL80211_ATTR_FRAME)
|
||||
C2S(NL80211_ATTR_SSID)
|
||||
C2S(NL80211_ATTR_AUTH_TYPE)
|
||||
C2S(NL80211_ATTR_REASON_CODE)
|
||||
|
||||
C2S(NL80211_ATTR_KEY_TYPE)
|
||||
|
||||
C2S(NL80211_ATTR_MAX_SCAN_IE_LEN)
|
||||
C2S(NL80211_ATTR_CIPHER_SUITES)
|
||||
|
||||
C2S(NL80211_ATTR_FREQ_BEFORE)
|
||||
C2S(NL80211_ATTR_FREQ_AFTER)
|
||||
|
||||
C2S(NL80211_ATTR_FREQ_FIXED)
|
||||
|
||||
|
||||
C2S(NL80211_ATTR_WIPHY_RETRY_SHORT)
|
||||
C2S(NL80211_ATTR_WIPHY_RETRY_LONG)
|
||||
C2S(NL80211_ATTR_WIPHY_FRAG_THRESHOLD)
|
||||
C2S(NL80211_ATTR_WIPHY_RTS_THRESHOLD)
|
||||
|
||||
C2S(NL80211_ATTR_TIMED_OUT)
|
||||
|
||||
C2S(NL80211_ATTR_USE_MFP)
|
||||
|
||||
C2S(NL80211_ATTR_STA_FLAGS2)
|
||||
|
||||
C2S(NL80211_ATTR_CONTROL_PORT)
|
||||
|
||||
C2S(NL80211_ATTR_TESTDATA)
|
||||
|
||||
C2S(NL80211_ATTR_PRIVACY)
|
||||
|
||||
C2S(NL80211_ATTR_DISCONNECTED_BY_AP)
|
||||
C2S(NL80211_ATTR_STATUS_CODE)
|
||||
|
||||
C2S(NL80211_ATTR_CIPHER_SUITES_PAIRWISE)
|
||||
C2S(NL80211_ATTR_CIPHER_SUITE_GROUP)
|
||||
C2S(NL80211_ATTR_WPA_VERSIONS)
|
||||
C2S(NL80211_ATTR_AKM_SUITES)
|
||||
|
||||
C2S(NL80211_ATTR_REQ_IE)
|
||||
C2S(NL80211_ATTR_RESP_IE)
|
||||
|
||||
C2S(NL80211_ATTR_PREV_BSSID)
|
||||
|
||||
C2S(NL80211_ATTR_KEY)
|
||||
C2S(NL80211_ATTR_KEYS)
|
||||
|
||||
C2S(NL80211_ATTR_PID)
|
||||
|
||||
C2S(NL80211_ATTR_4ADDR)
|
||||
|
||||
C2S(NL80211_ATTR_SURVEY_INFO)
|
||||
|
||||
C2S(NL80211_ATTR_PMKID)
|
||||
C2S(NL80211_ATTR_MAX_NUM_PMKIDS)
|
||||
|
||||
C2S(NL80211_ATTR_DURATION)
|
||||
|
||||
C2S(NL80211_ATTR_COOKIE)
|
||||
|
||||
C2S(NL80211_ATTR_WIPHY_COVERAGE_CLASS)
|
||||
|
||||
C2S(NL80211_ATTR_TX_RATES)
|
||||
|
||||
C2S(NL80211_ATTR_FRAME_MATCH)
|
||||
|
||||
C2S(NL80211_ATTR_ACK)
|
||||
|
||||
C2S(NL80211_ATTR_PS_STATE)
|
||||
|
||||
C2S(NL80211_ATTR_CQM)
|
||||
|
||||
C2S(NL80211_ATTR_LOCAL_STATE_CHANGE)
|
||||
|
||||
C2S(NL80211_ATTR_AP_ISOLATE)
|
||||
|
||||
C2S(NL80211_ATTR_WIPHY_TX_POWER_SETTING)
|
||||
C2S(NL80211_ATTR_WIPHY_TX_POWER_LEVEL)
|
||||
|
||||
C2S(NL80211_ATTR_TX_FRAME_TYPES)
|
||||
C2S(NL80211_ATTR_RX_FRAME_TYPES)
|
||||
C2S(NL80211_ATTR_FRAME_TYPE)
|
||||
|
||||
C2S(NL80211_ATTR_CONTROL_PORT_ETHERTYPE)
|
||||
C2S(NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT)
|
||||
|
||||
C2S(NL80211_ATTR_SUPPORT_IBSS_RSN)
|
||||
|
||||
C2S(NL80211_ATTR_WIPHY_ANTENNA_TX)
|
||||
C2S(NL80211_ATTR_WIPHY_ANTENNA_RX)
|
||||
|
||||
C2S(NL80211_ATTR_MCAST_RATE)
|
||||
|
||||
C2S(NL80211_ATTR_OFFCHANNEL_TX_OK)
|
||||
|
||||
C2S(NL80211_ATTR_BSS_HT_OPMODE)
|
||||
|
||||
C2S(NL80211_ATTR_KEY_DEFAULT_TYPES)
|
||||
|
||||
C2S(NL80211_ATTR_MAX_REMAIN_ON_CHANNEL_DURATION)
|
||||
|
||||
C2S(NL80211_ATTR_MESH_SETUP)
|
||||
|
||||
C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_TX)
|
||||
C2S(NL80211_ATTR_WIPHY_ANTENNA_AVAIL_RX)
|
||||
|
||||
C2S(NL80211_ATTR_SUPPORT_MESH_AUTH)
|
||||
C2S(NL80211_ATTR_STA_PLINK_STATE)
|
||||
|
||||
C2S(NL80211_ATTR_WOWLAN_TRIGGERS)
|
||||
C2S(NL80211_ATTR_WOWLAN_TRIGGERS_SUPPORTED)
|
||||
|
||||
C2S(NL80211_ATTR_SCHED_SCAN_INTERVAL)
|
||||
|
||||
C2S(NL80211_ATTR_INTERFACE_COMBINATIONS)
|
||||
C2S(NL80211_ATTR_SOFTWARE_IFTYPES)
|
||||
|
||||
C2S(NL80211_ATTR_REKEY_DATA)
|
||||
|
||||
C2S(NL80211_ATTR_MAX_NUM_SCHED_SCAN_SSIDS)
|
||||
C2S(NL80211_ATTR_MAX_SCHED_SCAN_IE_LEN)
|
||||
|
||||
C2S(NL80211_ATTR_SCAN_SUPP_RATES)
|
||||
|
||||
C2S(NL80211_ATTR_HIDDEN_SSID)
|
||||
|
||||
C2S(NL80211_ATTR_IE_PROBE_RESP)
|
||||
C2S(NL80211_ATTR_IE_ASSOC_RESP)
|
||||
|
||||
C2S(NL80211_ATTR_STA_WME)
|
||||
C2S(NL80211_ATTR_SUPPORT_AP_UAPSD)
|
||||
|
||||
C2S(NL80211_ATTR_ROAM_SUPPORT)
|
||||
|
||||
C2S(NL80211_ATTR_SCHED_SCAN_MATCH)
|
||||
C2S(NL80211_ATTR_MAX_MATCH_SETS)
|
||||
|
||||
C2S(NL80211_ATTR_PMKSA_CANDIDATE)
|
||||
|
||||
C2S(NL80211_ATTR_TX_NO_CCK_RATE)
|
||||
|
||||
C2S(NL80211_ATTR_TDLS_ACTION)
|
||||
C2S(NL80211_ATTR_TDLS_DIALOG_TOKEN)
|
||||
C2S(NL80211_ATTR_TDLS_OPERATION)
|
||||
C2S(NL80211_ATTR_TDLS_SUPPORT)
|
||||
C2S(NL80211_ATTR_TDLS_EXTERNAL_SETUP)
|
||||
|
||||
C2S(NL80211_ATTR_DEVICE_AP_SME)
|
||||
|
||||
C2S(NL80211_ATTR_DONT_WAIT_FOR_ACK)
|
||||
|
||||
C2S(NL80211_ATTR_FEATURE_FLAGS)
|
||||
|
||||
C2S(NL80211_ATTR_PROBE_RESP_OFFLOAD)
|
||||
|
||||
C2S(NL80211_ATTR_PROBE_RESP)
|
||||
|
||||
C2S(NL80211_ATTR_DFS_REGION)
|
||||
|
||||
C2S(NL80211_ATTR_DISABLE_HT)
|
||||
C2S(NL80211_ATTR_HT_CAPABILITY_MASK)
|
||||
|
||||
C2S(NL80211_ATTR_NOACK_MAP)
|
||||
|
||||
C2S(NL80211_ATTR_INACTIVITY_TIMEOUT)
|
||||
|
||||
C2S(NL80211_ATTR_RX_SIGNAL_DBM)
|
||||
|
||||
C2S(NL80211_ATTR_BG_SCAN_PERIOD)
|
||||
|
||||
C2S(NL80211_ATTR_WDEV)
|
||||
|
||||
C2S(NL80211_ATTR_USER_REG_HINT_TYPE)
|
||||
|
||||
C2S(NL80211_ATTR_CONN_FAILED_REASON)
|
||||
|
||||
C2S(NL80211_ATTR_SAE_DATA)
|
||||
|
||||
C2S(NL80211_ATTR_VHT_CAPABILITY)
|
||||
|
||||
C2S(NL80211_ATTR_SCAN_FLAGS)
|
||||
|
||||
C2S(NL80211_ATTR_CHANNEL_WIDTH)
|
||||
C2S(NL80211_ATTR_CENTER_FREQ1)
|
||||
C2S(NL80211_ATTR_CENTER_FREQ2)
|
||||
|
||||
C2S(NL80211_ATTR_P2P_CTWINDOW)
|
||||
C2S(NL80211_ATTR_P2P_OPPPS)
|
||||
|
||||
C2S(NL80211_ATTR_LOCAL_MESH_POWER_MODE)
|
||||
|
||||
C2S(NL80211_ATTR_ACL_POLICY)
|
||||
|
||||
C2S(NL80211_ATTR_MAC_ADDRS)
|
||||
|
||||
C2S(NL80211_ATTR_MAC_ACL_MAX)
|
||||
|
||||
C2S(NL80211_ATTR_RADAR_EVENT)
|
||||
|
||||
C2S(NL80211_ATTR_EXT_CAPA)
|
||||
C2S(NL80211_ATTR_EXT_CAPA_MASK)
|
||||
|
||||
C2S(NL80211_ATTR_STA_CAPABILITY)
|
||||
C2S(NL80211_ATTR_STA_EXT_CAPABILITY)
|
||||
|
||||
C2S(NL80211_ATTR_PROTOCOL_FEATURES)
|
||||
C2S(NL80211_ATTR_SPLIT_WIPHY_DUMP)
|
||||
|
||||
C2S(NL80211_ATTR_DISABLE_VHT)
|
||||
C2S(NL80211_ATTR_VHT_CAPABILITY_MASK)
|
||||
|
||||
C2S(NL80211_ATTR_MDID)
|
||||
C2S(NL80211_ATTR_IE_RIC)
|
||||
|
||||
C2S(NL80211_ATTR_CRIT_PROT_ID)
|
||||
C2S(NL80211_ATTR_MAX_CRIT_PROT_DURATION)
|
||||
|
||||
C2S(NL80211_ATTR_PEER_AID)
|
||||
|
||||
C2S(NL80211_ATTR_COALESCE_RULE)
|
||||
|
||||
C2S(NL80211_ATTR_CH_SWITCH_COUNT)
|
||||
C2S(NL80211_ATTR_CH_SWITCH_BLOCK_TX)
|
||||
C2S(NL80211_ATTR_CSA_IES)
|
||||
C2S(NL80211_ATTR_CSA_C_OFF_BEACON)
|
||||
C2S(NL80211_ATTR_CSA_C_OFF_PRESP)
|
||||
|
||||
C2S(NL80211_ATTR_RXMGMT_FLAGS)
|
||||
|
||||
C2S(NL80211_ATTR_STA_SUPPORTED_CHANNELS)
|
||||
|
||||
C2S(NL80211_ATTR_STA_SUPPORTED_OPER_CLASSES)
|
||||
|
||||
C2S(NL80211_ATTR_HANDLE_DFS)
|
||||
|
||||
C2S(NL80211_ATTR_SUPPORT_5_MHZ)
|
||||
C2S(NL80211_ATTR_SUPPORT_10_MHZ)
|
||||
|
||||
C2S(NL80211_ATTR_OPMODE_NOTIF)
|
||||
|
||||
C2S(NL80211_ATTR_VENDOR_ID)
|
||||
C2S(NL80211_ATTR_VENDOR_SUBCMD)
|
||||
C2S(NL80211_ATTR_VENDOR_DATA)
|
||||
C2S(NL80211_ATTR_VENDOR_EVENTS)
|
||||
|
||||
C2S(NL80211_ATTR_QOS_MAP)
|
||||
default:
|
||||
return "NL80211_ATTR_UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
void WifiEvent::log() {
|
||||
parse();
|
||||
|
||||
byte *data = (byte *)genlmsg_attrdata(mHeader, 0);
|
||||
int len = genlmsg_attrlen(mHeader, 0);
|
||||
ALOGD("cmd = %s, len = %d", get_cmdString(), len);
|
||||
ALOGD("vendor_id = %04x, vendor_subcmd = %d", get_vendor_id(), get_vendor_subcmd());
|
||||
|
||||
for (int i = 0; i < len; i += 16) {
|
||||
char line[81];
|
||||
int linelen = min(16, len - i);
|
||||
int offset = 0;
|
||||
appendFmt(line, offset, "%02x", data[i]);
|
||||
for (int j = 1; j < linelen; j++) {
|
||||
appendFmt(line, offset, " %02x", data[i+j]);
|
||||
}
|
||||
|
||||
for (int j = linelen; j < 16; j++) {
|
||||
appendFmt(line, offset, " ");
|
||||
}
|
||||
|
||||
line[23] = '-';
|
||||
|
||||
appendFmt(line, offset, " ");
|
||||
|
||||
for (int j = 0; j < linelen; j++) {
|
||||
if (isprint(data[i+j])) {
|
||||
appendFmt(line, offset, "%c", data[i+j]);
|
||||
} else {
|
||||
appendFmt(line, offset, "-");
|
||||
}
|
||||
}
|
||||
|
||||
ALOGD("%s", line);
|
||||
}
|
||||
|
||||
for (unsigned i = 0; i < NL80211_ATTR_MAX_INTERNAL; i++) {
|
||||
if (mAttributes[i] != NULL) {
|
||||
ALOGD("found attribute %s", attributeToString(i));
|
||||
}
|
||||
}
|
||||
|
||||
ALOGD("-- End of message --");
|
||||
}
|
||||
|
||||
const char *WifiEvent::get_cmdString() {
|
||||
return cmdToString(get_cmd());
|
||||
}
|
||||
|
||||
|
||||
int WifiEvent::parse() {
|
||||
if (mHeader != NULL) {
|
||||
return WIFI_SUCCESS;
|
||||
}
|
||||
mHeader = (genlmsghdr *)nlmsg_data(nlmsg_hdr(mMsg));
|
||||
int result = nla_parse(mAttributes, NL80211_ATTR_MAX_INTERNAL, genlmsg_attrdata(mHeader, 0),
|
||||
genlmsg_attrlen(mHeader, 0), NULL);
|
||||
|
||||
// ALOGD("event len = %d", nlmsg_hdr(mMsg)->nlmsg_len);
|
||||
return result;
|
||||
}
|
||||
|
||||
int WifiRequest::create(int family, uint8_t cmd, int flags, int hdrlen) {
|
||||
|
||||
destroy();
|
||||
|
||||
mMsg = nlmsg_alloc();
|
||||
if (mMsg != NULL) {
|
||||
genlmsg_put(mMsg, /* pid = */ 0, /* seq = */ 0, family,
|
||||
hdrlen, flags, cmd, /* version = */ 0);
|
||||
return WIFI_SUCCESS;
|
||||
} else {
|
||||
return WIFI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
|
||||
int WifiRequest::create(uint32_t id, int subcmd) {
|
||||
int res = create(NL80211_CMD_VENDOR);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = put_u32(NL80211_ATTR_VENDOR_ID, id);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = put_u32(NL80211_ATTR_VENDOR_SUBCMD, subcmd);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (mIface != -1) {
|
||||
res = set_iface_id(mIface);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static int no_seq_check(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
return NL_OK;
|
||||
}
|
||||
|
||||
int WifiCommand::requestResponse() {
|
||||
int err = create(); /* create the message */
|
||||
if (err < 0) {
|
||||
return err;
|
||||
}
|
||||
|
||||
return requestResponse(mMsg);
|
||||
}
|
||||
|
||||
int WifiCommand::requestResponse(WifiRequest& request) {
|
||||
int err = 0;
|
||||
|
||||
struct nl_cb *cb = nl_cb_alloc(NL_CB_DEFAULT);
|
||||
if (!cb)
|
||||
goto out;
|
||||
|
||||
err = nl_send_auto_complete(mInfo->cmd_sock, request.getMessage()); /* send message */
|
||||
if (err < 0)
|
||||
goto out;
|
||||
|
||||
err = 1;
|
||||
|
||||
nl_cb_set(cb, NL_CB_SEQ_CHECK, NL_CB_CUSTOM, no_seq_check, NULL);
|
||||
nl_cb_err(cb, NL_CB_CUSTOM, error_handler, &err);
|
||||
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, &err);
|
||||
nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, &err);
|
||||
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, response_handler, this);
|
||||
|
||||
while (err > 0) { /* wait for reply */
|
||||
int res = nl_recvmsgs(mInfo->cmd_sock, cb);
|
||||
if (res) {
|
||||
ALOGV("nl80211: %s->nl_recvmsgs failed: %d", __func__, res);
|
||||
}
|
||||
}
|
||||
out:
|
||||
nl_cb_put(cb);
|
||||
return err;
|
||||
}
|
||||
|
||||
int WifiCommand::requestEvent(int cmd) {
|
||||
|
||||
ALOGD("requesting event %d", cmd);
|
||||
|
||||
int res = wifi_register_handler(wifiHandle(), cmd, event_handler, this);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = create(); /* create the message */
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
ALOGD("waiting for response %d", cmd);
|
||||
|
||||
res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
ALOGD("waiting for event %d", cmd);
|
||||
res = mCondition.wait();
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
wifi_unregister_handler(wifiHandle(), cmd);
|
||||
return res;
|
||||
}
|
||||
|
||||
int WifiCommand::requestVendorEvent(uint32_t id, int subcmd) {
|
||||
|
||||
int res = wifi_register_vendor_handler(wifiHandle(), id, subcmd, event_handler, this);
|
||||
if (res < 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
res = create(); /* create the message */
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
res = nl_send_auto_complete(mInfo->cmd_sock, mMsg.getMessage()); /* send message */
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
res = mCondition.wait();
|
||||
if (res < 0)
|
||||
goto out;
|
||||
|
||||
out:
|
||||
wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Event handlers */
|
||||
int WifiCommand::response_handler(struct nl_msg *msg, void *arg) {
|
||||
// ALOGD("response_handler called");
|
||||
WifiCommand *cmd = (WifiCommand *)arg;
|
||||
WifiEvent reply(msg);
|
||||
int res = reply.parse();
|
||||
if (res < 0) {
|
||||
ALOGV("Failed to parse reply message = %d", res);
|
||||
return NL_SKIP;
|
||||
} else {
|
||||
// reply.log();
|
||||
return cmd->handleResponse(reply);
|
||||
}
|
||||
}
|
||||
|
||||
int WifiCommand::event_handler(struct nl_msg *msg, void *arg) {
|
||||
WifiCommand *cmd = (WifiCommand *)arg;
|
||||
WifiEvent event(msg);
|
||||
int res = event.parse();
|
||||
if (res < 0) {
|
||||
ALOGV("Failed to parse event = %d", res);
|
||||
res = NL_SKIP;
|
||||
} else {
|
||||
res = cmd->handleEvent(event);
|
||||
}
|
||||
|
||||
cmd->mCondition.signal();
|
||||
return res;
|
||||
}
|
||||
|
||||
/* Other event handlers */
|
||||
int WifiCommand::valid_handler(struct nl_msg *msg, void *arg) {
|
||||
// ALOGD("valid_handler called");
|
||||
int *err = (int *)arg;
|
||||
*err = 0;
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
int WifiCommand::ack_handler(struct nl_msg *msg, void *arg) {
|
||||
// ALOGD("ack_handler called");
|
||||
int *err = (int *)arg;
|
||||
*err = 0;
|
||||
return NL_STOP;
|
||||
}
|
||||
|
||||
int WifiCommand::finish_handler(struct nl_msg *msg, void *arg) {
|
||||
// ALOGD("finish_handler called");
|
||||
int *ret = (int *)arg;
|
||||
*ret = 0;
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
int WifiCommand::error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg) {
|
||||
int *ret = (int *)arg;
|
||||
*ret = err->error;
|
||||
|
||||
// ALOGD("error_handler received : %d", err->error);
|
||||
return NL_SKIP;
|
||||
}
|
367
android/hardware/realtek/wlan/wifi_hal/cpp_bindings.h
Normal file
367
android/hardware/realtek/wlan/wifi_hal/cpp_bindings.h
Normal file
|
@ -0,0 +1,367 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* 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 "wifi_hal.h"
|
||||
#include "common.h"
|
||||
#include "sync.h"
|
||||
|
||||
class WifiEvent
|
||||
{
|
||||
/* TODO: remove this when nl headers are updated */
|
||||
static const unsigned NL80211_ATTR_MAX_INTERNAL = 256;
|
||||
private:
|
||||
struct nl_msg *mMsg;
|
||||
struct genlmsghdr *mHeader;
|
||||
struct nlattr *mAttributes[NL80211_ATTR_MAX_INTERNAL + 1];
|
||||
|
||||
public:
|
||||
WifiEvent(nl_msg *msg) {
|
||||
mMsg = msg;
|
||||
mHeader = NULL;
|
||||
memset(mAttributes, 0, sizeof(mAttributes));
|
||||
}
|
||||
~WifiEvent() {
|
||||
/* don't destroy mMsg; it doesn't belong to us */
|
||||
}
|
||||
|
||||
void log();
|
||||
|
||||
int parse();
|
||||
|
||||
genlmsghdr *header() {
|
||||
return mHeader;
|
||||
}
|
||||
|
||||
int get_cmd() {
|
||||
return mHeader->cmd;
|
||||
}
|
||||
|
||||
int get_vendor_id() {
|
||||
return get_u32(NL80211_ATTR_VENDOR_ID);
|
||||
}
|
||||
|
||||
int get_vendor_subcmd() {
|
||||
return get_u32(NL80211_ATTR_VENDOR_SUBCMD);
|
||||
}
|
||||
|
||||
void *get_vendor_data() {
|
||||
return get_data(NL80211_ATTR_VENDOR_DATA);
|
||||
}
|
||||
|
||||
int get_vendor_data_len() {
|
||||
return get_len(NL80211_ATTR_VENDOR_DATA);
|
||||
}
|
||||
|
||||
const char *get_cmdString();
|
||||
|
||||
nlattr ** attributes() {
|
||||
return mAttributes;
|
||||
}
|
||||
|
||||
nlattr *get_attribute(int attribute) {
|
||||
return mAttributes[attribute];
|
||||
}
|
||||
|
||||
uint8_t get_u8(int attribute) {
|
||||
return mAttributes[attribute] ? nla_get_u8(mAttributes[attribute]) : 0;
|
||||
}
|
||||
|
||||
uint16_t get_u16(int attribute) {
|
||||
return mAttributes[attribute] ? nla_get_u16(mAttributes[attribute]) : 0;
|
||||
}
|
||||
|
||||
uint32_t get_u32(int attribute) {
|
||||
return mAttributes[attribute] ? nla_get_u32(mAttributes[attribute]) : 0;
|
||||
}
|
||||
|
||||
uint64_t get_u64(int attribute) {
|
||||
return mAttributes[attribute] ? nla_get_u64(mAttributes[attribute]) : 0;
|
||||
}
|
||||
|
||||
int get_len(int attribute) {
|
||||
return mAttributes[attribute] ? nla_len(mAttributes[attribute]) : 0;
|
||||
}
|
||||
|
||||
void *get_data(int attribute) {
|
||||
return mAttributes[attribute] ? nla_data(mAttributes[attribute]) : NULL;
|
||||
}
|
||||
|
||||
private:
|
||||
WifiEvent(const WifiEvent&); // hide copy constructor to prevent copies
|
||||
};
|
||||
|
||||
class nl_iterator {
|
||||
struct nlattr *pos;
|
||||
int rem;
|
||||
public:
|
||||
nl_iterator(struct nlattr *attr) {
|
||||
pos = (struct nlattr *)nla_data(attr);
|
||||
rem = nla_len(attr);
|
||||
}
|
||||
bool has_next() {
|
||||
return nla_ok(pos, rem);
|
||||
}
|
||||
void next() {
|
||||
pos = (struct nlattr *)nla_next(pos, &(rem));
|
||||
}
|
||||
struct nlattr *get() {
|
||||
return pos;
|
||||
}
|
||||
uint16_t get_type() {
|
||||
return pos->nla_type;
|
||||
}
|
||||
uint8_t get_u8() {
|
||||
return nla_get_u8(pos);
|
||||
}
|
||||
uint16_t get_u16() {
|
||||
return nla_get_u16(pos);
|
||||
}
|
||||
uint32_t get_u32() {
|
||||
return nla_get_u32(pos);
|
||||
}
|
||||
uint64_t get_u64() {
|
||||
return nla_get_u64(pos);
|
||||
}
|
||||
void* get_data() {
|
||||
return nla_data(pos);
|
||||
}
|
||||
int get_len() {
|
||||
return nla_len(pos);
|
||||
}
|
||||
private:
|
||||
nl_iterator(const nl_iterator&); // hide copy constructor to prevent copies
|
||||
};
|
||||
|
||||
class WifiRequest
|
||||
{
|
||||
private:
|
||||
int mFamily;
|
||||
int mIface;
|
||||
struct nl_msg *mMsg;
|
||||
|
||||
public:
|
||||
WifiRequest(int family) {
|
||||
mMsg = NULL;
|
||||
mFamily = family;
|
||||
mIface = -1;
|
||||
}
|
||||
|
||||
WifiRequest(int family, int iface) {
|
||||
mMsg = NULL;
|
||||
mFamily = family;
|
||||
mIface = iface;
|
||||
}
|
||||
|
||||
~WifiRequest() {
|
||||
destroy();
|
||||
}
|
||||
|
||||
void destroy() {
|
||||
if (mMsg) {
|
||||
nlmsg_free(mMsg);
|
||||
mMsg = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
nl_msg *getMessage() {
|
||||
return mMsg;
|
||||
}
|
||||
|
||||
/* Command assembly helpers */
|
||||
int create(int family, uint8_t cmd, int flags, int hdrlen);
|
||||
int create(uint8_t cmd) {
|
||||
return create(mFamily, cmd, 0, 0);
|
||||
}
|
||||
|
||||
int create(uint32_t id, int subcmd);
|
||||
|
||||
int put(int attribute, void *ptr, unsigned len) {
|
||||
return nla_put(mMsg, attribute, len, ptr);
|
||||
}
|
||||
int put_u8(int attribute, uint8_t value) {
|
||||
return nla_put(mMsg, attribute, sizeof(value), &value);
|
||||
}
|
||||
int put_u16(int attribute, uint16_t value) {
|
||||
return nla_put(mMsg, attribute, sizeof(value), &value);
|
||||
}
|
||||
int put_u32(int attribute, uint32_t value) {
|
||||
return nla_put(mMsg, attribute, sizeof(value), &value);
|
||||
}
|
||||
int put_u64(int attribute, uint64_t value) {
|
||||
return nla_put(mMsg, attribute, sizeof(value), &value);
|
||||
}
|
||||
int put_string(int attribute, const char *value) {
|
||||
return nla_put(mMsg, attribute, strlen(value) + 1, value);
|
||||
}
|
||||
int put_addr(int attribute, mac_addr value) {
|
||||
return nla_put(mMsg, attribute, sizeof(mac_addr), value);
|
||||
}
|
||||
|
||||
struct nlattr * attr_start(int attribute) {
|
||||
return nla_nest_start(mMsg, attribute);
|
||||
}
|
||||
void attr_end(struct nlattr *attr) {
|
||||
nla_nest_end(mMsg, attr);
|
||||
}
|
||||
|
||||
int set_iface_id(int ifindex) {
|
||||
return put_u32(NL80211_ATTR_IFINDEX, ifindex);
|
||||
}
|
||||
private:
|
||||
WifiRequest(const WifiRequest&); // hide copy constructor to prevent copies
|
||||
|
||||
};
|
||||
|
||||
class WifiCommand
|
||||
{
|
||||
protected:
|
||||
const char *mCmdType;
|
||||
hal_info *mInfo;
|
||||
WifiRequest mMsg;
|
||||
Condition mCondition;
|
||||
wifi_request_id mReqId;
|
||||
interface_info *mIfaceInfo;
|
||||
int mRefs;
|
||||
public:
|
||||
WifiCommand(const char *type, wifi_handle handle, wifi_request_id id)
|
||||
: mCmdType(type), mMsg(getHalInfo(handle)->nl80211_family_id), mReqId(id), mRefs(1)
|
||||
{
|
||||
mIfaceInfo = NULL;
|
||||
mInfo = getHalInfo(handle);
|
||||
// ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
|
||||
}
|
||||
|
||||
WifiCommand(const char *type, wifi_interface_handle iface, wifi_request_id id)
|
||||
: mCmdType(type), mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id),
|
||||
mReqId(id), mRefs(1)
|
||||
{
|
||||
mIfaceInfo = getIfaceInfo(iface);
|
||||
mInfo = getHalInfo(iface);
|
||||
// ALOGD("WifiCommand %p created, mInfo = %p, mIfaceInfo = %p", this, mInfo, mIfaceInfo);
|
||||
}
|
||||
|
||||
virtual ~WifiCommand() {
|
||||
// ALOGD("WifiCommand %p destroyed", this);
|
||||
}
|
||||
|
||||
wifi_request_id id() {
|
||||
return mReqId;
|
||||
}
|
||||
|
||||
const char *getType() {
|
||||
return mCmdType;
|
||||
}
|
||||
|
||||
virtual void addRef() {
|
||||
int refs = __sync_add_and_fetch(&mRefs, 1);
|
||||
// ALOGD("addRef: WifiCommand %p has %d references", this, refs);
|
||||
}
|
||||
|
||||
virtual void releaseRef() {
|
||||
int refs = __sync_sub_and_fetch(&mRefs, 1);
|
||||
if (refs == 0) {
|
||||
delete this;
|
||||
} else {
|
||||
// ALOGD("releaseRef: WifiCommand %p has %d references", this, refs);
|
||||
}
|
||||
}
|
||||
|
||||
virtual int create() {
|
||||
/* by default there is no way to cancel */
|
||||
ALOGD("WifiCommand %p can't be created", this);
|
||||
return WIFI_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
virtual int cancel() {
|
||||
/* by default there is no way to cancel */
|
||||
return WIFI_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
int requestResponse();
|
||||
int requestEvent(int cmd);
|
||||
int requestVendorEvent(uint32_t id, int subcmd);
|
||||
int requestResponse(WifiRequest& request);
|
||||
|
||||
protected:
|
||||
wifi_handle wifiHandle() {
|
||||
return getWifiHandle(mInfo);
|
||||
}
|
||||
|
||||
wifi_interface_handle ifaceHandle() {
|
||||
return getIfaceHandle(mIfaceInfo);
|
||||
}
|
||||
|
||||
int familyId() {
|
||||
return mInfo->nl80211_family_id;
|
||||
}
|
||||
|
||||
int ifaceId() {
|
||||
return mIfaceInfo->id;
|
||||
}
|
||||
|
||||
/* Override this method to parse reply and dig out data; save it in the object */
|
||||
virtual int handleResponse(WifiEvent& reply) {
|
||||
ALOGI("skipping a response");
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
/* Override this method to parse event and dig out data; save it in the object */
|
||||
virtual int handleEvent(WifiEvent& event) {
|
||||
ALOGI("skipping an event");
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
int registerHandler(int cmd) {
|
||||
return wifi_register_handler(wifiHandle(), cmd, &event_handler, this);
|
||||
}
|
||||
|
||||
void unregisterHandler(int cmd) {
|
||||
wifi_unregister_handler(wifiHandle(), cmd);
|
||||
}
|
||||
|
||||
int registerVendorHandler(uint32_t id, int subcmd) {
|
||||
return wifi_register_vendor_handler(wifiHandle(), id, subcmd, &event_handler, this);
|
||||
}
|
||||
|
||||
void unregisterVendorHandler(uint32_t id, int subcmd) {
|
||||
wifi_unregister_vendor_handler(wifiHandle(), id, subcmd);
|
||||
}
|
||||
|
||||
private:
|
||||
WifiCommand(const WifiCommand& ); // hide copy constructor to prevent copies
|
||||
|
||||
/* Event handling */
|
||||
static int response_handler(struct nl_msg *msg, void *arg);
|
||||
|
||||
static int event_handler(struct nl_msg *msg, void *arg);
|
||||
|
||||
/* Other event handlers */
|
||||
static int valid_handler(struct nl_msg *msg, void *arg);
|
||||
|
||||
static int ack_handler(struct nl_msg *msg, void *arg);
|
||||
|
||||
static int finish_handler(struct nl_msg *msg, void *arg);
|
||||
|
||||
static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err, void *arg);
|
||||
};
|
||||
|
||||
/* nl message processing macros (required to pass C++ type checks) */
|
||||
|
||||
#define for_each_attr(pos, nla, rem) \
|
||||
for (pos = (nlattr *)nla_data(nla), rem = nla_len(nla); \
|
||||
nla_ok(pos, rem); \
|
||||
pos = (nlattr *)nla_next(pos, &(rem)))
|
||||
|
1856
android/hardware/realtek/wlan/wifi_hal/gscan.cpp
Normal file
1856
android/hardware/realtek/wlan/wifi_hal/gscan.cpp
Normal file
File diff suppressed because it is too large
Load diff
256
android/hardware/realtek/wlan/wifi_hal/link_layer_stats.cpp
Normal file
256
android/hardware/realtek/wlan/wifi_hal/link_layer_stats.cpp
Normal file
|
@ -0,0 +1,256 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/family.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/errqueue.h>
|
||||
|
||||
#include <linux/pkt_sched.h>
|
||||
#include <netlink/object-api.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/socket.h>
|
||||
#include <netlink/handlers.h>
|
||||
|
||||
#include "sync.h"
|
||||
|
||||
#define LOG_TAG "WifiHAL"
|
||||
|
||||
#include <utils/Log.h>
|
||||
|
||||
#include "wifi_hal.h"
|
||||
#include "common.h"
|
||||
#include "cpp_bindings.h"
|
||||
|
||||
/* Internal radio statistics structure in the driver */
|
||||
typedef struct {
|
||||
wifi_radio radio;
|
||||
uint32_t on_time;
|
||||
uint32_t tx_time;
|
||||
uint32_t rx_time;
|
||||
uint32_t on_time_scan;
|
||||
uint32_t on_time_nbd;
|
||||
uint32_t on_time_gscan;
|
||||
uint32_t on_time_roam_scan;
|
||||
uint32_t on_time_pno_scan;
|
||||
uint32_t on_time_hs20;
|
||||
uint32_t num_channels;
|
||||
wifi_channel_stat channels[];
|
||||
} wifi_radio_stat_internal;
|
||||
|
||||
enum {
|
||||
LSTATS_SUBCMD_GET_INFO = ANDROID_NL80211_SUBCMD_LSTATS_RANGE_START,
|
||||
LSTATS_SUBCMD_SET_INFO,
|
||||
LSTATS_SUBCMD_CLEAR_INFO,
|
||||
};
|
||||
|
||||
class GetLinkStatsCommand : public WifiCommand
|
||||
{
|
||||
wifi_stats_result_handler mHandler;
|
||||
public:
|
||||
GetLinkStatsCommand(wifi_interface_handle iface, wifi_stats_result_handler handler)
|
||||
: WifiCommand("GetLinkStatsCommand", iface, 0), mHandler(handler)
|
||||
{ }
|
||||
|
||||
virtual int create() {
|
||||
// ALOGI("Creating message to get link statistics; iface = %d", mIfaceInfo->id);
|
||||
|
||||
int ret = mMsg.create(GOOGLE_OUI, LSTATS_SUBCMD_GET_INFO);
|
||||
if (ret < 0) {
|
||||
ALOGV("Failed to create %x - %d", LSTATS_SUBCMD_GET_INFO, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int handleResponse(WifiEvent& reply) {
|
||||
|
||||
// ALOGI("In GetLinkStatsCommand::handleResponse");
|
||||
|
||||
if (reply.get_cmd() != NL80211_CMD_VENDOR) {
|
||||
ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
int id = reply.get_vendor_id();
|
||||
int subcmd = reply.get_vendor_subcmd();
|
||||
|
||||
// ALOGI("Id = %0x, subcmd = %d", id, subcmd);
|
||||
|
||||
void *data = reply.get_vendor_data();
|
||||
int len = reply.get_vendor_data_len();
|
||||
wifi_radio_stat *radio_stat = (wifi_radio_stat *)data;
|
||||
if (!radio_stat) {
|
||||
ALOGV("Invalid stats pointer received");
|
||||
return NL_SKIP;
|
||||
}
|
||||
ALOGV("radio: = %d", radio_stat->radio);
|
||||
ALOGV("on_time: = %u ms", radio_stat->on_time);
|
||||
ALOGV("tx_time: = %u ms", radio_stat->tx_time);
|
||||
ALOGV("num_tx_levels: = %u", radio_stat->num_tx_levels);
|
||||
radio_stat->tx_time_per_levels = (u32*)((char*)data + sizeof(wifi_radio_stat) + sizeof(wifi_iface_stat));
|
||||
ALOGV("tx_time_per_levels: = %u ms", radio_stat->tx_time_per_levels[0]);
|
||||
ALOGV("rx_time: = %u ms", radio_stat->rx_time);
|
||||
ALOGV("on_time_scan: = %u ms", radio_stat->on_time_scan);
|
||||
ALOGV("on_time_nbd: = %u ms", radio_stat->on_time_nbd);
|
||||
ALOGV("on_time_gscan: = %u ms", radio_stat->on_time_gscan);
|
||||
ALOGV("on_time_pno_scan: = %u ms", radio_stat->on_time_pno_scan);
|
||||
ALOGV("on_time_hs20: = %u ms", radio_stat->on_time_hs20);
|
||||
if (radio_stat->num_channels > 11) {
|
||||
ALOGV("Incorrect number of channels = %d", radio_stat->num_channels);
|
||||
// dump data before num_channels
|
||||
ALOGV("radio: = %d", radio_stat->radio);
|
||||
ALOGV("on_time: = %u ms", radio_stat->on_time);
|
||||
ALOGV("tx_time: = %u ms", radio_stat->tx_time);
|
||||
ALOGV("rx_time: = %u ms", radio_stat->rx_time);
|
||||
ALOGV("on_time_scan: = %u ms", radio_stat->on_time_scan);
|
||||
ALOGV("on_time_nbd: = %u ms", radio_stat->on_time_nbd);
|
||||
ALOGV("on_time_gscan: = %u ms", radio_stat->on_time_gscan);
|
||||
ALOGV("on_time_pno_scan: = %u ms", radio_stat->on_time_pno_scan);
|
||||
ALOGV("on_time_hs20: = %u ms", radio_stat->on_time_hs20);
|
||||
free(radio_stat);
|
||||
return NL_SKIP;
|
||||
}
|
||||
wifi_iface_stat *iface_stat = NULL;
|
||||
iface_stat = (wifi_iface_stat *)((char* )data + sizeof(wifi_radio_stat));
|
||||
|
||||
if(*mHandler.on_link_stats_results == NULL) {
|
||||
ALOGV("*mHandler.on_link_stats_results is NULL");
|
||||
} else {
|
||||
(*mHandler.on_link_stats_results)(id, iface_stat, 1, radio_stat);
|
||||
}
|
||||
//free(radio_stat);
|
||||
return NL_OK;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class SetLinkStatsCommand : public WifiCommand
|
||||
{
|
||||
wifi_stats_result_handler mHandler;
|
||||
public:
|
||||
SetLinkStatsCommand(wifi_interface_handle iface)
|
||||
: WifiCommand("SetLinkStatsCommand", iface, 0)
|
||||
{ }
|
||||
|
||||
virtual int create() {
|
||||
// ALOGI("Creating message to get link statistics; iface = %d", mIfaceInfo->id);
|
||||
|
||||
int ret = mMsg.create(GOOGLE_OUI, LSTATS_SUBCMD_SET_INFO);
|
||||
if (ret < 0) {
|
||||
ALOGV("Failed to create %x - %d", LSTATS_SUBCMD_SET_INFO, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int handleResponse(WifiEvent& reply) {
|
||||
|
||||
// ALOGI("In GetLinkStatsCommand::handleResponse");
|
||||
|
||||
if (reply.get_cmd() != NL80211_CMD_VENDOR) {
|
||||
ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
int id = reply.get_vendor_id();
|
||||
int subcmd = reply.get_vendor_subcmd();
|
||||
|
||||
// ALOGI("Id = %0x, subcmd = %d", id, subcmd);
|
||||
|
||||
void *data = reply.get_vendor_data();
|
||||
int len = reply.get_vendor_data_len();
|
||||
return NL_OK;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
class ClearLinkStatsCommand : public WifiCommand
|
||||
{
|
||||
wifi_stats_result_handler mHandler;
|
||||
public:
|
||||
ClearLinkStatsCommand(wifi_interface_handle iface)
|
||||
: WifiCommand("ClearLinkStatsCommand", iface, 0)
|
||||
{ }
|
||||
|
||||
virtual int create() {
|
||||
// ALOGI("Creating message to get link statistics; iface = %d", mIfaceInfo->id);
|
||||
|
||||
int ret = mMsg.create(GOOGLE_OUI, LSTATS_SUBCMD_CLEAR_INFO);
|
||||
if (ret < 0) {
|
||||
ALOGV("Failed to create %x - %d", LSTATS_SUBCMD_CLEAR_INFO, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int handleResponse(WifiEvent& reply) {
|
||||
|
||||
// ALOGI("In GetLinkStatsCommand::handleResponse");
|
||||
|
||||
if (reply.get_cmd() != NL80211_CMD_VENDOR) {
|
||||
ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
int id = reply.get_vendor_id();
|
||||
int subcmd = reply.get_vendor_subcmd();
|
||||
|
||||
// ALOGI("Id = %0x, subcmd = %d", id, subcmd);
|
||||
|
||||
void *data = reply.get_vendor_data();
|
||||
int len = reply.get_vendor_data_len();
|
||||
return NL_OK;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
wifi_error wifi_get_link_stats(wifi_request_id id,
|
||||
wifi_interface_handle iface, wifi_stats_result_handler handler)
|
||||
{
|
||||
GetLinkStatsCommand command(iface, handler);
|
||||
return (wifi_error) command.requestResponse();
|
||||
}
|
||||
|
||||
wifi_error wifi_set_link_stats(
|
||||
wifi_interface_handle iface, wifi_link_layer_params params)
|
||||
{
|
||||
|
||||
SetLinkStatsCommand command(iface);
|
||||
return (wifi_error) command.requestResponse();
|
||||
//return WIFI_SUCCESS;
|
||||
}
|
||||
|
||||
wifi_error wifi_clear_link_stats(wifi_interface_handle iface,
|
||||
u32 stats_clear_req_mask, u32 *stats_clear_rsp_mask, u8 stop_req, u8 *stop_rsp)
|
||||
{
|
||||
|
||||
ClearLinkStatsCommand command(iface);
|
||||
return (wifi_error) command.requestResponse();
|
||||
//return WIFI_SUCCESS;
|
||||
}
|
699
android/hardware/realtek/wlan/wifi_hal/rtt.cpp
Normal file
699
android/hardware/realtek/wlan/wifi_hal/rtt.cpp
Normal file
|
@ -0,0 +1,699 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/family.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/errqueue.h>
|
||||
|
||||
#include <linux/pkt_sched.h>
|
||||
#include <netlink/object-api.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/socket.h>
|
||||
#include <netlink-private/object-api.h>
|
||||
#include <netlink-private/types.h>
|
||||
|
||||
#include "nl80211_copy.h"
|
||||
|
||||
#include "sync.h"
|
||||
|
||||
#define LOG_TAG "WifiHAL"
|
||||
|
||||
#include <utils/Log.h>
|
||||
#include <utils/String8.h>
|
||||
|
||||
#include "wifi_hal.h"
|
||||
#include "common.h"
|
||||
#include "cpp_bindings.h"
|
||||
|
||||
using namespace android;
|
||||
#define RTT_RESULT_SIZE (sizeof(wifi_rtt_result));
|
||||
typedef enum {
|
||||
|
||||
RTT_SUBCMD_SET_CONFIG = ANDROID_NL80211_SUBCMD_RTT_RANGE_START,
|
||||
RTT_SUBCMD_CANCEL_CONFIG,
|
||||
RTT_SUBCMD_GETCAPABILITY,
|
||||
RTT_SUBCMD_GETAVAILCHANNEL,
|
||||
RTT_SUBCMD_SET_RESPONDER,
|
||||
RTT_SUBCMD_CANCEL_RESPONDER,
|
||||
} RTT_SUB_COMMAND;
|
||||
|
||||
typedef enum {
|
||||
RTT_ATTRIBUTE_TARGET_CNT = 0,
|
||||
RTT_ATTRIBUTE_TARGET_INFO,
|
||||
RTT_ATTRIBUTE_TARGET_MAC,
|
||||
RTT_ATTRIBUTE_TARGET_TYPE,
|
||||
RTT_ATTRIBUTE_TARGET_PEER,
|
||||
RTT_ATTRIBUTE_TARGET_CHAN,
|
||||
RTT_ATTRIBUTE_TARGET_PERIOD,
|
||||
RTT_ATTRIBUTE_TARGET_NUM_BURST,
|
||||
RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
|
||||
RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
|
||||
RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
|
||||
RTT_ATTRIBUTE_TARGET_LCI,
|
||||
RTT_ATTRIBUTE_TARGET_LCR,
|
||||
RTT_ATTRIBUTE_TARGET_BURST_DURATION,
|
||||
RTT_ATTRIBUTE_TARGET_PREAMBLE,
|
||||
RTT_ATTRIBUTE_TARGET_BW,
|
||||
RTT_ATTRIBUTE_RESULTS_COMPLETE = 30,
|
||||
RTT_ATTRIBUTE_RESULTS_PER_TARGET,
|
||||
RTT_ATTRIBUTE_RESULT_CNT,
|
||||
RTT_ATTRIBUTE_RESULT
|
||||
} RTT_ATTRIBUTE;
|
||||
typedef struct strmap_entry {
|
||||
int id;
|
||||
String8 text;
|
||||
} strmap_entry_t;
|
||||
struct dot11_rm_ie {
|
||||
u8 id;
|
||||
u8 len;
|
||||
u8 token;
|
||||
u8 mode;
|
||||
u8 type;
|
||||
} __attribute__ ((packed));
|
||||
typedef struct dot11_rm_ie dot11_rm_ie_t;
|
||||
#define DOT11_HDR_LEN 2
|
||||
#define DOT11_RM_IE_LEN 5
|
||||
#define DOT11_MNG_MEASURE_REQUEST_ID 38 /* 11H MeasurementRequest */
|
||||
#define DOT11_MEASURE_TYPE_LCI 8 /* d11 measurement LCI type */
|
||||
#define DOT11_MEASURE_TYPE_CIVICLOC 11 /* d11 measurement location civic */
|
||||
|
||||
static const strmap_entry_t err_info[] = {
|
||||
{RTT_STATUS_SUCCESS, String8("Success")},
|
||||
{RTT_STATUS_FAILURE, String8("Failure")},
|
||||
{RTT_STATUS_FAIL_NO_RSP, String8("No reponse")},
|
||||
{RTT_STATUS_FAIL_INVALID_TS, String8("Invalid Timestamp")},
|
||||
{RTT_STATUS_FAIL_PROTOCOL, String8("Protocol error")},
|
||||
{RTT_STATUS_FAIL_REJECTED, String8("Rejected")},
|
||||
{RTT_STATUS_FAIL_NOT_SCHEDULED_YET, String8("not scheduled")},
|
||||
{RTT_STATUS_FAIL_SCHEDULE, String8("schedule failed")},
|
||||
{RTT_STATUS_FAIL_TM_TIMEOUT, String8("timeout")},
|
||||
{RTT_STATUS_FAIL_AP_ON_DIFF_CHANNEL, String8("AP is on difference channel")},
|
||||
{RTT_STATUS_FAIL_NO_CAPABILITY, String8("no capability")},
|
||||
{RTT_STATUS_FAIL_BUSY_TRY_LATER, String8("busy and try later")},
|
||||
{RTT_STATUS_ABORTED, String8("aborted")}
|
||||
};
|
||||
|
||||
static const char*
|
||||
get_err_info(int status)
|
||||
{
|
||||
int i;
|
||||
const strmap_entry_t *p_entry;
|
||||
int num_entries = sizeof(err_info)/ sizeof(err_info[0]);
|
||||
/* scan thru the table till end */
|
||||
p_entry = err_info;
|
||||
for (i = 0; i < (int) num_entries; i++)
|
||||
{
|
||||
if (p_entry->id == status)
|
||||
return p_entry->text;
|
||||
p_entry++; /* next entry */
|
||||
}
|
||||
return "unknown error"; /* not found */
|
||||
}
|
||||
|
||||
class GetRttCapabilitiesCommand : public WifiCommand
|
||||
{
|
||||
wifi_rtt_capabilities *mCapabilities;
|
||||
public:
|
||||
GetRttCapabilitiesCommand(wifi_interface_handle iface, wifi_rtt_capabilities *capabitlites)
|
||||
: WifiCommand("GetRttCapabilitiesCommand", iface, 0), mCapabilities(capabitlites)
|
||||
{
|
||||
memset(mCapabilities, 0, sizeof(*mCapabilities));
|
||||
}
|
||||
|
||||
virtual int create() {
|
||||
ALOGD("Creating message to get scan capablities; iface = %d", mIfaceInfo->id);
|
||||
|
||||
int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_GETCAPABILITY);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int handleResponse(WifiEvent& reply) {
|
||||
|
||||
ALOGD("In GetRttCapabilitiesCommand::handleResponse");
|
||||
|
||||
if (reply.get_cmd() != NL80211_CMD_VENDOR) {
|
||||
ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
int id = reply.get_vendor_id();
|
||||
int subcmd = reply.get_vendor_subcmd();
|
||||
|
||||
void *data = reply.get_vendor_data();
|
||||
int len = reply.get_vendor_data_len();
|
||||
|
||||
ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
|
||||
sizeof(*mCapabilities));
|
||||
|
||||
memcpy(mCapabilities, data, min(len, (int) sizeof(*mCapabilities)));
|
||||
|
||||
return NL_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class GetRttResponderInfoCommand : public WifiCommand
|
||||
{
|
||||
wifi_rtt_responder* mResponderInfo;
|
||||
public:
|
||||
GetRttResponderInfoCommand(wifi_interface_handle iface, wifi_rtt_responder *responderInfo)
|
||||
: WifiCommand("GetRttResponderInfoCommand", iface, 0), mResponderInfo(responderInfo)
|
||||
{
|
||||
memset(mResponderInfo, 0 , sizeof(*mResponderInfo));
|
||||
|
||||
}
|
||||
|
||||
virtual int create() {
|
||||
ALOGD("Creating message to get responder info ; iface = %d", mIfaceInfo->id);
|
||||
|
||||
int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_GETAVAILCHANNEL);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int handleResponse(WifiEvent& reply) {
|
||||
|
||||
ALOGD("In GetRttResponderInfoCommand::handleResponse");
|
||||
|
||||
if (reply.get_cmd() != NL80211_CMD_VENDOR) {
|
||||
ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
int id = reply.get_vendor_id();
|
||||
int subcmd = reply.get_vendor_subcmd();
|
||||
|
||||
void *data = reply.get_vendor_data();
|
||||
int len = reply.get_vendor_data_len();
|
||||
|
||||
ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
|
||||
sizeof(*mResponderInfo));
|
||||
|
||||
memcpy(mResponderInfo, data, min(len, (int) sizeof(*mResponderInfo)));
|
||||
|
||||
return NL_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class EnableResponderCommand : public WifiCommand
|
||||
{
|
||||
wifi_channel_info mChannelInfo;
|
||||
wifi_rtt_responder* mResponderInfo;
|
||||
unsigned m_max_duration_sec;
|
||||
public:
|
||||
EnableResponderCommand(wifi_interface_handle iface, int id, wifi_channel_info channel_hint,
|
||||
unsigned max_duration_seconds, wifi_rtt_responder *responderInfo)
|
||||
: WifiCommand("EnableResponderCommand", iface, 0), mChannelInfo(channel_hint),
|
||||
m_max_duration_sec(max_duration_seconds), mResponderInfo(responderInfo)
|
||||
{
|
||||
memset(mResponderInfo, 0, sizeof(*mResponderInfo));
|
||||
}
|
||||
|
||||
virtual int create() {
|
||||
ALOGD("Creating message to set responder ; iface = %d", mIfaceInfo->id);
|
||||
|
||||
int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_SET_RESPONDER);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int handleResponse(WifiEvent& reply) {
|
||||
|
||||
ALOGD("In EnableResponderCommand::handleResponse");
|
||||
|
||||
if (reply.get_cmd() != NL80211_CMD_VENDOR) {
|
||||
ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
int id = reply.get_vendor_id();
|
||||
int subcmd = reply.get_vendor_subcmd();
|
||||
|
||||
void *data = reply.get_vendor_data();
|
||||
int len = reply.get_vendor_data_len();
|
||||
|
||||
ALOGD("Id = %0x, subcmd = %d, len = %d, expected len = %d", id, subcmd, len,
|
||||
sizeof(*mResponderInfo));
|
||||
|
||||
memcpy(mResponderInfo, data, min(len, (int) sizeof(*mResponderInfo)));
|
||||
|
||||
return NL_OK;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class CancelResponderCommand : public WifiCommand
|
||||
{
|
||||
|
||||
public:
|
||||
CancelResponderCommand(wifi_interface_handle iface, int id)
|
||||
: WifiCommand("CancelResponderCommand", iface, 0)/*, mChannelInfo(channel)*/
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual int create() {
|
||||
ALOGD("Creating message to cancel responder ; iface = %d", mIfaceInfo->id);
|
||||
|
||||
int ret = mMsg.create(GOOGLE_OUI, RTT_SUBCMD_CANCEL_RESPONDER);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual int handleResponse(WifiEvent& reply) {
|
||||
/* Nothing to do on response! */
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class RttCommand : public WifiCommand
|
||||
{
|
||||
unsigned numRttParams;
|
||||
int mCompleted;
|
||||
int currentIdx;
|
||||
int totalCnt;
|
||||
static const int MAX_RESULTS = 1024;
|
||||
wifi_rtt_result *rttResults[MAX_RESULTS];
|
||||
wifi_rtt_config *rttParams = NULL;
|
||||
wifi_rtt_event_handler rttHandler;
|
||||
public:
|
||||
RttCommand(wifi_interface_handle iface, int id, unsigned num_rtt_config,
|
||||
wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler)
|
||||
: WifiCommand("RttCommand", iface, id), numRttParams(num_rtt_config), rttParams(rtt_config),
|
||||
rttHandler(handler)
|
||||
{
|
||||
memset(rttResults, 0, sizeof(rttResults));
|
||||
currentIdx = 0;
|
||||
mCompleted = 0;
|
||||
totalCnt = 0;
|
||||
}
|
||||
|
||||
RttCommand(wifi_interface_handle iface, int id)
|
||||
: WifiCommand("RttCommand", iface, id)
|
||||
{
|
||||
currentIdx = 0;
|
||||
mCompleted = 0;
|
||||
totalCnt = 0;
|
||||
numRttParams = 0;
|
||||
}
|
||||
|
||||
int createSetupRequest(WifiRequest& request) {
|
||||
int result = request.create(GOOGLE_OUI, RTT_SUBCMD_SET_CONFIG);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
|
||||
result = request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, numRttParams);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
nlattr *rtt_config = request.attr_start(RTT_ATTRIBUTE_TARGET_INFO);
|
||||
for (unsigned i = 0; i < numRttParams; i++) {
|
||||
nlattr *attr2 = request.attr_start(i);
|
||||
if (attr2 == NULL) {
|
||||
return WIFI_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, rttParams[i].addr);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u8(RTT_ATTRIBUTE_TARGET_TYPE, rttParams[i].type);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u8(RTT_ATTRIBUTE_TARGET_PEER, rttParams[i].peer);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put(RTT_ATTRIBUTE_TARGET_CHAN, &rttParams[i].channel,
|
||||
sizeof(wifi_channel_info));
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_BURST, rttParams[i].num_burst);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_FTM_BURST,
|
||||
rttParams[i].num_frames_per_burst);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTM,
|
||||
rttParams[i].num_retries_per_rtt_frame);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u32(RTT_ATTRIBUTE_TARGET_NUM_RETRY_FTMR,
|
||||
rttParams[i].num_retries_per_ftmr);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u32(RTT_ATTRIBUTE_TARGET_PERIOD,
|
||||
rttParams[i].burst_period);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u32(RTT_ATTRIBUTE_TARGET_BURST_DURATION,
|
||||
rttParams[i].burst_duration);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCI,
|
||||
rttParams[i].LCI_request);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u8(RTT_ATTRIBUTE_TARGET_LCR,
|
||||
rttParams[i].LCR_request);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u8(RTT_ATTRIBUTE_TARGET_BW,
|
||||
rttParams[i].bw);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u8(RTT_ATTRIBUTE_TARGET_PREAMBLE,
|
||||
rttParams[i].preamble);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
request.attr_end(attr2);
|
||||
}
|
||||
|
||||
request.attr_end(rtt_config);
|
||||
request.attr_end(data);
|
||||
return WIFI_SUCCESS;
|
||||
}
|
||||
|
||||
int createTeardownRequest(WifiRequest& request, unsigned num_devices, mac_addr addr[]) {
|
||||
int result = request.create(GOOGLE_OUI, RTT_SUBCMD_CANCEL_CONFIG);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
|
||||
request.put_u8(RTT_ATTRIBUTE_TARGET_CNT, num_devices);
|
||||
for(unsigned i = 0; i < num_devices; i++) {
|
||||
result = request.put_addr(RTT_ATTRIBUTE_TARGET_MAC, addr[i]);
|
||||
if (result < 0) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
request.attr_end(data);
|
||||
return result;
|
||||
}
|
||||
int start() {
|
||||
ALOGD("Setting RTT configuration");
|
||||
WifiRequest request(familyId(), ifaceId());
|
||||
int result = createSetupRequest(request);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGV("failed to create setup request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = requestResponse(request);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGV("failed to configure RTT setup; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
registerVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
|
||||
ALOGI("Successfully started RTT operation");
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual int cancel() {
|
||||
ALOGD("Stopping RTT");
|
||||
|
||||
WifiRequest request(familyId(), ifaceId());
|
||||
int result = createTeardownRequest(request, 0, NULL);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGV("failed to create stop request; result = %d", result);
|
||||
} else {
|
||||
result = requestResponse(request);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGV("failed to stop scan; result = %d", result);
|
||||
}
|
||||
}
|
||||
|
||||
unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
|
||||
return WIFI_SUCCESS;
|
||||
}
|
||||
|
||||
int cancel_specific(unsigned num_devices, mac_addr addr[]) {
|
||||
ALOGV("Stopping RTT");
|
||||
|
||||
WifiRequest request(familyId(), ifaceId());
|
||||
int result = createTeardownRequest(request, num_devices, addr);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGV("failed to create stop request; result = %d", result);
|
||||
} else {
|
||||
result = requestResponse(request);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGV("failed to stop RTT; result = %d", result);
|
||||
}
|
||||
}
|
||||
|
||||
unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
|
||||
return WIFI_SUCCESS;
|
||||
}
|
||||
|
||||
virtual int handleResponse(WifiEvent& reply) {
|
||||
/* Nothing to do on response! */
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
virtual int handleEvent(WifiEvent& event) {
|
||||
ALOGI("Got an RTT event");
|
||||
nlattr *vendor_data = event.get_attribute(NL80211_ATTR_VENDOR_DATA);
|
||||
int len = event.get_vendor_data_len();
|
||||
if (vendor_data == NULL || len == 0) {
|
||||
ALOGI("No rtt results found");
|
||||
}
|
||||
for (nl_iterator it(vendor_data); it.has_next(); it.next()) {
|
||||
if (it.get_type() == RTT_ATTRIBUTE_RESULTS_COMPLETE) {
|
||||
mCompleted = it.get_u32();
|
||||
ALOGI("retrieved completed flag : %d\n", mCompleted);
|
||||
} else if (it.get_type() == RTT_ATTRIBUTE_RESULTS_PER_TARGET) {
|
||||
int result_cnt = 0;
|
||||
mac_addr bssid;
|
||||
for (nl_iterator it2(it.get()); it2.has_next(); it2.next()) {
|
||||
if (it2.get_type() == RTT_ATTRIBUTE_TARGET_MAC) {
|
||||
memcpy(bssid, it2.get_data(), sizeof(mac_addr));
|
||||
ALOGI("retrived target mac : %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
bssid[0],
|
||||
bssid[1],
|
||||
bssid[2],
|
||||
bssid[3],
|
||||
bssid[4],
|
||||
bssid[5]);
|
||||
} else if (it2.get_type() == RTT_ATTRIBUTE_RESULT_CNT) {
|
||||
result_cnt = it2.get_u32();
|
||||
ALOGI("retrieved result_cnt : %d\n", result_cnt);
|
||||
} else if (it2.get_type() == RTT_ATTRIBUTE_RESULT) {
|
||||
int result_len = it2.get_len();
|
||||
rttResults[currentIdx] = (wifi_rtt_result *)malloc(it2.get_len());
|
||||
wifi_rtt_result *rtt_result = rttResults[currentIdx];
|
||||
if (rtt_result == NULL) {
|
||||
mCompleted = 1;
|
||||
ALOGV("failed to allocate the wifi_rtt_result\n");
|
||||
break;
|
||||
}
|
||||
memcpy(rtt_result, it2.get_data(), it2.get_len());
|
||||
result_len -= sizeof(wifi_rtt_result);
|
||||
if (result_len > 0) {
|
||||
result_len -= sizeof(wifi_rtt_result);
|
||||
dot11_rm_ie_t *ele_1;
|
||||
dot11_rm_ie_t *ele_2;
|
||||
/* The result has LCI or LCR element */
|
||||
ele_1 = (dot11_rm_ie_t *)(rtt_result + 1);
|
||||
if (ele_1->id == DOT11_MNG_MEASURE_REQUEST_ID) {
|
||||
if (ele_1->type == DOT11_MEASURE_TYPE_LCI) {
|
||||
rtt_result->LCI = (wifi_information_element *)ele_1;
|
||||
result_len -= (ele_1->len + DOT11_HDR_LEN);
|
||||
/* get a next rm ie */
|
||||
if (result_len > 0) {
|
||||
ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + (ele_1->len + DOT11_HDR_LEN));
|
||||
if ((ele_2->id == DOT11_MNG_MEASURE_REQUEST_ID) &&
|
||||
(ele_2->type == DOT11_MEASURE_TYPE_CIVICLOC)) {
|
||||
rtt_result->LCR = (wifi_information_element *)ele_2;
|
||||
}
|
||||
}
|
||||
} else if (ele_1->type == DOT11_MEASURE_TYPE_CIVICLOC){
|
||||
rtt_result->LCR = (wifi_information_element *)ele_1;
|
||||
result_len -= (ele_1->len + DOT11_HDR_LEN);
|
||||
/* get a next rm ie */
|
||||
if (result_len > 0) {
|
||||
ele_2 = (dot11_rm_ie_t *)((char *)ele_1 + (ele_1->len + DOT11_HDR_LEN));
|
||||
if ((ele_2->id == DOT11_MNG_MEASURE_REQUEST_ID) &&
|
||||
(ele_2->type == DOT11_MEASURE_TYPE_LCI)) {
|
||||
rtt_result->LCI = (wifi_information_element *)ele_2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
totalCnt++;
|
||||
ALOGI("retrived rtt_result : \n\tburst_num :%d, measurement_number : %d, success_number : %d\n"
|
||||
"\tnumber_per_burst_peer : %d, status : %s, retry_after_duration : %d s\n"
|
||||
"\trssi : %d dbm, rx_rate : %d Kbps, rtt : %llu ns, rtt_sd : %llu\n"
|
||||
"\tdistance : %d, burst_duration : %d ms, negotiated_burst_num : %d\n",
|
||||
rtt_result->burst_num, rtt_result->measurement_number,
|
||||
rtt_result->success_number, rtt_result->number_per_burst_peer,
|
||||
get_err_info(rtt_result->status), rtt_result->retry_after_duration,
|
||||
rtt_result->rssi, rtt_result->rx_rate.bitrate * 100,
|
||||
rtt_result->rtt/10, rtt_result->rtt_sd, rtt_result->distance_mm / 10,
|
||||
rtt_result->burst_duration, rtt_result->negotiated_burst_num);
|
||||
currentIdx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (mCompleted) {
|
||||
unregisterVendorHandler(GOOGLE_OUI, RTT_EVENT_COMPLETE);
|
||||
(*rttHandler.on_rtt_results)(id(), totalCnt, rttResults);
|
||||
for (int i = 0; i < currentIdx; i++) {
|
||||
free(rttResults[i]);
|
||||
rttResults[i] = NULL;
|
||||
}
|
||||
totalCnt = currentIdx = 0;
|
||||
WifiCommand *cmd = wifi_unregister_cmd(wifiHandle(), id());
|
||||
if (cmd)
|
||||
cmd->releaseRef();
|
||||
}
|
||||
return NL_SKIP;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* API to request RTT measurement */
|
||||
wifi_error wifi_rtt_range_request(wifi_request_id id, wifi_interface_handle iface,
|
||||
unsigned num_rtt_config, wifi_rtt_config rtt_config[], wifi_rtt_event_handler handler)
|
||||
{
|
||||
wifi_handle handle = getWifiHandle(iface);
|
||||
RttCommand *cmd = new RttCommand(iface, id, num_rtt_config, rtt_config, handler);
|
||||
NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
|
||||
wifi_error result = wifi_register_cmd(handle, id, cmd);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
cmd->releaseRef();
|
||||
return result;
|
||||
}
|
||||
result = (wifi_error)cmd->start();
|
||||
if (result != WIFI_SUCCESS) {
|
||||
wifi_unregister_cmd(handle, id);
|
||||
cmd->releaseRef();
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* API to cancel RTT measurements */
|
||||
wifi_error wifi_rtt_range_cancel(wifi_request_id id, wifi_interface_handle iface,
|
||||
unsigned num_devices, mac_addr addr[])
|
||||
{
|
||||
wifi_handle handle = getWifiHandle(iface);
|
||||
RttCommand *cmd = new RttCommand(iface, id);
|
||||
NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
|
||||
cmd->cancel_specific(num_devices, addr);
|
||||
cmd->releaseRef();
|
||||
return WIFI_SUCCESS;
|
||||
}
|
||||
|
||||
/* API to get RTT capability */
|
||||
wifi_error wifi_get_rtt_capabilities(wifi_interface_handle iface,
|
||||
wifi_rtt_capabilities *capabilities)
|
||||
{
|
||||
GetRttCapabilitiesCommand command(iface, capabilities);
|
||||
return (wifi_error) command.requestResponse();
|
||||
}
|
||||
|
||||
/* API to get the responder information */
|
||||
wifi_error wifi_rtt_get_responder_info(wifi_interface_handle iface,
|
||||
wifi_rtt_responder* responderInfo)
|
||||
{
|
||||
GetRttResponderInfoCommand command(iface, responderInfo);
|
||||
return (wifi_error) command.requestResponse();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable RTT responder mode.
|
||||
* channel_hint - hint of the channel information where RTT responder should be enabled on.
|
||||
* max_duration_seconds - timeout of responder mode.
|
||||
* wifi_rtt_responder - information for RTT responder e.g. channel used and preamble supported.
|
||||
*/
|
||||
wifi_error wifi_enable_responder(wifi_request_id id, wifi_interface_handle iface,
|
||||
wifi_channel_info channel_hint, unsigned max_duration_seconds,
|
||||
wifi_rtt_responder* responderInfo)
|
||||
{
|
||||
EnableResponderCommand command(iface, id, channel_hint, max_duration_seconds, responderInfo);
|
||||
return (wifi_error) command.requestResponse();
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable RTT responder mode.
|
||||
*/
|
||||
wifi_error wifi_disable_responder(wifi_request_id id, wifi_interface_handle iface)
|
||||
{
|
||||
CancelResponderCommand command(iface, id);
|
||||
return (wifi_error) command.requestResponse();
|
||||
}
|
||||
|
69
android/hardware/realtek/wlan/wifi_hal/sync.h
Normal file
69
android/hardware/realtek/wlan/wifi_hal/sync.h
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* 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 <pthread.h>
|
||||
|
||||
#ifndef __WIFI_HAL_SYNC_H__
|
||||
#define __WIFI_HAL_SYNC_H__
|
||||
|
||||
class Mutex
|
||||
{
|
||||
private:
|
||||
pthread_mutex_t mMutex;
|
||||
public:
|
||||
Mutex() {
|
||||
pthread_mutex_init(&mMutex, NULL);
|
||||
}
|
||||
~Mutex() {
|
||||
pthread_mutex_destroy(&mMutex);
|
||||
}
|
||||
int tryLock() {
|
||||
return pthread_mutex_trylock(&mMutex);
|
||||
}
|
||||
int lock() {
|
||||
return pthread_mutex_lock(&mMutex);
|
||||
}
|
||||
void unlock() {
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
}
|
||||
};
|
||||
|
||||
class Condition
|
||||
{
|
||||
private:
|
||||
pthread_cond_t mCondition;
|
||||
pthread_mutex_t mMutex;
|
||||
|
||||
public:
|
||||
Condition() {
|
||||
pthread_mutex_init(&mMutex, NULL);
|
||||
pthread_cond_init(&mCondition, NULL);
|
||||
}
|
||||
~Condition() {
|
||||
pthread_cond_destroy(&mCondition);
|
||||
pthread_mutex_destroy(&mMutex);
|
||||
}
|
||||
|
||||
int wait() {
|
||||
return pthread_cond_wait(&mCondition, &mMutex);
|
||||
}
|
||||
|
||||
void signal() {
|
||||
pthread_cond_signal(&mCondition);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
1352
android/hardware/realtek/wlan/wifi_hal/wifi_hal.cpp
Normal file
1352
android/hardware/realtek/wlan/wifi_hal/wifi_hal.cpp
Normal file
File diff suppressed because it is too large
Load diff
1148
android/hardware/realtek/wlan/wifi_hal/wifi_logger.cpp
Normal file
1148
android/hardware/realtek/wlan/wifi_hal/wifi_logger.cpp
Normal file
File diff suppressed because it is too large
Load diff
247
android/hardware/realtek/wlan/wifi_hal/wifi_offload.cpp
Normal file
247
android/hardware/realtek/wlan/wifi_hal/wifi_offload.cpp
Normal file
|
@ -0,0 +1,247 @@
|
|||
/*
|
||||
* Copyright (C) 2017 The Android Open Source Project
|
||||
*
|
||||
* 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 <stdint.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/family.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/errqueue.h>
|
||||
|
||||
#include <linux/pkt_sched.h>
|
||||
#include <netlink/object-api.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/socket.h>
|
||||
#include <netlink-private/object-api.h>
|
||||
#include <netlink-private/types.h>
|
||||
|
||||
|
||||
#include "nl80211_copy.h"
|
||||
#include "sync.h"
|
||||
|
||||
#define LOG_TAG "WifiHAL"
|
||||
|
||||
#include <log/log.h>
|
||||
|
||||
#include "wifi_hal.h"
|
||||
#include "common.h"
|
||||
#include "cpp_bindings.h"
|
||||
|
||||
typedef enum {
|
||||
WIFI_OFFLOAD_START_MKEEP_ALIVE = ANDROID_NL80211_SUBCMD_WIFI_OFFLOAD_RANGE_START,
|
||||
WIFI_OFFLOAD_STOP_MKEEP_ALIVE,
|
||||
} WIFI_OFFLOAD_SUB_COMMAND;
|
||||
|
||||
typedef enum {
|
||||
MKEEP_ALIVE_ATTRIBUTE_ID,
|
||||
MKEEP_ALIVE_ATTRIBUTE_IP_PKT,
|
||||
MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN,
|
||||
MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR,
|
||||
MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR,
|
||||
MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC
|
||||
} WIFI_MKEEP_ALIVE_ATTRIBUTE;
|
||||
|
||||
typedef enum {
|
||||
START_MKEEP_ALIVE,
|
||||
STOP_MKEEP_ALIVE,
|
||||
} GetCmdType;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
class MKeepAliveCommand : public WifiCommand
|
||||
{
|
||||
u8 mIndex;
|
||||
u8 *mIpPkt = NULL;
|
||||
u16 mIpPktLen;
|
||||
u8 *mSrcMacAddr = NULL;
|
||||
u8 *mDstMacAddr = NULL;
|
||||
u32 mPeriodMsec;
|
||||
GetCmdType mType;
|
||||
|
||||
public:
|
||||
|
||||
// constructor for start sending
|
||||
MKeepAliveCommand(wifi_interface_handle iface, u8 index, u8 *ip_packet, u16 ip_packet_len,
|
||||
u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec, GetCmdType cmdType)
|
||||
: WifiCommand("MKeepAliveCommand", iface, 0), mIndex(index), mIpPkt(ip_packet),
|
||||
mIpPktLen(ip_packet_len), mSrcMacAddr(src_mac_addr), mDstMacAddr(dst_mac_addr),
|
||||
mPeriodMsec(period_msec), mType(cmdType)
|
||||
{ }
|
||||
|
||||
// constructor for stop sending
|
||||
MKeepAliveCommand(wifi_interface_handle iface, u8 index, GetCmdType cmdType)
|
||||
: WifiCommand("MKeepAliveCommand", iface, 0), mIndex(index), mType(cmdType)
|
||||
{ }
|
||||
|
||||
int createRequest(WifiRequest &request) {
|
||||
int result;
|
||||
|
||||
switch (mType) {
|
||||
case START_MKEEP_ALIVE:
|
||||
{
|
||||
result = request.create(GOOGLE_OUI, WIFI_OFFLOAD_START_MKEEP_ALIVE);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGV("Failed to create start keep alive request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
|
||||
|
||||
result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex);
|
||||
if (result < 0) {
|
||||
ALOGV("Failed to put id request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u16(MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, mIpPktLen);
|
||||
if (result < 0) {
|
||||
ALOGV("Failed to put ip pkt len request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put(MKEEP_ALIVE_ATTRIBUTE_IP_PKT, (u8*)mIpPkt, mIpPktLen);
|
||||
if (result < 0) {
|
||||
ALOGV("Failed to put ip pkt request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_SRC_MAC_ADDR, mSrcMacAddr);
|
||||
if (result < 0) {
|
||||
ALOGV("Failed to put src mac address request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_addr(MKEEP_ALIVE_ATTRIBUTE_DST_MAC_ADDR, mDstMacAddr);
|
||||
if (result < 0) {
|
||||
ALOGV("Failed to put dst mac address request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u32(MKEEP_ALIVE_ATTRIBUTE_PERIOD_MSEC, mPeriodMsec);
|
||||
if (result < 0) {
|
||||
ALOGV("Failed to put period request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
request.attr_end(data);
|
||||
break;
|
||||
}
|
||||
|
||||
case STOP_MKEEP_ALIVE:
|
||||
{
|
||||
result = request.create(GOOGLE_OUI, WIFI_OFFLOAD_STOP_MKEEP_ALIVE);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGV("Failed to create stop keep alive request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
nlattr *data = request.attr_start(NL80211_ATTR_VENDOR_DATA);
|
||||
|
||||
result = request.put_u8(MKEEP_ALIVE_ATTRIBUTE_ID, mIndex);
|
||||
if (result < 0) {
|
||||
ALOGV("Failed to put id request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
request.attr_end(data);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ALOGV("Unknown wifi keep alive command");
|
||||
result = WIFI_ERROR_UNKNOWN;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int start() {
|
||||
ALOGD("Start mkeep_alive command");
|
||||
WifiRequest request(familyId(), ifaceId());
|
||||
int result = createRequest(request);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGV("Failed to create keep alive request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = requestResponse(request);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGV("Failed to register keep alive response; result = %d", result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
virtual int handleResponse(WifiEvent& reply) {
|
||||
ALOGD("In MKeepAliveCommand::handleResponse");
|
||||
|
||||
if (reply.get_cmd() != NL80211_CMD_VENDOR) {
|
||||
ALOGD("Ignoring reply with cmd = %d", reply.get_cmd());
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
switch (mType) {
|
||||
case START_MKEEP_ALIVE:
|
||||
case STOP_MKEEP_ALIVE:
|
||||
break;
|
||||
|
||||
default:
|
||||
ALOGW("Unknown mkeep_alive command");
|
||||
}
|
||||
return NL_OK;
|
||||
}
|
||||
|
||||
virtual int handleEvent(WifiEvent& event) {
|
||||
/* NO events! */
|
||||
return NL_SKIP;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/* API to send specified mkeep_alive packet periodically. */
|
||||
wifi_error wifi_start_sending_offloaded_packet(wifi_request_id index, wifi_interface_handle iface,
|
||||
u8 *ip_packet, u16 ip_packet_len, u8 *src_mac_addr, u8 *dst_mac_addr, u32 period_msec)
|
||||
{
|
||||
if ((index > 0 && index <= N_AVAIL_ID) && (ip_packet != NULL) && (src_mac_addr != NULL)
|
||||
&& (dst_mac_addr != NULL) && (period_msec > 0)
|
||||
&& (ip_packet_len <= MKEEP_ALIVE_IP_PKT_MAX)) {
|
||||
MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, ip_packet, ip_packet_len,
|
||||
src_mac_addr, dst_mac_addr, period_msec, START_MKEEP_ALIVE);
|
||||
NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
|
||||
wifi_error result = (wifi_error)cmd->start();
|
||||
cmd->releaseRef();
|
||||
return result;
|
||||
} else {
|
||||
ALOGV("Invalid mkeep_alive parameters");
|
||||
return WIFI_ERROR_INVALID_ARGS;
|
||||
}
|
||||
}
|
||||
|
||||
/* API to stop sending mkeep_alive packet. */
|
||||
wifi_error wifi_stop_sending_offloaded_packet(wifi_request_id index, wifi_interface_handle iface)
|
||||
{
|
||||
if (index > 0 && index <= N_AVAIL_ID) {
|
||||
MKeepAliveCommand *cmd = new MKeepAliveCommand(iface, index, STOP_MKEEP_ALIVE);
|
||||
NULL_CHECK_RETURN(cmd, "memory allocation failure", WIFI_ERROR_OUT_OF_MEMORY);
|
||||
wifi_error result = (wifi_error)cmd->start();
|
||||
cmd->releaseRef();
|
||||
return result;
|
||||
} else {
|
||||
ALOGV("Invalid mkeep_alive parameters");
|
||||
return WIFI_ERROR_INVALID_ARGS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
#
|
||||
# Copyright (C) 2008 The Android Open Source Project
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
ifeq ($(WPA_SUPPLICANT_VERSION),VER_0_8_X)
|
||||
|
||||
ifneq ($(BOARD_WPA_SUPPLICANT_DRIVER),)
|
||||
CONFIG_DRIVER_$(BOARD_WPA_SUPPLICANT_DRIVER) := y
|
||||
endif
|
||||
|
||||
WPA_SUPPL_DIR = external/wpa_supplicant_8
|
||||
WPA_SRC_FILE :=
|
||||
|
||||
include $(WPA_SUPPL_DIR)/wpa_supplicant/android.config
|
||||
|
||||
WPA_SUPPL_DIR_INCLUDE = $(WPA_SUPPL_DIR)/src \
|
||||
$(WPA_SUPPL_DIR)/src/common \
|
||||
$(WPA_SUPPL_DIR)/src/drivers \
|
||||
$(WPA_SUPPL_DIR)/src/l2_packet \
|
||||
$(WPA_SUPPL_DIR)/src/utils \
|
||||
$(WPA_SUPPL_DIR)/src/wps \
|
||||
$(WPA_SUPPL_DIR)/wpa_supplicant
|
||||
|
||||
ifdef CONFIG_DRIVER_NL80211
|
||||
WPA_SUPPL_DIR_INCLUDE += external/libnl/include
|
||||
WPA_SRC_FILE += driver_cmd_nl80211.c
|
||||
endif
|
||||
|
||||
ifdef CONFIG_DRIVER_WEXT
|
||||
WPA_SRC_FILE += driver_cmd_wext.c
|
||||
endif
|
||||
|
||||
ifeq ($(TARGET_ARCH),arm)
|
||||
# To force sizeof(enum) = 4
|
||||
L_CFLAGS += -mabi=aapcs-linux
|
||||
endif
|
||||
|
||||
ifdef CONFIG_ANDROID_LOG
|
||||
L_CFLAGS += -DCONFIG_ANDROID_LOG
|
||||
endif
|
||||
|
||||
ifdef CONFIG_P2P
|
||||
L_CFLAGS += -DCONFIG_P2P
|
||||
endif
|
||||
########################
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := lib_driver_cmd_rtl
|
||||
LOCAL_SHARED_LIBRARIES := libc libcutils
|
||||
LOCAL_CFLAGS := $(L_CFLAGS)
|
||||
LOCAL_SRC_FILES := $(WPA_SRC_FILE)
|
||||
LOCAL_C_INCLUDES := $(WPA_SUPPL_DIR_INCLUDE)
|
||||
LOCAL_PROPRIETARY_MODULE := true
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
||||
########################
|
||||
|
||||
endif
|
43
android/hardware/realtek/wlan/wpa_supplicant_8_lib/NOTICE
Normal file
43
android/hardware/realtek/wlan/wpa_supplicant_8_lib/NOTICE
Normal file
|
@ -0,0 +1,43 @@
|
|||
|
||||
Copyright (c) 2005-2010, The Android Open Source Project
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in
|
||||
the documentation and/or other materials provided with the
|
||||
distribution.
|
||||
* Neither the name of The Android Open Source Project nor the names
|
||||
of its contributors may be used to endorse or promote products
|
||||
derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
|
||||
* Copyright (c) 2002-2010, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2003-2004, Instant802 Networks, Inc.
|
||||
* Copyright (c) 2005-2006, Devicescape Software, Inc.
|
||||
* Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright (c) 2009-2010, Atheros Communications
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
|
@ -0,0 +1,224 @@
|
|||
/*
|
||||
* Driver interaction with extended Linux CFG8021
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "common.h"
|
||||
#include "linux_ioctl.h"
|
||||
#include "driver_nl80211.h"
|
||||
#include "rtw_version.h"
|
||||
#ifdef PURE_LINUX
|
||||
#ifndef SIOCDEVPRIVATE
|
||||
#define SIOCDEVPRIVATE 0x89F0 /* to 89FF */
|
||||
#endif
|
||||
#ifndef __unused
|
||||
#if __GNUC_PREREQ(2, 95) || defined(__INTEL_COMPILER)
|
||||
#define __unused __attribute__((__unused__))
|
||||
#else
|
||||
#define __unused
|
||||
#endif
|
||||
#endif
|
||||
#endif /* PURE_LINUX */
|
||||
#include "wpa_supplicant_i.h"
|
||||
#include "config.h"
|
||||
#ifdef ANDROID
|
||||
#include "android_drv.h"
|
||||
#endif
|
||||
|
||||
typedef struct android_wifi_priv_cmd {
|
||||
char *bufaddr;
|
||||
int used_len;
|
||||
int total_len;
|
||||
} android_wifi_priv_cmd;
|
||||
|
||||
static int drv_errors = 0;
|
||||
|
||||
static void wpa_driver_send_hang_msg(struct wpa_driver_nl80211_data *drv)
|
||||
{
|
||||
drv_errors++;
|
||||
if (drv_errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
|
||||
drv_errors = 0;
|
||||
wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
|
||||
}
|
||||
}
|
||||
|
||||
static void wpa_driver_notify_country_change(void *ctx, char *cmd)
|
||||
{
|
||||
if ((os_strncasecmp(cmd, "COUNTRY", 7) == 0) ||
|
||||
(os_strncasecmp(cmd, "SETBAND", 7) == 0)) {
|
||||
union wpa_event_data event;
|
||||
|
||||
os_memset(&event, 0, sizeof(event));
|
||||
event.channel_list_changed.initiator = REGDOM_SET_BY_USER;
|
||||
if (os_strncasecmp(cmd, "COUNTRY", 7) == 0) {
|
||||
event.channel_list_changed.type = REGDOM_TYPE_COUNTRY;
|
||||
if (os_strlen(cmd) > 9) {
|
||||
event.channel_list_changed.alpha2[0] = cmd[8];
|
||||
event.channel_list_changed.alpha2[1] = cmd[9];
|
||||
}
|
||||
} else {
|
||||
event.channel_list_changed.type = REGDOM_TYPE_UNKNOWN;
|
||||
}
|
||||
wpa_supplicant_event(ctx, EVENT_CHANNEL_LIST_CHANGED, &event);
|
||||
}
|
||||
}
|
||||
|
||||
int wpa_driver_nl80211_driver_cmd(void *priv, char *cmd, char *buf,
|
||||
size_t buf_len )
|
||||
{
|
||||
struct i802_bss *bss = priv;
|
||||
struct wpa_driver_nl80211_data *drv = bss->drv;
|
||||
struct ifreq ifr;
|
||||
android_wifi_priv_cmd priv_cmd;
|
||||
int ret = 0;
|
||||
|
||||
if (bss->ifindex <= 0 && bss->wdev_id > 0) {
|
||||
/* DRIVER CMD received on the DEDICATED P2P Interface which doesn't
|
||||
* have an NETDEVICE associated with it. So we have to re-route the
|
||||
* command to the parent NETDEVICE
|
||||
*/
|
||||
struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
|
||||
|
||||
wpa_printf(MSG_DEBUG, "Re-routing DRIVER cmd to parent iface");
|
||||
if (wpa_s && wpa_s->parent) {
|
||||
/* Update the nl80211 pointers corresponding to parent iface */
|
||||
bss = wpa_s->parent->drv_priv;
|
||||
drv = bss->drv;
|
||||
wpa_printf(MSG_DEBUG, "Re-routing command to iface: %s"
|
||||
" cmd (%s)", bss->ifname, cmd);
|
||||
}
|
||||
}
|
||||
|
||||
if (os_strcasecmp(cmd, "STOP") == 0) {
|
||||
linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 0);
|
||||
wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED");
|
||||
} else if (os_strcasecmp(cmd, "START") == 0) {
|
||||
linux_set_iface_flags(drv->global->ioctl_sock, bss->ifname, 1);
|
||||
wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED");
|
||||
} else if (os_strcasecmp(cmd, "lib_version") == 0) {
|
||||
wpa_msg(drv->ctx, MSG_INFO, RTW_VERSION);
|
||||
} else if (os_strcasecmp(cmd, "P2P_DISABLE") == 0) {
|
||||
os_memcpy(buf, "P2P_DISABLE", 12);
|
||||
wpa_printf(MSG_DEBUG, "P2P_DISABLE");
|
||||
} else if (os_strcasecmp(cmd, "MACADDR") == 0) {
|
||||
u8 macaddr[ETH_ALEN] = {};
|
||||
|
||||
ret = linux_get_ifhwaddr(drv->global->ioctl_sock, bss->ifname, macaddr);
|
||||
if (!ret)
|
||||
ret = os_snprintf(buf, buf_len,
|
||||
"Macaddr = " MACSTR "\n", MAC2STR(macaddr));
|
||||
} else { /* Use private command */
|
||||
os_memcpy(buf, cmd, strlen(cmd) + 1);
|
||||
memset(&ifr, 0, sizeof(ifr));
|
||||
memset(&priv_cmd, 0, sizeof(priv_cmd));
|
||||
os_strlcpy(ifr.ifr_name, bss->ifname, IFNAMSIZ);
|
||||
priv_cmd.bufaddr = buf;
|
||||
priv_cmd.used_len = buf_len;
|
||||
priv_cmd.total_len = buf_len;
|
||||
ifr.ifr_data = (void *)&priv_cmd;
|
||||
|
||||
if ((ret = ioctl(drv->global->ioctl_sock, SIOCDEVPRIVATE + 1, &ifr)) < 0) {
|
||||
wpa_printf(MSG_ERROR, "%s: failed to issue private command: %s", __func__, cmd);
|
||||
wpa_driver_send_hang_msg(drv);
|
||||
} else {
|
||||
drv_errors = 0;
|
||||
ret = 0;
|
||||
if ((os_strcasecmp(cmd, "LINKSPEED") == 0) ||
|
||||
(os_strcasecmp(cmd, "RSSI") == 0) ||
|
||||
(os_strcasecmp(cmd, "GETBAND") == 0) ||
|
||||
(os_strncasecmp(cmd, "WLS_BATCHING", 12) == 0))
|
||||
ret = strlen(buf);
|
||||
wpa_driver_notify_country_change(drv->ctx, cmd);
|
||||
wpa_printf(MSG_DEBUG, "%s %s len = %d, %zu", __func__, buf, ret, strlen(buf));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wpa_driver_set_p2p_noa(void *priv, u8 count, int start, int duration)
|
||||
{
|
||||
char buf[MAX_DRV_CMD_SIZE];
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
wpa_printf(MSG_DEBUG, "%s: Entry", __func__);
|
||||
snprintf(buf, sizeof(buf), "P2P_SET_NOA %d %d %d", count, start, duration);
|
||||
return wpa_driver_nl80211_driver_cmd(priv, buf, buf, strlen(buf)+1);
|
||||
}
|
||||
|
||||
int wpa_driver_get_p2p_noa(void *priv __unused, u8 *buf __unused, size_t len __unused)
|
||||
{
|
||||
/* Return 0 till we handle p2p_presence request completely in the driver */
|
||||
return 0;
|
||||
}
|
||||
|
||||
int wpa_driver_set_p2p_ps(void *priv, int legacy_ps, int opp_ps, int ctwindow)
|
||||
{
|
||||
char buf[MAX_DRV_CMD_SIZE];
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
wpa_printf(MSG_DEBUG, "%s: Entry", __func__);
|
||||
snprintf(buf, sizeof(buf), "P2P_SET_PS %d %d %d", legacy_ps, opp_ps, ctwindow);
|
||||
return wpa_driver_nl80211_driver_cmd(priv, buf, buf, strlen(buf) + 1);
|
||||
}
|
||||
|
||||
int wpa_driver_set_ap_wps_p2p_ie(void *priv, const struct wpabuf *beacon,
|
||||
const struct wpabuf *proberesp,
|
||||
const struct wpabuf *assocresp)
|
||||
{
|
||||
char *buf;
|
||||
const struct wpabuf *ap_wps_p2p_ie = NULL;
|
||||
|
||||
char *_cmd = "SET_AP_WPS_P2P_IE";
|
||||
char *pbuf;
|
||||
int ret = 0;
|
||||
int i, buf_len;
|
||||
struct cmd_desc {
|
||||
int cmd;
|
||||
const struct wpabuf *src;
|
||||
} cmd_arr[] = {
|
||||
{0x1, beacon},
|
||||
{0x2, proberesp},
|
||||
{0x4, assocresp},
|
||||
{-1, NULL}
|
||||
};
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: Entry", __func__);
|
||||
for (i = 0; cmd_arr[i].cmd != -1; i++) {
|
||||
ap_wps_p2p_ie = cmd_arr[i].src;
|
||||
if (ap_wps_p2p_ie) {
|
||||
buf_len = strlen(_cmd) + 3 + wpabuf_len(ap_wps_p2p_ie);
|
||||
buf = os_zalloc(buf_len);
|
||||
if (NULL == buf) {
|
||||
wpa_printf(MSG_ERROR, "%s: Out of memory",
|
||||
__func__);
|
||||
ret = -1;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
pbuf = buf;
|
||||
pbuf += snprintf(pbuf, buf_len - wpabuf_len(ap_wps_p2p_ie),
|
||||
"%s %d",_cmd, cmd_arr[i].cmd);
|
||||
*pbuf++ = '\0';
|
||||
os_memcpy(pbuf, wpabuf_head(ap_wps_p2p_ie), wpabuf_len(ap_wps_p2p_ie));
|
||||
ret = wpa_driver_nl80211_driver_cmd(priv, buf, buf, buf_len);
|
||||
os_free(buf);
|
||||
if (ret < 0)
|
||||
break;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
|
@ -0,0 +1,396 @@
|
|||
/*
|
||||
* Driver interaction with extended Linux Wireless Extensions
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <net/if.h>
|
||||
|
||||
#include "linux_wext.h"
|
||||
#include "common.h"
|
||||
#include "driver.h"
|
||||
#include "eloop.h"
|
||||
#include "priv_netlink.h"
|
||||
#include "driver_wext.h"
|
||||
#include "ieee802_11_defs.h"
|
||||
#include "wpa_common.h"
|
||||
#include "wpa_ctrl.h"
|
||||
#include "wpa_supplicant_i.h"
|
||||
#include "config.h"
|
||||
#include "linux_ioctl.h"
|
||||
#include "scan.h"
|
||||
|
||||
#include "driver_cmd_wext.h"
|
||||
#ifdef ANDROID
|
||||
#include "android_drv.h"
|
||||
#endif /* ANDROID */
|
||||
|
||||
#define RSSI_CMD "RSSI"
|
||||
#define LINKSPEED_CMD "LINKSPEED"
|
||||
|
||||
/**
|
||||
* wpa_driver_wext_set_scan_timeout - Set scan timeout to report scan completion
|
||||
* @priv: Pointer to private wext data from wpa_driver_wext_init()
|
||||
*
|
||||
* This function can be used to set registered timeout when starting a scan to
|
||||
* generate a scan completed event if the driver does not report this.
|
||||
*/
|
||||
static void wpa_driver_wext_set_scan_timeout(void *priv)
|
||||
{
|
||||
struct wpa_driver_wext_data *drv = priv;
|
||||
int timeout = 10; /* In case scan A and B bands it can be long */
|
||||
|
||||
/* Not all drivers generate "scan completed" wireless event, so try to
|
||||
* read results after a timeout. */
|
||||
if (drv->scan_complete_events) {
|
||||
/*
|
||||
* The driver seems to deliver SIOCGIWSCAN events to notify
|
||||
* when scan is complete, so use longer timeout to avoid race
|
||||
* conditions with scanning and following association request.
|
||||
*/
|
||||
timeout = 30;
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "Scan requested - scan timeout %d seconds",
|
||||
timeout);
|
||||
eloop_cancel_timeout(wpa_driver_wext_scan_timeout, drv, drv->ctx);
|
||||
eloop_register_timeout(timeout, 0, wpa_driver_wext_scan_timeout, drv,
|
||||
drv->ctx);
|
||||
}
|
||||
|
||||
/**
|
||||
* wpa_driver_wext_combo_scan - Request the driver to initiate combo scan
|
||||
* @priv: Pointer to private wext data from wpa_driver_wext_init()
|
||||
* @params: Scan parameters
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int wpa_driver_wext_combo_scan(void *priv, struct wpa_driver_scan_params *params)
|
||||
{
|
||||
char buf[WEXT_CSCAN_BUF_LEN];
|
||||
struct wpa_driver_wext_data *drv = priv;
|
||||
struct iwreq iwr;
|
||||
int ret, bp;
|
||||
unsigned i;
|
||||
|
||||
if (!drv->driver_is_started) {
|
||||
wpa_printf(MSG_DEBUG, "%s: Driver stopped", __func__);
|
||||
return 0;
|
||||
}
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: Start", __func__);
|
||||
|
||||
/* Set list of SSIDs */
|
||||
bp = WEXT_CSCAN_HEADER_SIZE;
|
||||
os_memcpy(buf, WEXT_CSCAN_HEADER, bp);
|
||||
for(i=0; i < params->num_ssids; i++) {
|
||||
if ((bp + IW_ESSID_MAX_SIZE + 10) >= (int)sizeof(buf))
|
||||
break;
|
||||
wpa_printf(MSG_DEBUG, "For Scan: %s", params->ssids[i].ssid);
|
||||
buf[bp++] = WEXT_CSCAN_SSID_SECTION;
|
||||
buf[bp++] = params->ssids[i].ssid_len;
|
||||
os_memcpy(&buf[bp], params->ssids[i].ssid, params->ssids[i].ssid_len);
|
||||
bp += params->ssids[i].ssid_len;
|
||||
}
|
||||
|
||||
/* Set list of channels */
|
||||
buf[bp++] = WEXT_CSCAN_CHANNEL_SECTION;
|
||||
buf[bp++] = 0;
|
||||
|
||||
/* Set passive dwell time (default is 250) */
|
||||
buf[bp++] = WEXT_CSCAN_PASV_DWELL_SECTION;
|
||||
buf[bp++] = (u8)WEXT_CSCAN_PASV_DWELL_TIME;
|
||||
buf[bp++] = (u8)(WEXT_CSCAN_PASV_DWELL_TIME >> 8);
|
||||
|
||||
/* Set home dwell time (default is 40) */
|
||||
buf[bp++] = WEXT_CSCAN_HOME_DWELL_SECTION;
|
||||
buf[bp++] = (u8)WEXT_CSCAN_HOME_DWELL_TIME;
|
||||
buf[bp++] = (u8)(WEXT_CSCAN_HOME_DWELL_TIME >> 8);
|
||||
|
||||
os_memset(&iwr, 0, sizeof(iwr));
|
||||
os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
|
||||
iwr.u.data.pointer = buf;
|
||||
iwr.u.data.length = bp;
|
||||
|
||||
if ((ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr)) < 0) {
|
||||
if (!drv->bgscan_enabled)
|
||||
wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (cscan): %d", ret);
|
||||
else
|
||||
ret = 0; /* Hide error in case of bg scan */
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wpa_driver_wext_set_cscan_params(char *buf, size_t buf_len, char *cmd)
|
||||
{
|
||||
char *pasv_ptr;
|
||||
int bp, i;
|
||||
u16 pasv_dwell = WEXT_CSCAN_PASV_DWELL_TIME_DEF;
|
||||
u8 channel;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s: %s", __func__, cmd);
|
||||
|
||||
/* Get command parameters */
|
||||
pasv_ptr = os_strstr(cmd, ",TIME=");
|
||||
if (pasv_ptr) {
|
||||
*pasv_ptr = '\0';
|
||||
pasv_ptr += 6;
|
||||
pasv_dwell = (u16)atoi(pasv_ptr);
|
||||
if (pasv_dwell == 0)
|
||||
pasv_dwell = WEXT_CSCAN_PASV_DWELL_TIME_DEF;
|
||||
}
|
||||
channel = (u8)atoi(cmd + 5);
|
||||
|
||||
bp = WEXT_CSCAN_HEADER_SIZE;
|
||||
os_memcpy(buf, WEXT_CSCAN_HEADER, bp);
|
||||
|
||||
/* Set list of channels */
|
||||
buf[bp++] = WEXT_CSCAN_CHANNEL_SECTION;
|
||||
buf[bp++] = channel;
|
||||
if (channel != 0) {
|
||||
i = (pasv_dwell - 1) / WEXT_CSCAN_PASV_DWELL_TIME_DEF;
|
||||
for (; i > 0; i--) {
|
||||
if ((size_t)(bp + 12) >= buf_len)
|
||||
break;
|
||||
buf[bp++] = WEXT_CSCAN_CHANNEL_SECTION;
|
||||
buf[bp++] = channel;
|
||||
}
|
||||
} else {
|
||||
if (pasv_dwell > WEXT_CSCAN_PASV_DWELL_TIME_MAX)
|
||||
pasv_dwell = WEXT_CSCAN_PASV_DWELL_TIME_MAX;
|
||||
}
|
||||
|
||||
/* Set passive dwell time (default is 250) */
|
||||
buf[bp++] = WEXT_CSCAN_PASV_DWELL_SECTION;
|
||||
if (channel != 0) {
|
||||
buf[bp++] = (u8)WEXT_CSCAN_PASV_DWELL_TIME_DEF;
|
||||
buf[bp++] = (u8)(WEXT_CSCAN_PASV_DWELL_TIME_DEF >> 8);
|
||||
} else {
|
||||
buf[bp++] = (u8)pasv_dwell;
|
||||
buf[bp++] = (u8)(pasv_dwell >> 8);
|
||||
}
|
||||
|
||||
/* Set home dwell time (default is 40) */
|
||||
buf[bp++] = WEXT_CSCAN_HOME_DWELL_SECTION;
|
||||
buf[bp++] = (u8)WEXT_CSCAN_HOME_DWELL_TIME;
|
||||
buf[bp++] = (u8)(WEXT_CSCAN_HOME_DWELL_TIME >> 8);
|
||||
|
||||
/* Set cscan type */
|
||||
buf[bp++] = WEXT_CSCAN_TYPE_SECTION;
|
||||
buf[bp++] = WEXT_CSCAN_TYPE_PASSIVE;
|
||||
return bp;
|
||||
}
|
||||
|
||||
static char *wpa_driver_get_country_code(int channels)
|
||||
{
|
||||
char *country = "US"; /* WEXT_NUMBER_SCAN_CHANNELS_FCC */
|
||||
|
||||
if (channels == WEXT_NUMBER_SCAN_CHANNELS_ETSI)
|
||||
country = "EU";
|
||||
else if( channels == WEXT_NUMBER_SCAN_CHANNELS_MKK1)
|
||||
country = "JP";
|
||||
return country;
|
||||
}
|
||||
|
||||
static int wpa_driver_set_backgroundscan_params(void *priv)
|
||||
{
|
||||
struct wpa_driver_wext_data *drv = priv;
|
||||
struct wpa_supplicant *wpa_s;
|
||||
struct iwreq iwr;
|
||||
int ret = 0, i = 0, bp;
|
||||
char buf[WEXT_PNO_MAX_COMMAND_SIZE];
|
||||
struct wpa_ssid *ssid_conf;
|
||||
|
||||
if (drv == NULL) {
|
||||
wpa_printf(MSG_ERROR, "%s: drv is NULL. Exiting", __func__);
|
||||
return -1;
|
||||
}
|
||||
if (drv->ctx == NULL) {
|
||||
wpa_printf(MSG_ERROR, "%s: drv->ctx is NULL. Exiting", __func__);
|
||||
return -1;
|
||||
}
|
||||
wpa_s = (struct wpa_supplicant *)(drv->ctx);
|
||||
if (wpa_s->conf == NULL) {
|
||||
wpa_printf(MSG_ERROR, "%s: wpa_s->conf is NULL. Exiting", __func__);
|
||||
return -1;
|
||||
}
|
||||
ssid_conf = wpa_s->conf->ssid;
|
||||
|
||||
bp = WEXT_PNOSETUP_HEADER_SIZE;
|
||||
os_memcpy(buf, WEXT_PNOSETUP_HEADER, bp);
|
||||
buf[bp++] = WEXT_PNO_TLV_PREFIX;
|
||||
buf[bp++] = WEXT_PNO_TLV_VERSION;
|
||||
buf[bp++] = WEXT_PNO_TLV_SUBVERSION;
|
||||
buf[bp++] = WEXT_PNO_TLV_RESERVED;
|
||||
|
||||
while ((i < WEXT_PNO_AMOUNT) && (ssid_conf != NULL)) {
|
||||
/* Check that there is enough space needed for 1 more SSID, the other sections and null termination */
|
||||
if ((bp + WEXT_PNO_SSID_HEADER_SIZE + IW_ESSID_MAX_SIZE + WEXT_PNO_NONSSID_SECTIONS_SIZE + 1) >= (int)sizeof(buf))
|
||||
break;
|
||||
if ((!ssid_conf->disabled) && (ssid_conf->ssid_len <= IW_ESSID_MAX_SIZE)){
|
||||
wpa_printf(MSG_DEBUG, "For PNO Scan: %s", ssid_conf->ssid);
|
||||
buf[bp++] = WEXT_PNO_SSID_SECTION;
|
||||
buf[bp++] = ssid_conf->ssid_len;
|
||||
os_memcpy(&buf[bp], ssid_conf->ssid, ssid_conf->ssid_len);
|
||||
bp += ssid_conf->ssid_len;
|
||||
i++;
|
||||
}
|
||||
ssid_conf = ssid_conf->next;
|
||||
}
|
||||
|
||||
buf[bp++] = WEXT_PNO_SCAN_INTERVAL_SECTION;
|
||||
os_snprintf(&buf[bp], WEXT_PNO_SCAN_INTERVAL_LENGTH + 1, "%x", WEXT_PNO_SCAN_INTERVAL);
|
||||
bp += WEXT_PNO_SCAN_INTERVAL_LENGTH;
|
||||
|
||||
buf[bp++] = WEXT_PNO_REPEAT_SECTION;
|
||||
os_snprintf(&buf[bp], WEXT_PNO_REPEAT_LENGTH + 1, "%x", WEXT_PNO_REPEAT);
|
||||
bp += WEXT_PNO_REPEAT_LENGTH;
|
||||
|
||||
buf[bp++] = WEXT_PNO_MAX_REPEAT_SECTION;
|
||||
os_snprintf(&buf[bp], WEXT_PNO_MAX_REPEAT_LENGTH + 1, "%x", WEXT_PNO_MAX_REPEAT);
|
||||
bp += WEXT_PNO_MAX_REPEAT_LENGTH + 1;
|
||||
|
||||
os_memset(&iwr, 0, sizeof(iwr));
|
||||
os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
|
||||
iwr.u.data.pointer = buf;
|
||||
iwr.u.data.length = bp;
|
||||
|
||||
ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr);
|
||||
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "ioctl[SIOCSIWPRIV] (pnosetup): %d", ret);
|
||||
drv->errors++;
|
||||
if (drv->errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
|
||||
drv->errors = 0;
|
||||
wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
|
||||
}
|
||||
} else {
|
||||
drv->errors = 0;
|
||||
}
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int wpa_driver_wext_driver_cmd( void *priv, char *cmd, char *buf, size_t buf_len )
|
||||
{
|
||||
struct wpa_driver_wext_data *drv = priv;
|
||||
struct wpa_supplicant *wpa_s = (struct wpa_supplicant *)(drv->ctx);
|
||||
struct iwreq iwr;
|
||||
int ret = 0, flags;
|
||||
|
||||
wpa_printf(MSG_DEBUG, "%s %s len = %d", __func__, cmd, buf_len);
|
||||
|
||||
if (!drv->driver_is_started && (os_strcasecmp(cmd, "START") != 0)) {
|
||||
wpa_printf(MSG_ERROR,"WEXT: Driver not initialized yet");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (os_strcasecmp(cmd, "RSSI-APPROX") == 0) {
|
||||
os_strlcpy(cmd, RSSI_CMD, MAX_DRV_CMD_SIZE);
|
||||
} else if( os_strncasecmp(cmd, "SCAN-CHANNELS", 13) == 0 ) {
|
||||
int no_of_chan;
|
||||
|
||||
no_of_chan = atoi(cmd + 13);
|
||||
os_snprintf(cmd, MAX_DRV_CMD_SIZE, "COUNTRY %s",
|
||||
wpa_driver_get_country_code(no_of_chan));
|
||||
} else if (os_strcasecmp(cmd, "STOP") == 0) {
|
||||
linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 0);
|
||||
} else if( os_strcasecmp(cmd, "RELOAD") == 0 ) {
|
||||
wpa_printf(MSG_DEBUG,"Reload command");
|
||||
wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
|
||||
return ret;
|
||||
} else if( os_strcasecmp(cmd, "BGSCAN-START") == 0 ) {
|
||||
ret = wpa_driver_set_backgroundscan_params(priv);
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
os_strlcpy(cmd, "PNOFORCE 1", MAX_DRV_CMD_SIZE);
|
||||
drv->bgscan_enabled = 1;
|
||||
} else if( os_strcasecmp(cmd, "BGSCAN-STOP") == 0 ) {
|
||||
os_strlcpy(cmd, "PNOFORCE 0", MAX_DRV_CMD_SIZE);
|
||||
drv->bgscan_enabled = 0;
|
||||
}
|
||||
|
||||
os_memset(&iwr, 0, sizeof(iwr));
|
||||
os_strlcpy(iwr.ifr_name, drv->ifname, IFNAMSIZ);
|
||||
os_memcpy(buf, cmd, strlen(cmd) + 1);
|
||||
iwr.u.data.pointer = buf;
|
||||
iwr.u.data.length = buf_len;
|
||||
|
||||
if( os_strncasecmp(cmd, "CSCAN", 5) == 0 ) {
|
||||
if (!wpa_s->scanning && ((wpa_s->wpa_state <= WPA_SCANNING) ||
|
||||
(wpa_s->wpa_state >= WPA_COMPLETED))) {
|
||||
iwr.u.data.length = wpa_driver_wext_set_cscan_params(buf, buf_len, cmd);
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "Ongoing Scan action...");
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
ret = ioctl(drv->ioctl_sock, SIOCSIWPRIV, &iwr);
|
||||
|
||||
if (ret < 0) {
|
||||
wpa_printf(MSG_ERROR, "%s failed (%d): %s", __func__, ret, cmd);
|
||||
drv->errors++;
|
||||
if (drv->errors > DRV_NUMBER_SEQUENTIAL_ERRORS) {
|
||||
drv->errors = 0;
|
||||
wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "HANGED");
|
||||
}
|
||||
} else {
|
||||
drv->errors = 0;
|
||||
ret = 0;
|
||||
if ((os_strcasecmp(cmd, RSSI_CMD) == 0) ||
|
||||
(os_strcasecmp(cmd, LINKSPEED_CMD) == 0) ||
|
||||
(os_strcasecmp(cmd, "MACADDR") == 0) ||
|
||||
(os_strcasecmp(cmd, "GETPOWER") == 0) ||
|
||||
(os_strcasecmp(cmd, "GETBAND") == 0)) {
|
||||
ret = strlen(buf);
|
||||
} else if (os_strcasecmp(cmd, "START") == 0) {
|
||||
drv->driver_is_started = TRUE;
|
||||
linux_set_iface_flags(drv->ioctl_sock, drv->ifname, 1);
|
||||
/* os_sleep(0, WPA_DRIVER_WEXT_WAIT_US);
|
||||
wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STARTED"); */
|
||||
} else if (os_strcasecmp(cmd, "STOP") == 0) {
|
||||
drv->driver_is_started = FALSE;
|
||||
/* wpa_msg(drv->ctx, MSG_INFO, WPA_EVENT_DRIVER_STATE "STOPPED"); */
|
||||
} else if (os_strncasecmp(cmd, "CSCAN", 5) == 0) {
|
||||
wpa_driver_wext_set_scan_timeout(priv);
|
||||
wpa_supplicant_notify_scanning(wpa_s, 1);
|
||||
}
|
||||
wpa_printf(MSG_DEBUG, "%s %s len = %d, %d", __func__, buf, ret, strlen(buf));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int wpa_driver_signal_poll(void *priv, struct wpa_signal_info *si)
|
||||
{
|
||||
char buf[MAX_DRV_CMD_SIZE];
|
||||
struct wpa_driver_wext_data *drv = priv;
|
||||
char *prssi;
|
||||
int res;
|
||||
|
||||
os_memset(si, 0, sizeof(*si));
|
||||
res = wpa_driver_wext_driver_cmd(priv, RSSI_CMD, buf, sizeof(buf));
|
||||
/* Answer: SSID rssi -Val */
|
||||
if (res < 0)
|
||||
return res;
|
||||
prssi = strcasestr(buf, RSSI_CMD);
|
||||
if (!prssi)
|
||||
return -1;
|
||||
si->current_signal = atoi(prssi + strlen(RSSI_CMD) + 1);
|
||||
|
||||
res = wpa_driver_wext_driver_cmd(priv, LINKSPEED_CMD, buf, sizeof(buf));
|
||||
/* Answer: LinkSpeed Val */
|
||||
if (res < 0)
|
||||
return res;
|
||||
si->current_txrate = atoi(buf + strlen(LINKSPEED_CMD) + 1) * 1000;
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* Driver interaction with extended Linux Wireless Extensions
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* Alternatively, this software may be distributed under the terms of BSD
|
||||
* license.
|
||||
*
|
||||
*/
|
||||
#ifndef DRIVER_CMD_WEXT_H
|
||||
#define DRIVER_CMD_WEXT_H
|
||||
|
||||
#define WEXT_NUMBER_SCAN_CHANNELS_FCC 11
|
||||
#define WEXT_NUMBER_SCAN_CHANNELS_ETSI 13
|
||||
#define WEXT_NUMBER_SCAN_CHANNELS_MKK1 14
|
||||
|
||||
#define WPA_DRIVER_WEXT_WAIT_US 400000
|
||||
#define WEXT_CSCAN_BUF_LEN 360
|
||||
#define WEXT_CSCAN_HEADER "CSCAN S\x01\x00\x00S\x00"
|
||||
#define WEXT_CSCAN_HEADER_SIZE 12
|
||||
#define WEXT_CSCAN_SSID_SECTION 'S'
|
||||
#define WEXT_CSCAN_CHANNEL_SECTION 'C'
|
||||
#define WEXT_CSCAN_NPROBE_SECTION 'N'
|
||||
#define WEXT_CSCAN_ACTV_DWELL_SECTION 'A'
|
||||
#define WEXT_CSCAN_PASV_DWELL_SECTION 'P'
|
||||
#define WEXT_CSCAN_HOME_DWELL_SECTION 'H'
|
||||
#define WEXT_CSCAN_TYPE_SECTION 'T'
|
||||
#define WEXT_CSCAN_TYPE_DEFAULT 0
|
||||
#define WEXT_CSCAN_TYPE_PASSIVE 1
|
||||
#define WEXT_CSCAN_PASV_DWELL_TIME 130
|
||||
#define WEXT_CSCAN_PASV_DWELL_TIME_DEF 250
|
||||
#define WEXT_CSCAN_PASV_DWELL_TIME_MAX 3000
|
||||
#define WEXT_CSCAN_HOME_DWELL_TIME 130
|
||||
|
||||
#endif /* DRIVER_CMD_WEXT_H */
|
|
@ -0,0 +1,251 @@
|
|||
/*
|
||||
* Driver interaction with Linux nl80211/cfg80211
|
||||
* Copyright (c) 2002-2014, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2003-2004, Instant802 Networks, Inc.
|
||||
* Copyright (c) 2005-2006, Devicescape Software, Inc.
|
||||
* Copyright (c) 2007, Johannes Berg <johannes@sipsolutions.net>
|
||||
* Copyright (c) 2009-2010, Atheros Communications
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef _DRIVER_NL80211_H_
|
||||
#define _DRIVER_NL80211_H_
|
||||
|
||||
#include "includes.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <net/if.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/family.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#ifdef CONFIG_LIBNL3_ROUTE
|
||||
#include <netlink/route/neighbour.h>
|
||||
#endif /* CONFIG_LIBNL3_ROUTE */
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <netpacket/packet.h>
|
||||
#include <linux/filter.h>
|
||||
#include <linux/errqueue.h>
|
||||
#include "nl80211_copy.h"
|
||||
|
||||
#include "common.h"
|
||||
#include "eloop.h"
|
||||
#include "utils/list.h"
|
||||
#include "common/qca-vendor.h"
|
||||
#include "common/qca-vendor-attr.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/ieee802_11_common.h"
|
||||
#include "l2_packet/l2_packet.h"
|
||||
#include "netlink.h"
|
||||
#include "linux_ioctl.h"
|
||||
#include "radiotap.h"
|
||||
#include "radiotap_iter.h"
|
||||
#include "rfkill.h"
|
||||
#include "driver.h"
|
||||
|
||||
#ifdef CONFIG_LIBNL20
|
||||
/* libnl 2.0 compatibility code */
|
||||
#define nl_handle nl_sock
|
||||
#define nl80211_handle_alloc nl_socket_alloc_cb
|
||||
#define nl80211_handle_destroy nl_socket_free
|
||||
#endif /* CONFIG_LIBNL20 */
|
||||
|
||||
#ifndef IFF_LOWER_UP
|
||||
#define IFF_LOWER_UP 0x10000 /* driver signals L1 up */
|
||||
#endif
|
||||
#ifndef IFF_DORMANT
|
||||
#define IFF_DORMANT 0x20000 /* driver signals dormant */
|
||||
#endif
|
||||
|
||||
#ifndef IF_OPER_DORMANT
|
||||
#define IF_OPER_DORMANT 5
|
||||
#endif
|
||||
#ifndef IF_OPER_UP
|
||||
#define IF_OPER_UP 6
|
||||
#endif
|
||||
|
||||
struct nl80211_global {
|
||||
void *ctx;
|
||||
struct dl_list interfaces;
|
||||
int if_add_ifindex;
|
||||
u64 if_add_wdevid;
|
||||
int if_add_wdevid_set;
|
||||
struct netlink_data *netlink;
|
||||
struct nl_cb *nl_cb;
|
||||
struct nl_handle *nl;
|
||||
int nl80211_id;
|
||||
int ioctl_sock; /* socket for ioctl() use */
|
||||
|
||||
struct nl_handle *nl_event;
|
||||
};
|
||||
|
||||
struct nl80211_wiphy_data {
|
||||
struct dl_list list;
|
||||
struct dl_list bsss;
|
||||
struct dl_list drvs;
|
||||
|
||||
struct nl_handle *nl_beacons;
|
||||
struct nl_cb *nl_cb;
|
||||
|
||||
int wiphy_idx;
|
||||
};
|
||||
|
||||
struct i802_bss {
|
||||
struct wpa_driver_nl80211_data *drv;
|
||||
struct i802_bss *next;
|
||||
int ifindex;
|
||||
int br_ifindex;
|
||||
u64 wdev_id;
|
||||
char ifname[IFNAMSIZ + 1];
|
||||
char brname[IFNAMSIZ];
|
||||
unsigned int beacon_set:1;
|
||||
unsigned int added_if_into_bridge:1;
|
||||
unsigned int added_bridge:1;
|
||||
unsigned int in_deinit:1;
|
||||
unsigned int wdev_id_set:1;
|
||||
unsigned int added_if:1;
|
||||
unsigned int static_ap:1;
|
||||
|
||||
u8 addr[ETH_ALEN];
|
||||
|
||||
int freq;
|
||||
int bandwidth;
|
||||
int if_dynamic;
|
||||
|
||||
void *ctx;
|
||||
struct nl_handle *nl_preq, *nl_mgmt;
|
||||
struct nl_cb *nl_cb;
|
||||
|
||||
struct nl80211_wiphy_data *wiphy_data;
|
||||
struct dl_list wiphy_list;
|
||||
};
|
||||
|
||||
struct wpa_driver_nl80211_data {
|
||||
struct nl80211_global *global;
|
||||
struct dl_list list;
|
||||
struct dl_list wiphy_list;
|
||||
char phyname[32];
|
||||
unsigned int wiphy_idx;
|
||||
u8 perm_addr[ETH_ALEN];
|
||||
void *ctx;
|
||||
int ifindex;
|
||||
int if_removed;
|
||||
int if_disabled;
|
||||
int ignore_if_down_event;
|
||||
struct rfkill_data *rfkill;
|
||||
struct wpa_driver_capa capa;
|
||||
u8 *extended_capa, *extended_capa_mask;
|
||||
unsigned int extended_capa_len;
|
||||
int has_capability;
|
||||
|
||||
int operstate;
|
||||
|
||||
int scan_complete_events;
|
||||
enum scan_states {
|
||||
NO_SCAN, SCAN_REQUESTED, SCAN_STARTED, SCAN_COMPLETED,
|
||||
SCAN_ABORTED, SCHED_SCAN_STARTED, SCHED_SCAN_STOPPED,
|
||||
SCHED_SCAN_RESULTS
|
||||
} scan_state;
|
||||
|
||||
//struct nl_cb *nl_cb;
|
||||
|
||||
u8 auth_bssid[ETH_ALEN];
|
||||
u8 auth_attempt_bssid[ETH_ALEN];
|
||||
u8 bssid[ETH_ALEN];
|
||||
u8 prev_bssid[ETH_ALEN];
|
||||
int associated;
|
||||
u8 ssid[32];
|
||||
size_t ssid_len;
|
||||
enum nl80211_iftype nlmode;
|
||||
enum nl80211_iftype ap_scan_as_station;
|
||||
unsigned int assoc_freq;
|
||||
|
||||
int monitor_sock;
|
||||
int monitor_ifidx;
|
||||
int monitor_refcount;
|
||||
|
||||
unsigned int disabled_11b_rates:1;
|
||||
unsigned int pending_remain_on_chan:1;
|
||||
unsigned int in_interface_list:1;
|
||||
unsigned int device_ap_sme:1;
|
||||
unsigned int poll_command_supported:1;
|
||||
unsigned int data_tx_status:1;
|
||||
unsigned int scan_for_auth:1;
|
||||
unsigned int retry_auth:1;
|
||||
unsigned int use_monitor:1;
|
||||
unsigned int ignore_next_local_disconnect:1;
|
||||
unsigned int ignore_next_local_deauth:1;
|
||||
//unsigned int allow_p2p_device:1;
|
||||
unsigned int hostapd:1;
|
||||
unsigned int start_mode_ap:1;
|
||||
unsigned int start_iface_up:1;
|
||||
unsigned int test_use_roc_tx:1;
|
||||
unsigned int ignore_deauth_event:1;
|
||||
unsigned int vendor_cmd_test_avail:1;
|
||||
unsigned int roaming_vendor_cmd_avail:1;
|
||||
unsigned int dfs_vendor_cmd_avail:1;
|
||||
unsigned int have_low_prio_scan:1;
|
||||
unsigned int force_connect_cmd:1;
|
||||
unsigned int addr_changed:1;
|
||||
unsigned int get_features_vendor_cmd_avail:1;
|
||||
unsigned int set_rekey_offload:1;
|
||||
unsigned int p2p_go_ctwindow_supported:1;
|
||||
unsigned int setband_vendor_cmd_avail:1;
|
||||
unsigned int get_pref_freq_list:1;
|
||||
unsigned int set_prob_oper_freq:1;
|
||||
unsigned int scan_vendor_cmd_avail:1;
|
||||
unsigned int connect_reassoc:1;
|
||||
|
||||
u64 vendor_scan_cookie;
|
||||
u64 remain_on_chan_cookie;
|
||||
u64 send_action_cookie;
|
||||
#define MAX_SEND_ACTION_COOKIES 20
|
||||
u64 send_action_cookies[MAX_SEND_ACTION_COOKIES];
|
||||
unsigned int num_send_action_cookies;
|
||||
|
||||
unsigned int last_mgmt_freq;
|
||||
|
||||
struct wpa_driver_scan_filter *filter_ssids;
|
||||
size_t num_filter_ssids;
|
||||
|
||||
struct i802_bss *first_bss;
|
||||
|
||||
int eapol_tx_sock;
|
||||
|
||||
int eapol_sock; /* socket for EAPOL frames */
|
||||
|
||||
struct nl_handle *rtnl_sk; /* nl_sock for NETLINK_ROUTE */
|
||||
|
||||
int default_if_indices[16];
|
||||
/* the AP/AP_VLAN iface that is in this bridge */
|
||||
int default_if_indices_reason[16];
|
||||
int *if_indices;
|
||||
int *if_indices_reason;
|
||||
int num_if_indices;
|
||||
|
||||
/* From failed authentication command */
|
||||
int auth_freq;
|
||||
u8 auth_bssid_[ETH_ALEN];
|
||||
u8 auth_ssid[32];
|
||||
size_t auth_ssid_len;
|
||||
int auth_alg;
|
||||
u8 *auth_ie;
|
||||
size_t auth_ie_len;
|
||||
u8 auth_wep_key[4][16];
|
||||
size_t auth_wep_key_len[4];
|
||||
int auth_wep_tx_keyidx;
|
||||
int auth_local_state_change;
|
||||
int auth_p2p;
|
||||
|
||||
/*
|
||||
* Tells whether the last scan issued from wpa_supplicant was a normal
|
||||
* scan (NL80211_CMD_TRIGGER_SCAN) or a vendor scan
|
||||
* (NL80211_CMD_VENDOR). 0 if no pending scan request.
|
||||
*/
|
||||
int last_scan_cmd;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,4 @@
|
|||
#ifndef RTW_VERSION_H
|
||||
#define RTW_VERSION_H
|
||||
#define RTW_VERSION "rtw_r24091.20170925"
|
||||
#endif /* RTW_VERSION_H */
|
Loading…
Add table
Add a link
Reference in a new issue