upload android base code part4
This commit is contained in:
parent
b9e30e05b1
commit
78ea2404cd
23455 changed files with 5250148 additions and 0 deletions
42
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/Android.mk
Normal file
42
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/Android.mk
Normal file
|
@ -0,0 +1,42 @@
|
|||
# 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 := -Wno-unused-parameter
|
||||
|
||||
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_MODULE := libwifi-hal-bcm
|
||||
LOCAL_PROPRIETARY_MODULE := true
|
||||
|
||||
include $(BUILD_STATIC_LIBRARY)
|
||||
|
245
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/common.cpp
Normal file
245
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/common.cpp
Normal file
|
@ -0,0 +1,245 @@
|
|||
#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) {
|
||||
ALOGE("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 {
|
||||
ALOGE("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;
|
||||
}
|
||||
|
257
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/common.h
Normal file
257
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/common.h
Normal file
|
@ -0,0 +1,257 @@
|
|||
|
||||
#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 {
|
||||
BRCM_RESERVED1,
|
||||
BRCM_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 NULL_CHECK_RETURN(ptr, str, ret) \
|
||||
do { \
|
||||
if (!(ptr)) { \
|
||||
ALOGE("%s(): null pointer - #ptr (%s)\n", __FUNCTION__, str); \
|
||||
return ret; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#endif
|
||||
|
733
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/cpp_bindings.cpp
Normal file
733
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/cpp_bindings.cpp
Normal file
|
@ -0,0 +1,733 @@
|
|||
|
||||
#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) {
|
||||
ALOGE("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) {
|
||||
ALOGE("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) {
|
||||
ALOGE("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;
|
||||
}
|
352
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/cpp_bindings.h
Normal file
352
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/cpp_bindings.h
Normal file
|
@ -0,0 +1,352 @@
|
|||
|
||||
#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 *mType;
|
||||
hal_info *mInfo;
|
||||
WifiRequest mMsg;
|
||||
Condition mCondition;
|
||||
wifi_request_id mId;
|
||||
interface_info *mIfaceInfo;
|
||||
int mRefs;
|
||||
public:
|
||||
WifiCommand(const char *type, wifi_handle handle, wifi_request_id id)
|
||||
: mType(type), mMsg(getHalInfo(handle)->nl80211_family_id), mId(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)
|
||||
: mType(type), mMsg(getHalInfo(iface)->nl80211_family_id, getIfaceInfo(iface)->id),
|
||||
mId(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 mId;
|
||||
}
|
||||
|
||||
const char *getType() {
|
||||
return mType;
|
||||
}
|
||||
|
||||
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)))
|
||||
|
1837
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/gscan.cpp
Normal file
1837
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/gscan.cpp
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,166 @@
|
|||
|
||||
#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,
|
||||
};
|
||||
|
||||
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) {
|
||||
ALOGE("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 =
|
||||
convertToExternalRadioStatStructure((wifi_radio_stat_internal *)data);
|
||||
if (!radio_stat) {
|
||||
ALOGE("Invalid stats pointer received");
|
||||
return NL_SKIP;
|
||||
}
|
||||
if (radio_stat->num_channels > 11) {
|
||||
ALOGE("Incorrect number of channels = %d", radio_stat->num_channels);
|
||||
// dump data before num_channels
|
||||
ALOGE("radio: = %d", radio_stat->radio);
|
||||
ALOGE("on_time: = %d", radio_stat->on_time);
|
||||
ALOGE("tx_time: = %d", radio_stat->tx_time);
|
||||
ALOGE("rx_time: = %d", radio_stat->rx_time);
|
||||
ALOGE("on_time_scan: = %d", radio_stat->on_time_scan);
|
||||
ALOGE("on_time_nbd: = %d", radio_stat->on_time_nbd);
|
||||
ALOGE("on_time_gscan: = %d", radio_stat->on_time_gscan);
|
||||
ALOGE("on_time_pno_scan: = %d", radio_stat->on_time_pno_scan);
|
||||
ALOGE("on_time_hs20: = %d", radio_stat->on_time_hs20);
|
||||
free(radio_stat);
|
||||
return NL_SKIP;
|
||||
}
|
||||
wifi_iface_stat *iface_stat =
|
||||
(wifi_iface_stat *)((char *)&((wifi_radio_stat_internal *)data)->channels
|
||||
+ radio_stat->num_channels * sizeof(wifi_channel_stat));
|
||||
(*mHandler.on_link_stats_results)(id, iface_stat, 1, radio_stat);
|
||||
free(radio_stat);
|
||||
return NL_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
wifi_radio_stat *convertToExternalRadioStatStructure(wifi_radio_stat_internal *internal_stat_ptr) {
|
||||
wifi_radio_stat *external_stat_ptr = NULL;
|
||||
if (internal_stat_ptr) {
|
||||
uint32_t channel_size = internal_stat_ptr->num_channels * sizeof(wifi_channel_stat);
|
||||
uint32_t total_size = sizeof(wifi_radio_stat) + channel_size;
|
||||
external_stat_ptr = (wifi_radio_stat *)malloc(total_size);
|
||||
if (external_stat_ptr) {
|
||||
external_stat_ptr->radio = internal_stat_ptr->radio;
|
||||
external_stat_ptr->on_time = internal_stat_ptr->on_time;
|
||||
external_stat_ptr->tx_time = internal_stat_ptr->tx_time;
|
||||
external_stat_ptr->rx_time = internal_stat_ptr->rx_time;
|
||||
external_stat_ptr->tx_time_per_levels = NULL;
|
||||
external_stat_ptr->num_tx_levels = 0;
|
||||
external_stat_ptr->on_time_scan = internal_stat_ptr->on_time_scan;
|
||||
external_stat_ptr->on_time_nbd = internal_stat_ptr->on_time_nbd;
|
||||
external_stat_ptr->on_time_gscan = internal_stat_ptr->on_time_gscan;
|
||||
external_stat_ptr->on_time_roam_scan = internal_stat_ptr->on_time_roam_scan;
|
||||
external_stat_ptr->on_time_pno_scan = internal_stat_ptr->on_time_pno_scan;
|
||||
external_stat_ptr->on_time_hs20 = internal_stat_ptr->on_time_hs20;
|
||||
external_stat_ptr->num_channels = internal_stat_ptr->num_channels;
|
||||
if (internal_stat_ptr->num_channels) {
|
||||
memcpy(&(external_stat_ptr->channels), &(internal_stat_ptr->channels),
|
||||
channel_size);
|
||||
}
|
||||
}
|
||||
}
|
||||
return external_stat_ptr;
|
||||
}
|
||||
};
|
||||
|
||||
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 */)
|
||||
{
|
||||
/* Return success here since bcom HAL does not need set link stats. */
|
||||
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 */)
|
||||
{
|
||||
/* Return success here since bcom HAL does not support clear link stats. */
|
||||
return WIFI_SUCCESS;
|
||||
}
|
683
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/rtt.cpp
Normal file
683
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/rtt.cpp
Normal file
|
@ -0,0 +1,683 @@
|
|||
#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;
|
||||
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) {
|
||||
ALOGE("failed to create setup request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = requestResponse(request);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGE("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) {
|
||||
ALOGE("failed to create stop request; result = %d", result);
|
||||
} else {
|
||||
result = requestResponse(request);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGE("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[]) {
|
||||
ALOGE("Stopping RTT");
|
||||
|
||||
WifiRequest request(familyId(), ifaceId());
|
||||
int result = createTeardownRequest(request, num_devices, addr);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGE("failed to create stop request; result = %d", result);
|
||||
} else {
|
||||
result = requestResponse(request);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGE("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;
|
||||
ALOGE("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();
|
||||
}
|
||||
|
54
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/sync.h
Normal file
54
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/sync.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
|
||||
#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
|
1312
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/wifi_hal.cpp
Normal file
1312
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/wifi_hal.cpp
Normal file
File diff suppressed because it is too large
Load diff
1091
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/wifi_logger.cpp
Normal file
1091
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/wifi_logger.cpp
Normal file
File diff suppressed because it is too large
Load diff
231
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/wifi_offload.cpp
Normal file
231
android/hardware/broadcom/wlan/bcmdhd/wifi_hal/wifi_offload.cpp
Normal file
|
@ -0,0 +1,231 @@
|
|||
#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;
|
||||
u16 mIpPktLen;
|
||||
u8 *mSrcMacAddr;
|
||||
u8 *mDstMacAddr;
|
||||
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) {
|
||||
ALOGE("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) {
|
||||
ALOGE("Failed to put id request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = request.put_u16(MKEEP_ALIVE_ATTRIBUTE_IP_PKT_LEN, mIpPktLen);
|
||||
if (result < 0) {
|
||||
ALOGE("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) {
|
||||
ALOGE("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) {
|
||||
ALOGE("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) {
|
||||
ALOGE("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) {
|
||||
ALOGE("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) {
|
||||
ALOGE("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) {
|
||||
ALOGE("Failed to put id request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
request.attr_end(data);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
ALOGE("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) {
|
||||
ALOGE("Failed to create keep alive request; result = %d", result);
|
||||
return result;
|
||||
}
|
||||
|
||||
result = requestResponse(request);
|
||||
if (result != WIFI_SUCCESS) {
|
||||
ALOGE("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 {
|
||||
ALOGE("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 {
|
||||
ALOGE("Invalid mkeep_alive parameters");
|
||||
return WIFI_ERROR_INVALID_ARGS;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue