replace common qcom sources with samsung ones
This commit is contained in:
84
qcom/opensource/fst-manager/Android.bp
Normal file
84
qcom/opensource/fst-manager/Android.bp
Normal file
@@ -0,0 +1,84 @@
|
||||
// Temporarily disable fst-manager service as part of disabling WIGIG modules
|
||||
/*
|
||||
PKG_CONFIG = ["pkg-config"]
|
||||
|
||||
LOCAL_INCLUDES = ["."]
|
||||
LOCAL_INCLUDES += ["hidl"]
|
||||
LOCAL_INCLUDES += ["external"]
|
||||
LOCAL_INCLUDES += ["external/common"]
|
||||
LOCAL_INCLUDES += ["external/fst"]
|
||||
LOCAL_INCLUDES += ["external/utils"]
|
||||
LOCAL_INCLUDES += ["external/inih"]
|
||||
// The iproute includes used for a correct linux/pkt_sched.h
|
||||
INCLUDES = ["external/iproute2/include"]
|
||||
INCLUDES += ["external/libnl/include"]
|
||||
|
||||
OBJS = ["fst_mux_bonding.c"]
|
||||
OBJS += ["fst_manager.c"]
|
||||
OBJS += ["fst_tc.c"]
|
||||
OBJS += ["fst_ctrl.c"]
|
||||
OBJS += ["main.c"]
|
||||
OBJS += ["fst_cfgmgr.c"]
|
||||
OBJS += ["fst_ini_conf.c"]
|
||||
OBJS += ["fst_rateupg.c"]
|
||||
OBJS += ["fst_capconfigstore.cpp"]
|
||||
OBJS += ["fst_tpoll.c"]
|
||||
|
||||
OBJS += ["hidl/fst_hidl.cpp"]
|
||||
OBJS += ["hidl/hidl_manager.cpp"]
|
||||
OBJS += ["hidl/FstManager.cpp"]
|
||||
OBJS += ["hidl/FstGroup.cpp"]
|
||||
|
||||
OBJS += ["external/wpa_ctrl.c"]
|
||||
OBJS += ["external/eloop.c"]
|
||||
OBJS += ["external/common.c"]
|
||||
OBJS += ["external/os_unix.c"]
|
||||
OBJS += ["external/wpa_debug.c"]
|
||||
OBJS += ["external/fst_ctrl_aux.c"]
|
||||
OBJS += ["external/inih/ini.c"]
|
||||
|
||||
L_CFLAGS = [
|
||||
"-DCONFIG_CTRL_IFACE",
|
||||
"-DCONFIG_CTRL_IFACE_UNIX",
|
||||
"-DCONFIG_FST",
|
||||
"-DCONFIG_LIBNL20",
|
||||
"-DANDROID",
|
||||
]
|
||||
L_CFLAGS += ["-DCONFIG_CTRL_IFACE_CLIENT_DIR=\"/data/vendor/wifi/sockets\""]
|
||||
L_CFLAGS += ["-DDEFAULT_HAPD_CLI_DIR=\"/data/vendor/wifi/hostapd\""]
|
||||
L_CFLAGS += ["-DDEFAULT_WPAS_CLI_DIR=\"\""]
|
||||
L_CFLAGS += ["-DCONFIG_ANDROID_LOG"]
|
||||
L_CFLAGS += ["-DANDROID_LOG_NAME=\"fstman\""]
|
||||
// Disable unused parameter warnings
|
||||
L_CFLAGS += ["-Wno-unused-parameter"]
|
||||
|
||||
prebuilt_etc {
|
||||
name: "fstman.ini",
|
||||
|
||||
src: "fstman.ini",
|
||||
sub_dir: "wifi",
|
||||
proprietary: true,
|
||||
|
||||
}
|
||||
|
||||
cc_binary {
|
||||
name: "fstman",
|
||||
init_rc: ["vendor.qti.hardware.fstman@1.0-service.rc"],
|
||||
vendor: true,
|
||||
shared_libs: [
|
||||
"libnl",
|
||||
"libcutils",
|
||||
"liblog",
|
||||
"libutils",
|
||||
"libhidlbase",
|
||||
"vendor.qti.hardware.capabilityconfigstore@1.0",
|
||||
"vendor.qti.hardware.fstman@1.0",
|
||||
],
|
||||
|
||||
header_libs: ["libcutils_headers"],
|
||||
cflags: L_CFLAGS,
|
||||
srcs: OBJS,
|
||||
include_dirs: INCLUDES,
|
||||
local_include_dirs: LOCAL_INCLUDES,
|
||||
}
|
||||
*/
|
||||
146
qcom/opensource/fst-manager/Makefile
Normal file
146
qcom/opensource/fst-manager/Makefile
Normal file
@@ -0,0 +1,146 @@
|
||||
-include $(TOPDIR)/rules.mk
|
||||
|
||||
CFLAGS := -Wall -g -MMD
|
||||
LDFLAGS :=
|
||||
LIBS :=
|
||||
LOCAL_CFLAGS :=
|
||||
EXTERNAL_CFLAGS :=
|
||||
|
||||
ifeq ($(CONFIG_TARGET_BOARD),"ipq806x")
|
||||
is_ipq806x = 1
|
||||
endif
|
||||
|
||||
ifeq ($(is_ipq806x), 1)
|
||||
ifneq ($(strip $(TOOLPREFIX)),)
|
||||
export CROSS:=$(TOOLPREFIX)
|
||||
endif
|
||||
|
||||
ifndef INSTALL_ROOT
|
||||
INSTALL_ROOT= $(FSTMANDIR)/install
|
||||
endif
|
||||
|
||||
export CC = $(CROSS)gcc
|
||||
CFLAGS += -L$(INSTALL_ROOT)/lib
|
||||
endif
|
||||
|
||||
external_srcs :=
|
||||
|
||||
ifeq ($(is_ipq806x), 1)
|
||||
CONFIG_MUX_L2DA:=1
|
||||
endif
|
||||
|
||||
PKG_CONFIG := pkg-config
|
||||
|
||||
EXTERNAL_SRC_DIR := external
|
||||
|
||||
progs := fstman
|
||||
|
||||
ifndef CONFIG_MUX_L2DA
|
||||
FST_MUX_SRCS=fst_mux_bonding.c fst_tc.c
|
||||
else
|
||||
FST_MUX_SRCS=fst_mux_l2da.c
|
||||
endif
|
||||
|
||||
local_srcs := $(FST_MUX_SRCS) \
|
||||
fst_manager.c
|
||||
|
||||
LOCAL_CFLAGS += -I$(EXTERNAL_SRC_DIR)/ -I$(EXTERNAL_SRC_DIR)/inih
|
||||
EXTERNAL_CFLAGS += $(addprefix -I,$(sort $(dir $(wildcard $(EXTERNAL_SRC_DIR)/*/))))
|
||||
|
||||
LOCAL_CFLAGS += $(shell $(PKG_CONFIG) --cflags libnl-3.0)
|
||||
ifeq ($(is_ipq806x), 1)
|
||||
LIBS += -lnl-3
|
||||
else
|
||||
LIBS += $(shell $(PKG_CONFIG) --libs libnl-3.0)
|
||||
endif
|
||||
|
||||
|
||||
ifndef CONFIG_DBUS
|
||||
|
||||
external_srcs += \
|
||||
$(EXTERNAL_SRC_DIR)/wpa_ctrl.c \
|
||||
$(EXTERNAL_SRC_DIR)/eloop.c \
|
||||
$(EXTERNAL_SRC_DIR)/common.c \
|
||||
$(EXTERNAL_SRC_DIR)/os_unix.c \
|
||||
$(EXTERNAL_SRC_DIR)/wpa_debug.c \
|
||||
$(EXTERNAL_SRC_DIR)/fst_ctrl_aux.c \
|
||||
$(EXTERNAL_SRC_DIR)/inih/ini.c
|
||||
|
||||
EXTERNAL_CFLAGS += -DCONFIG_CTRL_IFACE -DCONFIG_CTRL_IFACE_UNIX -DCONFIG_FST
|
||||
EXTERNAL_CFLAGS += -DCONFIG_DEBUG_FILE
|
||||
|
||||
local_srcs += fst_ctrl.c fst_cfgmgr.c fst_ini_conf.c main.c fst_rateupg.c fst_tpoll.c fst_capconfigstore.c
|
||||
|
||||
else
|
||||
|
||||
LOCAL_CFLAGS += \
|
||||
$(shell $(PKG_CONFIG) --cflags glib-2.0) \
|
||||
$(shell $(PKG_CONFIG) --cflags gio-2.0) \
|
||||
-DCONFIG_DBUS
|
||||
LIBS += \
|
||||
$(shell $(PKG_CONFIG) --libs glib-2.0) \
|
||||
$(shell $(PKG_CONFIG) --libs gio-2.0)
|
||||
|
||||
local_srcs += fst_ctrl_dbus.c main_dbus.c
|
||||
|
||||
external_srcs += \
|
||||
$(EXTERNAL_SRC_DIR)/os_unix.c \
|
||||
$(EXTERNAL_SRC_DIR)/fst_ctrl_aux.c
|
||||
|
||||
endif
|
||||
|
||||
ifeq ($(is_ipq806x), 1)
|
||||
# What we build by default:
|
||||
ALL = $(progs)
|
||||
endif
|
||||
|
||||
local_objs :=$(local_srcs:.c=.o)
|
||||
external_objs := $(external_srcs:.c=.o)
|
||||
all_objs :=$(local_objs) $(external_objs)
|
||||
|
||||
ifeq ($(is_ipq806x), 1)
|
||||
all prod prof: $(progs) install
|
||||
else
|
||||
all prod prof: $(progs)
|
||||
endif
|
||||
|
||||
fstman: $(all_objs)
|
||||
|
||||
prod prof: CFLAGS += -O2
|
||||
prof: CFLAGS += -pg
|
||||
|
||||
prod: strip
|
||||
|
||||
$(all_objs): %.o: %.c
|
||||
|
||||
$(local_objs):
|
||||
$(CC) $(CFLAGS) $(LOCAL_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(external_objs):
|
||||
$(CC) $(CFLAGS) $(EXTERNAL_CFLAGS) -o $@ -c $<
|
||||
|
||||
$(progs): %:
|
||||
$(CC) -o $@ $^ $(LDFLAGS) $(LIBS)
|
||||
|
||||
strip:
|
||||
strip $(progs)
|
||||
|
||||
# Doing installation (see comments at top of this file)
|
||||
install:
|
||||
ifeq ($(is_ipq806x), 1)
|
||||
mkdir -p $(INSTALL_ROOT)/usr/sbin/
|
||||
cp -a -f $(ALL) $(INSTALL_ROOT)/usr/sbin/
|
||||
@echo Installed outputs from `pwd`
|
||||
endif
|
||||
|
||||
|
||||
clean:
|
||||
ifeq ($(is_ipq806x), 1)
|
||||
rm -rf install/usr/sbin/fstman
|
||||
endif
|
||||
$(RM) $(all_objs) $(progs) $(all_objs:%.o=%.d)
|
||||
|
||||
echo:
|
||||
@echo $(progs) $(local_srcs) $(all_objs) $(all_objs:%.o=%.d)
|
||||
|
||||
-include $(all_objs:%.o=%.d)
|
||||
978
qcom/opensource/fst-manager/external/common.c
vendored
Normal file
978
qcom/opensource/fst-manager/external/common.c
vendored
Normal file
@@ -0,0 +1,978 @@
|
||||
/*
|
||||
* wpa_supplicant/hostapd / common helper functions, etc.
|
||||
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
|
||||
static int hex2num(char c)
|
||||
{
|
||||
if (c >= '0' && c <= '9')
|
||||
return c - '0';
|
||||
if (c >= 'a' && c <= 'f')
|
||||
return c - 'a' + 10;
|
||||
if (c >= 'A' && c <= 'F')
|
||||
return c - 'A' + 10;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int hex2byte(const char *hex)
|
||||
{
|
||||
int a, b;
|
||||
a = hex2num(*hex++);
|
||||
if (a < 0)
|
||||
return -1;
|
||||
b = hex2num(*hex++);
|
||||
if (b < 0)
|
||||
return -1;
|
||||
return (a << 4) | b;
|
||||
}
|
||||
|
||||
|
||||
static const char * hwaddr_parse(const char *txt, u8 *addr)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
int a;
|
||||
|
||||
a = hex2byte(txt);
|
||||
if (a < 0)
|
||||
return NULL;
|
||||
txt += 2;
|
||||
addr[i] = a;
|
||||
if (i < ETH_ALEN - 1 && *txt++ != ':')
|
||||
return NULL;
|
||||
}
|
||||
return txt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hwaddr_aton - Convert ASCII string to MAC address (colon-delimited format)
|
||||
* @txt: MAC address as a string (e.g., "00:11:22:33:44:55")
|
||||
* @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
|
||||
* Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
|
||||
*/
|
||||
int hwaddr_aton(const char *txt, u8 *addr)
|
||||
{
|
||||
return hwaddr_parse(txt, addr) ? 0 : -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hwaddr_masked_aton - Convert ASCII string with optional mask to MAC address (colon-delimited format)
|
||||
* @txt: MAC address with optional mask as a string (e.g., "00:11:22:33:44:55/ff:ff:ff:ff:00:00")
|
||||
* @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
|
||||
* @mask: Buffer for the MAC address mask (ETH_ALEN = 6 bytes)
|
||||
* @maskable: Flag to indicate whether a mask is allowed
|
||||
* Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
|
||||
*/
|
||||
int hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable)
|
||||
{
|
||||
const char *r;
|
||||
|
||||
/* parse address part */
|
||||
r = hwaddr_parse(txt, addr);
|
||||
if (!r)
|
||||
return -1;
|
||||
|
||||
/* check for optional mask */
|
||||
if (*r == '\0' || isspace(*r)) {
|
||||
/* no mask specified, assume default */
|
||||
os_memset(mask, 0xff, ETH_ALEN);
|
||||
} else if (maskable && *r == '/') {
|
||||
/* mask specified and allowed */
|
||||
r = hwaddr_parse(r + 1, mask);
|
||||
/* parser error? */
|
||||
if (!r)
|
||||
return -1;
|
||||
} else {
|
||||
/* mask specified but not allowed or trailing garbage */
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hwaddr_compact_aton - Convert ASCII string to MAC address (no colon delimitors format)
|
||||
* @txt: MAC address as a string (e.g., "001122334455")
|
||||
* @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
|
||||
* Returns: 0 on success, -1 on failure (e.g., string not a MAC address)
|
||||
*/
|
||||
int hwaddr_compact_aton(const char *txt, u8 *addr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
int a, b;
|
||||
|
||||
a = hex2num(*txt++);
|
||||
if (a < 0)
|
||||
return -1;
|
||||
b = hex2num(*txt++);
|
||||
if (b < 0)
|
||||
return -1;
|
||||
*addr++ = (a << 4) | b;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
|
||||
* @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
|
||||
* @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
|
||||
* Returns: Characters used (> 0) on success, -1 on failure
|
||||
*/
|
||||
int hwaddr_aton2(const char *txt, u8 *addr)
|
||||
{
|
||||
int i;
|
||||
const char *pos = txt;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
int a, b;
|
||||
|
||||
while (*pos == ':' || *pos == '.' || *pos == '-')
|
||||
pos++;
|
||||
|
||||
a = hex2num(*pos++);
|
||||
if (a < 0)
|
||||
return -1;
|
||||
b = hex2num(*pos++);
|
||||
if (b < 0)
|
||||
return -1;
|
||||
*addr++ = (a << 4) | b;
|
||||
}
|
||||
|
||||
return pos - txt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* hexstr2bin - Convert ASCII hex string into binary data
|
||||
* @hex: ASCII hex string (e.g., "01ab")
|
||||
* @buf: Buffer for the binary data
|
||||
* @len: Length of the text to convert in bytes (of buf); hex will be double
|
||||
* this size
|
||||
* Returns: 0 on success, -1 on failure (invalid hex string)
|
||||
*/
|
||||
int hexstr2bin(const char *hex, u8 *buf, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
int a;
|
||||
const char *ipos = hex;
|
||||
u8 *opos = buf;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
a = hex2byte(ipos);
|
||||
if (a < 0)
|
||||
return -1;
|
||||
*opos++ = a;
|
||||
ipos += 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask)
|
||||
{
|
||||
size_t i;
|
||||
int print_mask = 0;
|
||||
int res;
|
||||
|
||||
for (i = 0; i < ETH_ALEN; i++) {
|
||||
if (mask[i] != 0xff) {
|
||||
print_mask = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (print_mask)
|
||||
res = os_snprintf(buf, len, MACSTR "/" MACSTR,
|
||||
MAC2STR(addr), MAC2STR(mask));
|
||||
else
|
||||
res = os_snprintf(buf, len, MACSTR, MAC2STR(addr));
|
||||
if (os_snprintf_error(len, res))
|
||||
return -1;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* inc_byte_array - Increment arbitrary length byte array by one
|
||||
* @counter: Pointer to byte array
|
||||
* @len: Length of the counter in bytes
|
||||
*
|
||||
* This function increments the last byte of the counter by one and continues
|
||||
* rolling over to more significant bytes if the byte was incremented from
|
||||
* 0xff to 0x00.
|
||||
*/
|
||||
void inc_byte_array(u8 *counter, size_t len)
|
||||
{
|
||||
int pos = len - 1;
|
||||
while (pos >= 0) {
|
||||
counter[pos]++;
|
||||
if (counter[pos] != 0)
|
||||
break;
|
||||
pos--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void wpa_get_ntp_timestamp(u8 *buf)
|
||||
{
|
||||
struct os_time now;
|
||||
u32 sec, usec;
|
||||
be32 tmp;
|
||||
|
||||
/* 64-bit NTP timestamp (time from 1900-01-01 00:00:00) */
|
||||
os_get_time(&now);
|
||||
sec = now.sec + 2208988800U; /* Epoch to 1900 */
|
||||
/* Estimate 2^32/10^6 = 4295 - 1/32 - 1/512 */
|
||||
usec = now.usec;
|
||||
usec = 4295 * usec - (usec >> 5) - (usec >> 9);
|
||||
tmp = host_to_be32(sec);
|
||||
os_memcpy(buf, (u8 *) &tmp, 4);
|
||||
tmp = host_to_be32(usec);
|
||||
os_memcpy(buf + 4, (u8 *) &tmp, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* wpa_scnprintf - Simpler-to-use snprintf function
|
||||
* @buf: Output buffer
|
||||
* @size: Buffer size
|
||||
* @fmt: format
|
||||
*
|
||||
* Simpler snprintf version that doesn't require further error checks - the
|
||||
* return value only indicates how many bytes were actually written, excluding
|
||||
* the NULL byte (i.e., 0 on error, size-1 if buffer is not big enough).
|
||||
*/
|
||||
int wpa_scnprintf(char *buf, size_t size, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
if (!size)
|
||||
return 0;
|
||||
|
||||
va_start(ap, fmt);
|
||||
ret = vsnprintf(buf, size, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
if ((size_t) ret >= size)
|
||||
return size - 1;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline int _wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data,
|
||||
size_t len, int uppercase)
|
||||
{
|
||||
size_t i;
|
||||
char *pos = buf, *end = buf + buf_size;
|
||||
int ret;
|
||||
if (buf_size == 0)
|
||||
return 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
ret = os_snprintf(pos, end - pos, uppercase ? "%02X" : "%02x",
|
||||
data[i]);
|
||||
if (os_snprintf_error(end - pos, ret)) {
|
||||
end[-1] = '\0';
|
||||
return pos - buf;
|
||||
}
|
||||
pos += ret;
|
||||
}
|
||||
end[-1] = '\0';
|
||||
return pos - buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* wpa_snprintf_hex - Print data as a hex string into a buffer
|
||||
* @buf: Memory area to use as the output buffer
|
||||
* @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
|
||||
* @data: Data to be printed
|
||||
* @len: Length of data in bytes
|
||||
* Returns: Number of bytes written
|
||||
*/
|
||||
int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len)
|
||||
{
|
||||
return _wpa_snprintf_hex(buf, buf_size, data, len, 0);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpa_snprintf_hex_uppercase - Print data as a upper case hex string into buf
|
||||
* @buf: Memory area to use as the output buffer
|
||||
* @buf_size: Maximum buffer size in bytes (should be at least 2 * len + 1)
|
||||
* @data: Data to be printed
|
||||
* @len: Length of data in bytes
|
||||
* Returns: Number of bytes written
|
||||
*/
|
||||
int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
|
||||
size_t len)
|
||||
{
|
||||
return _wpa_snprintf_hex(buf, buf_size, data, len, 1);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_ANSI_C_EXTRA
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
void perror(const char *s)
|
||||
{
|
||||
wpa_printf(MSG_ERROR, "%s: GetLastError: %d",
|
||||
s, (int) GetLastError());
|
||||
}
|
||||
#endif /* _WIN32_WCE */
|
||||
|
||||
|
||||
int optind = 1;
|
||||
int optopt;
|
||||
char *optarg;
|
||||
|
||||
int getopt(int argc, char *const argv[], const char *optstring)
|
||||
{
|
||||
static int optchr = 1;
|
||||
char *cp;
|
||||
|
||||
if (optchr == 1) {
|
||||
if (optind >= argc) {
|
||||
/* all arguments processed */
|
||||
return EOF;
|
||||
}
|
||||
|
||||
if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
|
||||
/* no option characters */
|
||||
return EOF;
|
||||
}
|
||||
}
|
||||
|
||||
if (os_strcmp(argv[optind], "--") == 0) {
|
||||
/* no more options */
|
||||
optind++;
|
||||
return EOF;
|
||||
}
|
||||
|
||||
optopt = argv[optind][optchr];
|
||||
cp = os_strchr(optstring, optopt);
|
||||
if (cp == NULL || optopt == ':') {
|
||||
if (argv[optind][++optchr] == '\0') {
|
||||
optchr = 1;
|
||||
optind++;
|
||||
}
|
||||
return '?';
|
||||
}
|
||||
|
||||
if (cp[1] == ':') {
|
||||
/* Argument required */
|
||||
optchr = 1;
|
||||
if (argv[optind][optchr + 1]) {
|
||||
/* No space between option and argument */
|
||||
optarg = &argv[optind++][optchr + 1];
|
||||
} else if (++optind >= argc) {
|
||||
/* option requires an argument */
|
||||
return '?';
|
||||
} else {
|
||||
/* Argument in the next argv */
|
||||
optarg = argv[optind++];
|
||||
}
|
||||
} else {
|
||||
/* No argument */
|
||||
if (argv[optind][++optchr] == '\0') {
|
||||
optchr = 1;
|
||||
optind++;
|
||||
}
|
||||
optarg = NULL;
|
||||
}
|
||||
return *cp;
|
||||
}
|
||||
#endif /* CONFIG_ANSI_C_EXTRA */
|
||||
|
||||
|
||||
#ifdef CONFIG_NATIVE_WINDOWS
|
||||
/**
|
||||
* wpa_unicode2ascii_inplace - Convert unicode string into ASCII
|
||||
* @str: Pointer to string to convert
|
||||
*
|
||||
* This function converts a unicode string to ASCII using the same
|
||||
* buffer for output. If UNICODE is not set, the buffer is not
|
||||
* modified.
|
||||
*/
|
||||
void wpa_unicode2ascii_inplace(TCHAR *str)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
char *dst = (char *) str;
|
||||
while (*str)
|
||||
*dst++ = (char) *str++;
|
||||
*dst = '\0';
|
||||
#endif /* UNICODE */
|
||||
}
|
||||
|
||||
|
||||
TCHAR * wpa_strdup_tchar(const char *str)
|
||||
{
|
||||
#ifdef UNICODE
|
||||
TCHAR *buf;
|
||||
buf = os_malloc((strlen(str) + 1) * sizeof(TCHAR));
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
wsprintf(buf, L"%S", str);
|
||||
return buf;
|
||||
#else /* UNICODE */
|
||||
return os_strdup(str);
|
||||
#endif /* UNICODE */
|
||||
}
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||
|
||||
|
||||
void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len)
|
||||
{
|
||||
char *end = txt + maxlen;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (txt + 4 >= end)
|
||||
break;
|
||||
|
||||
switch (data[i]) {
|
||||
case '\"':
|
||||
*txt++ = '\\';
|
||||
*txt++ = '\"';
|
||||
break;
|
||||
case '\\':
|
||||
*txt++ = '\\';
|
||||
*txt++ = '\\';
|
||||
break;
|
||||
case '\033':
|
||||
*txt++ = '\\';
|
||||
*txt++ = 'e';
|
||||
break;
|
||||
case '\n':
|
||||
*txt++ = '\\';
|
||||
*txt++ = 'n';
|
||||
break;
|
||||
case '\r':
|
||||
*txt++ = '\\';
|
||||
*txt++ = 'r';
|
||||
break;
|
||||
case '\t':
|
||||
*txt++ = '\\';
|
||||
*txt++ = 't';
|
||||
break;
|
||||
default:
|
||||
if (data[i] >= 32 && data[i] <= 127) {
|
||||
*txt++ = data[i];
|
||||
} else {
|
||||
txt += os_snprintf(txt, end - txt, "\\x%02x",
|
||||
data[i]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
*txt = '\0';
|
||||
}
|
||||
|
||||
|
||||
size_t printf_decode(u8 *buf, size_t maxlen, const char *str)
|
||||
{
|
||||
const char *pos = str;
|
||||
size_t len = 0;
|
||||
int val;
|
||||
|
||||
while (*pos) {
|
||||
if (len + 1 >= maxlen)
|
||||
break;
|
||||
switch (*pos) {
|
||||
case '\\':
|
||||
pos++;
|
||||
switch (*pos) {
|
||||
case '\\':
|
||||
buf[len++] = '\\';
|
||||
pos++;
|
||||
break;
|
||||
case '"':
|
||||
buf[len++] = '"';
|
||||
pos++;
|
||||
break;
|
||||
case 'n':
|
||||
buf[len++] = '\n';
|
||||
pos++;
|
||||
break;
|
||||
case 'r':
|
||||
buf[len++] = '\r';
|
||||
pos++;
|
||||
break;
|
||||
case 't':
|
||||
buf[len++] = '\t';
|
||||
pos++;
|
||||
break;
|
||||
case 'e':
|
||||
buf[len++] = '\033';
|
||||
pos++;
|
||||
break;
|
||||
case 'x':
|
||||
pos++;
|
||||
val = hex2byte(pos);
|
||||
if (val < 0) {
|
||||
val = hex2num(*pos);
|
||||
if (val < 0)
|
||||
break;
|
||||
buf[len++] = val;
|
||||
pos++;
|
||||
} else {
|
||||
buf[len++] = val;
|
||||
pos += 2;
|
||||
}
|
||||
break;
|
||||
case '0':
|
||||
case '1':
|
||||
case '2':
|
||||
case '3':
|
||||
case '4':
|
||||
case '5':
|
||||
case '6':
|
||||
case '7':
|
||||
val = *pos++ - '0';
|
||||
if (*pos >= '0' && *pos <= '7')
|
||||
val = val * 8 + (*pos++ - '0');
|
||||
if (*pos >= '0' && *pos <= '7')
|
||||
val = val * 8 + (*pos++ - '0');
|
||||
buf[len++] = val;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
buf[len++] = *pos++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (maxlen > len)
|
||||
buf[len] = '\0';
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ssid_txt - Convert SSID to a printable string
|
||||
* @ssid: SSID (32-octet string)
|
||||
* @ssid_len: Length of ssid in octets
|
||||
* Returns: Pointer to a printable string
|
||||
*
|
||||
* This function can be used to convert SSIDs into printable form. In most
|
||||
* cases, SSIDs do not use unprintable characters, but IEEE 802.11 standard
|
||||
* does not limit the used character set, so anything could be used in an SSID.
|
||||
*
|
||||
* This function uses a static buffer, so only one call can be used at the
|
||||
* time, i.e., this is not re-entrant and the returned buffer must be used
|
||||
* before calling this again.
|
||||
*/
|
||||
const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len)
|
||||
{
|
||||
static char ssid_txt[32 * 4 + 1];
|
||||
|
||||
if (ssid == NULL) {
|
||||
ssid_txt[0] = '\0';
|
||||
return ssid_txt;
|
||||
}
|
||||
|
||||
printf_encode(ssid_txt, sizeof(ssid_txt), ssid, ssid_len);
|
||||
return ssid_txt;
|
||||
}
|
||||
|
||||
|
||||
void * __hide_aliasing_typecast(void *foo)
|
||||
{
|
||||
return foo;
|
||||
}
|
||||
|
||||
|
||||
char * wpa_config_parse_string(const char *value, size_t *len)
|
||||
{
|
||||
if (*value == '"') {
|
||||
const char *pos;
|
||||
char *str;
|
||||
value++;
|
||||
pos = os_strrchr(value, '"');
|
||||
if (pos == NULL || pos[1] != '\0')
|
||||
return NULL;
|
||||
*len = pos - value;
|
||||
str = dup_binstr(value, *len);
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
return str;
|
||||
} else if (*value == 'P' && value[1] == '"') {
|
||||
const char *pos;
|
||||
char *tstr, *str;
|
||||
size_t tlen;
|
||||
value += 2;
|
||||
pos = os_strrchr(value, '"');
|
||||
if (pos == NULL || pos[1] != '\0')
|
||||
return NULL;
|
||||
tlen = pos - value;
|
||||
tstr = dup_binstr(value, tlen);
|
||||
if (tstr == NULL)
|
||||
return NULL;
|
||||
|
||||
str = os_malloc(tlen + 1);
|
||||
if (str == NULL) {
|
||||
os_free(tstr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*len = printf_decode((u8 *) str, tlen + 1, tstr);
|
||||
os_free(tstr);
|
||||
|
||||
return str;
|
||||
} else {
|
||||
u8 *str;
|
||||
size_t tlen, hlen = os_strlen(value);
|
||||
if (hlen & 1)
|
||||
return NULL;
|
||||
tlen = hlen / 2;
|
||||
str = os_malloc(tlen + 1);
|
||||
if (str == NULL)
|
||||
return NULL;
|
||||
if (hexstr2bin(value, str, tlen)) {
|
||||
os_free(str);
|
||||
return NULL;
|
||||
}
|
||||
str[tlen] = '\0';
|
||||
*len = tlen;
|
||||
return (char *) str;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int is_hex(const u8 *data, size_t len)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (data[i] < 32 || data[i] >= 127)
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
size_t merge_byte_arrays(u8 *res, size_t res_len,
|
||||
const u8 *src1, size_t src1_len,
|
||||
const u8 *src2, size_t src2_len)
|
||||
{
|
||||
size_t len = 0;
|
||||
|
||||
os_memset(res, 0, res_len);
|
||||
|
||||
if (src1) {
|
||||
if (src1_len >= res_len) {
|
||||
os_memcpy(res, src1, res_len);
|
||||
return res_len;
|
||||
}
|
||||
|
||||
os_memcpy(res, src1, src1_len);
|
||||
len += src1_len;
|
||||
}
|
||||
|
||||
if (src2) {
|
||||
if (len + src2_len >= res_len) {
|
||||
os_memcpy(res + len, src2, res_len - len);
|
||||
return res_len;
|
||||
}
|
||||
|
||||
os_memcpy(res + len, src2, src2_len);
|
||||
len += src2_len;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
|
||||
char * dup_binstr(const void *src, size_t len)
|
||||
{
|
||||
char *res;
|
||||
|
||||
if (src == NULL)
|
||||
return NULL;
|
||||
res = os_malloc(len + 1);
|
||||
if (res == NULL)
|
||||
return NULL;
|
||||
os_memcpy(res, src, len);
|
||||
res[len] = '\0';
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value)
|
||||
{
|
||||
struct wpa_freq_range *freq = NULL, *n;
|
||||
unsigned int count = 0;
|
||||
const char *pos, *pos2, *pos3;
|
||||
|
||||
/*
|
||||
* Comma separated list of frequency ranges.
|
||||
* For example: 2412-2432,2462,5000-6000
|
||||
*/
|
||||
pos = value;
|
||||
while (pos && pos[0]) {
|
||||
n = os_realloc_array(freq, count + 1,
|
||||
sizeof(struct wpa_freq_range));
|
||||
if (n == NULL) {
|
||||
os_free(freq);
|
||||
return -1;
|
||||
}
|
||||
freq = n;
|
||||
freq[count].min = atoi(pos);
|
||||
pos2 = os_strchr(pos, '-');
|
||||
pos3 = os_strchr(pos, ',');
|
||||
if (pos2 && (!pos3 || pos2 < pos3)) {
|
||||
pos2++;
|
||||
freq[count].max = atoi(pos2);
|
||||
} else
|
||||
freq[count].max = freq[count].min;
|
||||
pos = pos3;
|
||||
if (pos)
|
||||
pos++;
|
||||
count++;
|
||||
}
|
||||
|
||||
os_free(res->range);
|
||||
res->range = freq;
|
||||
res->num = count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int freq_range_list_includes(const struct wpa_freq_range_list *list,
|
||||
unsigned int freq)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
if (list == NULL)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < list->num; i++) {
|
||||
if (freq >= list->range[i].min && freq <= list->range[i].max)
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char * freq_range_list_str(const struct wpa_freq_range_list *list)
|
||||
{
|
||||
char *buf, *pos, *end;
|
||||
size_t maxlen;
|
||||
unsigned int i;
|
||||
int res;
|
||||
|
||||
if (list->num == 0)
|
||||
return NULL;
|
||||
|
||||
maxlen = list->num * 30;
|
||||
buf = os_malloc(maxlen);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
pos = buf;
|
||||
end = buf + maxlen;
|
||||
|
||||
for (i = 0; i < list->num; i++) {
|
||||
struct wpa_freq_range *range = &list->range[i];
|
||||
|
||||
if (range->min == range->max)
|
||||
res = os_snprintf(pos, end - pos, "%s%u",
|
||||
i == 0 ? "" : ",", range->min);
|
||||
else
|
||||
res = os_snprintf(pos, end - pos, "%s%u-%u",
|
||||
i == 0 ? "" : ",",
|
||||
range->min, range->max);
|
||||
if (os_snprintf_error(end - pos, res)) {
|
||||
os_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
pos += res;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
int int_array_len(const int *a)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; a && a[i]; i++)
|
||||
;
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
void int_array_concat(int **res, const int *a)
|
||||
{
|
||||
int reslen, alen, i;
|
||||
int *n;
|
||||
|
||||
reslen = int_array_len(*res);
|
||||
alen = int_array_len(a);
|
||||
|
||||
n = os_realloc_array(*res, reslen + alen + 1, sizeof(int));
|
||||
if (n == NULL) {
|
||||
os_free(*res);
|
||||
*res = NULL;
|
||||
return;
|
||||
}
|
||||
for (i = 0; i <= alen; i++)
|
||||
n[reslen + i] = a[i];
|
||||
*res = n;
|
||||
}
|
||||
|
||||
|
||||
static int freq_cmp(const void *a, const void *b)
|
||||
{
|
||||
int _a = *(int *) a;
|
||||
int _b = *(int *) b;
|
||||
|
||||
if (_a == 0)
|
||||
return 1;
|
||||
if (_b == 0)
|
||||
return -1;
|
||||
return _a - _b;
|
||||
}
|
||||
|
||||
|
||||
void int_array_sort_unique(int *a)
|
||||
{
|
||||
int alen;
|
||||
int i, j;
|
||||
|
||||
if (a == NULL)
|
||||
return;
|
||||
|
||||
alen = int_array_len(a);
|
||||
qsort(a, alen, sizeof(int), freq_cmp);
|
||||
|
||||
i = 0;
|
||||
j = 1;
|
||||
while (a[i] && a[j]) {
|
||||
if (a[i] == a[j]) {
|
||||
j++;
|
||||
continue;
|
||||
}
|
||||
a[++i] = a[j++];
|
||||
}
|
||||
if (a[i])
|
||||
i++;
|
||||
a[i] = 0;
|
||||
}
|
||||
|
||||
|
||||
void int_array_add_unique(int **res, int a)
|
||||
{
|
||||
int reslen;
|
||||
int *n;
|
||||
|
||||
for (reslen = 0; *res && (*res)[reslen]; reslen++) {
|
||||
if ((*res)[reslen] == a)
|
||||
return; /* already in the list */
|
||||
}
|
||||
|
||||
n = os_realloc_array(*res, reslen + 2, sizeof(int));
|
||||
if (n == NULL) {
|
||||
os_free(*res);
|
||||
*res = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
n[reslen] = a;
|
||||
n[reslen + 1] = 0;
|
||||
|
||||
*res = n;
|
||||
}
|
||||
|
||||
|
||||
void str_clear_free(char *str)
|
||||
{
|
||||
if (str) {
|
||||
size_t len = os_strlen(str);
|
||||
os_memset(str, 0, len);
|
||||
os_free(str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void bin_clear_free(void *bin, size_t len)
|
||||
{
|
||||
if (bin) {
|
||||
os_memset(bin, 0, len);
|
||||
os_free(bin);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int random_mac_addr(u8 *addr)
|
||||
{
|
||||
if (os_get_random(addr, ETH_ALEN) < 0)
|
||||
return -1;
|
||||
addr[0] &= 0xfe; /* unicast */
|
||||
addr[0] |= 0x02; /* locally administered */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int random_mac_addr_keep_oui(u8 *addr)
|
||||
{
|
||||
if (os_get_random(addr + 3, 3) < 0)
|
||||
return -1;
|
||||
addr[0] &= 0xfe; /* unicast */
|
||||
addr[0] |= 0x02; /* locally administered */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* str_token - Get next token from a string
|
||||
* @buf: String to tokenize. Note that the string might be modified.
|
||||
* @delim: String of delimiters
|
||||
* @context: Pointer to save our context. Should be initialized with
|
||||
* NULL on the first call, and passed for any further call.
|
||||
* Returns: The next token, NULL if there are no more valid tokens.
|
||||
*/
|
||||
char * str_token(char *str, const char *delim, char **context)
|
||||
{
|
||||
char *end, *pos = str;
|
||||
|
||||
if (*context)
|
||||
pos = *context;
|
||||
|
||||
while (*pos && os_strchr(delim, *pos))
|
||||
pos++;
|
||||
if (!*pos)
|
||||
return NULL;
|
||||
|
||||
end = pos + 1;
|
||||
while (*end && !os_strchr(delim, *end))
|
||||
end++;
|
||||
|
||||
if (*end)
|
||||
*end++ = '\0';
|
||||
|
||||
*context = end;
|
||||
return pos;
|
||||
}
|
||||
329
qcom/opensource/fst-manager/external/common/defs.h
vendored
Normal file
329
qcom/opensource/fst-manager/external/common/defs.h
vendored
Normal file
@@ -0,0 +1,329 @@
|
||||
/*
|
||||
* WPA Supplicant - Common definitions
|
||||
* Copyright (c) 2004-2015, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef DEFS_H
|
||||
#define DEFS_H
|
||||
|
||||
#ifdef FALSE
|
||||
#undef FALSE
|
||||
#endif
|
||||
#ifdef TRUE
|
||||
#undef TRUE
|
||||
#endif
|
||||
typedef enum { FALSE = 0, TRUE = 1 } Boolean;
|
||||
|
||||
|
||||
#define WPA_CIPHER_NONE BIT(0)
|
||||
#define WPA_CIPHER_WEP40 BIT(1)
|
||||
#define WPA_CIPHER_WEP104 BIT(2)
|
||||
#define WPA_CIPHER_TKIP BIT(3)
|
||||
#define WPA_CIPHER_CCMP BIT(4)
|
||||
#define WPA_CIPHER_AES_128_CMAC BIT(5)
|
||||
#define WPA_CIPHER_GCMP BIT(6)
|
||||
#define WPA_CIPHER_SMS4 BIT(7)
|
||||
#define WPA_CIPHER_GCMP_256 BIT(8)
|
||||
#define WPA_CIPHER_CCMP_256 BIT(9)
|
||||
#define WPA_CIPHER_BIP_GMAC_128 BIT(11)
|
||||
#define WPA_CIPHER_BIP_GMAC_256 BIT(12)
|
||||
#define WPA_CIPHER_BIP_CMAC_256 BIT(13)
|
||||
#define WPA_CIPHER_GTK_NOT_USED BIT(14)
|
||||
|
||||
#define WPA_KEY_MGMT_IEEE8021X BIT(0)
|
||||
#define WPA_KEY_MGMT_PSK BIT(1)
|
||||
#define WPA_KEY_MGMT_NONE BIT(2)
|
||||
#define WPA_KEY_MGMT_IEEE8021X_NO_WPA BIT(3)
|
||||
#define WPA_KEY_MGMT_WPA_NONE BIT(4)
|
||||
#define WPA_KEY_MGMT_FT_IEEE8021X BIT(5)
|
||||
#define WPA_KEY_MGMT_FT_PSK BIT(6)
|
||||
#define WPA_KEY_MGMT_IEEE8021X_SHA256 BIT(7)
|
||||
#define WPA_KEY_MGMT_PSK_SHA256 BIT(8)
|
||||
#define WPA_KEY_MGMT_WPS BIT(9)
|
||||
#define WPA_KEY_MGMT_SAE BIT(10)
|
||||
#define WPA_KEY_MGMT_FT_SAE BIT(11)
|
||||
#define WPA_KEY_MGMT_WAPI_PSK BIT(12)
|
||||
#define WPA_KEY_MGMT_WAPI_CERT BIT(13)
|
||||
#define WPA_KEY_MGMT_CCKM BIT(14)
|
||||
#define WPA_KEY_MGMT_OSEN BIT(15)
|
||||
#define WPA_KEY_MGMT_IEEE8021X_SUITE_B BIT(16)
|
||||
#define WPA_KEY_MGMT_IEEE8021X_SUITE_B_192 BIT(17)
|
||||
|
||||
static inline int wpa_key_mgmt_wpa_ieee8021x(int akm)
|
||||
{
|
||||
return !!(akm & (WPA_KEY_MGMT_IEEE8021X |
|
||||
WPA_KEY_MGMT_FT_IEEE8021X |
|
||||
WPA_KEY_MGMT_CCKM |
|
||||
WPA_KEY_MGMT_OSEN |
|
||||
WPA_KEY_MGMT_IEEE8021X_SHA256 |
|
||||
WPA_KEY_MGMT_IEEE8021X_SUITE_B |
|
||||
WPA_KEY_MGMT_IEEE8021X_SUITE_B_192));
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_wpa_psk(int akm)
|
||||
{
|
||||
return !!(akm & (WPA_KEY_MGMT_PSK |
|
||||
WPA_KEY_MGMT_FT_PSK |
|
||||
WPA_KEY_MGMT_PSK_SHA256 |
|
||||
WPA_KEY_MGMT_SAE |
|
||||
WPA_KEY_MGMT_FT_SAE));
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_ft(int akm)
|
||||
{
|
||||
return !!(akm & (WPA_KEY_MGMT_FT_PSK |
|
||||
WPA_KEY_MGMT_FT_IEEE8021X |
|
||||
WPA_KEY_MGMT_FT_SAE));
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_sae(int akm)
|
||||
{
|
||||
return !!(akm & (WPA_KEY_MGMT_SAE |
|
||||
WPA_KEY_MGMT_FT_SAE));
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_sha256(int akm)
|
||||
{
|
||||
return !!(akm & (WPA_KEY_MGMT_PSK_SHA256 |
|
||||
WPA_KEY_MGMT_IEEE8021X_SHA256 |
|
||||
WPA_KEY_MGMT_OSEN |
|
||||
WPA_KEY_MGMT_IEEE8021X_SUITE_B));
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_sha384(int akm)
|
||||
{
|
||||
return !!(akm & WPA_KEY_MGMT_IEEE8021X_SUITE_B_192);
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_suite_b(int akm)
|
||||
{
|
||||
return !!(akm & (WPA_KEY_MGMT_IEEE8021X_SUITE_B |
|
||||
WPA_KEY_MGMT_IEEE8021X_SUITE_B_192));
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_wpa(int akm)
|
||||
{
|
||||
return wpa_key_mgmt_wpa_ieee8021x(akm) ||
|
||||
wpa_key_mgmt_wpa_psk(akm) ||
|
||||
wpa_key_mgmt_sae(akm);
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_wpa_any(int akm)
|
||||
{
|
||||
return wpa_key_mgmt_wpa(akm) || (akm & WPA_KEY_MGMT_WPA_NONE);
|
||||
}
|
||||
|
||||
static inline int wpa_key_mgmt_cckm(int akm)
|
||||
{
|
||||
return akm == WPA_KEY_MGMT_CCKM;
|
||||
}
|
||||
|
||||
|
||||
#define WPA_PROTO_WPA BIT(0)
|
||||
#define WPA_PROTO_RSN BIT(1)
|
||||
#define WPA_PROTO_WAPI BIT(2)
|
||||
#define WPA_PROTO_OSEN BIT(3)
|
||||
|
||||
#define WPA_AUTH_ALG_OPEN BIT(0)
|
||||
#define WPA_AUTH_ALG_SHARED BIT(1)
|
||||
#define WPA_AUTH_ALG_LEAP BIT(2)
|
||||
#define WPA_AUTH_ALG_FT BIT(3)
|
||||
#define WPA_AUTH_ALG_SAE BIT(4)
|
||||
|
||||
|
||||
enum wpa_alg {
|
||||
WPA_ALG_NONE,
|
||||
WPA_ALG_WEP,
|
||||
WPA_ALG_TKIP,
|
||||
WPA_ALG_CCMP,
|
||||
WPA_ALG_IGTK,
|
||||
WPA_ALG_PMK,
|
||||
WPA_ALG_GCMP,
|
||||
WPA_ALG_SMS4,
|
||||
WPA_ALG_KRK,
|
||||
WPA_ALG_GCMP_256,
|
||||
WPA_ALG_CCMP_256,
|
||||
WPA_ALG_BIP_GMAC_128,
|
||||
WPA_ALG_BIP_GMAC_256,
|
||||
WPA_ALG_BIP_CMAC_256
|
||||
};
|
||||
|
||||
/**
|
||||
* enum wpa_states - wpa_supplicant state
|
||||
*
|
||||
* These enumeration values are used to indicate the current wpa_supplicant
|
||||
* state (wpa_s->wpa_state). The current state can be retrieved with
|
||||
* wpa_supplicant_get_state() function and the state can be changed by calling
|
||||
* wpa_supplicant_set_state(). In WPA state machine (wpa.c and preauth.c), the
|
||||
* wrapper functions wpa_sm_get_state() and wpa_sm_set_state() should be used
|
||||
* to access the state variable.
|
||||
*/
|
||||
enum wpa_states {
|
||||
/**
|
||||
* WPA_DISCONNECTED - Disconnected state
|
||||
*
|
||||
* This state indicates that client is not associated, but is likely to
|
||||
* start looking for an access point. This state is entered when a
|
||||
* connection is lost.
|
||||
*/
|
||||
WPA_DISCONNECTED,
|
||||
|
||||
/**
|
||||
* WPA_INTERFACE_DISABLED - Interface disabled
|
||||
*
|
||||
* This stat eis entered if the network interface is disabled, e.g.,
|
||||
* due to rfkill. wpa_supplicant refuses any new operations that would
|
||||
* use the radio until the interface has been enabled.
|
||||
*/
|
||||
WPA_INTERFACE_DISABLED,
|
||||
|
||||
/**
|
||||
* WPA_INACTIVE - Inactive state (wpa_supplicant disabled)
|
||||
*
|
||||
* This state is entered if there are no enabled networks in the
|
||||
* configuration. wpa_supplicant is not trying to associate with a new
|
||||
* network and external interaction (e.g., ctrl_iface call to add or
|
||||
* enable a network) is needed to start association.
|
||||
*/
|
||||
WPA_INACTIVE,
|
||||
|
||||
/**
|
||||
* WPA_SCANNING - Scanning for a network
|
||||
*
|
||||
* This state is entered when wpa_supplicant starts scanning for a
|
||||
* network.
|
||||
*/
|
||||
WPA_SCANNING,
|
||||
|
||||
/**
|
||||
* WPA_AUTHENTICATING - Trying to authenticate with a BSS/SSID
|
||||
*
|
||||
* This state is entered when wpa_supplicant has found a suitable BSS
|
||||
* to authenticate with and the driver is configured to try to
|
||||
* authenticate with this BSS. This state is used only with drivers
|
||||
* that use wpa_supplicant as the SME.
|
||||
*/
|
||||
WPA_AUTHENTICATING,
|
||||
|
||||
/**
|
||||
* WPA_ASSOCIATING - Trying to associate with a BSS/SSID
|
||||
*
|
||||
* This state is entered when wpa_supplicant has found a suitable BSS
|
||||
* to associate with and the driver is configured to try to associate
|
||||
* with this BSS in ap_scan=1 mode. When using ap_scan=2 mode, this
|
||||
* state is entered when the driver is configured to try to associate
|
||||
* with a network using the configured SSID and security policy.
|
||||
*/
|
||||
WPA_ASSOCIATING,
|
||||
|
||||
/**
|
||||
* WPA_ASSOCIATED - Association completed
|
||||
*
|
||||
* This state is entered when the driver reports that association has
|
||||
* been successfully completed with an AP. If IEEE 802.1X is used
|
||||
* (with or without WPA/WPA2), wpa_supplicant remains in this state
|
||||
* until the IEEE 802.1X/EAPOL authentication has been completed.
|
||||
*/
|
||||
WPA_ASSOCIATED,
|
||||
|
||||
/**
|
||||
* WPA_4WAY_HANDSHAKE - WPA 4-Way Key Handshake in progress
|
||||
*
|
||||
* This state is entered when WPA/WPA2 4-Way Handshake is started. In
|
||||
* case of WPA-PSK, this happens when receiving the first EAPOL-Key
|
||||
* frame after association. In case of WPA-EAP, this state is entered
|
||||
* when the IEEE 802.1X/EAPOL authentication has been completed.
|
||||
*/
|
||||
WPA_4WAY_HANDSHAKE,
|
||||
|
||||
/**
|
||||
* WPA_GROUP_HANDSHAKE - WPA Group Key Handshake in progress
|
||||
*
|
||||
* This state is entered when 4-Way Key Handshake has been completed
|
||||
* (i.e., when the supplicant sends out message 4/4) and when Group
|
||||
* Key rekeying is started by the AP (i.e., when supplicant receives
|
||||
* message 1/2).
|
||||
*/
|
||||
WPA_GROUP_HANDSHAKE,
|
||||
|
||||
/**
|
||||
* WPA_COMPLETED - All authentication completed
|
||||
*
|
||||
* This state is entered when the full authentication process is
|
||||
* completed. In case of WPA2, this happens when the 4-Way Handshake is
|
||||
* successfully completed. With WPA, this state is entered after the
|
||||
* Group Key Handshake; with IEEE 802.1X (non-WPA) connection is
|
||||
* completed after dynamic keys are received (or if not used, after
|
||||
* the EAP authentication has been completed). With static WEP keys and
|
||||
* plaintext connections, this state is entered when an association
|
||||
* has been completed.
|
||||
*
|
||||
* This state indicates that the supplicant has completed its
|
||||
* processing for the association phase and that data connection is
|
||||
* fully configured.
|
||||
*/
|
||||
WPA_COMPLETED
|
||||
};
|
||||
|
||||
#define MLME_SETPROTECTION_PROTECT_TYPE_NONE 0
|
||||
#define MLME_SETPROTECTION_PROTECT_TYPE_RX 1
|
||||
#define MLME_SETPROTECTION_PROTECT_TYPE_TX 2
|
||||
#define MLME_SETPROTECTION_PROTECT_TYPE_RX_TX 3
|
||||
|
||||
#define MLME_SETPROTECTION_KEY_TYPE_GROUP 0
|
||||
#define MLME_SETPROTECTION_KEY_TYPE_PAIRWISE 1
|
||||
|
||||
|
||||
/**
|
||||
* enum mfp_options - Management frame protection (IEEE 802.11w) options
|
||||
*/
|
||||
enum mfp_options {
|
||||
NO_MGMT_FRAME_PROTECTION = 0,
|
||||
MGMT_FRAME_PROTECTION_OPTIONAL = 1,
|
||||
MGMT_FRAME_PROTECTION_REQUIRED = 2,
|
||||
};
|
||||
#define MGMT_FRAME_PROTECTION_DEFAULT 3
|
||||
|
||||
/**
|
||||
* enum hostapd_hw_mode - Hardware mode
|
||||
*/
|
||||
enum hostapd_hw_mode {
|
||||
HOSTAPD_MODE_IEEE80211B,
|
||||
HOSTAPD_MODE_IEEE80211G,
|
||||
HOSTAPD_MODE_IEEE80211A,
|
||||
HOSTAPD_MODE_IEEE80211AD,
|
||||
NUM_HOSTAPD_MODES
|
||||
};
|
||||
|
||||
/**
|
||||
* enum wpa_ctrl_req_type - Control interface request types
|
||||
*/
|
||||
enum wpa_ctrl_req_type {
|
||||
WPA_CTRL_REQ_UNKNOWN,
|
||||
WPA_CTRL_REQ_EAP_IDENTITY,
|
||||
WPA_CTRL_REQ_EAP_PASSWORD,
|
||||
WPA_CTRL_REQ_EAP_NEW_PASSWORD,
|
||||
WPA_CTRL_REQ_EAP_PIN,
|
||||
WPA_CTRL_REQ_EAP_OTP,
|
||||
WPA_CTRL_REQ_EAP_PASSPHRASE,
|
||||
WPA_CTRL_REQ_SIM,
|
||||
NUM_WPA_CTRL_REQS
|
||||
};
|
||||
|
||||
/* Maximum number of EAP methods to store for EAP server user information */
|
||||
#define EAP_MAX_METHODS 8
|
||||
|
||||
enum mesh_plink_state {
|
||||
PLINK_LISTEN = 1,
|
||||
PLINK_OPEN_SENT,
|
||||
PLINK_OPEN_RCVD,
|
||||
PLINK_CNF_RCVD,
|
||||
PLINK_ESTAB,
|
||||
PLINK_HOLDING,
|
||||
PLINK_BLOCKED,
|
||||
};
|
||||
|
||||
#endif /* DEFS_H */
|
||||
1437
qcom/opensource/fst-manager/external/common/ieee802_11_defs.h
vendored
Normal file
1437
qcom/opensource/fst-manager/external/common/ieee802_11_defs.h
vendored
Normal file
File diff suppressed because it is too large
Load Diff
442
qcom/opensource/fst-manager/external/common/wpa_ctrl.h
vendored
Normal file
442
qcom/opensource/fst-manager/external/common/wpa_ctrl.h
vendored
Normal file
@@ -0,0 +1,442 @@
|
||||
/*
|
||||
* wpa_supplicant/hostapd control interface library
|
||||
* Copyright (c) 2004-2006, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef WPA_CTRL_H
|
||||
#define WPA_CTRL_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* wpa_supplicant control interface - fixed message prefixes */
|
||||
|
||||
/** Interactive request for identity/password/pin */
|
||||
#define WPA_CTRL_REQ "CTRL-REQ-"
|
||||
|
||||
/** Response to identity/password/pin request */
|
||||
#define WPA_CTRL_RSP "CTRL-RSP-"
|
||||
|
||||
/* Event messages with fixed prefix */
|
||||
/** Authentication completed successfully and data connection enabled */
|
||||
#define WPA_EVENT_CONNECTED "CTRL-EVENT-CONNECTED "
|
||||
/** Disconnected, data connection is not available */
|
||||
#define WPA_EVENT_DISCONNECTED "CTRL-EVENT-DISCONNECTED "
|
||||
/** Association rejected during connection attempt */
|
||||
#define WPA_EVENT_ASSOC_REJECT "CTRL-EVENT-ASSOC-REJECT "
|
||||
/** wpa_supplicant is exiting */
|
||||
#define WPA_EVENT_TERMINATING "CTRL-EVENT-TERMINATING "
|
||||
/** Password change was completed successfully */
|
||||
#define WPA_EVENT_PASSWORD_CHANGED "CTRL-EVENT-PASSWORD-CHANGED "
|
||||
/** EAP-Request/Notification received */
|
||||
#define WPA_EVENT_EAP_NOTIFICATION "CTRL-EVENT-EAP-NOTIFICATION "
|
||||
/** EAP authentication started (EAP-Request/Identity received) */
|
||||
#define WPA_EVENT_EAP_STARTED "CTRL-EVENT-EAP-STARTED "
|
||||
/** EAP method proposed by the server */
|
||||
#define WPA_EVENT_EAP_PROPOSED_METHOD "CTRL-EVENT-EAP-PROPOSED-METHOD "
|
||||
/** EAP method selected */
|
||||
#define WPA_EVENT_EAP_METHOD "CTRL-EVENT-EAP-METHOD "
|
||||
/** EAP peer certificate from TLS */
|
||||
#define WPA_EVENT_EAP_PEER_CERT "CTRL-EVENT-EAP-PEER-CERT "
|
||||
/** EAP peer certificate alternative subject name component from TLS */
|
||||
#define WPA_EVENT_EAP_PEER_ALT "CTRL-EVENT-EAP-PEER-ALT "
|
||||
/** EAP TLS certificate chain validation error */
|
||||
#define WPA_EVENT_EAP_TLS_CERT_ERROR "CTRL-EVENT-EAP-TLS-CERT-ERROR "
|
||||
/** EAP status */
|
||||
#define WPA_EVENT_EAP_STATUS "CTRL-EVENT-EAP-STATUS "
|
||||
/** EAP authentication completed successfully */
|
||||
#define WPA_EVENT_EAP_SUCCESS "CTRL-EVENT-EAP-SUCCESS "
|
||||
/** EAP authentication failed (EAP-Failure received) */
|
||||
#define WPA_EVENT_EAP_FAILURE "CTRL-EVENT-EAP-FAILURE "
|
||||
/** Network block temporarily disabled (e.g., due to authentication failure) */
|
||||
#define WPA_EVENT_TEMP_DISABLED "CTRL-EVENT-SSID-TEMP-DISABLED "
|
||||
/** Temporarily disabled network block re-enabled */
|
||||
#define WPA_EVENT_REENABLED "CTRL-EVENT-SSID-REENABLED "
|
||||
/** New scan started */
|
||||
#define WPA_EVENT_SCAN_STARTED "CTRL-EVENT-SCAN-STARTED "
|
||||
/** New scan results available */
|
||||
#define WPA_EVENT_SCAN_RESULTS "CTRL-EVENT-SCAN-RESULTS "
|
||||
/** Scan command failed */
|
||||
#define WPA_EVENT_SCAN_FAILED "CTRL-EVENT-SCAN-FAILED "
|
||||
/** wpa_supplicant state change */
|
||||
#define WPA_EVENT_STATE_CHANGE "CTRL-EVENT-STATE-CHANGE "
|
||||
/** A new BSS entry was added (followed by BSS entry id and BSSID) */
|
||||
#define WPA_EVENT_BSS_ADDED "CTRL-EVENT-BSS-ADDED "
|
||||
/** A BSS entry was removed (followed by BSS entry id and BSSID) */
|
||||
#define WPA_EVENT_BSS_REMOVED "CTRL-EVENT-BSS-REMOVED "
|
||||
/** Change in the signal level was reported by the driver */
|
||||
#define WPA_EVENT_SIGNAL_CHANGE "CTRL-EVENT-SIGNAL-CHANGE "
|
||||
/** Regulatory domain channel */
|
||||
#define WPA_EVENT_REGDOM_CHANGE "CTRL-EVENT-REGDOM-CHANGE "
|
||||
|
||||
/** RSN IBSS 4-way handshakes completed with specified peer */
|
||||
#define IBSS_RSN_COMPLETED "IBSS-RSN-COMPLETED "
|
||||
|
||||
/** Notification of frequency conflict due to a concurrent operation.
|
||||
*
|
||||
* The indicated network is disabled and needs to be re-enabled before it can
|
||||
* be used again.
|
||||
*/
|
||||
#define WPA_EVENT_FREQ_CONFLICT "CTRL-EVENT-FREQ-CONFLICT "
|
||||
/** Frequency ranges that the driver recommends to avoid */
|
||||
#define WPA_EVENT_AVOID_FREQ "CTRL-EVENT-AVOID-FREQ "
|
||||
/** WPS overlap detected in PBC mode */
|
||||
#define WPS_EVENT_OVERLAP "WPS-OVERLAP-DETECTED "
|
||||
/** Available WPS AP with active PBC found in scan results */
|
||||
#define WPS_EVENT_AP_AVAILABLE_PBC "WPS-AP-AVAILABLE-PBC "
|
||||
/** Available WPS AP with our address as authorized in scan results */
|
||||
#define WPS_EVENT_AP_AVAILABLE_AUTH "WPS-AP-AVAILABLE-AUTH "
|
||||
/** Available WPS AP with recently selected PIN registrar found in scan results
|
||||
*/
|
||||
#define WPS_EVENT_AP_AVAILABLE_PIN "WPS-AP-AVAILABLE-PIN "
|
||||
/** Available WPS AP found in scan results */
|
||||
#define WPS_EVENT_AP_AVAILABLE "WPS-AP-AVAILABLE "
|
||||
/** A new credential received */
|
||||
#define WPS_EVENT_CRED_RECEIVED "WPS-CRED-RECEIVED "
|
||||
/** M2D received */
|
||||
#define WPS_EVENT_M2D "WPS-M2D "
|
||||
/** WPS registration failed after M2/M2D */
|
||||
#define WPS_EVENT_FAIL "WPS-FAIL "
|
||||
/** WPS registration completed successfully */
|
||||
#define WPS_EVENT_SUCCESS "WPS-SUCCESS "
|
||||
/** WPS enrollment attempt timed out and was terminated */
|
||||
#define WPS_EVENT_TIMEOUT "WPS-TIMEOUT "
|
||||
/* PBC mode was activated */
|
||||
#define WPS_EVENT_ACTIVE "WPS-PBC-ACTIVE "
|
||||
/* PBC mode was disabled */
|
||||
#define WPS_EVENT_DISABLE "WPS-PBC-DISABLE "
|
||||
|
||||
#define WPS_EVENT_ENROLLEE_SEEN "WPS-ENROLLEE-SEEN "
|
||||
|
||||
#define WPS_EVENT_OPEN_NETWORK "WPS-OPEN-NETWORK "
|
||||
|
||||
/* WPS ER events */
|
||||
#define WPS_EVENT_ER_AP_ADD "WPS-ER-AP-ADD "
|
||||
#define WPS_EVENT_ER_AP_REMOVE "WPS-ER-AP-REMOVE "
|
||||
#define WPS_EVENT_ER_ENROLLEE_ADD "WPS-ER-ENROLLEE-ADD "
|
||||
#define WPS_EVENT_ER_ENROLLEE_REMOVE "WPS-ER-ENROLLEE-REMOVE "
|
||||
#define WPS_EVENT_ER_AP_SETTINGS "WPS-ER-AP-SETTINGS "
|
||||
#define WPS_EVENT_ER_SET_SEL_REG "WPS-ER-AP-SET-SEL-REG "
|
||||
|
||||
/* MESH events */
|
||||
#define MESH_GROUP_STARTED "MESH-GROUP-STARTED "
|
||||
#define MESH_GROUP_REMOVED "MESH-GROUP-REMOVED "
|
||||
#define MESH_PEER_CONNECTED "MESH-PEER-CONNECTED "
|
||||
#define MESH_PEER_DISCONNECTED "MESH-PEER-DISCONNECTED "
|
||||
|
||||
/* WMM AC events */
|
||||
#define WMM_AC_EVENT_TSPEC_ADDED "TSPEC-ADDED "
|
||||
#define WMM_AC_EVENT_TSPEC_REMOVED "TSPEC-REMOVED "
|
||||
#define WMM_AC_EVENT_TSPEC_REQ_FAILED "TSPEC-REQ-FAILED "
|
||||
|
||||
/** P2P device found */
|
||||
#define P2P_EVENT_DEVICE_FOUND "P2P-DEVICE-FOUND "
|
||||
|
||||
/** P2P device lost */
|
||||
#define P2P_EVENT_DEVICE_LOST "P2P-DEVICE-LOST "
|
||||
|
||||
/** A P2P device requested GO negotiation, but we were not ready to start the
|
||||
* negotiation */
|
||||
#define P2P_EVENT_GO_NEG_REQUEST "P2P-GO-NEG-REQUEST "
|
||||
#define P2P_EVENT_GO_NEG_SUCCESS "P2P-GO-NEG-SUCCESS "
|
||||
#define P2P_EVENT_GO_NEG_FAILURE "P2P-GO-NEG-FAILURE "
|
||||
#define P2P_EVENT_GROUP_FORMATION_SUCCESS "P2P-GROUP-FORMATION-SUCCESS "
|
||||
#define P2P_EVENT_GROUP_FORMATION_FAILURE "P2P-GROUP-FORMATION-FAILURE "
|
||||
#define P2P_EVENT_GROUP_STARTED "P2P-GROUP-STARTED "
|
||||
#define P2P_EVENT_GROUP_REMOVED "P2P-GROUP-REMOVED "
|
||||
#define P2P_EVENT_CROSS_CONNECT_ENABLE "P2P-CROSS-CONNECT-ENABLE "
|
||||
#define P2P_EVENT_CROSS_CONNECT_DISABLE "P2P-CROSS-CONNECT-DISABLE "
|
||||
/* parameters: <peer address> <PIN> */
|
||||
#define P2P_EVENT_PROV_DISC_SHOW_PIN "P2P-PROV-DISC-SHOW-PIN "
|
||||
/* parameters: <peer address> */
|
||||
#define P2P_EVENT_PROV_DISC_ENTER_PIN "P2P-PROV-DISC-ENTER-PIN "
|
||||
/* parameters: <peer address> */
|
||||
#define P2P_EVENT_PROV_DISC_PBC_REQ "P2P-PROV-DISC-PBC-REQ "
|
||||
/* parameters: <peer address> */
|
||||
#define P2P_EVENT_PROV_DISC_PBC_RESP "P2P-PROV-DISC-PBC-RESP "
|
||||
/* parameters: <peer address> <status> */
|
||||
#define P2P_EVENT_PROV_DISC_FAILURE "P2P-PROV-DISC-FAILURE"
|
||||
/* parameters: <freq> <src addr> <dialog token> <update indicator> <TLVs> */
|
||||
#define P2P_EVENT_SERV_DISC_REQ "P2P-SERV-DISC-REQ "
|
||||
/* parameters: <src addr> <update indicator> <TLVs> */
|
||||
#define P2P_EVENT_SERV_DISC_RESP "P2P-SERV-DISC-RESP "
|
||||
#define P2P_EVENT_INVITATION_RECEIVED "P2P-INVITATION-RECEIVED "
|
||||
#define P2P_EVENT_INVITATION_RESULT "P2P-INVITATION-RESULT "
|
||||
#define P2P_EVENT_FIND_STOPPED "P2P-FIND-STOPPED "
|
||||
#define P2P_EVENT_PERSISTENT_PSK_FAIL "P2P-PERSISTENT-PSK-FAIL id="
|
||||
#define P2P_EVENT_PRESENCE_RESPONSE "P2P-PRESENCE-RESPONSE "
|
||||
#define P2P_EVENT_NFC_BOTH_GO "P2P-NFC-BOTH-GO "
|
||||
#define P2P_EVENT_NFC_PEER_CLIENT "P2P-NFC-PEER-CLIENT "
|
||||
#define P2P_EVENT_NFC_WHILE_CLIENT "P2P-NFC-WHILE-CLIENT "
|
||||
|
||||
/* parameters: <PMF enabled> <timeout in ms> <Session Information URL> */
|
||||
#define ESS_DISASSOC_IMMINENT "ESS-DISASSOC-IMMINENT "
|
||||
#define P2P_EVENT_REMOVE_AND_REFORM_GROUP "P2P-REMOVE-AND-REFORM-GROUP "
|
||||
|
||||
#define INTERWORKING_AP "INTERWORKING-AP "
|
||||
#define INTERWORKING_BLACKLISTED "INTERWORKING-BLACKLISTED "
|
||||
#define INTERWORKING_NO_MATCH "INTERWORKING-NO-MATCH "
|
||||
#define INTERWORKING_ALREADY_CONNECTED "INTERWORKING-ALREADY-CONNECTED "
|
||||
#define INTERWORKING_SELECTED "INTERWORKING-SELECTED "
|
||||
|
||||
/* Credential block added; parameters: <id> */
|
||||
#define CRED_ADDED "CRED-ADDED "
|
||||
/* Credential block modified; parameters: <id> <field> */
|
||||
#define CRED_MODIFIED "CRED-MODIFIED "
|
||||
/* Credential block removed; parameters: <id> */
|
||||
#define CRED_REMOVED "CRED-REMOVED "
|
||||
|
||||
#define GAS_RESPONSE_INFO "GAS-RESPONSE-INFO "
|
||||
/* parameters: <addr> <dialog_token> <freq> */
|
||||
#define GAS_QUERY_START "GAS-QUERY-START "
|
||||
/* parameters: <addr> <dialog_token> <freq> <status_code> <result> */
|
||||
#define GAS_QUERY_DONE "GAS-QUERY-DONE "
|
||||
|
||||
/* parameters: <addr> <result> */
|
||||
#define ANQP_QUERY_DONE "ANQP-QUERY-DONE "
|
||||
|
||||
#define HS20_SUBSCRIPTION_REMEDIATION "HS20-SUBSCRIPTION-REMEDIATION "
|
||||
#define HS20_DEAUTH_IMMINENT_NOTICE "HS20-DEAUTH-IMMINENT-NOTICE "
|
||||
|
||||
#define EXT_RADIO_WORK_START "EXT-RADIO-WORK-START "
|
||||
#define EXT_RADIO_WORK_TIMEOUT "EXT-RADIO-WORK-TIMEOUT "
|
||||
|
||||
#define RRM_EVENT_NEIGHBOR_REP_RXED "RRM-NEIGHBOR-REP-RECEIVED "
|
||||
#define RRM_EVENT_NEIGHBOR_REP_FAILED "RRM-NEIGHBOR-REP-REQUEST-FAILED "
|
||||
|
||||
/* hostapd control interface - fixed message prefixes */
|
||||
#define WPS_EVENT_PIN_NEEDED "WPS-PIN-NEEDED "
|
||||
#define WPS_EVENT_NEW_AP_SETTINGS "WPS-NEW-AP-SETTINGS "
|
||||
#define WPS_EVENT_REG_SUCCESS "WPS-REG-SUCCESS "
|
||||
#define WPS_EVENT_AP_SETUP_LOCKED "WPS-AP-SETUP-LOCKED "
|
||||
#define WPS_EVENT_AP_SETUP_UNLOCKED "WPS-AP-SETUP-UNLOCKED "
|
||||
#define WPS_EVENT_AP_PIN_ENABLED "WPS-AP-PIN-ENABLED "
|
||||
#define WPS_EVENT_AP_PIN_DISABLED "WPS-AP-PIN-DISABLED "
|
||||
#define AP_STA_CONNECTED "AP-STA-CONNECTED "
|
||||
#define AP_STA_DISCONNECTED "AP-STA-DISCONNECTED "
|
||||
|
||||
#define AP_REJECTED_MAX_STA "AP-REJECTED-MAX-STA "
|
||||
#define AP_REJECTED_BLOCKED_STA "AP-REJECTED-BLOCKED-STA "
|
||||
|
||||
#define AP_EVENT_ENABLED "AP-ENABLED "
|
||||
#define AP_EVENT_DISABLED "AP-DISABLED "
|
||||
|
||||
#define INTERFACE_ENABLED "INTERFACE-ENABLED "
|
||||
#define INTERFACE_DISABLED "INTERFACE-DISABLED "
|
||||
|
||||
#define ACS_EVENT_STARTED "ACS-STARTED "
|
||||
#define ACS_EVENT_COMPLETED "ACS-COMPLETED "
|
||||
#define ACS_EVENT_FAILED "ACS-FAILED "
|
||||
|
||||
#define DFS_EVENT_RADAR_DETECTED "DFS-RADAR-DETECTED "
|
||||
#define DFS_EVENT_NEW_CHANNEL "DFS-NEW-CHANNEL "
|
||||
#define DFS_EVENT_CAC_START "DFS-CAC-START "
|
||||
#define DFS_EVENT_CAC_COMPLETED "DFS-CAC-COMPLETED "
|
||||
#define DFS_EVENT_NOP_FINISHED "DFS-NOP-FINISHED "
|
||||
|
||||
#define AP_CSA_FINISHED "AP-CSA-FINISHED "
|
||||
|
||||
/* BSS Transition Management Response frame received */
|
||||
#define BSS_TM_RESP "BSS-TM-RESP "
|
||||
|
||||
/* BSS command information masks */
|
||||
|
||||
#define WPA_BSS_MASK_ALL 0xFFFDFFFF
|
||||
#define WPA_BSS_MASK_ID BIT(0)
|
||||
#define WPA_BSS_MASK_BSSID BIT(1)
|
||||
#define WPA_BSS_MASK_FREQ BIT(2)
|
||||
#define WPA_BSS_MASK_BEACON_INT BIT(3)
|
||||
#define WPA_BSS_MASK_CAPABILITIES BIT(4)
|
||||
#define WPA_BSS_MASK_QUAL BIT(5)
|
||||
#define WPA_BSS_MASK_NOISE BIT(6)
|
||||
#define WPA_BSS_MASK_LEVEL BIT(7)
|
||||
#define WPA_BSS_MASK_TSF BIT(8)
|
||||
#define WPA_BSS_MASK_AGE BIT(9)
|
||||
#define WPA_BSS_MASK_IE BIT(10)
|
||||
#define WPA_BSS_MASK_FLAGS BIT(11)
|
||||
#define WPA_BSS_MASK_SSID BIT(12)
|
||||
#define WPA_BSS_MASK_WPS_SCAN BIT(13)
|
||||
#define WPA_BSS_MASK_P2P_SCAN BIT(14)
|
||||
#define WPA_BSS_MASK_INTERNETW BIT(15)
|
||||
#define WPA_BSS_MASK_WIFI_DISPLAY BIT(16)
|
||||
#define WPA_BSS_MASK_DELIM BIT(17)
|
||||
#define WPA_BSS_MASK_MESH_SCAN BIT(18)
|
||||
#define WPA_BSS_MASK_FST BIT(19)
|
||||
|
||||
|
||||
/* VENDOR_ELEM_* frame id values */
|
||||
enum wpa_vendor_elem_frame {
|
||||
VENDOR_ELEM_PROBE_REQ_P2P = 0,
|
||||
VENDOR_ELEM_PROBE_RESP_P2P = 1,
|
||||
VENDOR_ELEM_PROBE_RESP_P2P_GO = 2,
|
||||
VENDOR_ELEM_BEACON_P2P_GO = 3,
|
||||
VENDOR_ELEM_P2P_PD_REQ = 4,
|
||||
VENDOR_ELEM_P2P_PD_RESP = 5,
|
||||
VENDOR_ELEM_P2P_GO_NEG_REQ = 6,
|
||||
VENDOR_ELEM_P2P_GO_NEG_RESP = 7,
|
||||
VENDOR_ELEM_P2P_GO_NEG_CONF = 8,
|
||||
VENDOR_ELEM_P2P_INV_REQ = 9,
|
||||
VENDOR_ELEM_P2P_INV_RESP = 10,
|
||||
VENDOR_ELEM_P2P_ASSOC_REQ = 11,
|
||||
VENDOR_ELEM_P2P_ASSOC_RESP = 12,
|
||||
VENDOR_ELEM_ASSOC_REQ = 13,
|
||||
NUM_VENDOR_ELEM_FRAMES
|
||||
};
|
||||
|
||||
|
||||
/* wpa_supplicant/hostapd control interface access */
|
||||
|
||||
/**
|
||||
* wpa_ctrl_open - Open a control interface to wpa_supplicant/hostapd
|
||||
* @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used.
|
||||
* Returns: Pointer to abstract control interface data or %NULL on failure
|
||||
*
|
||||
* This function is used to open a control interface to wpa_supplicant/hostapd.
|
||||
* ctrl_path is usually /var/run/wpa_supplicant or /var/run/hostapd. This path
|
||||
* is configured in wpa_supplicant/hostapd and other programs using the control
|
||||
* interface need to use matching path configuration.
|
||||
*/
|
||||
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path);
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_close - Close a control interface to wpa_supplicant/hostapd
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
*
|
||||
* This function is used to close a control interface.
|
||||
*/
|
||||
void wpa_ctrl_close(struct wpa_ctrl *ctrl);
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_request - Send a command to wpa_supplicant/hostapd
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
* @cmd: Command; usually, ASCII text, e.g., "PING"
|
||||
* @cmd_len: Length of the cmd in bytes
|
||||
* @reply: Buffer for the response
|
||||
* @reply_len: Reply buffer length
|
||||
* @msg_cb: Callback function for unsolicited messages or %NULL if not used
|
||||
* Returns: 0 on success, -1 on error (send or receive failed), -2 on timeout
|
||||
*
|
||||
* This function is used to send commands to wpa_supplicant/hostapd. Received
|
||||
* response will be written to reply and reply_len is set to the actual length
|
||||
* of the reply. This function will block for up to two seconds while waiting
|
||||
* for the reply. If unsolicited messages are received, the blocking time may
|
||||
* be longer.
|
||||
*
|
||||
* msg_cb can be used to register a callback function that will be called for
|
||||
* unsolicited messages received while waiting for the command response. These
|
||||
* messages may be received if wpa_ctrl_request() is called at the same time as
|
||||
* wpa_supplicant/hostapd is sending such a message. This can happen only if
|
||||
* the program has used wpa_ctrl_attach() to register itself as a monitor for
|
||||
* event messages. Alternatively to msg_cb, programs can register two control
|
||||
* interface connections and use one of them for commands and the other one for
|
||||
* receiving event messages, in other words, call wpa_ctrl_attach() only for
|
||||
* the control interface connection that will be used for event messages.
|
||||
*/
|
||||
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
|
||||
char *reply, size_t *reply_len,
|
||||
void (*msg_cb)(char *msg, size_t len));
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_attach - Register as an event monitor for the control interface
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
* Returns: 0 on success, -1 on failure, -2 on timeout
|
||||
*
|
||||
* This function registers the control interface connection as a monitor for
|
||||
* wpa_supplicant/hostapd events. After a success wpa_ctrl_attach() call, the
|
||||
* control interface connection starts receiving event messages that can be
|
||||
* read with wpa_ctrl_recv().
|
||||
*/
|
||||
int wpa_ctrl_attach(struct wpa_ctrl *ctrl);
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_detach - Unregister event monitor from the control interface
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
* Returns: 0 on success, -1 on failure, -2 on timeout
|
||||
*
|
||||
* This function unregisters the control interface connection as a monitor for
|
||||
* wpa_supplicant/hostapd events, i.e., cancels the registration done with
|
||||
* wpa_ctrl_attach().
|
||||
*/
|
||||
int wpa_ctrl_detach(struct wpa_ctrl *ctrl);
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_recv - Receive a pending control interface message
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
* @reply: Buffer for the message data
|
||||
* @reply_len: Length of the reply buffer
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function will receive a pending control interface message. The received
|
||||
* response will be written to reply and reply_len is set to the actual length
|
||||
* of the reply.
|
||||
|
||||
* wpa_ctrl_recv() is only used for event messages, i.e., wpa_ctrl_attach()
|
||||
* must have been used to register the control interface as an event monitor.
|
||||
*/
|
||||
int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len);
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_pending - Check whether there are pending event messages
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
* Returns: 1 if there are pending messages, 0 if no, or -1 on error
|
||||
*
|
||||
* This function will check whether there are any pending control interface
|
||||
* message available to be received with wpa_ctrl_recv(). wpa_ctrl_pending() is
|
||||
* only used for event messages, i.e., wpa_ctrl_attach() must have been used to
|
||||
* register the control interface as an event monitor.
|
||||
*/
|
||||
int wpa_ctrl_pending(struct wpa_ctrl *ctrl);
|
||||
|
||||
|
||||
/**
|
||||
* wpa_ctrl_get_fd - Get file descriptor used by the control interface
|
||||
* @ctrl: Control interface data from wpa_ctrl_open()
|
||||
* Returns: File descriptor used for the connection
|
||||
*
|
||||
* This function can be used to get the file descriptor that is used for the
|
||||
* control interface connection. The returned value can be used, e.g., with
|
||||
* select() while waiting for multiple events.
|
||||
*
|
||||
* The returned file descriptor must not be used directly for sending or
|
||||
* receiving packets; instead, the library functions wpa_ctrl_request() and
|
||||
* wpa_ctrl_recv() must be used for this.
|
||||
*/
|
||||
int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl);
|
||||
|
||||
#ifdef ANDROID
|
||||
/**
|
||||
* wpa_ctrl_cleanup() - Delete any local UNIX domain socket files that
|
||||
* may be left over from clients that were previously connected to
|
||||
* wpa_supplicant. This keeps these files from being orphaned in the
|
||||
* event of crashes that prevented them from being removed as part
|
||||
* of the normal orderly shutdown.
|
||||
*/
|
||||
void wpa_ctrl_cleanup(void);
|
||||
#endif /* ANDROID */
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP
|
||||
/* Port range for multiple wpa_supplicant instances and multiple VIFs */
|
||||
#define WPA_CTRL_IFACE_PORT 9877
|
||||
#define WPA_CTRL_IFACE_PORT_LIMIT 50 /* decremented from start */
|
||||
#define WPA_GLOBAL_CTRL_IFACE_PORT 9878
|
||||
#define WPA_GLOBAL_CTRL_IFACE_PORT_LIMIT 20 /* incremented from start */
|
||||
|
||||
char * wpa_ctrl_get_remote_ifname(struct wpa_ctrl *ctrl);
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP */
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* WPA_CTRL_H */
|
||||
1113
qcom/opensource/fst-manager/external/eloop.c
vendored
Normal file
1113
qcom/opensource/fst-manager/external/eloop.c
vendored
Normal file
File diff suppressed because it is too large
Load Diff
103
qcom/opensource/fst-manager/external/fst/fst_ctrl_aux.h
vendored
Normal file
103
qcom/opensource/fst-manager/external/fst/fst_ctrl_aux.h
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* FST module - miscellaneous definitions
|
||||
* Copyright (c) 2014, Qualcomm Atheros, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef FST_MISC_H
|
||||
#define FST_MISC_H
|
||||
|
||||
#include "common/defs.h"
|
||||
|
||||
/* FST module control interface API */
|
||||
#define FST_INVALID_SESSION_ID ((u32)-1)
|
||||
#define FST_MAX_GROUP_ID_SIZE 32
|
||||
#define FST_MAX_INTERFACE_SIZE 32
|
||||
|
||||
enum fst_session_state {
|
||||
FST_SESSION_STATE_INITIAL,
|
||||
FST_SESSION_STATE_SETUP_COMPLETION,
|
||||
FST_SESSION_STATE_TRANSITION_DONE,
|
||||
FST_SESSION_STATE_TRANSITION_CONFIRMED,
|
||||
FST_SESSION_STATE_LAST
|
||||
};
|
||||
|
||||
enum fst_event_type {
|
||||
EVENT_FST_IFACE_STATE_CHANGED, /* An interface has been either attached
|
||||
* to or detached from an FST group */
|
||||
EVENT_FST_ESTABLISHED, /* FST Session has been established */
|
||||
EVENT_FST_SETUP, /* FST Session request received */
|
||||
EVENT_FST_SESSION_STATE_CHANGED,/* FST Session state has been changed */
|
||||
EVENT_PEER_STATE_CHANGED, /* FST related generic event occurred,
|
||||
* see struct fst_hostap_event_data for
|
||||
* more info */
|
||||
|
||||
/* FST Manager internal events */
|
||||
EVENT_FST_SCAN_STARTED = 100,
|
||||
EVENT_FST_SCAN_COMPLETED,
|
||||
EVENT_FST_SIGNAL_CHANGE,
|
||||
};
|
||||
|
||||
enum fst_reason {
|
||||
REASON_TEARDOWN,
|
||||
REASON_SETUP,
|
||||
REASON_SWITCH,
|
||||
REASON_STT,
|
||||
REASON_REJECT,
|
||||
REASON_ERROR_PARAMS,
|
||||
REASON_RESET,
|
||||
REASON_DETACH_IFACE,
|
||||
};
|
||||
|
||||
enum fst_initiator {
|
||||
FST_INITIATOR_UNDEFINED,
|
||||
FST_INITIATOR_LOCAL,
|
||||
FST_INITIATOR_REMOTE,
|
||||
};
|
||||
|
||||
union fst_event_extra {
|
||||
struct fst_event_extra_iface_state {
|
||||
Boolean attached;
|
||||
char ifname[FST_MAX_INTERFACE_SIZE];
|
||||
char group_id[FST_MAX_GROUP_ID_SIZE];
|
||||
} iface_state; /* for EVENT_FST_IFACE_STATE_CHANGED */
|
||||
struct fst_event_extra_peer_state {
|
||||
Boolean connected;
|
||||
char ifname[FST_MAX_INTERFACE_SIZE];
|
||||
u8 addr[ETH_ALEN];
|
||||
} peer_state; /* for EVENT_PEER_STATE_CHANGED */
|
||||
struct fst_event_extra_session_state {
|
||||
enum fst_session_state old_state;
|
||||
enum fst_session_state new_state;
|
||||
union fst_session_state_switch_extra {
|
||||
struct {
|
||||
enum fst_reason reason;
|
||||
u8 reject_code; /* REASON_REJECT */
|
||||
/* REASON_SWITCH,
|
||||
* REASON_TEARDOWN,
|
||||
* REASON_REJECT
|
||||
*/
|
||||
enum fst_initiator initiator;
|
||||
} to_initial;
|
||||
} extra;
|
||||
} session_state; /* for EVENT_FST_SESSION_STATE_CHANGED */
|
||||
};
|
||||
|
||||
/* helpers - prints enum in string form */
|
||||
#define FST_NAME_UNKNOWN "UNKNOWN"
|
||||
|
||||
const char *_fst_get_str_name(unsigned index, const char *names[],
|
||||
size_t names_size);
|
||||
int _fst_get_str_num(const char *name, const char *names[],
|
||||
size_t names_size);
|
||||
|
||||
const char *fst_session_event_type_name(enum fst_event_type);
|
||||
const char *fst_reason_name(enum fst_reason reason);
|
||||
const char *fst_session_state_name(enum fst_session_state state);
|
||||
int fst_session_event_num(const char *name);
|
||||
int fst_reason_num(const char *name);
|
||||
int fst_session_state_num(const char *name);
|
||||
|
||||
#endif /* FST_MISC_H */
|
||||
229
qcom/opensource/fst-manager/external/fst/fst_ctrl_defs.h
vendored
Normal file
229
qcom/opensource/fst-manager/external/fst/fst_ctrl_defs.h
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* FST module - shared Control interface definitions
|
||||
* Copyright (c) 2014, Qualcomm Atheros, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef FST_CTRL_DEFS_H
|
||||
#define FST_CTRL_DEFS_H
|
||||
|
||||
/* Undefined value */
|
||||
#define FST_CTRL_PVAL_NONE "NONE"
|
||||
|
||||
/* FST-ATTACH parameters */
|
||||
#define FST_ATTACH_CMD_PNAME_LLT "llt" /* pval = desired LLT */
|
||||
#define FST_ATTACH_CMD_PNAME_PRIORITY "priority" /* pval = desired priority */
|
||||
|
||||
/* FST-MANAGER parameters */
|
||||
/* FST Session states */
|
||||
#define FST_CS_PVAL_STATE_INITIAL "INITIAL"
|
||||
#define FST_CS_PVAL_STATE_SETUP_COMPLETION "SETUP_COMPLETION"
|
||||
#define FST_CS_PVAL_STATE_TRANSITION_DONE "TRANSITION_DONE"
|
||||
#define FST_CS_PVAL_STATE_TRANSITION_CONFIRMED "TRANSITION_CONFIRMED"
|
||||
|
||||
/* FST Session reset reasons */
|
||||
#define FST_CS_PVAL_REASON_TEARDOWN "REASON_TEARDOWN"
|
||||
#define FST_CS_PVAL_REASON_SETUP "REASON_SETUP"
|
||||
#define FST_CS_PVAL_REASON_SWITCH "REASON_SWITCH"
|
||||
#define FST_CS_PVAL_REASON_STT "REASON_STT"
|
||||
#define FST_CS_PVAL_REASON_REJECT "REASON_REJECT"
|
||||
#define FST_CS_PVAL_REASON_ERROR_PARAMS "REASON_ERROR_PARAMS"
|
||||
#define FST_CS_PVAL_REASON_RESET "REASON_RESET"
|
||||
#define FST_CS_PVAL_REASON_DETACH_IFACE "REASON_DETACH_IFACE"
|
||||
|
||||
/* FST Session responses */
|
||||
#define FST_CS_PVAL_RESPONSE_ACCEPT "ACCEPT"
|
||||
#define FST_CS_PVAL_RESPONSE_REJECT "REJECT"
|
||||
|
||||
/* FST Session action initiator */
|
||||
#define FST_CS_PVAL_INITIATOR_LOCAL "LOCAL"
|
||||
#define FST_CS_PVAL_INITIATOR_REMOTE "REMOTE"
|
||||
|
||||
/* FST-CLI subcommands and parameter names */
|
||||
#define FST_CMD_HELP "help"
|
||||
#define FST_CMD_LIST_GROUPS "list_groups"
|
||||
#define FST_CMD_LIST_IFACES "list_ifaces"
|
||||
#define FST_CMD_IFACE_PEERS "iface_peers"
|
||||
#define FST_CMD_GET_PEER_MBIES "get_peer_mbies"
|
||||
#define FST_CMD_LIST_SESSIONS "list_sessions"
|
||||
#define FST_CMD_SESSION_ADD "session_add"
|
||||
#define FST_CMD_SESSION_REMOVE "session_remove"
|
||||
#define FST_CMD_SESSION_GET "session_get"
|
||||
#define FST_CSG_PNAME_OLD_PEER_ADDR "old_peer_addr" /* pval = address string */
|
||||
#define FST_CSG_PNAME_NEW_PEER_ADDR "new_peer_addr" /* pval = address string */
|
||||
#define FST_CSG_PNAME_OLD_IFNAME "old_ifname" /* pval = ifname */
|
||||
#define FST_CSG_PNAME_NEW_IFNAME "new_ifname" /* pval = ifname */
|
||||
#define FST_CSG_PNAME_LLT "llt" /* pval = numeric llt value */
|
||||
#define FST_CSG_PNAME_STATE "state" /* pval = FST_CS_PVAL_STATE_... */
|
||||
#define FST_CMD_SESSION_SET "session_set"
|
||||
#define FST_CSS_PNAME_OLD_PEER_ADDR FST_CSG_PNAME_OLD_PEER_ADDR
|
||||
#define FST_CSS_PNAME_NEW_PEER_ADDR FST_CSG_PNAME_NEW_PEER_ADDR
|
||||
#define FST_CSS_PNAME_OLD_IFNAME FST_CSG_PNAME_OLD_IFNAME
|
||||
#define FST_CSS_PNAME_NEW_IFNAME FST_CSG_PNAME_NEW_IFNAME
|
||||
#define FST_CSS_PNAME_LLT FST_CSG_PNAME_LLT
|
||||
#define FST_CMD_SESSION_INITIATE "session_initiate"
|
||||
#define FST_CMD_SESSION_RESPOND "session_respond"
|
||||
#define FST_CMD_SESSION_TRANSFER "session_transfer"
|
||||
#define FST_CMD_SESSION_TEARDOWN "session_teardown"
|
||||
|
||||
#ifdef CONFIG_FST_TEST
|
||||
#define FST_CTR_PVAL_BAD_NEW_BAND "bad_new_band"
|
||||
|
||||
#define FST_CMD_TEST_REQUEST "test_request"
|
||||
#define FST_CTR_IS_SUPPORTED "is_supported"
|
||||
#define FST_CTR_SEND_SETUP_REQUEST "send_setup_request"
|
||||
#define FST_CTR_SEND_SETUP_RESPONSE "send_setup_response"
|
||||
#define FST_CTR_SEND_ACK_REQUEST "send_ack_request"
|
||||
#define FST_CTR_SEND_ACK_RESPONSE "send_ack_response"
|
||||
#define FST_CTR_SEND_TEAR_DOWN "send_tear_down"
|
||||
#define FST_CTR_GET_FSTS_ID "get_fsts_id"
|
||||
#define FST_CTR_GET_LOCAL_MBIES "get_local_mbies"
|
||||
#endif
|
||||
|
||||
/* Events */
|
||||
#define FST_CTRL_EVENT_IFACE "FST-EVENT-IFACE"
|
||||
#define FST_CEI_PNAME_IFNAME "ifname"
|
||||
#define FST_CEI_PNAME_GROUP "group"
|
||||
#define FST_CEI_PNAME_ATTACHED "attached"
|
||||
#define FST_CEI_PNAME_DETACHED "detached"
|
||||
#define FST_CTRL_EVENT_PEER "FST-EVENT-PEER"
|
||||
#define FST_CEP_PNAME_IFNAME "ifname"
|
||||
#define FST_CEP_PNAME_ADDR "peer_addr"
|
||||
#define FST_CEP_PNAME_CONNECTED "connected"
|
||||
#define FST_CEP_PNAME_DISCONNECTED "disconnected"
|
||||
#define FST_CTRL_EVENT_SESSION "FST-EVENT-SESSION"
|
||||
#define FST_CES_PNAME_SESSION_ID "session_id"
|
||||
#define FST_CES_PNAME_EVT_TYPE "event_type"
|
||||
#define FST_PVAL_EVT_TYPE_SESSION_STATE "EVENT_FST_SESSION_STATE"
|
||||
/* old_state/new_state: pval = FST_CS_PVAL_STATE_... */
|
||||
#define FST_CES_PNAME_OLD_STATE "old_state"
|
||||
#define FST_CES_PNAME_NEW_STATE "new_state"
|
||||
#define FST_CES_PNAME_REASON "reason" /* pval = FST_CS_PVAL_REASON_... */
|
||||
#define FST_CES_PNAME_REJECT_CODE "reject_code" /* pval = u8 code */
|
||||
#define FST_CES_PNAME_INITIATOR "initiator" /* pval = FST_CS_PVAL_INITIATOR_... */
|
||||
#define FST_PVAL_EVT_TYPE_ESTABLISHED "EVENT_FST_ESTABLISHED"
|
||||
#define FST_PVAL_EVT_TYPE_SETUP "EVENT_FST_SETUP"
|
||||
|
||||
#ifdef CONFIG_DBUS
|
||||
|
||||
#define WPAS_DBUS_NEW_SERVICE "fi.w1.wpa_supplicant1"
|
||||
#define WPAS_DBUS_NEW_PATH "/fi/w1/wpa_supplicant1"
|
||||
#define WPAS_DBUS_NEW_INTERFACE "fi.w1.wpa_supplicant1"
|
||||
|
||||
#define WPAS_DBUS_NEW_PATH_INTERFACES WPAS_DBUS_NEW_PATH "/Interfaces"
|
||||
#define WPAS_DBUS_NEW_IFACE_INTERFACE WPAS_DBUS_NEW_INTERFACE ".Interface"
|
||||
#define WPAS_DBUS_NEW_IFACE_WPS WPAS_DBUS_NEW_IFACE_INTERFACE ".WPS"
|
||||
|
||||
#define WPAS_DBUS_NEW_PATH_FST WPAS_DBUS_NEW_PATH "/FST"
|
||||
#define WPAS_DBUS_NEW_IFACE_FST WPAS_DBUS_NEW_INTERFACE ".FST"
|
||||
|
||||
#define WPAS_DBUS_NEW_FST_GROUPS_PART "Groups"
|
||||
#define WPAS_DBUS_NEW_IFACE_FST_GROUP WPAS_DBUS_NEW_IFACE_FST ".Group"
|
||||
|
||||
#define WPAS_DBUS_NEW_FST_INTERFACES_PART "Interfaces"
|
||||
#define WPAS_DBUS_NEW_IFACE_FST_INTERFACE WPAS_DBUS_NEW_IFACE_FST ".Interface"
|
||||
|
||||
#define WPAS_DBUS_NEW_FST_SESSIONS_PART "Sessions"
|
||||
#define WPAS_DBUS_NEW_IFACE_FST_SESSION WPAS_DBUS_NEW_IFACE_FST ".Session"
|
||||
|
||||
/*
|
||||
* Global FST properties, methods and signals
|
||||
*/
|
||||
#define FST_DBUS_GLOBAL_PROP_GROUPS "Groups"
|
||||
#define FST_DBUS_GLOBAL_PROP_SESSIONS "Sessions"
|
||||
|
||||
|
||||
/* Session state change to INITIAL specific fields */
|
||||
#define FST_DBUS_SIG_SSTATE_PNAME_INIT_REASON "init_reason"
|
||||
#define FST_DBUS_SIG_SSTATE_PNAME_INIT_REJECT_CODE "reject_code"
|
||||
#define FST_DBUS_SIG_SSTATE_PNAME_INIT_INITIATOR "initiator"
|
||||
|
||||
|
||||
#define FST_DBUS_GLOBAL_SIG "Global"
|
||||
#define FST_DBUS_GLOBAL_SIG_PARAM_PATH "path"
|
||||
#define FST_DBUS_GLOBAL_SIG_PARAM_EVENT "event"
|
||||
#define FST_DBUS_GLOBAL_SIG_PARAM_PARAMS "params"
|
||||
|
||||
#define FST_DBUS_GLOBAL_SIG_SALL_PNAME_SESSION_ID "session_id"
|
||||
#define FST_DBUS_GLOBAL_SIG_EVT_SESSION_SETUP "SessionSetup"
|
||||
#define FST_DBUS_GLOBAL_SIG_EVT_SESSION_STATE "SessionState"
|
||||
#define FST_DBUS_GLOBAL_SIG_SSTATE_PNAME_OLD_STATE "old_state"
|
||||
#define FST_DBUS_GLOBAL_SIG_SSTATE_PNAME_NEW_STATE "new_state"
|
||||
#define FST_DBUS_GLOBAL_SIG_SSTATE_PNAME_INIT_REASON \
|
||||
FST_DBUS_SIG_SSTATE_PNAME_INIT_REASON
|
||||
#define FST_DBUS_GLOBAL_SIG_SSTATE_PNAME_INIT_REJECT_CODE \
|
||||
FST_DBUS_SIG_SSTATE_PNAME_INIT_REJECT_CODE
|
||||
#define FST_DBUS_GLOBAL_SIG_SSTATE_PNAME_INIT_INITIATOR \
|
||||
FST_DBUS_SIG_SSTATE_PNAME_INIT_INITIATOR
|
||||
#define FST_DBUS_GLOBAL_SIG_EVT_SESSION_ESTAB "SessionEstablished"
|
||||
#define FST_DBUS_GLOBAL_SIG_EVT_IFACE_PEER_STATE "InterfacePeerState"
|
||||
#define FST_DBUS_GLOBAL_SIG_PNAME_IFNAME "path"
|
||||
#define FST_DBUS_GLOBAL_SIG_PNAME_CONNECTED "connected"
|
||||
#define FST_DBUS_GLOBAL_SIG_PNAME_PEER_ADDR "peer_addr"
|
||||
|
||||
/*
|
||||
* Group FST properties, methods and signals
|
||||
*/
|
||||
#define FST_DBUS_GROUP_PROP_SESSIONS "Sessions"
|
||||
#define FST_DBUS_GROUP_PROP_IFACES "Interfaces"
|
||||
|
||||
#define FST_DBUS_GROUP_MTHD_ADD_SESSION "AddSession"
|
||||
#define FST_DBUS_GROUP_MTHD_ADD_SESSION_ID_PARAM "session_id"
|
||||
|
||||
|
||||
#define FST_DBUS_GROUP_SIG_SESSION_SETUP "Setup"
|
||||
#define FST_DBUS_GROUP_SIG_SSESSION_PARAM_PATH "path"
|
||||
|
||||
/*
|
||||
* Session FST properties, methods and signals
|
||||
*/
|
||||
#define FST_DBUS_SESSION_SIG_STATE "State"
|
||||
#define FST_DBUS_SESSION_SIG_PARAM_OLD_STATE "old_state"
|
||||
#define FST_DBUS_SESSION_SIG_PARAM_NEW_STATE "new_state"
|
||||
#define FST_DBUS_SESSION_SIG_PARAM_PARAMS "params"
|
||||
#define FST_DBUS_SESSION_SIG_PNAME_REASON \
|
||||
FST_DBUS_SIG_SSTATE_PNAME_INIT_REASON
|
||||
#define FST_DBUS_SESSION_SIG_PNAME_REJECT_CODE \
|
||||
FST_DBUS_SIG_SSTATE_PNAME_INIT_REJECT_CODE
|
||||
#define FST_DBUS_SESSION_SIG_PNAME_INITIATOR \
|
||||
FST_DBUS_SIG_SSTATE_PNAME_INIT_INITIATOR
|
||||
#define FST_DBUS_SESSION_SIG_ESTABLISHED "Established"
|
||||
|
||||
#define FST_DBUS_SESSION_MTHD_SET "Set"
|
||||
#define FST_DBUS_SESSION_MTHD_SET_PNAME_PNAME "pname"
|
||||
#define FST_DBUS_SESSION_MTHD_SET_PNAME_PVAL "pvalue"
|
||||
#define FST_DBUS_SESSION_MTHD_INITIATE "Initiate"
|
||||
#define FST_DBUS_SESSION_MTHD_RESPOND "Respond"
|
||||
#define FST_DBUS_SESSION_MTHD_RESPOND_PNAME_STATUS "respond_status"
|
||||
#define FST_DBUS_SESSION_MTHD_TRANSFER "Transfer"
|
||||
#define FST_DBUS_SESSION_MTHD_TEARDOWN "TearDown"
|
||||
#define FST_DBUS_SESSION_MTHD_REMOVE "Remove"
|
||||
|
||||
#define FST_DBUS_SESSION_PROP_GROUP "Group"
|
||||
#define FST_DBUS_SESSION_PROP_ID "ID"
|
||||
#define FST_DBUS_SESSION_PROP_STATE "State"
|
||||
#define FST_DBUS_SESSION_PROP_OLD_IFACE "OldInterface"
|
||||
#define FST_DBUS_SESSION_PROP_NEW_IFACE "NewInterface"
|
||||
#define FST_DBUS_SESSION_PROP_OWN_ADDR "OwnAddress"
|
||||
#define FST_DBUS_SESSION_PROP_PEER_ADDR "PeerAddress"
|
||||
#define FST_DBUS_SESSION_PROP_LLT "LLT"
|
||||
|
||||
/*
|
||||
* Interface FST properties, methods and signals
|
||||
*/
|
||||
|
||||
#define FST_DBUS_IFACE_PROP_GROUP_ID "GroupID"
|
||||
#define FST_DBUS_IFACE_PROP_PRIORITY "Priority"
|
||||
#define FST_DBUS_IFACE_PROP_LLT "LLT"
|
||||
#define FST_DBUS_IFACE_PROP_PEER_ADDR "PeerAddress"
|
||||
#define FST_DBUS_IFACE_PROP_PEER_MBIEs "PeerMBIEs"
|
||||
|
||||
#define FST_DBUS_IFACE_SIG_PEER_STATE "PeerState"
|
||||
#define FST_DBUS_IFACE_SIG_PNAME_CONNECTED "connected"
|
||||
#define FST_DBUS_IFACE_SIG_PNAME_PEER_ADDR "peer_addr"
|
||||
|
||||
#endif
|
||||
|
||||
#endif /* FST_CTRL_DEFS_H */
|
||||
92
qcom/opensource/fst-manager/external/fst_ctrl_aux.c
vendored
Normal file
92
qcom/opensource/fst-manager/external/fst_ctrl_aux.c
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* FST module implementation
|
||||
* Copyright (c) 2014, Qualcomm Atheros, Inc.
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "common/defs.h"
|
||||
#include "fst_ctrl_defs.h"
|
||||
#include "fst_ctrl_aux.h"
|
||||
|
||||
static const char *session_event_names[] = {
|
||||
[EVENT_FST_ESTABLISHED] = FST_PVAL_EVT_TYPE_ESTABLISHED,
|
||||
[EVENT_FST_SETUP] = FST_PVAL_EVT_TYPE_SETUP,
|
||||
[EVENT_FST_SESSION_STATE_CHANGED] = FST_PVAL_EVT_TYPE_SESSION_STATE,
|
||||
};
|
||||
|
||||
static const char *reason_names[] = {
|
||||
[REASON_TEARDOWN] = FST_CS_PVAL_REASON_TEARDOWN,
|
||||
[REASON_SETUP] = FST_CS_PVAL_REASON_SETUP,
|
||||
[REASON_SWITCH] = FST_CS_PVAL_REASON_SWITCH,
|
||||
[REASON_STT] = FST_CS_PVAL_REASON_STT,
|
||||
[REASON_REJECT] = FST_CS_PVAL_REASON_REJECT,
|
||||
[REASON_ERROR_PARAMS] = FST_CS_PVAL_REASON_ERROR_PARAMS,
|
||||
[REASON_RESET] = FST_CS_PVAL_REASON_RESET,
|
||||
[REASON_DETACH_IFACE] = FST_CS_PVAL_REASON_DETACH_IFACE,
|
||||
};
|
||||
|
||||
static const char *session_state_names[] = {
|
||||
[FST_SESSION_STATE_INITIAL] = FST_CS_PVAL_STATE_INITIAL,
|
||||
[FST_SESSION_STATE_SETUP_COMPLETION] = FST_CS_PVAL_STATE_SETUP_COMPLETION,
|
||||
[FST_SESSION_STATE_TRANSITION_DONE] = FST_CS_PVAL_STATE_TRANSITION_DONE,
|
||||
[FST_SESSION_STATE_TRANSITION_CONFIRMED] = FST_CS_PVAL_STATE_TRANSITION_CONFIRMED,
|
||||
};
|
||||
|
||||
/* helpers */
|
||||
const char *_fst_get_str_name(unsigned index, const char *names[],
|
||||
size_t names_size)
|
||||
{
|
||||
if (index >= names_size || !names[index])
|
||||
return FST_NAME_UNKNOWN;
|
||||
return names[index];
|
||||
}
|
||||
|
||||
int _fst_get_str_num(const char *name, const char *names[],
|
||||
size_t names_size)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < names_size; i++)
|
||||
if (names[i] && !strncmp(name, names[i], strlen(names[i])))
|
||||
return i;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
const char *fst_session_event_type_name(enum fst_event_type event)
|
||||
{
|
||||
return _fst_get_str_name(event, session_event_names,
|
||||
ARRAY_SIZE(session_event_names));
|
||||
}
|
||||
|
||||
int fst_session_event_num(const char *name)
|
||||
{
|
||||
return _fst_get_str_num(name, session_event_names,
|
||||
ARRAY_SIZE(session_event_names));
|
||||
}
|
||||
|
||||
const char *fst_reason_name(enum fst_reason reason)
|
||||
{
|
||||
return _fst_get_str_name(reason, reason_names, ARRAY_SIZE(reason_names));
|
||||
}
|
||||
|
||||
int fst_reason_num(const char *name)
|
||||
{
|
||||
return _fst_get_str_num(name, reason_names, ARRAY_SIZE(reason_names));
|
||||
}
|
||||
|
||||
const char *fst_session_state_name(enum fst_session_state state)
|
||||
{
|
||||
return _fst_get_str_name(state, session_state_names,
|
||||
ARRAY_SIZE(session_state_names));
|
||||
}
|
||||
|
||||
int fst_session_state_num(const char *name)
|
||||
{
|
||||
return _fst_get_str_num(name, session_state_names,
|
||||
ARRAY_SIZE(session_state_names));
|
||||
}
|
||||
27
qcom/opensource/fst-manager/external/inih/LICENSE.txt
vendored
Normal file
27
qcom/opensource/fst-manager/external/inih/LICENSE.txt
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
|
||||
The "inih" library is distributed under the New BSD license:
|
||||
|
||||
Copyright (c) 2009, Ben Hoyt
|
||||
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 Ben Hoyt 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 BEN HOYT ''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 BEN HOYT 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.
|
||||
179
qcom/opensource/fst-manager/external/inih/ini.c
vendored
Normal file
179
qcom/opensource/fst-manager/external/inih/ini.c
vendored
Normal file
@@ -0,0 +1,179 @@
|
||||
/* inih -- simple .INI file parser
|
||||
|
||||
inih is released under the New BSD license (see LICENSE.txt). Go to the project
|
||||
home page for more info:
|
||||
|
||||
https://github.com/benhoyt/inih
|
||||
|
||||
*/
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ini.h"
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
|
||||
#if !INI_USE_STACK
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
|
||||
#define MAX_SECTION 50
|
||||
#define MAX_NAME 50
|
||||
|
||||
/* Strip whitespace chars off end of given string, in place. Return s. */
|
||||
static char* rstrip(char* s)
|
||||
{
|
||||
char* p = s + strlen(s);
|
||||
while (p > s && isspace((unsigned char)(*--p)))
|
||||
*p = '\0';
|
||||
return s;
|
||||
}
|
||||
|
||||
/* Return pointer to first non-whitespace char in given string. */
|
||||
static char* lskip(const char* s)
|
||||
{
|
||||
while (*s && isspace((unsigned char)(*s)))
|
||||
s++;
|
||||
return (char*)s;
|
||||
}
|
||||
|
||||
/* Return pointer to first char c or ';' comment in given string, or pointer to
|
||||
null at end of string if neither found. ';' must be prefixed by a whitespace
|
||||
character to register as a comment. */
|
||||
static char* find_char_or_comment(const char* s, char c)
|
||||
{
|
||||
int was_whitespace = 0;
|
||||
while (*s && *s != c && !(was_whitespace && *s == ';')) {
|
||||
was_whitespace = isspace((unsigned char)(*s));
|
||||
s++;
|
||||
}
|
||||
return (char*)s;
|
||||
}
|
||||
|
||||
/* See documentation in header file. */
|
||||
int ini_parse_file(FILE* file,
|
||||
int (*handler)(void*, const char*, const char*,
|
||||
const char*),
|
||||
void* user)
|
||||
{
|
||||
/* Uses a fair bit of stack (use heap instead if you need to) */
|
||||
#if INI_USE_STACK
|
||||
char line[INI_MAX_LINE];
|
||||
#else
|
||||
char* line;
|
||||
#endif
|
||||
char section[MAX_SECTION] = "";
|
||||
char prev_name[MAX_NAME] = "";
|
||||
|
||||
char* start;
|
||||
char* end;
|
||||
char* name;
|
||||
char* value;
|
||||
int lineno = 0;
|
||||
int error = 0;
|
||||
|
||||
#if !INI_USE_STACK
|
||||
line = (char*)malloc(INI_MAX_LINE);
|
||||
if (!line) {
|
||||
return -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Scan through file line by line */
|
||||
while (fgets(line, INI_MAX_LINE, file) != NULL) {
|
||||
lineno++;
|
||||
|
||||
start = line;
|
||||
#if INI_ALLOW_BOM
|
||||
if (lineno == 1 && (unsigned char)start[0] == 0xEF &&
|
||||
(unsigned char)start[1] == 0xBB &&
|
||||
(unsigned char)start[2] == 0xBF) {
|
||||
start += 3;
|
||||
}
|
||||
#endif
|
||||
start = lskip(rstrip(start));
|
||||
|
||||
if (*start == ';' || *start == '#') {
|
||||
/* Per Python ConfigParser, allow '#' comments at start of line */
|
||||
}
|
||||
#if INI_ALLOW_MULTILINE
|
||||
else if (*prev_name && *start && start > line) {
|
||||
/* Non-black line with leading whitespace, treat as continuation
|
||||
of previous name's value (as per Python ConfigParser). */
|
||||
if (!handler(user, section, prev_name, start) && !error)
|
||||
error = lineno;
|
||||
}
|
||||
#endif
|
||||
else if (*start == '[') {
|
||||
/* A "[section]" line */
|
||||
end = find_char_or_comment(start + 1, ']');
|
||||
if (*end == ']') {
|
||||
*end = '\0';
|
||||
os_strlcpy(section, start + 1, sizeof(section));
|
||||
*prev_name = '\0';
|
||||
}
|
||||
else if (!error) {
|
||||
/* No ']' found on section line */
|
||||
error = lineno;
|
||||
}
|
||||
}
|
||||
else if (*start && *start != ';') {
|
||||
/* Not a comment, must be a name[=:]value pair */
|
||||
end = find_char_or_comment(start, '=');
|
||||
if (*end != '=') {
|
||||
end = find_char_or_comment(start, ':');
|
||||
}
|
||||
if (*end == '=' || *end == ':') {
|
||||
*end = '\0';
|
||||
name = rstrip(start);
|
||||
value = lskip(end + 1);
|
||||
end = find_char_or_comment(value, '\0');
|
||||
if (*end == ';')
|
||||
*end = '\0';
|
||||
rstrip(value);
|
||||
|
||||
/* Valid name[=:]value pair found, call handler */
|
||||
os_strlcpy(prev_name, name, sizeof(prev_name));
|
||||
if (!handler(user, section, name, value) && !error)
|
||||
error = lineno;
|
||||
}
|
||||
else if (!error) {
|
||||
/* No '=' or ':' found on name[=:]value line */
|
||||
error = lineno;
|
||||
}
|
||||
}
|
||||
|
||||
#if INI_STOP_ON_FIRST_ERROR
|
||||
if (error)
|
||||
break;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !INI_USE_STACK
|
||||
free(line);
|
||||
#endif
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
/* See documentation in header file. */
|
||||
int ini_parse(const char* filename,
|
||||
int (*handler)(void*, const char*, const char*, const char*),
|
||||
void* user)
|
||||
{
|
||||
FILE* file;
|
||||
int error;
|
||||
|
||||
file = fopen(filename, "r");
|
||||
if (!file)
|
||||
return -1;
|
||||
error = ini_parse_file(file, handler, user);
|
||||
fclose(file);
|
||||
return error;
|
||||
}
|
||||
77
qcom/opensource/fst-manager/external/inih/ini.h
vendored
Normal file
77
qcom/opensource/fst-manager/external/inih/ini.h
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
/* inih -- simple .INI file parser
|
||||
|
||||
inih is released under the New BSD license (see LICENSE.txt). Go to the project
|
||||
home page for more info:
|
||||
|
||||
https://github.com/benhoyt/inih
|
||||
|
||||
*/
|
||||
|
||||
#ifndef __INI_H__
|
||||
#define __INI_H__
|
||||
|
||||
/* Make this header file easier to include in C++ code */
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* Parse given INI-style file. May have [section]s, name=value pairs
|
||||
(whitespace stripped), and comments starting with ';' (semicolon). Section
|
||||
is "" if name=value pair parsed before any section heading. name:value
|
||||
pairs are also supported as a concession to Python's ConfigParser.
|
||||
|
||||
For each name=value pair parsed, call handler function with given user
|
||||
pointer as well as section, name, and value (data only valid for duration
|
||||
of handler call). Handler should return nonzero on success, zero on error.
|
||||
|
||||
Returns 0 on success, line number of first error on parse error (doesn't
|
||||
stop on first error), -1 on file open error, or -2 on memory allocation
|
||||
error (only when INI_USE_STACK is zero).
|
||||
*/
|
||||
int ini_parse(const char* filename,
|
||||
int (*handler)(void* user, const char* section,
|
||||
const char* name, const char* value),
|
||||
void* user);
|
||||
|
||||
/* Same as ini_parse(), but takes a FILE* instead of filename. This doesn't
|
||||
close the file when it's finished -- the caller must do that. */
|
||||
int ini_parse_file(FILE* file,
|
||||
int (*handler)(void* user, const char* section,
|
||||
const char* name, const char* value),
|
||||
void* user);
|
||||
|
||||
/* Nonzero to allow multi-line value parsing, in the style of Python's
|
||||
ConfigParser. If allowed, ini_parse() will call the handler with the same
|
||||
name for each subsequent line parsed. */
|
||||
#ifndef INI_ALLOW_MULTILINE
|
||||
#define INI_ALLOW_MULTILINE 1
|
||||
#endif
|
||||
|
||||
/* Nonzero to allow a UTF-8 BOM sequence (0xEF 0xBB 0xBF) at the start of
|
||||
the file. See http://code.google.com/p/inih/issues/detail?id=21 */
|
||||
#ifndef INI_ALLOW_BOM
|
||||
#define INI_ALLOW_BOM 1
|
||||
#endif
|
||||
|
||||
/* Nonzero to use stack, zero to use heap (malloc/free). */
|
||||
#ifndef INI_USE_STACK
|
||||
#define INI_USE_STACK 1
|
||||
#endif
|
||||
|
||||
/* Stop parsing on first error (default is to keep parsing). */
|
||||
#ifndef INI_STOP_ON_FIRST_ERROR
|
||||
#define INI_STOP_ON_FIRST_ERROR 0
|
||||
#endif
|
||||
|
||||
/* Maximum line length for any line in INI file. */
|
||||
#ifndef INI_MAX_LINE
|
||||
#define INI_MAX_LINE 200
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __INI_H__ */
|
||||
707
qcom/opensource/fst-manager/external/os_unix.c
vendored
Normal file
707
qcom/opensource/fst-manager/external/os_unix.c
vendored
Normal file
@@ -0,0 +1,707 @@
|
||||
/*
|
||||
* OS specific functions for UNIX/POSIX systems
|
||||
* Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include <time.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <sys/capability.h>
|
||||
#include <sys/prctl.h>
|
||||
#include <cutils/android_filesystem_config.h>
|
||||
#endif /* ANDROID */
|
||||
|
||||
#include "os.h"
|
||||
#include "common.h"
|
||||
|
||||
#ifdef WPA_TRACE
|
||||
|
||||
#include "wpa_debug.h"
|
||||
#include "trace.h"
|
||||
#include "list.h"
|
||||
|
||||
static struct dl_list alloc_list;
|
||||
|
||||
#define ALLOC_MAGIC 0xa84ef1b2
|
||||
#define FREED_MAGIC 0x67fd487a
|
||||
|
||||
struct os_alloc_trace {
|
||||
unsigned int magic;
|
||||
struct dl_list list;
|
||||
size_t len;
|
||||
WPA_TRACE_INFO
|
||||
};
|
||||
|
||||
#endif /* WPA_TRACE */
|
||||
|
||||
|
||||
void os_sleep(os_time_t sec, os_time_t usec)
|
||||
{
|
||||
if (sec)
|
||||
sleep(sec);
|
||||
if (usec)
|
||||
usleep(usec);
|
||||
}
|
||||
|
||||
|
||||
int os_get_time(struct os_time *t)
|
||||
{
|
||||
int res;
|
||||
struct timeval tv = {};
|
||||
res = gettimeofday(&tv, NULL);
|
||||
t->sec = tv.tv_sec;
|
||||
t->usec = tv.tv_usec;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int os_get_reltime(struct os_reltime *t)
|
||||
{
|
||||
#if defined(CLOCK_BOOTTIME)
|
||||
static clockid_t clock_id = CLOCK_BOOTTIME;
|
||||
#elif defined(CLOCK_MONOTONIC)
|
||||
static clockid_t clock_id = CLOCK_MONOTONIC;
|
||||
#else
|
||||
static clockid_t clock_id = CLOCK_REALTIME;
|
||||
#endif
|
||||
struct timespec ts;
|
||||
int res;
|
||||
|
||||
while (1) {
|
||||
res = clock_gettime(clock_id, &ts);
|
||||
if (res == 0) {
|
||||
t->sec = ts.tv_sec;
|
||||
t->usec = ts.tv_nsec / 1000;
|
||||
return 0;
|
||||
}
|
||||
switch (clock_id) {
|
||||
#ifdef CLOCK_BOOTTIME
|
||||
case CLOCK_BOOTTIME:
|
||||
clock_id = CLOCK_MONOTONIC;
|
||||
break;
|
||||
#endif
|
||||
#ifdef CLOCK_MONOTONIC
|
||||
case CLOCK_MONOTONIC:
|
||||
clock_id = CLOCK_REALTIME;
|
||||
break;
|
||||
#endif
|
||||
case CLOCK_REALTIME:
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int os_mktime(int year, int month, int day, int hour, int min, int sec,
|
||||
os_time_t *t)
|
||||
{
|
||||
struct tm tm, *tm1;
|
||||
time_t t_local, t1, t2;
|
||||
os_time_t tz_offset;
|
||||
|
||||
if (year < 1970 || month < 1 || month > 12 || day < 1 || day > 31 ||
|
||||
hour < 0 || hour > 23 || min < 0 || min > 59 || sec < 0 ||
|
||||
sec > 60)
|
||||
return -1;
|
||||
|
||||
memset(&tm, 0, sizeof(tm));
|
||||
tm.tm_year = year - 1900;
|
||||
tm.tm_mon = month - 1;
|
||||
tm.tm_mday = day;
|
||||
tm.tm_hour = hour;
|
||||
tm.tm_min = min;
|
||||
tm.tm_sec = sec;
|
||||
|
||||
t_local = mktime(&tm);
|
||||
|
||||
/* figure out offset to UTC */
|
||||
tm1 = localtime(&t_local);
|
||||
if (tm1) {
|
||||
t1 = mktime(tm1);
|
||||
tm1 = gmtime(&t_local);
|
||||
if (tm1) {
|
||||
t2 = mktime(tm1);
|
||||
tz_offset = t2 - t1;
|
||||
} else
|
||||
tz_offset = 0;
|
||||
} else
|
||||
tz_offset = 0;
|
||||
|
||||
*t = (os_time_t) t_local - tz_offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int os_gmtime(os_time_t t, struct os_tm *tm)
|
||||
{
|
||||
struct tm *tm2;
|
||||
time_t t2 = t;
|
||||
|
||||
tm2 = gmtime(&t2);
|
||||
if (tm2 == NULL)
|
||||
return -1;
|
||||
tm->sec = tm2->tm_sec;
|
||||
tm->min = tm2->tm_min;
|
||||
tm->hour = tm2->tm_hour;
|
||||
tm->day = tm2->tm_mday;
|
||||
tm->month = tm2->tm_mon + 1;
|
||||
tm->year = tm2->tm_year + 1900;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <fcntl.h>
|
||||
static int os_daemon(int nochdir, int noclose)
|
||||
{
|
||||
int devnull;
|
||||
|
||||
if (chdir("/") < 0)
|
||||
return -1;
|
||||
|
||||
devnull = open("/dev/null", O_RDWR);
|
||||
if (devnull < 0)
|
||||
return -1;
|
||||
|
||||
if (dup2(devnull, STDIN_FILENO) < 0) {
|
||||
close(devnull);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dup2(devnull, STDOUT_FILENO) < 0) {
|
||||
close(devnull);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (dup2(devnull, STDERR_FILENO) < 0) {
|
||||
close(devnull);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else /* __APPLE__ */
|
||||
#define os_daemon daemon
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
|
||||
int os_daemonize(const char *pid_file)
|
||||
{
|
||||
#if defined(__uClinux__) || defined(__sun__)
|
||||
return -1;
|
||||
#else /* defined(__uClinux__) || defined(__sun__) */
|
||||
if (os_daemon(0, 0)) {
|
||||
perror("daemon");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pid_file) {
|
||||
FILE *f = fopen(pid_file, "w");
|
||||
if (f) {
|
||||
fprintf(f, "%u\n", getpid());
|
||||
fclose(f);
|
||||
}
|
||||
}
|
||||
|
||||
return -0;
|
||||
#endif /* defined(__uClinux__) || defined(__sun__) */
|
||||
}
|
||||
|
||||
|
||||
void os_daemonize_terminate(const char *pid_file)
|
||||
{
|
||||
if (pid_file)
|
||||
unlink(pid_file);
|
||||
}
|
||||
|
||||
|
||||
int os_get_random(unsigned char *buf, size_t len)
|
||||
{
|
||||
FILE *f;
|
||||
size_t rc;
|
||||
|
||||
f = fopen("/dev/urandom", "rb");
|
||||
if (f == NULL) {
|
||||
printf("Could not open /dev/urandom.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = fread(buf, 1, len, f);
|
||||
fclose(f);
|
||||
|
||||
return rc != len ? -1 : 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned long os_random(void)
|
||||
{
|
||||
return random();
|
||||
}
|
||||
|
||||
|
||||
char * os_rel2abs_path(const char *rel_path)
|
||||
{
|
||||
char *buf = NULL, *cwd, *ret;
|
||||
size_t len = 128, cwd_len, rel_len, ret_len;
|
||||
int last_errno;
|
||||
|
||||
if (!rel_path)
|
||||
return NULL;
|
||||
|
||||
if (rel_path[0] == '/')
|
||||
return os_strdup(rel_path);
|
||||
|
||||
for (;;) {
|
||||
buf = os_malloc(len);
|
||||
if (buf == NULL)
|
||||
return NULL;
|
||||
cwd = getcwd(buf, len);
|
||||
if (cwd == NULL) {
|
||||
last_errno = errno;
|
||||
os_free(buf);
|
||||
if (last_errno != ERANGE)
|
||||
return NULL;
|
||||
len *= 2;
|
||||
if (len > 2000)
|
||||
return NULL;
|
||||
} else {
|
||||
buf[len - 1] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
cwd_len = os_strlen(cwd);
|
||||
rel_len = os_strlen(rel_path);
|
||||
ret_len = cwd_len + 1 + rel_len + 1;
|
||||
ret = os_malloc(ret_len);
|
||||
if (ret) {
|
||||
os_memcpy(ret, cwd, cwd_len);
|
||||
ret[cwd_len] = '/';
|
||||
os_memcpy(ret + cwd_len + 1, rel_path, rel_len);
|
||||
ret[ret_len - 1] = '\0';
|
||||
}
|
||||
os_free(buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int os_program_init(void)
|
||||
{
|
||||
#ifdef ANDROID
|
||||
/*
|
||||
* We ignore errors here since errors are normal if we
|
||||
* are already running as non-root.
|
||||
*/
|
||||
#ifdef ANDROID_SETGROUPS_OVERRIDE
|
||||
gid_t groups[] = { ANDROID_SETGROUPS_OVERRIDE };
|
||||
#else /* ANDROID_SETGROUPS_OVERRIDE */
|
||||
gid_t groups[] = { AID_INET, AID_WIFI, AID_KEYSTORE };
|
||||
#endif /* ANDROID_SETGROUPS_OVERRIDE */
|
||||
struct __user_cap_header_struct header;
|
||||
struct __user_cap_data_struct cap;
|
||||
|
||||
setgroups(ARRAY_SIZE(groups), groups);
|
||||
|
||||
prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);
|
||||
|
||||
setgid(AID_WIFI);
|
||||
setuid(AID_WIFI);
|
||||
|
||||
header.version = _LINUX_CAPABILITY_VERSION;
|
||||
header.pid = 0;
|
||||
cap.effective = cap.permitted =
|
||||
(1 << CAP_NET_ADMIN) | (1 << CAP_NET_RAW);
|
||||
cap.inheritable = 0;
|
||||
capset(&header, &cap);
|
||||
#endif /* ANDROID */
|
||||
|
||||
#ifdef WPA_TRACE
|
||||
dl_list_init(&alloc_list);
|
||||
#endif /* WPA_TRACE */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void os_program_deinit(void)
|
||||
{
|
||||
#ifdef WPA_TRACE
|
||||
struct os_alloc_trace *a;
|
||||
unsigned long total = 0;
|
||||
dl_list_for_each(a, &alloc_list, struct os_alloc_trace, list) {
|
||||
total += a->len;
|
||||
if (a->magic != ALLOC_MAGIC) {
|
||||
wpa_printf(MSG_INFO, "MEMLEAK[%p]: invalid magic 0x%x "
|
||||
"len %lu",
|
||||
a, a->magic, (unsigned long) a->len);
|
||||
continue;
|
||||
}
|
||||
wpa_printf(MSG_INFO, "MEMLEAK[%p]: len %lu",
|
||||
a, (unsigned long) a->len);
|
||||
wpa_trace_dump("memleak", a);
|
||||
}
|
||||
if (total)
|
||||
wpa_printf(MSG_INFO, "MEMLEAK: total %lu bytes",
|
||||
(unsigned long) total);
|
||||
#endif /* WPA_TRACE */
|
||||
}
|
||||
|
||||
|
||||
int os_setenv(const char *name, const char *value, int overwrite)
|
||||
{
|
||||
return setenv(name, value, overwrite);
|
||||
}
|
||||
|
||||
|
||||
int os_unsetenv(const char *name)
|
||||
{
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__APPLE__) || \
|
||||
defined(__OpenBSD__)
|
||||
unsetenv(name);
|
||||
return 0;
|
||||
#else
|
||||
return unsetenv(name);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
char * os_readfile(const char *name, size_t *len)
|
||||
{
|
||||
FILE *f;
|
||||
char *buf;
|
||||
long pos;
|
||||
|
||||
f = fopen(name, "rb");
|
||||
if (f == NULL)
|
||||
return NULL;
|
||||
|
||||
if (fseek(f, 0, SEEK_END) < 0 || (pos = ftell(f)) < 0) {
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
*len = pos;
|
||||
if (fseek(f, 0, SEEK_SET) < 0) {
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
buf = os_malloc(*len);
|
||||
if (buf == NULL) {
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (fread(buf, 1, *len, f) != *len) {
|
||||
fclose(f);
|
||||
os_free(buf);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
int os_file_exists(const char *fname)
|
||||
{
|
||||
FILE *f = fopen(fname, "rb");
|
||||
if (f == NULL)
|
||||
return 0;
|
||||
fclose(f);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
#ifndef WPA_TRACE
|
||||
void * os_zalloc(size_t size)
|
||||
{
|
||||
return calloc(1, size);
|
||||
}
|
||||
#endif /* WPA_TRACE */
|
||||
|
||||
|
||||
size_t os_strlcpy(char *dest, const char *src, size_t siz)
|
||||
{
|
||||
const char *s = src;
|
||||
size_t left = siz;
|
||||
|
||||
if (left) {
|
||||
/* Copy string up to the maximum size of the dest buffer */
|
||||
while (--left != 0) {
|
||||
if ((*dest++ = *s++) == '\0')
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (left == 0) {
|
||||
/* Not enough room for the string; force NUL-termination */
|
||||
if (siz != 0)
|
||||
*dest = '\0';
|
||||
while (*s++)
|
||||
; /* determine total src string length */
|
||||
}
|
||||
|
||||
return s - src - 1;
|
||||
}
|
||||
|
||||
|
||||
int os_memcmp_const(const void *a, const void *b, size_t len)
|
||||
{
|
||||
const u8 *aa = a;
|
||||
const u8 *bb = b;
|
||||
size_t i;
|
||||
u8 res;
|
||||
|
||||
for (res = 0, i = 0; i < len; i++)
|
||||
res |= aa[i] ^ bb[i];
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#ifdef WPA_TRACE
|
||||
|
||||
#if defined(WPA_TRACE_BFD) && defined(CONFIG_TESTING_OPTIONS)
|
||||
char wpa_trace_fail_func[256] = { 0 };
|
||||
unsigned int wpa_trace_fail_after;
|
||||
|
||||
static int testing_fail_alloc(void)
|
||||
{
|
||||
const char *func[WPA_TRACE_LEN];
|
||||
size_t i, res, len;
|
||||
char *pos, *next;
|
||||
int match;
|
||||
|
||||
if (!wpa_trace_fail_after)
|
||||
return 0;
|
||||
|
||||
res = wpa_trace_calling_func(func, WPA_TRACE_LEN);
|
||||
i = 0;
|
||||
if (i < res && os_strcmp(func[i], __func__) == 0)
|
||||
i++;
|
||||
if (i < res && os_strcmp(func[i], "os_malloc") == 0)
|
||||
i++;
|
||||
if (i < res && os_strcmp(func[i], "os_zalloc") == 0)
|
||||
i++;
|
||||
if (i < res && os_strcmp(func[i], "os_calloc") == 0)
|
||||
i++;
|
||||
if (i < res && os_strcmp(func[i], "os_realloc") == 0)
|
||||
i++;
|
||||
if (i < res && os_strcmp(func[i], "os_realloc_array") == 0)
|
||||
i++;
|
||||
if (i < res && os_strcmp(func[i], "os_strdup") == 0)
|
||||
i++;
|
||||
|
||||
pos = wpa_trace_fail_func;
|
||||
|
||||
match = 0;
|
||||
while (i < res) {
|
||||
int allow_skip = 1;
|
||||
int maybe = 0;
|
||||
|
||||
if (*pos == '=') {
|
||||
allow_skip = 0;
|
||||
pos++;
|
||||
} else if (*pos == '?') {
|
||||
maybe = 1;
|
||||
pos++;
|
||||
}
|
||||
next = os_strchr(pos, ';');
|
||||
if (next)
|
||||
len = next - pos;
|
||||
else
|
||||
len = os_strlen(pos);
|
||||
if (os_memcmp(pos, func[i], len) != 0) {
|
||||
if (maybe && next) {
|
||||
pos = next + 1;
|
||||
continue;
|
||||
}
|
||||
if (allow_skip) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (!next) {
|
||||
match = 1;
|
||||
break;
|
||||
}
|
||||
pos = next + 1;
|
||||
i++;
|
||||
}
|
||||
if (!match)
|
||||
return 0;
|
||||
|
||||
wpa_trace_fail_after--;
|
||||
if (wpa_trace_fail_after == 0) {
|
||||
wpa_printf(MSG_INFO, "TESTING: fail allocation at %s",
|
||||
wpa_trace_fail_func);
|
||||
for (i = 0; i < res; i++)
|
||||
wpa_printf(MSG_INFO, "backtrace[%d] = %s",
|
||||
(int) i, func[i]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static inline int testing_fail_alloc(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void * os_malloc(size_t size)
|
||||
{
|
||||
struct os_alloc_trace *a;
|
||||
|
||||
if (testing_fail_alloc())
|
||||
return NULL;
|
||||
|
||||
a = malloc(sizeof(*a) + size);
|
||||
if (a == NULL)
|
||||
return NULL;
|
||||
a->magic = ALLOC_MAGIC;
|
||||
dl_list_add(&alloc_list, &a->list);
|
||||
a->len = size;
|
||||
wpa_trace_record(a);
|
||||
return a + 1;
|
||||
}
|
||||
|
||||
|
||||
void * os_realloc(void *ptr, size_t size)
|
||||
{
|
||||
struct os_alloc_trace *a;
|
||||
size_t copy_len;
|
||||
void *n;
|
||||
|
||||
if (ptr == NULL)
|
||||
return os_malloc(size);
|
||||
|
||||
a = (struct os_alloc_trace *) ptr - 1;
|
||||
if (a->magic != ALLOC_MAGIC) {
|
||||
wpa_printf(MSG_INFO, "REALLOC[%p]: invalid magic 0x%x%s",
|
||||
a, a->magic,
|
||||
a->magic == FREED_MAGIC ? " (already freed)" : "");
|
||||
wpa_trace_show("Invalid os_realloc() call");
|
||||
abort();
|
||||
}
|
||||
n = os_malloc(size);
|
||||
if (n == NULL)
|
||||
return NULL;
|
||||
copy_len = a->len;
|
||||
if (copy_len > size)
|
||||
copy_len = size;
|
||||
os_memcpy(n, a + 1, copy_len);
|
||||
os_free(ptr);
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
void os_free(void *ptr)
|
||||
{
|
||||
struct os_alloc_trace *a;
|
||||
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
a = (struct os_alloc_trace *) ptr - 1;
|
||||
if (a->magic != ALLOC_MAGIC) {
|
||||
wpa_printf(MSG_INFO, "FREE[%p]: invalid magic 0x%x%s",
|
||||
a, a->magic,
|
||||
a->magic == FREED_MAGIC ? " (already freed)" : "");
|
||||
wpa_trace_show("Invalid os_free() call");
|
||||
abort();
|
||||
}
|
||||
dl_list_del(&a->list);
|
||||
a->magic = FREED_MAGIC;
|
||||
|
||||
wpa_trace_check_ref(ptr);
|
||||
free(a);
|
||||
}
|
||||
|
||||
|
||||
void * os_zalloc(size_t size)
|
||||
{
|
||||
void *ptr = os_malloc(size);
|
||||
if (ptr)
|
||||
os_memset(ptr, 0, size);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
|
||||
char * os_strdup(const char *s)
|
||||
{
|
||||
size_t len;
|
||||
char *d;
|
||||
len = os_strlen(s);
|
||||
d = os_malloc(len + 1);
|
||||
if (d == NULL)
|
||||
return NULL;
|
||||
os_memcpy(d, s, len);
|
||||
d[len] = '\0';
|
||||
return d;
|
||||
}
|
||||
|
||||
#endif /* WPA_TRACE */
|
||||
|
||||
|
||||
int os_exec(const char *program, const char *arg, int wait_completion)
|
||||
{
|
||||
pid_t pid;
|
||||
int pid_status;
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("fork");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
/* run the external command in the child process */
|
||||
const int MAX_ARG = 30;
|
||||
char *_program, *_arg, *pos;
|
||||
char *argv[MAX_ARG + 1];
|
||||
int i;
|
||||
|
||||
_program = os_strdup(program);
|
||||
_arg = os_strdup(arg);
|
||||
|
||||
argv[0] = _program;
|
||||
|
||||
i = 1;
|
||||
pos = _arg;
|
||||
while (i < MAX_ARG && pos && *pos) {
|
||||
while (*pos == ' ')
|
||||
pos++;
|
||||
if (*pos == '\0')
|
||||
break;
|
||||
argv[i++] = pos;
|
||||
pos = os_strchr(pos, ' ');
|
||||
if (pos)
|
||||
*pos++ = '\0';
|
||||
}
|
||||
argv[i] = NULL;
|
||||
|
||||
execv(program, argv);
|
||||
perror("execv");
|
||||
os_free(_program);
|
||||
os_free(_arg);
|
||||
exit(0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (wait_completion) {
|
||||
/* wait for the child process to complete in the parent */
|
||||
waitpid(pid, &pid_status, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
0
qcom/opensource/fst-manager/external/utils/build_config.h
vendored
Normal file
0
qcom/opensource/fst-manager/external/utils/build_config.h
vendored
Normal file
579
qcom/opensource/fst-manager/external/utils/common.h
vendored
Normal file
579
qcom/opensource/fst-manager/external/utils/common.h
vendored
Normal file
@@ -0,0 +1,579 @@
|
||||
/*
|
||||
* wpa_supplicant/hostapd / common helper functions, etc.
|
||||
* Copyright (c) 2002-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef COMMON_H
|
||||
#define COMMON_H
|
||||
|
||||
#include "os.h"
|
||||
|
||||
#if defined(__linux__) || defined(__GLIBC__)
|
||||
#include <endian.h>
|
||||
#include <byteswap.h>
|
||||
#endif /* __linux__ */
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__) || \
|
||||
defined(__OpenBSD__)
|
||||
#include <sys/types.h>
|
||||
#include <sys/endian.h>
|
||||
#define __BYTE_ORDER _BYTE_ORDER
|
||||
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
|
||||
#define __BIG_ENDIAN _BIG_ENDIAN
|
||||
#ifdef __OpenBSD__
|
||||
#define bswap_16 swap16
|
||||
#define bswap_32 swap32
|
||||
#define bswap_64 swap64
|
||||
#else /* __OpenBSD__ */
|
||||
#define bswap_16 bswap16
|
||||
#define bswap_32 bswap32
|
||||
#define bswap_64 bswap64
|
||||
#endif /* __OpenBSD__ */
|
||||
#endif /* defined(__FreeBSD__) || defined(__NetBSD__) ||
|
||||
* defined(__DragonFly__) || defined(__OpenBSD__) */
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <sys/types.h>
|
||||
#include <machine/endian.h>
|
||||
#define __BYTE_ORDER _BYTE_ORDER
|
||||
#define __LITTLE_ENDIAN _LITTLE_ENDIAN
|
||||
#define __BIG_ENDIAN _BIG_ENDIAN
|
||||
static inline unsigned short bswap_16(unsigned short v)
|
||||
{
|
||||
return ((v & 0xff) << 8) | (v >> 8);
|
||||
}
|
||||
|
||||
static inline unsigned int bswap_32(unsigned int v)
|
||||
{
|
||||
return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
|
||||
((v & 0xff0000) >> 8) | (v >> 24);
|
||||
}
|
||||
#endif /* __APPLE__ */
|
||||
|
||||
#ifdef CONFIG_TI_COMPILER
|
||||
#define __BIG_ENDIAN 4321
|
||||
#define __LITTLE_ENDIAN 1234
|
||||
#ifdef __big_endian__
|
||||
#define __BYTE_ORDER __BIG_ENDIAN
|
||||
#else
|
||||
#define __BYTE_ORDER __LITTLE_ENDIAN
|
||||
#endif
|
||||
#endif /* CONFIG_TI_COMPILER */
|
||||
|
||||
#ifdef CONFIG_NATIVE_WINDOWS
|
||||
#include <winsock.h>
|
||||
|
||||
typedef int socklen_t;
|
||||
|
||||
#ifndef MSG_DONTWAIT
|
||||
#define MSG_DONTWAIT 0 /* not supported */
|
||||
#endif
|
||||
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define inline __inline
|
||||
|
||||
#undef vsnprintf
|
||||
#define vsnprintf _vsnprintf
|
||||
#undef close
|
||||
#define close closesocket
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
|
||||
/* Define platform specific integer types */
|
||||
|
||||
#ifdef _MSC_VER
|
||||
typedef UINT64 u64;
|
||||
typedef UINT32 u32;
|
||||
typedef UINT16 u16;
|
||||
typedef UINT8 u8;
|
||||
typedef INT64 s64;
|
||||
typedef INT32 s32;
|
||||
typedef INT16 s16;
|
||||
typedef INT8 s8;
|
||||
#define WPA_TYPES_DEFINED
|
||||
#endif /* _MSC_VER */
|
||||
|
||||
#ifdef __vxworks
|
||||
typedef unsigned long long u64;
|
||||
typedef UINT32 u32;
|
||||
typedef UINT16 u16;
|
||||
typedef UINT8 u8;
|
||||
typedef long long s64;
|
||||
typedef INT32 s32;
|
||||
typedef INT16 s16;
|
||||
typedef INT8 s8;
|
||||
#define WPA_TYPES_DEFINED
|
||||
#endif /* __vxworks */
|
||||
|
||||
#ifdef CONFIG_TI_COMPILER
|
||||
#ifdef _LLONG_AVAILABLE
|
||||
typedef unsigned long long u64;
|
||||
#else
|
||||
/*
|
||||
* TODO: 64-bit variable not available. Using long as a workaround to test the
|
||||
* build, but this will likely not work for all operations.
|
||||
*/
|
||||
typedef unsigned long u64;
|
||||
#endif
|
||||
typedef unsigned int u32;
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned char u8;
|
||||
#define WPA_TYPES_DEFINED
|
||||
#endif /* CONFIG_TI_COMPILER */
|
||||
|
||||
#ifndef WPA_TYPES_DEFINED
|
||||
#ifdef CONFIG_USE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
typedef uint64_t u64;
|
||||
typedef uint32_t u32;
|
||||
typedef uint16_t u16;
|
||||
typedef uint8_t u8;
|
||||
typedef int64_t s64;
|
||||
typedef int32_t s32;
|
||||
typedef int16_t s16;
|
||||
typedef int8_t s8;
|
||||
#define WPA_TYPES_DEFINED
|
||||
#endif /* !WPA_TYPES_DEFINED */
|
||||
|
||||
|
||||
/* Define platform specific byte swapping macros */
|
||||
|
||||
#if defined(__CYGWIN__) || defined(CONFIG_NATIVE_WINDOWS)
|
||||
|
||||
static inline unsigned short wpa_swap_16(unsigned short v)
|
||||
{
|
||||
return ((v & 0xff) << 8) | (v >> 8);
|
||||
}
|
||||
|
||||
static inline unsigned int wpa_swap_32(unsigned int v)
|
||||
{
|
||||
return ((v & 0xff) << 24) | ((v & 0xff00) << 8) |
|
||||
((v & 0xff0000) >> 8) | (v >> 24);
|
||||
}
|
||||
|
||||
#define le_to_host16(n) (n)
|
||||
#define host_to_le16(n) (n)
|
||||
#define be_to_host16(n) wpa_swap_16(n)
|
||||
#define host_to_be16(n) wpa_swap_16(n)
|
||||
#define le_to_host32(n) (n)
|
||||
#define host_to_le32(n) (n)
|
||||
#define be_to_host32(n) wpa_swap_32(n)
|
||||
#define host_to_be32(n) wpa_swap_32(n)
|
||||
|
||||
#define WPA_BYTE_SWAP_DEFINED
|
||||
|
||||
#endif /* __CYGWIN__ || CONFIG_NATIVE_WINDOWS */
|
||||
|
||||
|
||||
#ifndef WPA_BYTE_SWAP_DEFINED
|
||||
|
||||
#ifndef __BYTE_ORDER
|
||||
#ifndef __LITTLE_ENDIAN
|
||||
#ifndef __BIG_ENDIAN
|
||||
#define __LITTLE_ENDIAN 1234
|
||||
#define __BIG_ENDIAN 4321
|
||||
#if defined(sparc)
|
||||
#define __BYTE_ORDER __BIG_ENDIAN
|
||||
#endif
|
||||
#endif /* __BIG_ENDIAN */
|
||||
#endif /* __LITTLE_ENDIAN */
|
||||
#endif /* __BYTE_ORDER */
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
#define le_to_host16(n) ((__force u16) (le16) (n))
|
||||
#define host_to_le16(n) ((__force le16) (u16) (n))
|
||||
#define be_to_host16(n) bswap_16((__force u16) (be16) (n))
|
||||
#define host_to_be16(n) ((__force be16) bswap_16((n)))
|
||||
#define le_to_host32(n) ((__force u32) (le32) (n))
|
||||
#define host_to_le32(n) ((__force le32) (u32) (n))
|
||||
#define be_to_host32(n) bswap_32((__force u32) (be32) (n))
|
||||
#define host_to_be32(n) ((__force be32) bswap_32((n)))
|
||||
#define le_to_host64(n) ((__force u64) (le64) (n))
|
||||
#define host_to_le64(n) ((__force le64) (u64) (n))
|
||||
#define be_to_host64(n) bswap_64((__force u64) (be64) (n))
|
||||
#define host_to_be64(n) ((__force be64) bswap_64((n)))
|
||||
#elif __BYTE_ORDER == __BIG_ENDIAN
|
||||
#define le_to_host16(n) bswap_16(n)
|
||||
#define host_to_le16(n) bswap_16(n)
|
||||
#define be_to_host16(n) (n)
|
||||
#define host_to_be16(n) (n)
|
||||
#define le_to_host32(n) bswap_32(n)
|
||||
#define host_to_le32(n) bswap_32(n)
|
||||
#define be_to_host32(n) (n)
|
||||
#define host_to_be32(n) (n)
|
||||
#define le_to_host64(n) bswap_64(n)
|
||||
#define host_to_le64(n) bswap_64(n)
|
||||
#define be_to_host64(n) (n)
|
||||
#define host_to_be64(n) (n)
|
||||
#ifndef WORDS_BIGENDIAN
|
||||
#define WORDS_BIGENDIAN
|
||||
#endif
|
||||
#else
|
||||
#error Could not determine CPU byte order
|
||||
#endif
|
||||
|
||||
#define WPA_BYTE_SWAP_DEFINED
|
||||
#endif /* !WPA_BYTE_SWAP_DEFINED */
|
||||
|
||||
|
||||
/* Macros for handling unaligned memory accesses */
|
||||
|
||||
static inline u16 WPA_GET_BE16(const u8 *a)
|
||||
{
|
||||
return (a[0] << 8) | a[1];
|
||||
}
|
||||
|
||||
static inline void WPA_PUT_BE16(u8 *a, u16 val)
|
||||
{
|
||||
a[0] = val >> 8;
|
||||
a[1] = val & 0xff;
|
||||
}
|
||||
|
||||
static inline u16 WPA_GET_LE16(const u8 *a)
|
||||
{
|
||||
return (a[1] << 8) | a[0];
|
||||
}
|
||||
|
||||
static inline void WPA_PUT_LE16(u8 *a, u16 val)
|
||||
{
|
||||
a[1] = val >> 8;
|
||||
a[0] = val & 0xff;
|
||||
}
|
||||
|
||||
static inline u32 WPA_GET_BE24(const u8 *a)
|
||||
{
|
||||
return (a[0] << 16) | (a[1] << 8) | a[2];
|
||||
}
|
||||
|
||||
static inline void WPA_PUT_BE24(u8 *a, u32 val)
|
||||
{
|
||||
a[0] = (val >> 16) & 0xff;
|
||||
a[1] = (val >> 8) & 0xff;
|
||||
a[2] = val & 0xff;
|
||||
}
|
||||
|
||||
static inline u32 WPA_GET_BE32(const u8 *a)
|
||||
{
|
||||
return (a[0] << 24) | (a[1] << 16) | (a[2] << 8) | a[3];
|
||||
}
|
||||
|
||||
static inline void WPA_PUT_BE32(u8 *a, u32 val)
|
||||
{
|
||||
a[0] = (val >> 24) & 0xff;
|
||||
a[1] = (val >> 16) & 0xff;
|
||||
a[2] = (val >> 8) & 0xff;
|
||||
a[3] = val & 0xff;
|
||||
}
|
||||
|
||||
static inline u32 WPA_GET_LE32(const u8 *a)
|
||||
{
|
||||
return (a[3] << 24) | (a[2] << 16) | (a[1] << 8) | a[0];
|
||||
}
|
||||
|
||||
static inline void WPA_PUT_LE32(u8 *a, u32 val)
|
||||
{
|
||||
a[3] = (val >> 24) & 0xff;
|
||||
a[2] = (val >> 16) & 0xff;
|
||||
a[1] = (val >> 8) & 0xff;
|
||||
a[0] = val & 0xff;
|
||||
}
|
||||
|
||||
static inline u64 WPA_GET_BE64(const u8 *a)
|
||||
{
|
||||
return (((u64) a[0]) << 56) | (((u64) a[1]) << 48) |
|
||||
(((u64) a[2]) << 40) | (((u64) a[3]) << 32) |
|
||||
(((u64) a[4]) << 24) | (((u64) a[5]) << 16) |
|
||||
(((u64) a[6]) << 8) | ((u64) a[7]);
|
||||
}
|
||||
|
||||
static inline void WPA_PUT_BE64(u8 *a, u64 val)
|
||||
{
|
||||
a[0] = val >> 56;
|
||||
a[1] = val >> 48;
|
||||
a[2] = val >> 40;
|
||||
a[3] = val >> 32;
|
||||
a[4] = val >> 24;
|
||||
a[5] = val >> 16;
|
||||
a[6] = val >> 8;
|
||||
a[7] = val & 0xff;
|
||||
}
|
||||
|
||||
static inline u64 WPA_GET_LE64(const u8 *a)
|
||||
{
|
||||
return (((u64) a[7]) << 56) | (((u64) a[6]) << 48) |
|
||||
(((u64) a[5]) << 40) | (((u64) a[4]) << 32) |
|
||||
(((u64) a[3]) << 24) | (((u64) a[2]) << 16) |
|
||||
(((u64) a[1]) << 8) | ((u64) a[0]);
|
||||
}
|
||||
|
||||
static inline void WPA_PUT_LE64(u8 *a, u64 val)
|
||||
{
|
||||
a[7] = val >> 56;
|
||||
a[6] = val >> 48;
|
||||
a[5] = val >> 40;
|
||||
a[4] = val >> 32;
|
||||
a[3] = val >> 24;
|
||||
a[2] = val >> 16;
|
||||
a[1] = val >> 8;
|
||||
a[0] = val & 0xff;
|
||||
}
|
||||
|
||||
|
||||
#ifndef ETH_ALEN
|
||||
#define ETH_ALEN 6
|
||||
#endif
|
||||
#ifndef ETH_HLEN
|
||||
#define ETH_HLEN 14
|
||||
#endif
|
||||
#ifndef IFNAMSIZ
|
||||
#define IFNAMSIZ 16
|
||||
#endif
|
||||
#ifndef ETH_P_ALL
|
||||
#define ETH_P_ALL 0x0003
|
||||
#endif
|
||||
#ifndef ETH_P_80211_ENCAP
|
||||
#define ETH_P_80211_ENCAP 0x890d /* TDLS comes under this category */
|
||||
#endif
|
||||
#ifndef ETH_P_PAE
|
||||
#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
|
||||
#endif /* ETH_P_PAE */
|
||||
#ifndef ETH_P_EAPOL
|
||||
#define ETH_P_EAPOL ETH_P_PAE
|
||||
#endif /* ETH_P_EAPOL */
|
||||
#ifndef ETH_P_RSN_PREAUTH
|
||||
#define ETH_P_RSN_PREAUTH 0x88c7
|
||||
#endif /* ETH_P_RSN_PREAUTH */
|
||||
#ifndef ETH_P_RRB
|
||||
#define ETH_P_RRB 0x890D
|
||||
#endif /* ETH_P_RRB */
|
||||
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define PRINTF_FORMAT(a,b) __attribute__ ((format (printf, (a), (b))))
|
||||
#define STRUCT_PACKED __attribute__ ((packed))
|
||||
#else
|
||||
#define PRINTF_FORMAT(a,b)
|
||||
#define STRUCT_PACKED
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef CONFIG_ANSI_C_EXTRA
|
||||
|
||||
#if !defined(_MSC_VER) || _MSC_VER < 1400
|
||||
/* snprintf - used in number of places; sprintf() is _not_ a good replacement
|
||||
* due to possible buffer overflow; see, e.g.,
|
||||
* http://www.ijs.si/software/snprintf/ for portable implementation of
|
||||
* snprintf. */
|
||||
int snprintf(char *str, size_t size, const char *format, ...);
|
||||
|
||||
/* vsnprintf - only used for wpa_msg() in wpa_supplicant.c */
|
||||
int vsnprintf(char *str, size_t size, const char *format, va_list ap);
|
||||
#endif /* !defined(_MSC_VER) || _MSC_VER < 1400 */
|
||||
|
||||
/* getopt - only used in main.c */
|
||||
int getopt(int argc, char *const argv[], const char *optstring);
|
||||
extern char *optarg;
|
||||
extern int optind;
|
||||
|
||||
#ifndef CONFIG_NO_SOCKLEN_T_TYPEDEF
|
||||
#ifndef __socklen_t_defined
|
||||
typedef int socklen_t;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* inline - define as __inline or just define it to be empty, if needed */
|
||||
#ifdef CONFIG_NO_INLINE
|
||||
#define inline
|
||||
#else
|
||||
#define inline __inline
|
||||
#endif
|
||||
|
||||
#ifndef __func__
|
||||
#define __func__ "__func__ not defined"
|
||||
#endif
|
||||
|
||||
#ifndef bswap_16
|
||||
#define bswap_16(a) ((((u16) (a) << 8) & 0xff00) | (((u16) (a) >> 8) & 0xff))
|
||||
#endif
|
||||
|
||||
#ifndef bswap_32
|
||||
#define bswap_32(a) ((((u32) (a) << 24) & 0xff000000) | \
|
||||
(((u32) (a) << 8) & 0xff0000) | \
|
||||
(((u32) (a) >> 8) & 0xff00) | \
|
||||
(((u32) (a) >> 24) & 0xff))
|
||||
#endif
|
||||
|
||||
#ifndef MSG_DONTWAIT
|
||||
#define MSG_DONTWAIT 0
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
void perror(const char *s);
|
||||
#endif /* _WIN32_WCE */
|
||||
|
||||
#endif /* CONFIG_ANSI_C_EXTRA */
|
||||
|
||||
#ifndef MAC2STR
|
||||
#define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5]
|
||||
#define MACSTR "%02x:%02x:%02x:%02x:%02x:%02x"
|
||||
|
||||
/*
|
||||
* Compact form for string representation of MAC address
|
||||
* To be used, e.g., for constructing dbus paths for P2P Devices
|
||||
*/
|
||||
#define COMPACT_MACSTR "%02x%02x%02x%02x%02x%02x"
|
||||
#endif
|
||||
|
||||
#ifndef BIT
|
||||
#define BIT(x) (1 << (x))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Definitions for sparse validation
|
||||
* (http://kernel.org/pub/linux/kernel/people/josh/sparse/)
|
||||
*/
|
||||
#ifdef __CHECKER__
|
||||
#define __force __attribute__((force))
|
||||
#define __bitwise __attribute__((bitwise))
|
||||
#else
|
||||
#define __force
|
||||
#ifndef __bitwise
|
||||
#define __bitwise
|
||||
#endif
|
||||
#endif
|
||||
|
||||
typedef u16 __bitwise be16;
|
||||
typedef u16 __bitwise le16;
|
||||
typedef u32 __bitwise be32;
|
||||
typedef u32 __bitwise le32;
|
||||
typedef u64 __bitwise be64;
|
||||
typedef u64 __bitwise le64;
|
||||
|
||||
#ifndef __must_check
|
||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
#define __must_check __attribute__((__warn_unused_result__))
|
||||
#else
|
||||
#define __must_check
|
||||
#endif /* __GNUC__ */
|
||||
#endif /* __must_check */
|
||||
|
||||
#ifndef __maybe_unused
|
||||
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
|
||||
#define __maybe_unused __attribute__((unused))
|
||||
#else
|
||||
#define __maybe_unused
|
||||
#endif /* __GNUC__ */
|
||||
#endif /* __must_check */
|
||||
|
||||
int hwaddr_aton(const char *txt, u8 *addr);
|
||||
int hwaddr_masked_aton(const char *txt, u8 *addr, u8 *mask, u8 maskable);
|
||||
int hwaddr_compact_aton(const char *txt, u8 *addr);
|
||||
int hwaddr_aton2(const char *txt, u8 *addr);
|
||||
int hex2byte(const char *hex);
|
||||
int hexstr2bin(const char *hex, u8 *buf, size_t len);
|
||||
void inc_byte_array(u8 *counter, size_t len);
|
||||
void wpa_get_ntp_timestamp(u8 *buf);
|
||||
int wpa_scnprintf(char *buf, size_t size, const char *fmt, ...);
|
||||
int wpa_snprintf_hex(char *buf, size_t buf_size, const u8 *data, size_t len);
|
||||
int wpa_snprintf_hex_uppercase(char *buf, size_t buf_size, const u8 *data,
|
||||
size_t len);
|
||||
|
||||
int hwaddr_mask_txt(char *buf, size_t len, const u8 *addr, const u8 *mask);
|
||||
|
||||
#ifdef CONFIG_NATIVE_WINDOWS
|
||||
void wpa_unicode2ascii_inplace(TCHAR *str);
|
||||
TCHAR * wpa_strdup_tchar(const char *str);
|
||||
#else /* CONFIG_NATIVE_WINDOWS */
|
||||
#define wpa_unicode2ascii_inplace(s) do { } while (0)
|
||||
#define wpa_strdup_tchar(s) strdup((s))
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||
|
||||
void printf_encode(char *txt, size_t maxlen, const u8 *data, size_t len);
|
||||
size_t printf_decode(u8 *buf, size_t maxlen, const char *str);
|
||||
|
||||
const char * wpa_ssid_txt(const u8 *ssid, size_t ssid_len);
|
||||
|
||||
char * wpa_config_parse_string(const char *value, size_t *len);
|
||||
int is_hex(const u8 *data, size_t len);
|
||||
size_t merge_byte_arrays(u8 *res, size_t res_len,
|
||||
const u8 *src1, size_t src1_len,
|
||||
const u8 *src2, size_t src2_len);
|
||||
char * dup_binstr(const void *src, size_t len);
|
||||
|
||||
static inline int is_zero_ether_addr(const u8 *a)
|
||||
{
|
||||
return !(a[0] | a[1] | a[2] | a[3] | a[4] | a[5]);
|
||||
}
|
||||
|
||||
static inline int is_broadcast_ether_addr(const u8 *a)
|
||||
{
|
||||
return (a[0] & a[1] & a[2] & a[3] & a[4] & a[5]) == 0xff;
|
||||
}
|
||||
|
||||
static inline int is_multicast_ether_addr(const u8 *a)
|
||||
{
|
||||
return a[0] & 0x01;
|
||||
}
|
||||
|
||||
#define broadcast_ether_addr (const u8 *) "\xff\xff\xff\xff\xff\xff"
|
||||
|
||||
#include "wpa_debug.h"
|
||||
|
||||
|
||||
struct wpa_freq_range_list {
|
||||
struct wpa_freq_range {
|
||||
unsigned int min;
|
||||
unsigned int max;
|
||||
} *range;
|
||||
unsigned int num;
|
||||
};
|
||||
|
||||
int freq_range_list_parse(struct wpa_freq_range_list *res, const char *value);
|
||||
int freq_range_list_includes(const struct wpa_freq_range_list *list,
|
||||
unsigned int freq);
|
||||
char * freq_range_list_str(const struct wpa_freq_range_list *list);
|
||||
|
||||
int int_array_len(const int *a);
|
||||
void int_array_concat(int **res, const int *a);
|
||||
void int_array_sort_unique(int *a);
|
||||
void int_array_add_unique(int **res, int a);
|
||||
|
||||
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
|
||||
|
||||
void str_clear_free(char *str);
|
||||
void bin_clear_free(void *bin, size_t len);
|
||||
|
||||
int random_mac_addr(u8 *addr);
|
||||
int random_mac_addr_keep_oui(u8 *addr);
|
||||
|
||||
char * str_token(char *str, const char *delim, char **context);
|
||||
|
||||
|
||||
/*
|
||||
* gcc 4.4 ends up generating strict-aliasing warnings about some very common
|
||||
* networking socket uses that do not really result in a real problem and
|
||||
* cannot be easily avoided with union-based type-punning due to struct
|
||||
* definitions including another struct in system header files. To avoid having
|
||||
* to fully disable strict-aliasing warnings, provide a mechanism to hide the
|
||||
* typecast from aliasing for now. A cleaner solution will hopefully be found
|
||||
* in the future to handle these cases.
|
||||
*/
|
||||
void * __hide_aliasing_typecast(void *foo);
|
||||
#define aliasing_hide_typecast(a,t) (t *) __hide_aliasing_typecast((a))
|
||||
|
||||
#ifdef CONFIG_VALGRIND
|
||||
#include <valgrind/memcheck.h>
|
||||
#define WPA_MEM_DEFINED(ptr, len) VALGRIND_MAKE_MEM_DEFINED((ptr), (len))
|
||||
#else /* CONFIG_VALGRIND */
|
||||
#define WPA_MEM_DEFINED(ptr, len) do { } while (0)
|
||||
#endif /* CONFIG_VALGRIND */
|
||||
|
||||
#endif /* COMMON_H */
|
||||
359
qcom/opensource/fst-manager/external/utils/eloop.h
vendored
Normal file
359
qcom/opensource/fst-manager/external/utils/eloop.h
vendored
Normal file
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* Event loop
|
||||
* Copyright (c) 2002-2006, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*
|
||||
* This file defines an event loop interface that supports processing events
|
||||
* from registered timeouts (i.e., do something after N seconds), sockets
|
||||
* (e.g., a new packet available for reading), and signals. eloop.c is an
|
||||
* implementation of this interface using select() and sockets. This is
|
||||
* suitable for most UNIX/POSIX systems. When porting to other operating
|
||||
* systems, it may be necessary to replace that implementation with OS specific
|
||||
* mechanisms.
|
||||
*/
|
||||
|
||||
#ifndef ELOOP_H
|
||||
#define ELOOP_H
|
||||
|
||||
/**
|
||||
* ELOOP_ALL_CTX - eloop_cancel_timeout() magic number to match all timeouts
|
||||
*/
|
||||
#define ELOOP_ALL_CTX (void *) -1
|
||||
|
||||
/**
|
||||
* eloop_event_type - eloop socket event type for eloop_register_sock()
|
||||
* @EVENT_TYPE_READ: Socket has data available for reading
|
||||
* @EVENT_TYPE_WRITE: Socket has room for new data to be written
|
||||
* @EVENT_TYPE_EXCEPTION: An exception has been reported
|
||||
*/
|
||||
typedef enum {
|
||||
EVENT_TYPE_READ = 0,
|
||||
EVENT_TYPE_WRITE,
|
||||
EVENT_TYPE_EXCEPTION
|
||||
} eloop_event_type;
|
||||
|
||||
/**
|
||||
* eloop_sock_handler - eloop socket event callback type
|
||||
* @sock: File descriptor number for the socket
|
||||
* @eloop_ctx: Registered callback context data (eloop_data)
|
||||
* @sock_ctx: Registered callback context data (user_data)
|
||||
*/
|
||||
typedef void (*eloop_sock_handler)(int sock, void *eloop_ctx, void *sock_ctx);
|
||||
|
||||
/**
|
||||
* eloop_event_handler - eloop generic event callback type
|
||||
* @eloop_ctx: Registered callback context data (eloop_data)
|
||||
* @sock_ctx: Registered callback context data (user_data)
|
||||
*/
|
||||
typedef void (*eloop_event_handler)(void *eloop_data, void *user_ctx);
|
||||
|
||||
/**
|
||||
* eloop_timeout_handler - eloop timeout event callback type
|
||||
* @eloop_ctx: Registered callback context data (eloop_data)
|
||||
* @sock_ctx: Registered callback context data (user_data)
|
||||
*/
|
||||
typedef void (*eloop_timeout_handler)(void *eloop_data, void *user_ctx);
|
||||
|
||||
/**
|
||||
* eloop_signal_handler - eloop signal event callback type
|
||||
* @sig: Signal number
|
||||
* @signal_ctx: Registered callback context data (user_data from
|
||||
* eloop_register_signal(), eloop_register_signal_terminate(), or
|
||||
* eloop_register_signal_reconfig() call)
|
||||
*/
|
||||
typedef void (*eloop_signal_handler)(int sig, void *signal_ctx);
|
||||
|
||||
/**
|
||||
* eloop_init() - Initialize global event loop data
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function must be called before any other eloop_* function.
|
||||
*/
|
||||
int eloop_init(void);
|
||||
|
||||
/**
|
||||
* eloop_register_read_sock - Register handler for read events
|
||||
* @sock: File descriptor number for the socket
|
||||
* @handler: Callback function to be called when data is available for reading
|
||||
* @eloop_data: Callback context data (eloop_ctx)
|
||||
* @user_data: Callback context data (sock_ctx)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Register a read socket notifier for the given file descriptor. The handler
|
||||
* function will be called whenever data is available for reading from the
|
||||
* socket. The handler function is responsible for clearing the event after
|
||||
* having processed it in order to avoid eloop from calling the handler again
|
||||
* for the same event.
|
||||
*/
|
||||
int eloop_register_read_sock(int sock, eloop_sock_handler handler,
|
||||
void *eloop_data, void *user_data);
|
||||
|
||||
/**
|
||||
* eloop_unregister_read_sock - Unregister handler for read events
|
||||
* @sock: File descriptor number for the socket
|
||||
*
|
||||
* Unregister a read socket notifier that was previously registered with
|
||||
* eloop_register_read_sock().
|
||||
*/
|
||||
void eloop_unregister_read_sock(int sock);
|
||||
|
||||
/**
|
||||
* eloop_register_sock - Register handler for socket events
|
||||
* @sock: File descriptor number for the socket
|
||||
* @type: Type of event to wait for
|
||||
* @handler: Callback function to be called when the event is triggered
|
||||
* @eloop_data: Callback context data (eloop_ctx)
|
||||
* @user_data: Callback context data (sock_ctx)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Register an event notifier for the given socket's file descriptor. The
|
||||
* handler function will be called whenever the that event is triggered for the
|
||||
* socket. The handler function is responsible for clearing the event after
|
||||
* having processed it in order to avoid eloop from calling the handler again
|
||||
* for the same event.
|
||||
*/
|
||||
int eloop_register_sock(int sock, eloop_event_type type,
|
||||
eloop_sock_handler handler,
|
||||
void *eloop_data, void *user_data);
|
||||
|
||||
/**
|
||||
* eloop_unregister_sock - Unregister handler for socket events
|
||||
* @sock: File descriptor number for the socket
|
||||
* @type: Type of event for which sock was registered
|
||||
*
|
||||
* Unregister a socket event notifier that was previously registered with
|
||||
* eloop_register_sock().
|
||||
*/
|
||||
void eloop_unregister_sock(int sock, eloop_event_type type);
|
||||
|
||||
/**
|
||||
* eloop_register_event - Register handler for generic events
|
||||
* @event: Event to wait (eloop implementation specific)
|
||||
* @event_size: Size of event data
|
||||
* @handler: Callback function to be called when event is triggered
|
||||
* @eloop_data: Callback context data (eloop_data)
|
||||
* @user_data: Callback context data (user_data)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Register an event handler for the given event. This function is used to
|
||||
* register eloop implementation specific events which are mainly targeted for
|
||||
* operating system specific code (driver interface and l2_packet) since the
|
||||
* portable code will not be able to use such an OS-specific call. The handler
|
||||
* function will be called whenever the event is triggered. The handler
|
||||
* function is responsible for clearing the event after having processed it in
|
||||
* order to avoid eloop from calling the handler again for the same event.
|
||||
*
|
||||
* In case of Windows implementation (eloop_win.c), event pointer is of HANDLE
|
||||
* type, i.e., void*. The callers are likely to have 'HANDLE h' type variable,
|
||||
* and they would call this function with eloop_register_event(h, sizeof(h),
|
||||
* ...).
|
||||
*/
|
||||
int eloop_register_event(void *event, size_t event_size,
|
||||
eloop_event_handler handler,
|
||||
void *eloop_data, void *user_data);
|
||||
|
||||
/**
|
||||
* eloop_unregister_event - Unregister handler for a generic event
|
||||
* @event: Event to cancel (eloop implementation specific)
|
||||
* @event_size: Size of event data
|
||||
*
|
||||
* Unregister a generic event notifier that was previously registered with
|
||||
* eloop_register_event().
|
||||
*/
|
||||
void eloop_unregister_event(void *event, size_t event_size);
|
||||
|
||||
/**
|
||||
* eloop_register_timeout - Register timeout
|
||||
* @secs: Number of seconds to the timeout
|
||||
* @usecs: Number of microseconds to the timeout
|
||||
* @handler: Callback function to be called when timeout occurs
|
||||
* @eloop_data: Callback context data (eloop_ctx)
|
||||
* @user_data: Callback context data (sock_ctx)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Register a timeout that will cause the handler function to be called after
|
||||
* given time.
|
||||
*/
|
||||
int eloop_register_timeout(unsigned int secs, unsigned int usecs,
|
||||
eloop_timeout_handler handler,
|
||||
void *eloop_data, void *user_data);
|
||||
|
||||
/**
|
||||
* eloop_cancel_timeout - Cancel timeouts
|
||||
* @handler: Matching callback function
|
||||
* @eloop_data: Matching eloop_data or %ELOOP_ALL_CTX to match all
|
||||
* @user_data: Matching user_data or %ELOOP_ALL_CTX to match all
|
||||
* Returns: Number of cancelled timeouts
|
||||
*
|
||||
* Cancel matching <handler,eloop_data,user_data> timeouts registered with
|
||||
* eloop_register_timeout(). ELOOP_ALL_CTX can be used as a wildcard for
|
||||
* cancelling all timeouts regardless of eloop_data/user_data.
|
||||
*/
|
||||
int eloop_cancel_timeout(eloop_timeout_handler handler,
|
||||
void *eloop_data, void *user_data);
|
||||
|
||||
/**
|
||||
* eloop_cancel_timeout_one - Cancel a single timeout
|
||||
* @handler: Matching callback function
|
||||
* @eloop_data: Matching eloop_data
|
||||
* @user_data: Matching user_data
|
||||
* @remaining: Time left on the cancelled timer
|
||||
* Returns: Number of cancelled timeouts
|
||||
*
|
||||
* Cancel matching <handler,eloop_data,user_data> timeout registered with
|
||||
* eloop_register_timeout() and return the remaining time left.
|
||||
*/
|
||||
int eloop_cancel_timeout_one(eloop_timeout_handler handler,
|
||||
void *eloop_data, void *user_data,
|
||||
struct os_reltime *remaining);
|
||||
|
||||
/**
|
||||
* eloop_is_timeout_registered - Check if a timeout is already registered
|
||||
* @handler: Matching callback function
|
||||
* @eloop_data: Matching eloop_data
|
||||
* @user_data: Matching user_data
|
||||
* Returns: 1 if the timeout is registered, 0 if the timeout is not registered
|
||||
*
|
||||
* Determine if a matching <handler,eloop_data,user_data> timeout is registered
|
||||
* with eloop_register_timeout().
|
||||
*/
|
||||
int eloop_is_timeout_registered(eloop_timeout_handler handler,
|
||||
void *eloop_data, void *user_data);
|
||||
|
||||
/**
|
||||
* eloop_deplete_timeout - Deplete a timeout that is already registered
|
||||
* @req_secs: Requested number of seconds to the timeout
|
||||
* @req_usecs: Requested number of microseconds to the timeout
|
||||
* @handler: Matching callback function
|
||||
* @eloop_data: Matching eloop_data
|
||||
* @user_data: Matching user_data
|
||||
* Returns: 1 if the timeout is depleted, 0 if no change is made, -1 if no
|
||||
* timeout matched
|
||||
*
|
||||
* Find a registered matching <handler,eloop_data,user_data> timeout. If found,
|
||||
* deplete the timeout if remaining time is more than the requested time.
|
||||
*/
|
||||
int eloop_deplete_timeout(unsigned int req_secs, unsigned int req_usecs,
|
||||
eloop_timeout_handler handler, void *eloop_data,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* eloop_replenish_timeout - Replenish a timeout that is already registered
|
||||
* @req_secs: Requested number of seconds to the timeout
|
||||
* @req_usecs: Requested number of microseconds to the timeout
|
||||
* @handler: Matching callback function
|
||||
* @eloop_data: Matching eloop_data
|
||||
* @user_data: Matching user_data
|
||||
* Returns: 1 if the timeout is replenished, 0 if no change is made, -1 if no
|
||||
* timeout matched
|
||||
*
|
||||
* Find a registered matching <handler,eloop_data,user_data> timeout. If found,
|
||||
* replenish the timeout if remaining time is less than the requested time.
|
||||
*/
|
||||
int eloop_replenish_timeout(unsigned int req_secs, unsigned int req_usecs,
|
||||
eloop_timeout_handler handler, void *eloop_data,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* eloop_register_signal - Register handler for signals
|
||||
* @sig: Signal number (e.g., SIGHUP)
|
||||
* @handler: Callback function to be called when the signal is received
|
||||
* @user_data: Callback context data (signal_ctx)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Register a callback function that will be called when a signal is received.
|
||||
* The callback function is actually called only after the system signal
|
||||
* handler has returned. This means that the normal limits for sighandlers
|
||||
* (i.e., only "safe functions" allowed) do not apply for the registered
|
||||
* callback.
|
||||
*/
|
||||
int eloop_register_signal(int sig, eloop_signal_handler handler,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* eloop_register_signal_terminate - Register handler for terminate signals
|
||||
* @handler: Callback function to be called when the signal is received
|
||||
* @user_data: Callback context data (signal_ctx)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Register a callback function that will be called when a process termination
|
||||
* signal is received. The callback function is actually called only after the
|
||||
* system signal handler has returned. This means that the normal limits for
|
||||
* sighandlers (i.e., only "safe functions" allowed) do not apply for the
|
||||
* registered callback.
|
||||
*
|
||||
* This function is a more portable version of eloop_register_signal() since
|
||||
* the knowledge of exact details of the signals is hidden in eloop
|
||||
* implementation. In case of operating systems using signal(), this function
|
||||
* registers handlers for SIGINT and SIGTERM.
|
||||
*/
|
||||
int eloop_register_signal_terminate(eloop_signal_handler handler,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* eloop_register_signal_reconfig - Register handler for reconfig signals
|
||||
* @handler: Callback function to be called when the signal is received
|
||||
* @user_data: Callback context data (signal_ctx)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Register a callback function that will be called when a reconfiguration /
|
||||
* hangup signal is received. The callback function is actually called only
|
||||
* after the system signal handler has returned. This means that the normal
|
||||
* limits for sighandlers (i.e., only "safe functions" allowed) do not apply
|
||||
* for the registered callback.
|
||||
*
|
||||
* This function is a more portable version of eloop_register_signal() since
|
||||
* the knowledge of exact details of the signals is hidden in eloop
|
||||
* implementation. In case of operating systems using signal(), this function
|
||||
* registers a handler for SIGHUP.
|
||||
*/
|
||||
int eloop_register_signal_reconfig(eloop_signal_handler handler,
|
||||
void *user_data);
|
||||
|
||||
/**
|
||||
* eloop_run - Start the event loop
|
||||
*
|
||||
* Start the event loop and continue running as long as there are any
|
||||
* registered event handlers. This function is run after event loop has been
|
||||
* initialized with event_init() and one or more events have been registered.
|
||||
*/
|
||||
void eloop_run(void);
|
||||
|
||||
/**
|
||||
* eloop_terminate - Terminate event loop
|
||||
*
|
||||
* Terminate event loop even if there are registered events. This can be used
|
||||
* to request the program to be terminated cleanly.
|
||||
*/
|
||||
void eloop_terminate(void);
|
||||
|
||||
/**
|
||||
* eloop_destroy - Free any resources allocated for the event loop
|
||||
*
|
||||
* After calling eloop_destroy(), other eloop_* functions must not be called
|
||||
* before re-running eloop_init().
|
||||
*/
|
||||
void eloop_destroy(void);
|
||||
|
||||
/**
|
||||
* eloop_terminated - Check whether event loop has been terminated
|
||||
* Returns: 1 = event loop terminate, 0 = event loop still running
|
||||
*
|
||||
* This function can be used to check whether eloop_terminate() has been called
|
||||
* to request termination of the event loop. This is normally used to abort
|
||||
* operations that may still be queued to be run when eloop_terminate() was
|
||||
* called.
|
||||
*/
|
||||
int eloop_terminated(void);
|
||||
|
||||
/**
|
||||
* eloop_wait_for_read_sock - Wait for a single reader
|
||||
* @sock: File descriptor number for the socket
|
||||
*
|
||||
* Do a blocking wait for a single read socket.
|
||||
*/
|
||||
void eloop_wait_for_read_sock(int sock);
|
||||
|
||||
#endif /* ELOOP_H */
|
||||
50
qcom/opensource/fst-manager/external/utils/includes.h
vendored
Normal file
50
qcom/opensource/fst-manager/external/utils/includes.h
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* wpa_supplicant/hostapd - Default include files
|
||||
* Copyright (c) 2005-2006, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*
|
||||
* This header file is included into all C files so that commonly used header
|
||||
* files can be selected with OS specific ifdef blocks in one place instead of
|
||||
* having to have OS/C library specific selection in many files.
|
||||
*/
|
||||
|
||||
#ifndef INCLUDES_H
|
||||
#define INCLUDES_H
|
||||
|
||||
/* Include possible build time configuration before including anything else */
|
||||
#include "build_config.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#ifndef _WIN32_WCE
|
||||
#ifndef CONFIG_TI_COMPILER
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#endif /* CONFIG_TI_COMPILER */
|
||||
#include <errno.h>
|
||||
#endif /* _WIN32_WCE */
|
||||
#include <ctype.h>
|
||||
|
||||
#ifndef CONFIG_TI_COMPILER
|
||||
#ifndef _MSC_VER
|
||||
#include <unistd.h>
|
||||
#endif /* _MSC_VER */
|
||||
#endif /* CONFIG_TI_COMPILER */
|
||||
|
||||
#ifndef CONFIG_NATIVE_WINDOWS
|
||||
#ifndef CONFIG_TI_COMPILER
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#ifndef __vxworks
|
||||
#include <sys/uio.h>
|
||||
#include <sys/time.h>
|
||||
#endif /* __vxworks */
|
||||
#endif /* CONFIG_TI_COMPILER */
|
||||
#endif /* CONFIG_NATIVE_WINDOWS */
|
||||
|
||||
#endif /* INCLUDES_H */
|
||||
95
qcom/opensource/fst-manager/external/utils/list.h
vendored
Normal file
95
qcom/opensource/fst-manager/external/utils/list.h
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Doubly-linked list
|
||||
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef LIST_H
|
||||
#define LIST_H
|
||||
|
||||
/**
|
||||
* struct dl_list - Doubly-linked list
|
||||
*/
|
||||
struct dl_list {
|
||||
struct dl_list *next;
|
||||
struct dl_list *prev;
|
||||
};
|
||||
|
||||
static inline void dl_list_init(struct dl_list *list)
|
||||
{
|
||||
list->next = list;
|
||||
list->prev = list;
|
||||
}
|
||||
|
||||
static inline void dl_list_add(struct dl_list *list, struct dl_list *item)
|
||||
{
|
||||
item->next = list->next;
|
||||
item->prev = list;
|
||||
list->next->prev = item;
|
||||
list->next = item;
|
||||
}
|
||||
|
||||
static inline void dl_list_add_tail(struct dl_list *list, struct dl_list *item)
|
||||
{
|
||||
dl_list_add(list->prev, item);
|
||||
}
|
||||
|
||||
static inline void dl_list_del(struct dl_list *item)
|
||||
{
|
||||
item->next->prev = item->prev;
|
||||
item->prev->next = item->next;
|
||||
item->next = NULL;
|
||||
item->prev = NULL;
|
||||
}
|
||||
|
||||
static inline int dl_list_empty(struct dl_list *list)
|
||||
{
|
||||
return list->next == list;
|
||||
}
|
||||
|
||||
static inline unsigned int dl_list_len(struct dl_list *list)
|
||||
{
|
||||
struct dl_list *item;
|
||||
int count = 0;
|
||||
for (item = list->next; item != list; item = item->next)
|
||||
count++;
|
||||
return count;
|
||||
}
|
||||
|
||||
#ifndef offsetof
|
||||
#define offsetof(type, member) ((long) &((type *) 0)->member)
|
||||
#endif
|
||||
|
||||
#define dl_list_entry(item, type, member) \
|
||||
((type *) ((char *) item - offsetof(type, member)))
|
||||
|
||||
#define dl_list_first(list, type, member) \
|
||||
(dl_list_empty((list)) ? NULL : \
|
||||
dl_list_entry((list)->next, type, member))
|
||||
|
||||
#define dl_list_last(list, type, member) \
|
||||
(dl_list_empty((list)) ? NULL : \
|
||||
dl_list_entry((list)->prev, type, member))
|
||||
|
||||
#define dl_list_for_each(item, list, type, member) \
|
||||
for (item = dl_list_entry((list)->next, type, member); \
|
||||
&item->member != (list); \
|
||||
item = dl_list_entry(item->member.next, type, member))
|
||||
|
||||
#define dl_list_for_each_safe(item, n, list, type, member) \
|
||||
for (item = dl_list_entry((list)->next, type, member), \
|
||||
n = dl_list_entry(item->member.next, type, member); \
|
||||
&item->member != (list); \
|
||||
item = n, n = dl_list_entry(n->member.next, type, member))
|
||||
|
||||
#define dl_list_for_each_reverse(item, list, type, member) \
|
||||
for (item = dl_list_entry((list)->prev, type, member); \
|
||||
&item->member != (list); \
|
||||
item = dl_list_entry(item->member.prev, type, member))
|
||||
|
||||
#define DEFINE_DL_LIST(name) \
|
||||
struct dl_list name = { &(name), &(name) }
|
||||
|
||||
#endif /* LIST_H */
|
||||
676
qcom/opensource/fst-manager/external/utils/os.h
vendored
Normal file
676
qcom/opensource/fst-manager/external/utils/os.h
vendored
Normal file
@@ -0,0 +1,676 @@
|
||||
/*
|
||||
* OS specific functions
|
||||
* Copyright (c) 2005-2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef OS_H
|
||||
#define OS_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef long os_time_t;
|
||||
|
||||
/**
|
||||
* os_sleep - Sleep (sec, usec)
|
||||
* @sec: Number of seconds to sleep
|
||||
* @usec: Number of microseconds to sleep
|
||||
*/
|
||||
void os_sleep(os_time_t sec, os_time_t usec);
|
||||
|
||||
struct os_time {
|
||||
os_time_t sec;
|
||||
os_time_t usec;
|
||||
};
|
||||
|
||||
struct os_reltime {
|
||||
os_time_t sec;
|
||||
os_time_t usec;
|
||||
};
|
||||
|
||||
/**
|
||||
* os_get_time - Get current time (sec, usec)
|
||||
* @t: Pointer to buffer for the time
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int os_get_time(struct os_time *t);
|
||||
|
||||
/**
|
||||
* os_get_reltime - Get relative time (sec, usec)
|
||||
* @t: Pointer to buffer for the time
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int os_get_reltime(struct os_reltime *t);
|
||||
|
||||
|
||||
/* Helpers for handling struct os_time */
|
||||
|
||||
static inline int os_time_before(struct os_time *a, struct os_time *b)
|
||||
{
|
||||
return (a->sec < b->sec) ||
|
||||
(a->sec == b->sec && a->usec < b->usec);
|
||||
}
|
||||
|
||||
|
||||
static inline void os_time_sub(struct os_time *a, struct os_time *b,
|
||||
struct os_time *res)
|
||||
{
|
||||
res->sec = a->sec - b->sec;
|
||||
res->usec = a->usec - b->usec;
|
||||
if (res->usec < 0) {
|
||||
res->sec--;
|
||||
res->usec += 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Helpers for handling struct os_reltime */
|
||||
|
||||
static inline int os_reltime_before(struct os_reltime *a,
|
||||
struct os_reltime *b)
|
||||
{
|
||||
return (a->sec < b->sec) ||
|
||||
(a->sec == b->sec && a->usec < b->usec);
|
||||
}
|
||||
|
||||
|
||||
static inline void os_reltime_sub(struct os_reltime *a, struct os_reltime *b,
|
||||
struct os_reltime *res)
|
||||
{
|
||||
res->sec = a->sec - b->sec;
|
||||
res->usec = a->usec - b->usec;
|
||||
if (res->usec < 0) {
|
||||
res->sec--;
|
||||
res->usec += 1000000;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static inline void os_reltime_age(struct os_reltime *start,
|
||||
struct os_reltime *age)
|
||||
{
|
||||
struct os_reltime now;
|
||||
|
||||
os_get_reltime(&now);
|
||||
os_reltime_sub(&now, start, age);
|
||||
}
|
||||
|
||||
|
||||
static inline int os_reltime_expired(struct os_reltime *now,
|
||||
struct os_reltime *ts,
|
||||
os_time_t timeout_secs)
|
||||
{
|
||||
struct os_reltime age;
|
||||
|
||||
os_reltime_sub(now, ts, &age);
|
||||
return (age.sec > timeout_secs) ||
|
||||
(age.sec == timeout_secs && age.usec > 0);
|
||||
}
|
||||
|
||||
|
||||
static inline int os_reltime_initialized(struct os_reltime *t)
|
||||
{
|
||||
return t->sec != 0 || t->usec != 0;
|
||||
}
|
||||
|
||||
static inline size_t memscpy(void* dst, size_t dst_size,
|
||||
const void* src, size_t src_size)
|
||||
{
|
||||
size_t copy_size = (dst_size <= src_size)? dst_size : src_size;
|
||||
|
||||
memcpy(dst, src, copy_size);
|
||||
|
||||
return copy_size;
|
||||
}
|
||||
|
||||
static inline size_t memsmove(void *dst, size_t dst_size,
|
||||
const void *src, size_t src_size)
|
||||
{
|
||||
size_t copy_size = (dst_size <= src_size)? dst_size : src_size;
|
||||
|
||||
memmove(dst, src, copy_size);
|
||||
|
||||
return copy_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* os_mktime - Convert broken-down time into seconds since 1970-01-01
|
||||
* @year: Four digit year
|
||||
* @month: Month (1 .. 12)
|
||||
* @day: Day of month (1 .. 31)
|
||||
* @hour: Hour (0 .. 23)
|
||||
* @min: Minute (0 .. 59)
|
||||
* @sec: Second (0 .. 60)
|
||||
* @t: Buffer for returning calendar time representation (seconds since
|
||||
* 1970-01-01 00:00:00)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* Note: The result is in seconds from Epoch, i.e., in UTC, not in local time
|
||||
* which is used by POSIX mktime().
|
||||
*/
|
||||
int os_mktime(int year, int month, int day, int hour, int min, int sec,
|
||||
os_time_t *t);
|
||||
|
||||
struct os_tm {
|
||||
int sec; /* 0..59 or 60 for leap seconds */
|
||||
int min; /* 0..59 */
|
||||
int hour; /* 0..23 */
|
||||
int day; /* 1..31 */
|
||||
int month; /* 1..12 */
|
||||
int year; /* Four digit year */
|
||||
};
|
||||
|
||||
int os_gmtime(os_time_t t, struct os_tm *tm);
|
||||
|
||||
/**
|
||||
* os_daemonize - Run in the background (detach from the controlling terminal)
|
||||
* @pid_file: File name to write the process ID to or %NULL to skip this
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int os_daemonize(const char *pid_file);
|
||||
|
||||
/**
|
||||
* os_daemonize_terminate - Stop running in the background (remove pid file)
|
||||
* @pid_file: File name to write the process ID to or %NULL to skip this
|
||||
*/
|
||||
void os_daemonize_terminate(const char *pid_file);
|
||||
|
||||
/**
|
||||
* os_get_random - Get cryptographically strong pseudo random data
|
||||
* @buf: Buffer for pseudo random data
|
||||
* @len: Length of the buffer
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*/
|
||||
int os_get_random(unsigned char *buf, size_t len);
|
||||
|
||||
/**
|
||||
* os_random - Get pseudo random value (not necessarily very strong)
|
||||
* Returns: Pseudo random value
|
||||
*/
|
||||
unsigned long os_random(void);
|
||||
|
||||
/**
|
||||
* os_rel2abs_path - Get an absolute path for a file
|
||||
* @rel_path: Relative path to a file
|
||||
* Returns: Absolute path for the file or %NULL on failure
|
||||
*
|
||||
* This function tries to convert a relative path of a file to an absolute path
|
||||
* in order for the file to be found even if current working directory has
|
||||
* changed. The returned value is allocated and caller is responsible for
|
||||
* freeing it. It is acceptable to just return the same path in an allocated
|
||||
* buffer, e.g., return strdup(rel_path). This function is only used to find
|
||||
* configuration files when os_daemonize() may have changed the current working
|
||||
* directory and relative path would be pointing to a different location.
|
||||
*/
|
||||
char * os_rel2abs_path(const char *rel_path);
|
||||
|
||||
/**
|
||||
* os_program_init - Program initialization (called at start)
|
||||
* Returns: 0 on success, -1 on failure
|
||||
*
|
||||
* This function is called when a programs starts. If there are any OS specific
|
||||
* processing that is needed, it can be placed here. It is also acceptable to
|
||||
* just return 0 if not special processing is needed.
|
||||
*/
|
||||
int os_program_init(void);
|
||||
|
||||
/**
|
||||
* os_program_deinit - Program deinitialization (called just before exit)
|
||||
*
|
||||
* This function is called just before a program exists. If there are any OS
|
||||
* specific processing, e.g., freeing resourced allocated in os_program_init(),
|
||||
* it should be done here. It is also acceptable for this function to do
|
||||
* nothing.
|
||||
*/
|
||||
void os_program_deinit(void);
|
||||
|
||||
/**
|
||||
* os_setenv - Set environment variable
|
||||
* @name: Name of the variable
|
||||
* @value: Value to set to the variable
|
||||
* @overwrite: Whether existing variable should be overwritten
|
||||
* Returns: 0 on success, -1 on error
|
||||
*
|
||||
* This function is only used for wpa_cli action scripts. OS wrapper does not
|
||||
* need to implement this if such functionality is not needed.
|
||||
*/
|
||||
int os_setenv(const char *name, const char *value, int overwrite);
|
||||
|
||||
/**
|
||||
* os_unsetenv - Delete environent variable
|
||||
* @name: Name of the variable
|
||||
* Returns: 0 on success, -1 on error
|
||||
*
|
||||
* This function is only used for wpa_cli action scripts. OS wrapper does not
|
||||
* need to implement this if such functionality is not needed.
|
||||
*/
|
||||
int os_unsetenv(const char *name);
|
||||
|
||||
/**
|
||||
* os_readfile - Read a file to an allocated memory buffer
|
||||
* @name: Name of the file to read
|
||||
* @len: For returning the length of the allocated buffer
|
||||
* Returns: Pointer to the allocated buffer or %NULL on failure
|
||||
*
|
||||
* This function allocates memory and reads the given file to this buffer. Both
|
||||
* binary and text files can be read with this function. The caller is
|
||||
* responsible for freeing the returned buffer with os_free().
|
||||
*/
|
||||
char * os_readfile(const char *name, size_t *len);
|
||||
|
||||
/**
|
||||
* os_file_exists - Check whether the specified file exists
|
||||
* @fname: Path and name of the file
|
||||
* Returns: 1 if the file exists or 0 if not
|
||||
*/
|
||||
int os_file_exists(const char *fname);
|
||||
|
||||
/**
|
||||
* os_zalloc - Allocate and zero memory
|
||||
* @size: Number of bytes to allocate
|
||||
* Returns: Pointer to allocated and zeroed memory or %NULL on failure
|
||||
*
|
||||
* Caller is responsible for freeing the returned buffer with os_free().
|
||||
*/
|
||||
void * os_zalloc(size_t size);
|
||||
|
||||
/**
|
||||
* os_calloc - Allocate and zero memory for an array
|
||||
* @nmemb: Number of members in the array
|
||||
* @size: Number of bytes in each member
|
||||
* Returns: Pointer to allocated and zeroed memory or %NULL on failure
|
||||
*
|
||||
* This function can be used as a wrapper for os_zalloc(nmemb * size) when an
|
||||
* allocation is used for an array. The main benefit over os_zalloc() is in
|
||||
* having an extra check to catch integer overflows in multiplication.
|
||||
*
|
||||
* Caller is responsible for freeing the returned buffer with os_free().
|
||||
*/
|
||||
static inline void * os_calloc(size_t nmemb, size_t size)
|
||||
{
|
||||
if (size && nmemb > (~(size_t) 0) / size)
|
||||
return NULL;
|
||||
return os_zalloc(nmemb * size);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The following functions are wrapper for standard ANSI C or POSIX functions.
|
||||
* By default, they are just defined to use the standard function name and no
|
||||
* os_*.c implementation is needed for them. This avoids extra function calls
|
||||
* by allowing the C pre-processor take care of the function name mapping.
|
||||
*
|
||||
* If the target system uses a C library that does not provide these functions,
|
||||
* build_config.h can be used to define the wrappers to use a different
|
||||
* function name. This can be done on function-by-function basis since the
|
||||
* defines here are only used if build_config.h does not define the os_* name.
|
||||
* If needed, os_*.c file can be used to implement the functions that are not
|
||||
* included in the C library on the target system. Alternatively,
|
||||
* OS_NO_C_LIB_DEFINES can be defined to skip all defines here in which case
|
||||
* these functions need to be implemented in os_*.c file for the target system.
|
||||
*/
|
||||
|
||||
#ifdef OS_NO_C_LIB_DEFINES
|
||||
|
||||
/**
|
||||
* os_malloc - Allocate dynamic memory
|
||||
* @size: Size of the buffer to allocate
|
||||
* Returns: Allocated buffer or %NULL on failure
|
||||
*
|
||||
* Caller is responsible for freeing the returned buffer with os_free().
|
||||
*/
|
||||
void * os_malloc(size_t size);
|
||||
|
||||
/**
|
||||
* os_realloc - Re-allocate dynamic memory
|
||||
* @ptr: Old buffer from os_malloc() or os_realloc()
|
||||
* @size: Size of the new buffer
|
||||
* Returns: Allocated buffer or %NULL on failure
|
||||
*
|
||||
* Caller is responsible for freeing the returned buffer with os_free().
|
||||
* If re-allocation fails, %NULL is returned and the original buffer (ptr) is
|
||||
* not freed and caller is still responsible for freeing it.
|
||||
*/
|
||||
void * os_realloc(void *ptr, size_t size);
|
||||
|
||||
/**
|
||||
* os_free - Free dynamic memory
|
||||
* @ptr: Old buffer from os_malloc() or os_realloc(); can be %NULL
|
||||
*/
|
||||
void os_free(void *ptr);
|
||||
|
||||
/**
|
||||
* os_memcpy - Copy memory area
|
||||
* @dest: Destination
|
||||
* @src: Source
|
||||
* @n: Number of bytes to copy
|
||||
* Returns: dest
|
||||
*
|
||||
* The memory areas src and dst must not overlap. os_memmove() can be used with
|
||||
* overlapping memory.
|
||||
*/
|
||||
void * os_memcpy(void *dest, const void *src, size_t n);
|
||||
|
||||
/**
|
||||
* os_memmove - Copy memory area
|
||||
* @dest: Destination
|
||||
* @src: Source
|
||||
* @n: Number of bytes to copy
|
||||
* Returns: dest
|
||||
*
|
||||
* The memory areas src and dst may overlap.
|
||||
*/
|
||||
void * os_memmove(void *dest, const void *src, size_t n);
|
||||
|
||||
/**
|
||||
* os_memset - Fill memory with a constant byte
|
||||
* @s: Memory area to be filled
|
||||
* @c: Constant byte
|
||||
* @n: Number of bytes started from s to fill with c
|
||||
* Returns: s
|
||||
*/
|
||||
void * os_memset(void *s, int c, size_t n);
|
||||
|
||||
/**
|
||||
* os_memcmp - Compare memory areas
|
||||
* @s1: First buffer
|
||||
* @s2: Second buffer
|
||||
* @n: Maximum numbers of octets to compare
|
||||
* Returns: An integer less than, equal to, or greater than zero if s1 is
|
||||
* found to be less than, to match, or be greater than s2. Only first n
|
||||
* characters will be compared.
|
||||
*/
|
||||
int os_memcmp(const void *s1, const void *s2, size_t n);
|
||||
|
||||
/**
|
||||
* os_strdup - Duplicate a string
|
||||
* @s: Source string
|
||||
* Returns: Allocated buffer with the string copied into it or %NULL on failure
|
||||
*
|
||||
* Caller is responsible for freeing the returned buffer with os_free().
|
||||
*/
|
||||
char * os_strdup(const char *s);
|
||||
|
||||
/**
|
||||
* os_strlen - Calculate the length of a string
|
||||
* @s: '\0' terminated string
|
||||
* Returns: Number of characters in s (not counting the '\0' terminator)
|
||||
*/
|
||||
size_t os_strlen(const char *s);
|
||||
|
||||
/**
|
||||
* os_strcasecmp - Compare two strings ignoring case
|
||||
* @s1: First string
|
||||
* @s2: Second string
|
||||
* Returns: An integer less than, equal to, or greater than zero if s1 is
|
||||
* found to be less than, to match, or be greatred than s2
|
||||
*/
|
||||
int os_strcasecmp(const char *s1, const char *s2);
|
||||
|
||||
/**
|
||||
* os_strncasecmp - Compare two strings ignoring case
|
||||
* @s1: First string
|
||||
* @s2: Second string
|
||||
* @n: Maximum numbers of characters to compare
|
||||
* Returns: An integer less than, equal to, or greater than zero if s1 is
|
||||
* found to be less than, to match, or be greater than s2. Only first n
|
||||
* characters will be compared.
|
||||
*/
|
||||
int os_strncasecmp(const char *s1, const char *s2, size_t n);
|
||||
|
||||
/**
|
||||
* os_strchr - Locate the first occurrence of a character in string
|
||||
* @s: String
|
||||
* @c: Character to search for
|
||||
* Returns: Pointer to the matched character or %NULL if not found
|
||||
*/
|
||||
char * os_strchr(const char *s, int c);
|
||||
|
||||
/**
|
||||
* os_strrchr - Locate the last occurrence of a character in string
|
||||
* @s: String
|
||||
* @c: Character to search for
|
||||
* Returns: Pointer to the matched character or %NULL if not found
|
||||
*/
|
||||
char * os_strrchr(const char *s, int c);
|
||||
|
||||
/**
|
||||
* os_strcmp - Compare two strings
|
||||
* @s1: First string
|
||||
* @s2: Second string
|
||||
* Returns: An integer less than, equal to, or greater than zero if s1 is
|
||||
* found to be less than, to match, or be greatred than s2
|
||||
*/
|
||||
int os_strcmp(const char *s1, const char *s2);
|
||||
|
||||
/**
|
||||
* os_strncmp - Compare two strings
|
||||
* @s1: First string
|
||||
* @s2: Second string
|
||||
* @n: Maximum numbers of characters to compare
|
||||
* Returns: An integer less than, equal to, or greater than zero if s1 is
|
||||
* found to be less than, to match, or be greater than s2. Only first n
|
||||
* characters will be compared.
|
||||
*/
|
||||
int os_strncmp(const char *s1, const char *s2, size_t n);
|
||||
|
||||
/**
|
||||
* os_strstr - Locate a substring
|
||||
* @haystack: String (haystack) to search from
|
||||
* @needle: Needle to search from haystack
|
||||
* Returns: Pointer to the beginning of the substring or %NULL if not found
|
||||
*/
|
||||
char * os_strstr(const char *haystack, const char *needle);
|
||||
|
||||
/**
|
||||
* os_snprintf - Print to a memory buffer
|
||||
* @str: Memory buffer to print into
|
||||
* @size: Maximum length of the str buffer
|
||||
* @format: printf format
|
||||
* Returns: Number of characters printed (not including trailing '\0').
|
||||
*
|
||||
* If the output buffer is truncated, number of characters which would have
|
||||
* been written is returned. Since some C libraries return -1 in such a case,
|
||||
* the caller must be prepared on that value, too, to indicate truncation.
|
||||
*
|
||||
* Note: Some C library implementations of snprintf() may not guarantee null
|
||||
* termination in case the output is truncated. The OS wrapper function of
|
||||
* os_snprintf() should provide this guarantee, i.e., to null terminate the
|
||||
* output buffer if a C library version of the function is used and if that
|
||||
* function does not guarantee null termination.
|
||||
*
|
||||
* If the target system does not include snprintf(), see, e.g.,
|
||||
* http://www.ijs.si/software/snprintf/ for an example of a portable
|
||||
* implementation of snprintf.
|
||||
*/
|
||||
int os_snprintf(char *str, size_t size, const char *format, ...);
|
||||
|
||||
#else /* OS_NO_C_LIB_DEFINES */
|
||||
|
||||
#ifdef WPA_TRACE
|
||||
void * os_malloc(size_t size);
|
||||
void * os_realloc(void *ptr, size_t size);
|
||||
void os_free(void *ptr);
|
||||
char * os_strdup(const char *s);
|
||||
#else /* WPA_TRACE */
|
||||
#ifndef os_malloc
|
||||
#define os_malloc(s) malloc((s))
|
||||
#endif
|
||||
#ifndef os_realloc
|
||||
#define os_realloc(p, s) realloc((p), (s))
|
||||
#endif
|
||||
#ifndef os_free
|
||||
#define os_free(p) free((p))
|
||||
#endif
|
||||
#ifndef os_strdup
|
||||
#ifdef _MSC_VER
|
||||
#define os_strdup(s) _strdup(s)
|
||||
#else
|
||||
#define os_strdup(s) strdup(s)
|
||||
#endif
|
||||
#endif
|
||||
#endif /* WPA_TRACE */
|
||||
|
||||
#ifndef os_memcpy
|
||||
#define os_memcpy(d, s, n) memscpy((d), (n), (s), (n))
|
||||
#endif
|
||||
#ifndef os_memmove
|
||||
#define os_memmove(d, s, n) memsmove((d), (n), (s), (n))
|
||||
#endif
|
||||
#ifndef os_memset
|
||||
#define os_memset(s, c, n) memset(s, c, n)
|
||||
#endif
|
||||
#ifndef os_memcmp
|
||||
#define os_memcmp(s1, s2, n) memcmp((s1), (s2), (n))
|
||||
#endif
|
||||
|
||||
#ifndef os_strlen
|
||||
#define os_strlen(s) strlen(s)
|
||||
#endif
|
||||
#ifndef os_strcasecmp
|
||||
#ifdef _MSC_VER
|
||||
#define os_strcasecmp(s1, s2) _stricmp((s1), (s2))
|
||||
#else
|
||||
#define os_strcasecmp(s1, s2) strcasecmp((s1), (s2))
|
||||
#endif
|
||||
#endif
|
||||
#ifndef os_strncasecmp
|
||||
#ifdef _MSC_VER
|
||||
#define os_strncasecmp(s1, s2, n) _strnicmp((s1), (s2), (n))
|
||||
#else
|
||||
#define os_strncasecmp(s1, s2, n) strncasecmp((s1), (s2), (n))
|
||||
#endif
|
||||
#endif
|
||||
#ifndef os_strchr
|
||||
#define os_strchr(s, c) strchr((s), (c))
|
||||
#endif
|
||||
#ifndef os_strcmp
|
||||
#define os_strcmp(s1, s2) strcmp((s1), (s2))
|
||||
#endif
|
||||
#ifndef os_strncmp
|
||||
#define os_strncmp(s1, s2, n) strncmp((s1), (s2), (n))
|
||||
#endif
|
||||
#ifndef os_strrchr
|
||||
#define os_strrchr(s, c) strrchr((s), (c))
|
||||
#endif
|
||||
#ifndef os_strstr
|
||||
#define os_strstr(h, n) strstr((h), (n))
|
||||
#endif
|
||||
|
||||
#ifndef os_snprintf
|
||||
#ifdef _MSC_VER
|
||||
#define os_snprintf _snprintf
|
||||
#else
|
||||
#define os_snprintf snprintf
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* OS_NO_C_LIB_DEFINES */
|
||||
|
||||
|
||||
static inline int os_snprintf_error(size_t size, int res)
|
||||
{
|
||||
return res < 0 || (unsigned int) res >= size;
|
||||
}
|
||||
|
||||
|
||||
static inline void * os_realloc_array(void *ptr, size_t nmemb, size_t size)
|
||||
{
|
||||
if (size && nmemb > (~(size_t) 0) / size)
|
||||
return NULL;
|
||||
return os_realloc(ptr, nmemb * size);
|
||||
}
|
||||
|
||||
/**
|
||||
* os_remove_in_array - Remove a member from an array by index
|
||||
* @ptr: Pointer to the array
|
||||
* @nmemb: Current member count of the array
|
||||
* @size: The size per member of the array
|
||||
* @idx: Index of the member to be removed
|
||||
*/
|
||||
static inline void os_remove_in_array(void *ptr, size_t nmemb, size_t size,
|
||||
size_t idx)
|
||||
{
|
||||
if (idx < nmemb - 1)
|
||||
os_memmove(((unsigned char *) ptr) + idx * size,
|
||||
((unsigned char *) ptr) + (idx + 1) * size,
|
||||
(nmemb - idx - 1) * size);
|
||||
}
|
||||
|
||||
/**
|
||||
* os_strlcpy - Copy a string with size bound and NUL-termination
|
||||
* @dest: Destination
|
||||
* @src: Source
|
||||
* @siz: Size of the target buffer
|
||||
* Returns: Total length of the target string (length of src) (not including
|
||||
* NUL-termination)
|
||||
*
|
||||
* This function matches in behavior with the strlcpy(3) function in OpenBSD.
|
||||
*/
|
||||
size_t os_strlcpy(char *dest, const char *src, size_t siz);
|
||||
|
||||
/**
|
||||
* os_memcmp_const - Constant time memory comparison
|
||||
* @a: First buffer to compare
|
||||
* @b: Second buffer to compare
|
||||
* @len: Number of octets to compare
|
||||
* Returns: 0 if buffers are equal, non-zero if not
|
||||
*
|
||||
* This function is meant for comparing passwords or hash values where
|
||||
* difference in execution time could provide external observer information
|
||||
* about the location of the difference in the memory buffers. The return value
|
||||
* does not behave like os_memcmp(), i.e., os_memcmp_const() cannot be used to
|
||||
* sort items into a defined order. Unlike os_memcmp(), execution time of
|
||||
* os_memcmp_const() does not depend on the contents of the compared memory
|
||||
* buffers, but only on the total compared length.
|
||||
*/
|
||||
int os_memcmp_const(const void *a, const void *b, size_t len);
|
||||
|
||||
/**
|
||||
* os_exec - Execute an external program
|
||||
* @program: Path to the program
|
||||
* @arg: Command line argument string
|
||||
* @wait_completion: Whether to wait until the program execution completes
|
||||
* Returns: 0 on success, -1 on error
|
||||
*/
|
||||
int os_exec(const char *program, const char *arg, int wait_completion);
|
||||
|
||||
|
||||
#ifdef OS_REJECT_C_LIB_FUNCTIONS
|
||||
#define malloc OS_DO_NOT_USE_malloc
|
||||
#define realloc OS_DO_NOT_USE_realloc
|
||||
#define free OS_DO_NOT_USE_free
|
||||
#define memcpy OS_DO_NOT_USE_memcpy
|
||||
#define memmove OS_DO_NOT_USE_memmove
|
||||
#define memset OS_DO_NOT_USE_memset
|
||||
#define memcmp OS_DO_NOT_USE_memcmp
|
||||
#undef strdup
|
||||
#define strdup OS_DO_NOT_USE_strdup
|
||||
#define strlen OS_DO_NOT_USE_strlen
|
||||
#define strcasecmp OS_DO_NOT_USE_strcasecmp
|
||||
#define strncasecmp OS_DO_NOT_USE_strncasecmp
|
||||
#undef strchr
|
||||
#define strchr OS_DO_NOT_USE_strchr
|
||||
#undef strcmp
|
||||
#define strcmp OS_DO_NOT_USE_strcmp
|
||||
#undef strncmp
|
||||
#define strncmp OS_DO_NOT_USE_strncmp
|
||||
#undef strncpy
|
||||
#define strncpy OS_DO_NOT_USE_strncpy
|
||||
#define strrchr OS_DO_NOT_USE_strrchr
|
||||
#define strstr OS_DO_NOT_USE_strstr
|
||||
#undef snprintf
|
||||
#define snprintf OS_DO_NOT_USE_snprintf
|
||||
|
||||
#define strcpy OS_DO_NOT_USE_strcpy
|
||||
#endif /* OS_REJECT_C_LIB_FUNCTIONS */
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* OS_H */
|
||||
69
qcom/opensource/fst-manager/external/utils/trace.h
vendored
Normal file
69
qcom/opensource/fst-manager/external/utils/trace.h
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Backtrace debugging
|
||||
* Copyright (c) 2009, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef TRACE_H
|
||||
#define TRACE_H
|
||||
|
||||
#define WPA_TRACE_LEN 16
|
||||
|
||||
#ifdef WPA_TRACE
|
||||
#include <execinfo.h>
|
||||
|
||||
#include "list.h"
|
||||
|
||||
#define WPA_TRACE_INFO void *btrace[WPA_TRACE_LEN]; int btrace_num;
|
||||
|
||||
struct wpa_trace_ref {
|
||||
struct dl_list list;
|
||||
const void *addr;
|
||||
WPA_TRACE_INFO
|
||||
};
|
||||
#define WPA_TRACE_REF(name) struct wpa_trace_ref wpa_trace_ref_##name
|
||||
|
||||
#define wpa_trace_dump(title, ptr) \
|
||||
wpa_trace_dump_func((title), (ptr)->btrace, (ptr)->btrace_num)
|
||||
void wpa_trace_dump_func(const char *title, void **btrace, int btrace_num);
|
||||
#define wpa_trace_record(ptr) \
|
||||
(ptr)->btrace_num = backtrace((ptr)->btrace, WPA_TRACE_LEN)
|
||||
void wpa_trace_show(const char *title);
|
||||
#define wpa_trace_add_ref(ptr, name, addr) \
|
||||
wpa_trace_add_ref_func(&(ptr)->wpa_trace_ref_##name, (addr))
|
||||
void wpa_trace_add_ref_func(struct wpa_trace_ref *ref, const void *addr);
|
||||
#define wpa_trace_remove_ref(ptr, name, addr) \
|
||||
do { \
|
||||
if ((addr)) \
|
||||
dl_list_del(&(ptr)->wpa_trace_ref_##name.list); \
|
||||
} while (0)
|
||||
void wpa_trace_check_ref(const void *addr);
|
||||
size_t wpa_trace_calling_func(const char *buf[], size_t len);
|
||||
|
||||
#else /* WPA_TRACE */
|
||||
|
||||
#define WPA_TRACE_INFO
|
||||
#define WPA_TRACE_REF(n)
|
||||
#define wpa_trace_dump(title, ptr) do { } while (0)
|
||||
#define wpa_trace_record(ptr) do { } while (0)
|
||||
#define wpa_trace_show(title) do { } while (0)
|
||||
#define wpa_trace_add_ref(ptr, name, addr) do { } while (0)
|
||||
#define wpa_trace_remove_ref(ptr, name, addr) do { } while (0)
|
||||
#define wpa_trace_check_ref(addr) do { } while (0)
|
||||
|
||||
#endif /* WPA_TRACE */
|
||||
|
||||
|
||||
#ifdef WPA_TRACE_BFD
|
||||
|
||||
void wpa_trace_dump_funcname(const char *title, void *pc);
|
||||
|
||||
#else /* WPA_TRACE_BFD */
|
||||
|
||||
#define wpa_trace_dump_funcname(title, pc) do { } while (0)
|
||||
|
||||
#endif /* WPA_TRACE_BFD */
|
||||
|
||||
#endif /* TRACE_H */
|
||||
375
qcom/opensource/fst-manager/external/utils/wpa_debug.h
vendored
Normal file
375
qcom/opensource/fst-manager/external/utils/wpa_debug.h
vendored
Normal file
@@ -0,0 +1,375 @@
|
||||
/*
|
||||
* wpa_supplicant/hostapd / Debug prints
|
||||
* Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef WPA_DEBUG_H
|
||||
#define WPA_DEBUG_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include "wpabuf.h"
|
||||
|
||||
extern int wpa_debug_level;
|
||||
extern int wpa_debug_show_keys;
|
||||
extern int wpa_debug_timestamp;
|
||||
|
||||
/* Debugging function - conditional printf and hex dump. Driver wrappers can
|
||||
* use these for debugging purposes. */
|
||||
|
||||
enum {
|
||||
MSG_EXCESSIVE, MSG_MSGDUMP, MSG_DEBUG, MSG_INFO, MSG_WARNING, MSG_ERROR
|
||||
};
|
||||
|
||||
#ifdef CONFIG_NO_STDOUT_DEBUG
|
||||
|
||||
#define wpa_debug_print_timestamp() do { } while (0)
|
||||
#define wpa_printf(args...) do { } while (0)
|
||||
#define wpa_hexdump(l,t,b,le) do { } while (0)
|
||||
#define wpa_hexdump_buf(l,t,b) do { } while (0)
|
||||
#define wpa_hexdump_key(l,t,b,le) do { } while (0)
|
||||
#define wpa_hexdump_buf_key(l,t,b) do { } while (0)
|
||||
#define wpa_hexdump_ascii(l,t,b,le) do { } while (0)
|
||||
#define wpa_hexdump_ascii_key(l,t,b,le) do { } while (0)
|
||||
#define wpa_debug_open_file(p) do { } while (0)
|
||||
#define wpa_debug_close_file() do { } while (0)
|
||||
#define wpa_debug_setup_stdout() do { } while (0)
|
||||
#define wpa_dbg(args...) do { } while (0)
|
||||
|
||||
static inline int wpa_debug_reopen_file(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* CONFIG_NO_STDOUT_DEBUG */
|
||||
|
||||
int wpa_debug_open_file(const char *path);
|
||||
int wpa_debug_reopen_file(void);
|
||||
void wpa_debug_close_file(void);
|
||||
void wpa_debug_setup_stdout(void);
|
||||
|
||||
/**
|
||||
* wpa_debug_printf_timestamp - Print timestamp for debug output
|
||||
*
|
||||
* This function prints a timestamp in seconds_from_1970.microsoconds
|
||||
* format if debug output has been configured to include timestamps in debug
|
||||
* messages.
|
||||
*/
|
||||
void wpa_debug_print_timestamp(void);
|
||||
|
||||
/**
|
||||
* wpa_printf - conditional printf
|
||||
* @level: priority level (MSG_*) of the message
|
||||
* @fmt: printf format string, followed by optional arguments
|
||||
*
|
||||
* This function is used to print conditional debugging and error messages. The
|
||||
* output may be directed to stdout, stderr, and/or syslog based on
|
||||
* configuration.
|
||||
*
|
||||
* Note: New line '\n' is added to the end of the text when printing to stdout.
|
||||
*/
|
||||
void wpa_printf(int level, const char *fmt, ...)
|
||||
PRINTF_FORMAT(2, 3);
|
||||
|
||||
/**
|
||||
* wpa_hexdump - conditional hex dump
|
||||
* @level: priority level (MSG_*) of the message
|
||||
* @title: title of for the message
|
||||
* @buf: data buffer to be dumped
|
||||
* @len: length of the buf
|
||||
*
|
||||
* This function is used to print conditional debugging and error messages. The
|
||||
* output may be directed to stdout, stderr, and/or syslog based on
|
||||
* configuration. The contents of buf is printed out has hex dump.
|
||||
*/
|
||||
void wpa_hexdump(int level, const char *title, const void *buf, size_t len);
|
||||
|
||||
static inline void wpa_hexdump_buf(int level, const char *title,
|
||||
const struct wpabuf *buf)
|
||||
{
|
||||
wpa_hexdump(level, title, buf ? wpabuf_head(buf) : NULL,
|
||||
buf ? wpabuf_len(buf) : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* wpa_hexdump_key - conditional hex dump, hide keys
|
||||
* @level: priority level (MSG_*) of the message
|
||||
* @title: title of for the message
|
||||
* @buf: data buffer to be dumped
|
||||
* @len: length of the buf
|
||||
*
|
||||
* This function is used to print conditional debugging and error messages. The
|
||||
* output may be directed to stdout, stderr, and/or syslog based on
|
||||
* configuration. The contents of buf is printed out has hex dump. This works
|
||||
* like wpa_hexdump(), but by default, does not include secret keys (passwords,
|
||||
* etc.) in debug output.
|
||||
*/
|
||||
void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len);
|
||||
|
||||
static inline void wpa_hexdump_buf_key(int level, const char *title,
|
||||
const struct wpabuf *buf)
|
||||
{
|
||||
wpa_hexdump_key(level, title, buf ? wpabuf_head(buf) : NULL,
|
||||
buf ? wpabuf_len(buf) : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* wpa_hexdump_ascii - conditional hex dump
|
||||
* @level: priority level (MSG_*) of the message
|
||||
* @title: title of for the message
|
||||
* @buf: data buffer to be dumped
|
||||
* @len: length of the buf
|
||||
*
|
||||
* This function is used to print conditional debugging and error messages. The
|
||||
* output may be directed to stdout, stderr, and/or syslog based on
|
||||
* configuration. The contents of buf is printed out has hex dump with both
|
||||
* the hex numbers and ASCII characters (for printable range) are shown. 16
|
||||
* bytes per line will be shown.
|
||||
*/
|
||||
void wpa_hexdump_ascii(int level, const char *title, const void *buf,
|
||||
size_t len);
|
||||
|
||||
/**
|
||||
* wpa_hexdump_ascii_key - conditional hex dump, hide keys
|
||||
* @level: priority level (MSG_*) of the message
|
||||
* @title: title of for the message
|
||||
* @buf: data buffer to be dumped
|
||||
* @len: length of the buf
|
||||
*
|
||||
* This function is used to print conditional debugging and error messages. The
|
||||
* output may be directed to stdout, stderr, and/or syslog based on
|
||||
* configuration. The contents of buf is printed out has hex dump with both
|
||||
* the hex numbers and ASCII characters (for printable range) are shown. 16
|
||||
* bytes per line will be shown. This works like wpa_hexdump_ascii(), but by
|
||||
* default, does not include secret keys (passwords, etc.) in debug output.
|
||||
*/
|
||||
void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
|
||||
size_t len);
|
||||
|
||||
/*
|
||||
* wpa_dbg() behaves like wpa_msg(), but it can be removed from build to reduce
|
||||
* binary size. As such, it should be used with debugging messages that are not
|
||||
* needed in the control interface while wpa_msg() has to be used for anything
|
||||
* that needs to shown to control interface monitors.
|
||||
*/
|
||||
#define wpa_dbg(args...) wpa_msg(args)
|
||||
|
||||
#endif /* CONFIG_NO_STDOUT_DEBUG */
|
||||
|
||||
|
||||
#ifdef CONFIG_NO_WPA_MSG
|
||||
#define wpa_msg(args...) do { } while (0)
|
||||
#define wpa_msg_ctrl(args...) do { } while (0)
|
||||
#define wpa_msg_global(args...) do { } while (0)
|
||||
#define wpa_msg_global_ctrl(args...) do { } while (0)
|
||||
#define wpa_msg_no_global(args...) do { } while (0)
|
||||
#define wpa_msg_global_only(args...) do { } while (0)
|
||||
#define wpa_msg_register_cb(f) do { } while (0)
|
||||
#define wpa_msg_register_ifname_cb(f) do { } while (0)
|
||||
#else /* CONFIG_NO_WPA_MSG */
|
||||
/**
|
||||
* wpa_msg - Conditional printf for default target and ctrl_iface monitors
|
||||
* @ctx: Pointer to context data; this is the ctx variable registered
|
||||
* with struct wpa_driver_ops::init()
|
||||
* @level: priority level (MSG_*) of the message
|
||||
* @fmt: printf format string, followed by optional arguments
|
||||
*
|
||||
* This function is used to print conditional debugging and error messages. The
|
||||
* output may be directed to stdout, stderr, and/or syslog based on
|
||||
* configuration. This function is like wpa_printf(), but it also sends the
|
||||
* same message to all attached ctrl_iface monitors.
|
||||
*
|
||||
* Note: New line '\n' is added to the end of the text when printing to stdout.
|
||||
*/
|
||||
void wpa_msg(void *ctx, int level, const char *fmt, ...) PRINTF_FORMAT(3, 4);
|
||||
|
||||
/**
|
||||
* wpa_msg_ctrl - Conditional printf for ctrl_iface monitors
|
||||
* @ctx: Pointer to context data; this is the ctx variable registered
|
||||
* with struct wpa_driver_ops::init()
|
||||
* @level: priority level (MSG_*) of the message
|
||||
* @fmt: printf format string, followed by optional arguments
|
||||
*
|
||||
* This function is used to print conditional debugging and error messages.
|
||||
* This function is like wpa_msg(), but it sends the output only to the
|
||||
* attached ctrl_iface monitors. In other words, it can be used for frequent
|
||||
* events that do not need to be sent to syslog.
|
||||
*/
|
||||
void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
|
||||
PRINTF_FORMAT(3, 4);
|
||||
|
||||
/**
|
||||
* wpa_msg_global - Global printf for ctrl_iface monitors
|
||||
* @ctx: Pointer to context data; this is the ctx variable registered
|
||||
* with struct wpa_driver_ops::init()
|
||||
* @level: priority level (MSG_*) of the message
|
||||
* @fmt: printf format string, followed by optional arguments
|
||||
*
|
||||
* This function is used to print conditional debugging and error messages.
|
||||
* This function is like wpa_msg(), but it sends the output as a global event,
|
||||
* i.e., without being specific to an interface. For backwards compatibility,
|
||||
* an old style event is also delivered on one of the interfaces (the one
|
||||
* specified by the context data).
|
||||
*/
|
||||
void wpa_msg_global(void *ctx, int level, const char *fmt, ...)
|
||||
PRINTF_FORMAT(3, 4);
|
||||
|
||||
/**
|
||||
* wpa_msg_global_ctrl - Conditional global printf for ctrl_iface monitors
|
||||
* @ctx: Pointer to context data; this is the ctx variable registered
|
||||
* with struct wpa_driver_ops::init()
|
||||
* @level: priority level (MSG_*) of the message
|
||||
* @fmt: printf format string, followed by optional arguments
|
||||
*
|
||||
* This function is used to print conditional debugging and error messages.
|
||||
* This function is like wpa_msg_global(), but it sends the output only to the
|
||||
* attached global ctrl_iface monitors. In other words, it can be used for
|
||||
* frequent events that do not need to be sent to syslog.
|
||||
*/
|
||||
void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...)
|
||||
PRINTF_FORMAT(3, 4);
|
||||
|
||||
/**
|
||||
* wpa_msg_no_global - Conditional printf for ctrl_iface monitors
|
||||
* @ctx: Pointer to context data; this is the ctx variable registered
|
||||
* with struct wpa_driver_ops::init()
|
||||
* @level: priority level (MSG_*) of the message
|
||||
* @fmt: printf format string, followed by optional arguments
|
||||
*
|
||||
* This function is used to print conditional debugging and error messages.
|
||||
* This function is like wpa_msg(), but it does not send the output as a global
|
||||
* event.
|
||||
*/
|
||||
void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...)
|
||||
PRINTF_FORMAT(3, 4);
|
||||
|
||||
/**
|
||||
* wpa_msg_global_only - Conditional printf for ctrl_iface monitors
|
||||
* @ctx: Pointer to context data; this is the ctx variable registered
|
||||
* with struct wpa_driver_ops::init()
|
||||
* @level: priority level (MSG_*) of the message
|
||||
* @fmt: printf format string, followed by optional arguments
|
||||
*
|
||||
* This function is used to print conditional debugging and error messages.
|
||||
* This function is like wpa_msg_global(), but it sends the output only as a
|
||||
* global event.
|
||||
*/
|
||||
void wpa_msg_global_only(void *ctx, int level, const char *fmt, ...)
|
||||
PRINTF_FORMAT(3, 4);
|
||||
|
||||
enum wpa_msg_type {
|
||||
WPA_MSG_PER_INTERFACE,
|
||||
WPA_MSG_GLOBAL,
|
||||
WPA_MSG_NO_GLOBAL,
|
||||
WPA_MSG_ONLY_GLOBAL,
|
||||
};
|
||||
|
||||
typedef void (*wpa_msg_cb_func)(void *ctx, int level, enum wpa_msg_type type,
|
||||
const char *txt, size_t len);
|
||||
|
||||
/**
|
||||
* wpa_msg_register_cb - Register callback function for wpa_msg() messages
|
||||
* @func: Callback function (%NULL to unregister)
|
||||
*/
|
||||
void wpa_msg_register_cb(wpa_msg_cb_func func);
|
||||
|
||||
typedef const char * (*wpa_msg_get_ifname_func)(void *ctx);
|
||||
void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func);
|
||||
|
||||
#endif /* CONFIG_NO_WPA_MSG */
|
||||
|
||||
#ifdef CONFIG_NO_HOSTAPD_LOGGER
|
||||
#define hostapd_logger(args...) do { } while (0)
|
||||
#define hostapd_logger_register_cb(f) do { } while (0)
|
||||
#else /* CONFIG_NO_HOSTAPD_LOGGER */
|
||||
void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
|
||||
const char *fmt, ...) PRINTF_FORMAT(5, 6);
|
||||
|
||||
typedef void (*hostapd_logger_cb_func)(void *ctx, const u8 *addr,
|
||||
unsigned int module, int level,
|
||||
const char *txt, size_t len);
|
||||
|
||||
/**
|
||||
* hostapd_logger_register_cb - Register callback function for hostapd_logger()
|
||||
* @func: Callback function (%NULL to unregister)
|
||||
*/
|
||||
void hostapd_logger_register_cb(hostapd_logger_cb_func func);
|
||||
#endif /* CONFIG_NO_HOSTAPD_LOGGER */
|
||||
|
||||
#define HOSTAPD_MODULE_IEEE80211 0x00000001
|
||||
#define HOSTAPD_MODULE_IEEE8021X 0x00000002
|
||||
#define HOSTAPD_MODULE_RADIUS 0x00000004
|
||||
#define HOSTAPD_MODULE_WPA 0x00000008
|
||||
#define HOSTAPD_MODULE_DRIVER 0x00000010
|
||||
#define HOSTAPD_MODULE_IAPP 0x00000020
|
||||
#define HOSTAPD_MODULE_MLME 0x00000040
|
||||
|
||||
enum hostapd_logger_level {
|
||||
HOSTAPD_LEVEL_DEBUG_VERBOSE = 0,
|
||||
HOSTAPD_LEVEL_DEBUG = 1,
|
||||
HOSTAPD_LEVEL_INFO = 2,
|
||||
HOSTAPD_LEVEL_NOTICE = 3,
|
||||
HOSTAPD_LEVEL_WARNING = 4
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_DEBUG_SYSLOG
|
||||
|
||||
void wpa_debug_open_syslog(void);
|
||||
void wpa_debug_close_syslog(void);
|
||||
|
||||
#else /* CONFIG_DEBUG_SYSLOG */
|
||||
|
||||
static inline void wpa_debug_open_syslog(void)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void wpa_debug_close_syslog(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DEBUG_SYSLOG */
|
||||
|
||||
#ifdef CONFIG_DEBUG_LINUX_TRACING
|
||||
|
||||
int wpa_debug_open_linux_tracing(void);
|
||||
void wpa_debug_close_linux_tracing(void);
|
||||
|
||||
#else /* CONFIG_DEBUG_LINUX_TRACING */
|
||||
|
||||
static inline int wpa_debug_open_linux_tracing(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void wpa_debug_close_linux_tracing(void)
|
||||
{
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DEBUG_LINUX_TRACING */
|
||||
|
||||
|
||||
#ifdef EAPOL_TEST
|
||||
#define WPA_ASSERT(a) \
|
||||
do { \
|
||||
if (!(a)) { \
|
||||
printf("WPA_ASSERT FAILED '" #a "' " \
|
||||
"%s %s:%d\n", \
|
||||
__FUNCTION__, __FILE__, __LINE__); \
|
||||
exit(1); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define WPA_ASSERT(a) do { } while (0)
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* WPA_DEBUG_H */
|
||||
163
qcom/opensource/fst-manager/external/utils/wpabuf.h
vendored
Normal file
163
qcom/opensource/fst-manager/external/utils/wpabuf.h
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
/*
|
||||
* Dynamic data buffer
|
||||
* Copyright (c) 2007-2012, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#ifndef WPABUF_H
|
||||
#define WPABUF_H
|
||||
|
||||
/* wpabuf::buf is a pointer to external data */
|
||||
#define WPABUF_FLAG_EXT_DATA BIT(0)
|
||||
|
||||
/*
|
||||
* Internal data structure for wpabuf. Please do not touch this directly from
|
||||
* elsewhere. This is only defined in header file to allow inline functions
|
||||
* from this file to access data.
|
||||
*/
|
||||
struct wpabuf {
|
||||
size_t size; /* total size of the allocated buffer */
|
||||
size_t used; /* length of data in the buffer */
|
||||
u8 *buf; /* pointer to the head of the buffer */
|
||||
unsigned int flags;
|
||||
/* optionally followed by the allocated buffer */
|
||||
};
|
||||
|
||||
|
||||
int wpabuf_resize(struct wpabuf **buf, size_t add_len);
|
||||
struct wpabuf * wpabuf_alloc(size_t len);
|
||||
struct wpabuf * wpabuf_alloc_ext_data(u8 *data, size_t len);
|
||||
struct wpabuf * wpabuf_alloc_copy(const void *data, size_t len);
|
||||
struct wpabuf * wpabuf_dup(const struct wpabuf *src);
|
||||
void wpabuf_free(struct wpabuf *buf);
|
||||
void wpabuf_clear_free(struct wpabuf *buf);
|
||||
void * wpabuf_put(struct wpabuf *buf, size_t len);
|
||||
struct wpabuf * wpabuf_concat(struct wpabuf *a, struct wpabuf *b);
|
||||
struct wpabuf * wpabuf_zeropad(struct wpabuf *buf, size_t len);
|
||||
void wpabuf_printf(struct wpabuf *buf, char *fmt, ...) PRINTF_FORMAT(2, 3);
|
||||
|
||||
|
||||
/**
|
||||
* wpabuf_size - Get the currently allocated size of a wpabuf buffer
|
||||
* @buf: wpabuf buffer
|
||||
* Returns: Currently allocated size of the buffer
|
||||
*/
|
||||
static inline size_t wpabuf_size(const struct wpabuf *buf)
|
||||
{
|
||||
return buf->size;
|
||||
}
|
||||
|
||||
/**
|
||||
* wpabuf_len - Get the current length of a wpabuf buffer data
|
||||
* @buf: wpabuf buffer
|
||||
* Returns: Currently used length of the buffer
|
||||
*/
|
||||
static inline size_t wpabuf_len(const struct wpabuf *buf)
|
||||
{
|
||||
return buf->used;
|
||||
}
|
||||
|
||||
/**
|
||||
* wpabuf_tailroom - Get size of available tail room in the end of the buffer
|
||||
* @buf: wpabuf buffer
|
||||
* Returns: Tail room (in bytes) of available space in the end of the buffer
|
||||
*/
|
||||
static inline size_t wpabuf_tailroom(const struct wpabuf *buf)
|
||||
{
|
||||
return buf->size - buf->used;
|
||||
}
|
||||
|
||||
/**
|
||||
* wpabuf_head - Get pointer to the head of the buffer data
|
||||
* @buf: wpabuf buffer
|
||||
* Returns: Pointer to the head of the buffer data
|
||||
*/
|
||||
static inline const void * wpabuf_head(const struct wpabuf *buf)
|
||||
{
|
||||
return buf->buf;
|
||||
}
|
||||
|
||||
static inline const u8 * wpabuf_head_u8(const struct wpabuf *buf)
|
||||
{
|
||||
return (const u8 *)wpabuf_head(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* wpabuf_mhead - Get modifiable pointer to the head of the buffer data
|
||||
* @buf: wpabuf buffer
|
||||
* Returns: Pointer to the head of the buffer data
|
||||
*/
|
||||
static inline void * wpabuf_mhead(struct wpabuf *buf)
|
||||
{
|
||||
return buf->buf;
|
||||
}
|
||||
|
||||
static inline u8 * wpabuf_mhead_u8(struct wpabuf *buf)
|
||||
{
|
||||
return (u8 *)wpabuf_mhead(buf);
|
||||
}
|
||||
|
||||
static inline void wpabuf_put_u8(struct wpabuf *buf, u8 data)
|
||||
{
|
||||
u8 *pos = (u8 *)wpabuf_put(buf, 1);
|
||||
*pos = data;
|
||||
}
|
||||
|
||||
static inline void wpabuf_put_le16(struct wpabuf *buf, u16 data)
|
||||
{
|
||||
u8 *pos = (u8 *)wpabuf_put(buf, 2);
|
||||
WPA_PUT_LE16(pos, data);
|
||||
}
|
||||
|
||||
static inline void wpabuf_put_le32(struct wpabuf *buf, u32 data)
|
||||
{
|
||||
u8 *pos = (u8 *)wpabuf_put(buf, 4);
|
||||
WPA_PUT_LE32(pos, data);
|
||||
}
|
||||
|
||||
static inline void wpabuf_put_be16(struct wpabuf *buf, u16 data)
|
||||
{
|
||||
u8 *pos = (u8 *)wpabuf_put(buf, 2);
|
||||
WPA_PUT_BE16(pos, data);
|
||||
}
|
||||
|
||||
static inline void wpabuf_put_be24(struct wpabuf *buf, u32 data)
|
||||
{
|
||||
u8 *pos = (u8 *)wpabuf_put(buf, 3);
|
||||
WPA_PUT_BE24(pos, data);
|
||||
}
|
||||
|
||||
static inline void wpabuf_put_be32(struct wpabuf *buf, u32 data)
|
||||
{
|
||||
u8 *pos = (u8 *)wpabuf_put(buf, 4);
|
||||
WPA_PUT_BE32(pos, data);
|
||||
}
|
||||
|
||||
static inline void wpabuf_put_data(struct wpabuf *buf, const void *data,
|
||||
size_t len)
|
||||
{
|
||||
if (data)
|
||||
os_memcpy(wpabuf_put(buf, len), data, len);
|
||||
}
|
||||
|
||||
static inline void wpabuf_put_buf(struct wpabuf *dst,
|
||||
const struct wpabuf *src)
|
||||
{
|
||||
wpabuf_put_data(dst, wpabuf_head(src), wpabuf_len(src));
|
||||
}
|
||||
|
||||
static inline void wpabuf_set(struct wpabuf *buf, const void *data, size_t len)
|
||||
{
|
||||
buf->buf = (u8 *) data;
|
||||
buf->flags = WPABUF_FLAG_EXT_DATA;
|
||||
buf->size = buf->used = len;
|
||||
}
|
||||
|
||||
static inline void wpabuf_put_str(struct wpabuf *dst, const char *str)
|
||||
{
|
||||
wpabuf_put_data(dst, str, os_strlen(str));
|
||||
}
|
||||
|
||||
#endif /* WPABUF_H */
|
||||
733
qcom/opensource/fst-manager/external/wpa_ctrl.c
vendored
Normal file
733
qcom/opensource/fst-manager/external/wpa_ctrl.c
vendored
Normal file
@@ -0,0 +1,733 @@
|
||||
/*
|
||||
* wpa_supplicant/hostapd control interface library
|
||||
* Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE_UNIX
|
||||
#include <sys/un.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#endif /* CONFIG_CTRL_IFACE_UNIX */
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
|
||||
#include <netdb.h>
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include <cutils/sockets.h>
|
||||
#include "cutils/android_filesystem_config.h"
|
||||
#endif /* ANDROID */
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||
#include <net/if.h>
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
|
||||
#include "wpa_ctrl.h"
|
||||
#include "common.h"
|
||||
|
||||
|
||||
#if defined(CONFIG_CTRL_IFACE_UNIX) || defined(CONFIG_CTRL_IFACE_UDP)
|
||||
#define CTRL_IFACE_SOCKET
|
||||
#endif /* CONFIG_CTRL_IFACE_UNIX || CONFIG_CTRL_IFACE_UDP */
|
||||
|
||||
|
||||
/**
|
||||
* struct wpa_ctrl - Internal structure for control interface library
|
||||
*
|
||||
* This structure is used by the wpa_supplicant/hostapd control interface
|
||||
* library to store internal data. Programs using the library should not touch
|
||||
* this data directly. They can only use the pointer to the data structure as
|
||||
* an identifier for the control interface connection and use this as one of
|
||||
* the arguments for most of the control interface library functions.
|
||||
*/
|
||||
struct wpa_ctrl {
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP
|
||||
int s;
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||
struct sockaddr_in6 local;
|
||||
struct sockaddr_in6 dest;
|
||||
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
struct sockaddr_in local;
|
||||
struct sockaddr_in dest;
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
char *cookie;
|
||||
char *remote_ifname;
|
||||
char *remote_ip;
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP */
|
||||
#ifdef CONFIG_CTRL_IFACE_UNIX
|
||||
int s;
|
||||
struct sockaddr_un local;
|
||||
struct sockaddr_un dest;
|
||||
#endif /* CONFIG_CTRL_IFACE_UNIX */
|
||||
#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
|
||||
HANDLE pipe;
|
||||
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
|
||||
};
|
||||
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE_UNIX
|
||||
|
||||
#ifndef CONFIG_CTRL_IFACE_CLIENT_DIR
|
||||
#define CONFIG_CTRL_IFACE_CLIENT_DIR "/tmp"
|
||||
#endif /* CONFIG_CTRL_IFACE_CLIENT_DIR */
|
||||
#ifndef CONFIG_CTRL_IFACE_CLIENT_PREFIX
|
||||
#define CONFIG_CTRL_IFACE_CLIENT_PREFIX "wpa_ctrl_"
|
||||
#endif /* CONFIG_CTRL_IFACE_CLIENT_PREFIX */
|
||||
|
||||
|
||||
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
|
||||
{
|
||||
struct wpa_ctrl *ctrl;
|
||||
static int counter = 0;
|
||||
int ret;
|
||||
size_t res;
|
||||
int tries = 0;
|
||||
int flags;
|
||||
|
||||
if (ctrl_path == NULL)
|
||||
return NULL;
|
||||
|
||||
ctrl = os_zalloc(sizeof(*ctrl));
|
||||
if (ctrl == NULL)
|
||||
return NULL;
|
||||
|
||||
ctrl->s = socket(PF_UNIX, SOCK_DGRAM, 0);
|
||||
if (ctrl->s < 0) {
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ctrl->local.sun_family = AF_UNIX;
|
||||
counter++;
|
||||
try_again:
|
||||
ret = os_snprintf(ctrl->local.sun_path, sizeof(ctrl->local.sun_path),
|
||||
CONFIG_CTRL_IFACE_CLIENT_DIR "/"
|
||||
CONFIG_CTRL_IFACE_CLIENT_PREFIX "%d-%d",
|
||||
(int) getpid(), counter);
|
||||
if (os_snprintf_error(sizeof(ctrl->local.sun_path), ret)) {
|
||||
close(ctrl->s);
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
tries++;
|
||||
if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
|
||||
sizeof(ctrl->local)) < 0) {
|
||||
if (errno == EADDRINUSE && tries < 2) {
|
||||
/*
|
||||
* getpid() returns unique identifier for this instance
|
||||
* of wpa_ctrl, so the existing socket file must have
|
||||
* been left by unclean termination of an earlier run.
|
||||
* Remove the file and try again.
|
||||
*/
|
||||
unlink(ctrl->local.sun_path);
|
||||
goto try_again;
|
||||
}
|
||||
close(ctrl->s);
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
chmod(ctrl->local.sun_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);
|
||||
chown(ctrl->local.sun_path, AID_SYSTEM, AID_WIFI);
|
||||
|
||||
if (os_strncmp(ctrl_path, "@android:", 9) == 0) {
|
||||
if (socket_local_client_connect(
|
||||
ctrl->s, ctrl_path + 9,
|
||||
ANDROID_SOCKET_NAMESPACE_RESERVED,
|
||||
SOCK_DGRAM) < 0) {
|
||||
close(ctrl->s);
|
||||
unlink(ctrl->local.sun_path);
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
/*
|
||||
* If the ctrl_path isn't an absolute pathname, assume that
|
||||
* it's the name of a socket in the Android reserved namespace.
|
||||
* Otherwise, it's a normal UNIX domain socket appearing in the
|
||||
* filesystem.
|
||||
*/
|
||||
if (*ctrl_path != '/') {
|
||||
char buf[21];
|
||||
os_snprintf(buf, sizeof(buf), "wpa_%s", ctrl_path);
|
||||
if (socket_local_client_connect(
|
||||
ctrl->s, buf,
|
||||
ANDROID_SOCKET_NAMESPACE_RESERVED,
|
||||
SOCK_DGRAM) < 0) {
|
||||
close(ctrl->s);
|
||||
unlink(ctrl->local.sun_path);
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
return ctrl;
|
||||
}
|
||||
#endif /* ANDROID */
|
||||
|
||||
ctrl->dest.sun_family = AF_UNIX;
|
||||
if (os_strncmp(ctrl_path, "@abstract:", 10) == 0) {
|
||||
ctrl->dest.sun_path[0] = '\0';
|
||||
os_strlcpy(ctrl->dest.sun_path + 1, ctrl_path + 10,
|
||||
sizeof(ctrl->dest.sun_path) - 1);
|
||||
} else {
|
||||
res = os_strlcpy(ctrl->dest.sun_path, ctrl_path,
|
||||
sizeof(ctrl->dest.sun_path));
|
||||
if (res >= sizeof(ctrl->dest.sun_path)) {
|
||||
close(ctrl->s);
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
|
||||
sizeof(ctrl->dest)) < 0) {
|
||||
close(ctrl->s);
|
||||
unlink(ctrl->local.sun_path);
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Make socket non-blocking so that we don't hang forever if
|
||||
* target dies unexpectedly.
|
||||
*/
|
||||
flags = fcntl(ctrl->s, F_GETFL);
|
||||
if (flags >= 0) {
|
||||
flags |= O_NONBLOCK;
|
||||
if (fcntl(ctrl->s, F_SETFL, flags) < 0) {
|
||||
perror("fcntl(ctrl->s, O_NONBLOCK)");
|
||||
/* Not fatal, continue on.*/
|
||||
}
|
||||
}
|
||||
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
|
||||
void wpa_ctrl_close(struct wpa_ctrl *ctrl)
|
||||
{
|
||||
if (ctrl == NULL)
|
||||
return;
|
||||
unlink(ctrl->local.sun_path);
|
||||
if (ctrl->s >= 0)
|
||||
close(ctrl->s);
|
||||
os_free(ctrl);
|
||||
}
|
||||
|
||||
|
||||
#ifdef ANDROID
|
||||
/**
|
||||
* wpa_ctrl_cleanup() - Delete any local UNIX domain socket files that
|
||||
* may be left over from clients that were previously connected to
|
||||
* wpa_supplicant. This keeps these files from being orphaned in the
|
||||
* event of crashes that prevented them from being removed as part
|
||||
* of the normal orderly shutdown.
|
||||
*/
|
||||
void wpa_ctrl_cleanup(void)
|
||||
{
|
||||
DIR *dir;
|
||||
struct dirent entry;
|
||||
struct dirent *result;
|
||||
size_t dirnamelen;
|
||||
size_t maxcopy;
|
||||
char pathname[PATH_MAX];
|
||||
char *namep;
|
||||
|
||||
if ((dir = opendir(CONFIG_CTRL_IFACE_CLIENT_DIR)) == NULL)
|
||||
return;
|
||||
|
||||
dirnamelen = (size_t) os_snprintf(pathname, sizeof(pathname), "%s/",
|
||||
CONFIG_CTRL_IFACE_CLIENT_DIR);
|
||||
if (dirnamelen >= sizeof(pathname)) {
|
||||
closedir(dir);
|
||||
return;
|
||||
}
|
||||
namep = pathname + dirnamelen;
|
||||
maxcopy = PATH_MAX - dirnamelen;
|
||||
while (readdir_r(dir, &entry, &result) == 0 && result != NULL) {
|
||||
if (os_strlcpy(namep, entry.d_name, maxcopy) < maxcopy)
|
||||
unlink(pathname);
|
||||
}
|
||||
closedir(dir);
|
||||
}
|
||||
#endif /* ANDROID */
|
||||
|
||||
#else /* CONFIG_CTRL_IFACE_UNIX */
|
||||
|
||||
#ifdef ANDROID
|
||||
void wpa_ctrl_cleanup(void)
|
||||
{
|
||||
}
|
||||
#endif /* ANDROID */
|
||||
|
||||
#endif /* CONFIG_CTRL_IFACE_UNIX */
|
||||
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP
|
||||
|
||||
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
|
||||
{
|
||||
struct wpa_ctrl *ctrl;
|
||||
char buf[128];
|
||||
size_t len;
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
|
||||
struct hostent *h;
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||
|
||||
ctrl = os_zalloc(sizeof(*ctrl));
|
||||
if (ctrl == NULL)
|
||||
return NULL;
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||
ctrl->s = socket(PF_INET6, SOCK_DGRAM, 0);
|
||||
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
ctrl->s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
if (ctrl->s < 0) {
|
||||
perror("socket");
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||
ctrl->local.sin6_family = AF_INET6;
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
|
||||
ctrl->local.sin6_addr = in6addr_any;
|
||||
#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||
inet_pton(AF_INET6, "::1", &ctrl->local.sin6_addr);
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
ctrl->local.sin_family = AF_INET;
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
|
||||
ctrl->local.sin_addr.s_addr = INADDR_ANY;
|
||||
#else /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||
ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1);
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
|
||||
if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
|
||||
sizeof(ctrl->local)) < 0) {
|
||||
close(ctrl->s);
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||
ctrl->dest.sin6_family = AF_INET6;
|
||||
inet_pton(AF_INET6, "::1", &ctrl->dest.sin6_addr);
|
||||
ctrl->dest.sin6_port = htons(WPA_CTRL_IFACE_PORT);
|
||||
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
ctrl->dest.sin_family = AF_INET;
|
||||
ctrl->dest.sin_addr.s_addr = htonl((127 << 24) | 1);
|
||||
ctrl->dest.sin_port = htons(WPA_CTRL_IFACE_PORT);
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_REMOTE
|
||||
if (ctrl_path) {
|
||||
char *port, *name;
|
||||
int port_id;
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||
char *scope;
|
||||
int scope_id = 0;
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
|
||||
name = os_strdup(ctrl_path);
|
||||
if (name == NULL) {
|
||||
close(ctrl->s);
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||
port = os_strchr(name, ',');
|
||||
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
port = os_strchr(name, ':');
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
|
||||
if (port) {
|
||||
port_id = atoi(&port[1]);
|
||||
port[0] = '\0';
|
||||
} else
|
||||
port_id = WPA_CTRL_IFACE_PORT;
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||
scope = os_strchr(name, '%');
|
||||
if (scope) {
|
||||
scope_id = if_nametoindex(&scope[1]);
|
||||
scope[0] = '\0';
|
||||
}
|
||||
h = gethostbyname2(name, AF_INET6);
|
||||
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
h = gethostbyname(name);
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
ctrl->remote_ip = os_strdup(name);
|
||||
os_free(name);
|
||||
if (h == NULL) {
|
||||
perror("gethostbyname");
|
||||
close(ctrl->s);
|
||||
os_free(ctrl->remote_ip);
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||
ctrl->dest.sin6_scope_id = scope_id;
|
||||
ctrl->dest.sin6_port = htons(port_id);
|
||||
os_memcpy(&ctrl->dest.sin6_addr, h->h_addr, h->h_length);
|
||||
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
ctrl->dest.sin_port = htons(port_id);
|
||||
os_memcpy(&ctrl->dest.sin_addr.s_addr, h->h_addr, h->h_length);
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
} else
|
||||
ctrl->remote_ip = os_strdup("localhost");
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_REMOTE */
|
||||
|
||||
if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
|
||||
sizeof(ctrl->dest)) < 0) {
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP_IPV6
|
||||
char addr[INET6_ADDRSTRLEN];
|
||||
wpa_printf(MSG_ERROR, "connect(%s:%d) failed: %s",
|
||||
inet_ntop(AF_INET6, &ctrl->dest.sin6_addr, addr,
|
||||
sizeof(ctrl->dest)),
|
||||
ntohs(ctrl->dest.sin6_port),
|
||||
strerror(errno));
|
||||
#else /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
wpa_printf(MSG_ERROR, "connect(%s:%d) failed: %s",
|
||||
inet_ntoa(ctrl->dest.sin_addr),
|
||||
ntohs(ctrl->dest.sin_port),
|
||||
strerror(errno));
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP_IPV6 */
|
||||
close(ctrl->s);
|
||||
os_free(ctrl->remote_ip);
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = sizeof(buf) - 1;
|
||||
if (wpa_ctrl_request(ctrl, "GET_COOKIE", 10, buf, &len, NULL) == 0) {
|
||||
buf[len] = '\0';
|
||||
ctrl->cookie = os_strdup(buf);
|
||||
}
|
||||
|
||||
if (wpa_ctrl_request(ctrl, "IFNAME", 6, buf, &len, NULL) == 0) {
|
||||
buf[len] = '\0';
|
||||
ctrl->remote_ifname = os_strdup(buf);
|
||||
}
|
||||
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
|
||||
char * wpa_ctrl_get_remote_ifname(struct wpa_ctrl *ctrl)
|
||||
{
|
||||
#define WPA_CTRL_MAX_PS_NAME 100
|
||||
static char ps[WPA_CTRL_MAX_PS_NAME] = {};
|
||||
os_snprintf(ps, WPA_CTRL_MAX_PS_NAME, "%s/%s",
|
||||
ctrl->remote_ip, ctrl->remote_ifname);
|
||||
return ps;
|
||||
}
|
||||
|
||||
|
||||
void wpa_ctrl_close(struct wpa_ctrl *ctrl)
|
||||
{
|
||||
close(ctrl->s);
|
||||
os_free(ctrl->cookie);
|
||||
os_free(ctrl->remote_ifname);
|
||||
os_free(ctrl->remote_ip);
|
||||
os_free(ctrl);
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP */
|
||||
|
||||
|
||||
#ifdef CTRL_IFACE_SOCKET
|
||||
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
|
||||
char *reply, size_t *reply_len,
|
||||
void (*msg_cb)(char *msg, size_t len))
|
||||
{
|
||||
struct timeval tv;
|
||||
struct os_reltime started_at;
|
||||
int res;
|
||||
fd_set rfds;
|
||||
const char *_cmd;
|
||||
char *cmd_buf = NULL;
|
||||
size_t _cmd_len;
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE_UDP
|
||||
if (ctrl->cookie) {
|
||||
char *pos;
|
||||
_cmd_len = os_strlen(ctrl->cookie) + 1 + cmd_len;
|
||||
cmd_buf = os_malloc(_cmd_len);
|
||||
if (cmd_buf == NULL)
|
||||
return -1;
|
||||
_cmd = cmd_buf;
|
||||
pos = cmd_buf;
|
||||
os_strlcpy(pos, ctrl->cookie, _cmd_len);
|
||||
pos += os_strlen(ctrl->cookie);
|
||||
*pos++ = ' ';
|
||||
os_memcpy(pos, cmd, cmd_len);
|
||||
} else
|
||||
#endif /* CONFIG_CTRL_IFACE_UDP */
|
||||
{
|
||||
_cmd = cmd;
|
||||
_cmd_len = cmd_len;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
started_at.sec = 0;
|
||||
started_at.usec = 0;
|
||||
retry_send:
|
||||
if (send(ctrl->s, _cmd, _cmd_len, 0) < 0) {
|
||||
if (errno == EAGAIN || errno == EBUSY || errno == EWOULDBLOCK)
|
||||
{
|
||||
/*
|
||||
* Must be a non-blocking socket... Try for a bit
|
||||
* longer before giving up.
|
||||
*/
|
||||
if (started_at.sec == 0)
|
||||
os_get_reltime(&started_at);
|
||||
else {
|
||||
struct os_reltime n;
|
||||
os_get_reltime(&n);
|
||||
/* Try for a few seconds. */
|
||||
if (os_reltime_expired(&n, &started_at, 5))
|
||||
goto send_err;
|
||||
}
|
||||
os_sleep(1, 0);
|
||||
goto retry_send;
|
||||
}
|
||||
send_err:
|
||||
os_free(cmd_buf);
|
||||
return -1;
|
||||
}
|
||||
os_free(cmd_buf);
|
||||
|
||||
for (;;) {
|
||||
tv.tv_sec = 10;
|
||||
tv.tv_usec = 0;
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(ctrl->s, &rfds);
|
||||
res = select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
|
||||
if (res < 0)
|
||||
return res;
|
||||
if (FD_ISSET(ctrl->s, &rfds)) {
|
||||
res = recv(ctrl->s, reply, *reply_len, 0);
|
||||
if (res < 0)
|
||||
return res;
|
||||
if (res > 0 && reply[0] == '<') {
|
||||
/* This is an unsolicited message from
|
||||
* wpa_supplicant, not the reply to the
|
||||
* request. Use msg_cb to report this to the
|
||||
* caller. */
|
||||
if (msg_cb) {
|
||||
/* Make sure the message is nul
|
||||
* terminated. */
|
||||
if ((size_t) res == *reply_len)
|
||||
res = (*reply_len) - 1;
|
||||
reply[res] = '\0';
|
||||
msg_cb(reply, res);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
*reply_len = res;
|
||||
break;
|
||||
} else {
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif /* CTRL_IFACE_SOCKET */
|
||||
|
||||
|
||||
static int wpa_ctrl_attach_helper(struct wpa_ctrl *ctrl, int attach)
|
||||
{
|
||||
char buf[10];
|
||||
int ret;
|
||||
size_t len = 10;
|
||||
|
||||
ret = wpa_ctrl_request(ctrl, attach ? "ATTACH" : "DETACH", 6,
|
||||
buf, &len, NULL);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
if (len == 3 && os_memcmp(buf, "OK\n", 3) == 0)
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
int wpa_ctrl_attach(struct wpa_ctrl *ctrl)
|
||||
{
|
||||
return wpa_ctrl_attach_helper(ctrl, 1);
|
||||
}
|
||||
|
||||
|
||||
int wpa_ctrl_detach(struct wpa_ctrl *ctrl)
|
||||
{
|
||||
return wpa_ctrl_attach_helper(ctrl, 0);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CTRL_IFACE_SOCKET
|
||||
|
||||
int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = recv(ctrl->s, reply, *reply_len, 0);
|
||||
if (res < 0)
|
||||
return res;
|
||||
*reply_len = res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int wpa_ctrl_pending(struct wpa_ctrl *ctrl)
|
||||
{
|
||||
struct timeval tv;
|
||||
fd_set rfds;
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 0;
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(ctrl->s, &rfds);
|
||||
select(ctrl->s + 1, &rfds, NULL, NULL, &tv);
|
||||
return FD_ISSET(ctrl->s, &rfds);
|
||||
}
|
||||
|
||||
|
||||
int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl)
|
||||
{
|
||||
return ctrl->s;
|
||||
}
|
||||
|
||||
#endif /* CTRL_IFACE_SOCKET */
|
||||
|
||||
|
||||
#ifdef CONFIG_CTRL_IFACE_NAMED_PIPE
|
||||
|
||||
#ifndef WPA_SUPPLICANT_NAMED_PIPE
|
||||
#define WPA_SUPPLICANT_NAMED_PIPE "WpaSupplicant"
|
||||
#endif
|
||||
#define NAMED_PIPE_PREFIX TEXT("\\\\.\\pipe\\") TEXT(WPA_SUPPLICANT_NAMED_PIPE)
|
||||
|
||||
struct wpa_ctrl * wpa_ctrl_open(const char *ctrl_path)
|
||||
{
|
||||
struct wpa_ctrl *ctrl;
|
||||
DWORD mode;
|
||||
TCHAR name[256];
|
||||
int i, ret;
|
||||
|
||||
ctrl = os_malloc(sizeof(*ctrl));
|
||||
if (ctrl == NULL)
|
||||
return NULL;
|
||||
os_memset(ctrl, 0, sizeof(*ctrl));
|
||||
|
||||
#ifdef UNICODE
|
||||
if (ctrl_path == NULL)
|
||||
ret = _snwprintf(name, 256, NAMED_PIPE_PREFIX);
|
||||
else
|
||||
ret = _snwprintf(name, 256, NAMED_PIPE_PREFIX TEXT("-%S"),
|
||||
ctrl_path);
|
||||
#else /* UNICODE */
|
||||
if (ctrl_path == NULL)
|
||||
ret = os_snprintf(name, 256, NAMED_PIPE_PREFIX);
|
||||
else
|
||||
ret = os_snprintf(name, 256, NAMED_PIPE_PREFIX "-%s",
|
||||
ctrl_path);
|
||||
#endif /* UNICODE */
|
||||
if (os_snprintf_error(256, ret)) {
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < 10; i++) {
|
||||
ctrl->pipe = CreateFile(name, GENERIC_READ | GENERIC_WRITE, 0,
|
||||
NULL, OPEN_EXISTING, 0, NULL);
|
||||
/*
|
||||
* Current named pipe server side in wpa_supplicant is
|
||||
* re-opening the pipe for new clients only after the previous
|
||||
* one is taken into use. This leaves a small window for race
|
||||
* conditions when two connections are being opened at almost
|
||||
* the same time. Retry if that was the case.
|
||||
*/
|
||||
if (ctrl->pipe != INVALID_HANDLE_VALUE ||
|
||||
GetLastError() != ERROR_PIPE_BUSY)
|
||||
break;
|
||||
WaitNamedPipe(name, 1000);
|
||||
}
|
||||
if (ctrl->pipe == INVALID_HANDLE_VALUE) {
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
mode = PIPE_READMODE_MESSAGE;
|
||||
if (!SetNamedPipeHandleState(ctrl->pipe, &mode, NULL, NULL)) {
|
||||
CloseHandle(ctrl->pipe);
|
||||
os_free(ctrl);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ctrl;
|
||||
}
|
||||
|
||||
|
||||
void wpa_ctrl_close(struct wpa_ctrl *ctrl)
|
||||
{
|
||||
CloseHandle(ctrl->pipe);
|
||||
os_free(ctrl);
|
||||
}
|
||||
|
||||
|
||||
int wpa_ctrl_request(struct wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
|
||||
char *reply, size_t *reply_len,
|
||||
void (*msg_cb)(char *msg, size_t len))
|
||||
{
|
||||
DWORD written;
|
||||
DWORD readlen = *reply_len;
|
||||
|
||||
if (!WriteFile(ctrl->pipe, cmd, cmd_len, &written, NULL))
|
||||
return -1;
|
||||
|
||||
if (!ReadFile(ctrl->pipe, reply, *reply_len, &readlen, NULL))
|
||||
return -1;
|
||||
*reply_len = readlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int wpa_ctrl_recv(struct wpa_ctrl *ctrl, char *reply, size_t *reply_len)
|
||||
{
|
||||
DWORD len = *reply_len;
|
||||
if (!ReadFile(ctrl->pipe, reply, *reply_len, &len, NULL))
|
||||
return -1;
|
||||
*reply_len = len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int wpa_ctrl_pending(struct wpa_ctrl *ctrl)
|
||||
{
|
||||
DWORD left;
|
||||
|
||||
if (!PeekNamedPipe(ctrl->pipe, NULL, 0, NULL, &left, NULL))
|
||||
return -1;
|
||||
return left ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
int wpa_ctrl_get_fd(struct wpa_ctrl *ctrl)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_CTRL_IFACE_NAMED_PIPE */
|
||||
|
||||
#endif /* CONFIG_CTRL_IFACE */
|
||||
819
qcom/opensource/fst-manager/external/wpa_debug.c
vendored
Normal file
819
qcom/opensource/fst-manager/external/wpa_debug.c
vendored
Normal file
@@ -0,0 +1,819 @@
|
||||
/*
|
||||
* wpa_supplicant/hostapd / Debug prints
|
||||
* Copyright (c) 2002-2013, Jouni Malinen <j@w1.fi>
|
||||
*
|
||||
* This software may be distributed under the terms of the BSD license.
|
||||
* See README for more details.
|
||||
*/
|
||||
|
||||
#include "includes.h"
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#ifdef CONFIG_DEBUG_SYSLOG
|
||||
#include <syslog.h>
|
||||
|
||||
static int wpa_debug_syslog = 0;
|
||||
#endif /* CONFIG_DEBUG_SYSLOG */
|
||||
|
||||
#ifdef CONFIG_DEBUG_LINUX_TRACING
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
static FILE *wpa_debug_tracing_file = NULL;
|
||||
|
||||
#define WPAS_TRACE_PFX "wpas <%d>: "
|
||||
#endif /* CONFIG_DEBUG_LINUX_TRACING */
|
||||
|
||||
|
||||
int wpa_debug_level = MSG_INFO;
|
||||
int wpa_debug_show_keys = 0;
|
||||
int wpa_debug_timestamp = 0;
|
||||
|
||||
|
||||
#ifdef CONFIG_ANDROID_LOG
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#ifndef ANDROID_LOG_NAME
|
||||
#define ANDROID_LOG_NAME "wpa_supplicant"
|
||||
#endif /* ANDROID_LOG_NAME */
|
||||
|
||||
static int wpa_to_android_level(int level)
|
||||
{
|
||||
if (level == MSG_ERROR)
|
||||
return ANDROID_LOG_ERROR;
|
||||
if (level == MSG_WARNING)
|
||||
return ANDROID_LOG_WARN;
|
||||
if (level == MSG_INFO)
|
||||
return ANDROID_LOG_INFO;
|
||||
return ANDROID_LOG_DEBUG;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_ANDROID_LOG */
|
||||
|
||||
#ifndef CONFIG_NO_STDOUT_DEBUG
|
||||
|
||||
#ifdef CONFIG_DEBUG_FILE
|
||||
static FILE *out_file = NULL;
|
||||
#endif /* CONFIG_DEBUG_FILE */
|
||||
|
||||
|
||||
void wpa_debug_print_timestamp(void)
|
||||
{
|
||||
#ifndef CONFIG_ANDROID_LOG
|
||||
struct os_time tv;
|
||||
|
||||
if (!wpa_debug_timestamp)
|
||||
return;
|
||||
|
||||
os_get_time(&tv);
|
||||
#ifdef CONFIG_DEBUG_FILE
|
||||
if (out_file) {
|
||||
fprintf(out_file, "%ld.%06u: ", (long) tv.sec,
|
||||
(unsigned int) tv.usec);
|
||||
} else
|
||||
#endif /* CONFIG_DEBUG_FILE */
|
||||
printf("%ld.%06u: ", (long) tv.sec, (unsigned int) tv.usec);
|
||||
#endif /* CONFIG_ANDROID_LOG */
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_DEBUG_SYSLOG
|
||||
#ifndef LOG_HOSTAPD
|
||||
#define LOG_HOSTAPD LOG_DAEMON
|
||||
#endif /* LOG_HOSTAPD */
|
||||
|
||||
void wpa_debug_open_syslog(void)
|
||||
{
|
||||
openlog("wpa_supplicant", LOG_PID | LOG_NDELAY, LOG_HOSTAPD);
|
||||
wpa_debug_syslog++;
|
||||
}
|
||||
|
||||
|
||||
void wpa_debug_close_syslog(void)
|
||||
{
|
||||
if (wpa_debug_syslog)
|
||||
closelog();
|
||||
}
|
||||
|
||||
|
||||
static int syslog_priority(int level)
|
||||
{
|
||||
switch (level) {
|
||||
case MSG_MSGDUMP:
|
||||
case MSG_DEBUG:
|
||||
return LOG_DEBUG;
|
||||
case MSG_INFO:
|
||||
return LOG_NOTICE;
|
||||
case MSG_WARNING:
|
||||
return LOG_WARNING;
|
||||
case MSG_ERROR:
|
||||
return LOG_ERR;
|
||||
}
|
||||
return LOG_INFO;
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_SYSLOG */
|
||||
|
||||
|
||||
#ifdef CONFIG_DEBUG_LINUX_TRACING
|
||||
|
||||
int wpa_debug_open_linux_tracing(void)
|
||||
{
|
||||
int mounts, trace_fd;
|
||||
char buf[4096] = {};
|
||||
ssize_t buflen;
|
||||
char *line, *tmp1, *path = NULL;
|
||||
|
||||
mounts = open("/proc/mounts", O_RDONLY);
|
||||
if (mounts < 0) {
|
||||
printf("no /proc/mounts\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
buflen = read(mounts, buf, sizeof(buf) - 1);
|
||||
close(mounts);
|
||||
if (buflen < 0) {
|
||||
printf("failed to read /proc/mounts\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
line = strtok_r(buf, "\n", &tmp1);
|
||||
while (line) {
|
||||
char *tmp2, *tmp_path, *fstype;
|
||||
/* "<dev> <mountpoint> <fs type> ..." */
|
||||
strtok_r(line, " ", &tmp2);
|
||||
tmp_path = strtok_r(NULL, " ", &tmp2);
|
||||
fstype = strtok_r(NULL, " ", &tmp2);
|
||||
if (strcmp(fstype, "debugfs") == 0) {
|
||||
path = tmp_path;
|
||||
break;
|
||||
}
|
||||
|
||||
line = strtok_r(NULL, "\n", &tmp1);
|
||||
}
|
||||
|
||||
if (path == NULL) {
|
||||
printf("debugfs mountpoint not found\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf) - 1, "%s/tracing/trace_marker", path);
|
||||
|
||||
trace_fd = open(buf, O_WRONLY);
|
||||
if (trace_fd < 0) {
|
||||
printf("failed to open trace_marker file\n");
|
||||
return -1;
|
||||
}
|
||||
wpa_debug_tracing_file = fdopen(trace_fd, "w");
|
||||
if (wpa_debug_tracing_file == NULL) {
|
||||
close(trace_fd);
|
||||
printf("failed to fdopen()\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void wpa_debug_close_linux_tracing(void)
|
||||
{
|
||||
if (wpa_debug_tracing_file == NULL)
|
||||
return;
|
||||
fclose(wpa_debug_tracing_file);
|
||||
wpa_debug_tracing_file = NULL;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_DEBUG_LINUX_TRACING */
|
||||
|
||||
|
||||
/**
|
||||
* wpa_printf - conditional printf
|
||||
* @level: priority level (MSG_*) of the message
|
||||
* @fmt: printf format string, followed by optional arguments
|
||||
*
|
||||
* This function is used to print conditional debugging and error messages. The
|
||||
* output may be directed to stdout, stderr, and/or syslog based on
|
||||
* configuration.
|
||||
*
|
||||
* Note: New line '\n' is added to the end of the text when printing to stdout.
|
||||
*/
|
||||
void wpa_printf(int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
if (level >= wpa_debug_level) {
|
||||
#ifdef CONFIG_ANDROID_LOG
|
||||
__android_log_vprint(wpa_to_android_level(level),
|
||||
ANDROID_LOG_NAME, fmt, ap);
|
||||
#else /* CONFIG_ANDROID_LOG */
|
||||
#ifdef CONFIG_DEBUG_SYSLOG
|
||||
if (wpa_debug_syslog) {
|
||||
vsyslog(syslog_priority(level), fmt, ap);
|
||||
} else {
|
||||
#endif /* CONFIG_DEBUG_SYSLOG */
|
||||
wpa_debug_print_timestamp();
|
||||
#ifdef CONFIG_DEBUG_FILE
|
||||
if (out_file) {
|
||||
vfprintf(out_file, fmt, ap);
|
||||
fprintf(out_file, "\n");
|
||||
} else {
|
||||
#endif /* CONFIG_DEBUG_FILE */
|
||||
vprintf(fmt, ap);
|
||||
printf("\n");
|
||||
#ifdef CONFIG_DEBUG_FILE
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_FILE */
|
||||
#ifdef CONFIG_DEBUG_SYSLOG
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_SYSLOG */
|
||||
#endif /* CONFIG_ANDROID_LOG */
|
||||
}
|
||||
va_end(ap);
|
||||
|
||||
#ifdef CONFIG_DEBUG_LINUX_TRACING
|
||||
if (wpa_debug_tracing_file != NULL) {
|
||||
va_start(ap, fmt);
|
||||
fprintf(wpa_debug_tracing_file, WPAS_TRACE_PFX, level);
|
||||
vfprintf(wpa_debug_tracing_file, fmt, ap);
|
||||
fprintf(wpa_debug_tracing_file, "\n");
|
||||
fflush(wpa_debug_tracing_file);
|
||||
va_end(ap);
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_LINUX_TRACING */
|
||||
}
|
||||
|
||||
|
||||
static void _wpa_hexdump(int level, const char *title, const u8 *buf,
|
||||
size_t len, int show)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
#ifdef CONFIG_DEBUG_LINUX_TRACING
|
||||
if (wpa_debug_tracing_file != NULL) {
|
||||
fprintf(wpa_debug_tracing_file,
|
||||
WPAS_TRACE_PFX "%s - hexdump(len=%lu):",
|
||||
level, title, (unsigned long) len);
|
||||
if (buf == NULL) {
|
||||
fprintf(wpa_debug_tracing_file, " [NULL]\n");
|
||||
} else if (!show) {
|
||||
fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
|
||||
} else {
|
||||
for (i = 0; i < len; i++)
|
||||
fprintf(wpa_debug_tracing_file,
|
||||
" %02x", buf[i]);
|
||||
}
|
||||
fflush(wpa_debug_tracing_file);
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_LINUX_TRACING */
|
||||
|
||||
if (level < wpa_debug_level)
|
||||
return;
|
||||
#ifdef CONFIG_ANDROID_LOG
|
||||
{
|
||||
const char *display;
|
||||
char *strbuf = NULL;
|
||||
size_t slen = len;
|
||||
if (buf == NULL) {
|
||||
display = " [NULL]";
|
||||
} else if (len == 0) {
|
||||
display = "";
|
||||
} else if (show && len) {
|
||||
/* Limit debug message length for Android log */
|
||||
if (slen > 32)
|
||||
slen = 32;
|
||||
strbuf = os_malloc(1 + 3 * slen);
|
||||
if (strbuf == NULL) {
|
||||
wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
|
||||
"allocate message buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < slen; i++)
|
||||
os_snprintf(&strbuf[i * 3], 4, " %02x",
|
||||
buf[i]);
|
||||
|
||||
display = strbuf;
|
||||
} else {
|
||||
display = " [REMOVED]";
|
||||
}
|
||||
|
||||
__android_log_print(wpa_to_android_level(level),
|
||||
ANDROID_LOG_NAME,
|
||||
"%s - hexdump(len=%lu):%s%s",
|
||||
title, (long unsigned int) len, display,
|
||||
len > slen ? " ..." : "");
|
||||
os_free(strbuf);
|
||||
return;
|
||||
}
|
||||
#else /* CONFIG_ANDROID_LOG */
|
||||
#ifdef CONFIG_DEBUG_SYSLOG
|
||||
if (wpa_debug_syslog) {
|
||||
const char *display;
|
||||
char *strbuf = NULL;
|
||||
|
||||
if (buf == NULL) {
|
||||
display = " [NULL]";
|
||||
} else if (len == 0) {
|
||||
display = "";
|
||||
} else if (show && len) {
|
||||
strbuf = os_malloc(1 + 3 * len);
|
||||
if (strbuf == NULL) {
|
||||
wpa_printf(MSG_ERROR, "wpa_hexdump: Failed to "
|
||||
"allocate message buffer");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
os_snprintf(&strbuf[i * 3], 4, " %02x",
|
||||
buf[i]);
|
||||
|
||||
display = strbuf;
|
||||
} else {
|
||||
display = " [REMOVED]";
|
||||
}
|
||||
|
||||
syslog(syslog_priority(level), "%s - hexdump(len=%lu):%s",
|
||||
title, (unsigned long) len, display);
|
||||
os_free(strbuf);
|
||||
return;
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_SYSLOG */
|
||||
wpa_debug_print_timestamp();
|
||||
#ifdef CONFIG_DEBUG_FILE
|
||||
if (out_file) {
|
||||
fprintf(out_file, "%s - hexdump(len=%lu):",
|
||||
title, (unsigned long) len);
|
||||
if (buf == NULL) {
|
||||
fprintf(out_file, " [NULL]");
|
||||
} else if (show) {
|
||||
for (i = 0; i < len; i++)
|
||||
fprintf(out_file, " %02x", buf[i]);
|
||||
} else {
|
||||
fprintf(out_file, " [REMOVED]");
|
||||
}
|
||||
fprintf(out_file, "\n");
|
||||
} else {
|
||||
#endif /* CONFIG_DEBUG_FILE */
|
||||
printf("%s - hexdump(len=%lu):", title, (unsigned long) len);
|
||||
if (buf == NULL) {
|
||||
printf(" [NULL]");
|
||||
} else if (show) {
|
||||
for (i = 0; i < len; i++)
|
||||
printf(" %02x", buf[i]);
|
||||
} else {
|
||||
printf(" [REMOVED]");
|
||||
}
|
||||
printf("\n");
|
||||
#ifdef CONFIG_DEBUG_FILE
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_FILE */
|
||||
#endif /* CONFIG_ANDROID_LOG */
|
||||
}
|
||||
|
||||
void wpa_hexdump(int level, const char *title, const void *buf, size_t len)
|
||||
{
|
||||
_wpa_hexdump(level, title, buf, len, 1);
|
||||
}
|
||||
|
||||
|
||||
void wpa_hexdump_key(int level, const char *title, const void *buf, size_t len)
|
||||
{
|
||||
_wpa_hexdump(level, title, buf, len, wpa_debug_show_keys);
|
||||
}
|
||||
|
||||
|
||||
static void _wpa_hexdump_ascii(int level, const char *title, const void *buf,
|
||||
size_t len, int show)
|
||||
{
|
||||
size_t i, llen;
|
||||
const u8 *pos = buf;
|
||||
const size_t line_len = 16;
|
||||
|
||||
#ifdef CONFIG_DEBUG_LINUX_TRACING
|
||||
if (wpa_debug_tracing_file != NULL) {
|
||||
fprintf(wpa_debug_tracing_file,
|
||||
WPAS_TRACE_PFX "%s - hexdump_ascii(len=%lu):",
|
||||
level, title, (unsigned long) len);
|
||||
if (buf == NULL) {
|
||||
fprintf(wpa_debug_tracing_file, " [NULL]\n");
|
||||
} else if (!show) {
|
||||
fprintf(wpa_debug_tracing_file, " [REMOVED]\n");
|
||||
} else {
|
||||
/* can do ascii processing in userspace */
|
||||
for (i = 0; i < len; i++)
|
||||
fprintf(wpa_debug_tracing_file,
|
||||
" %02x", pos[i]);
|
||||
}
|
||||
fflush(wpa_debug_tracing_file);
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_LINUX_TRACING */
|
||||
|
||||
if (level < wpa_debug_level)
|
||||
return;
|
||||
#ifdef CONFIG_ANDROID_LOG
|
||||
_wpa_hexdump(level, title, buf, len, show);
|
||||
#else /* CONFIG_ANDROID_LOG */
|
||||
wpa_debug_print_timestamp();
|
||||
#ifdef CONFIG_DEBUG_FILE
|
||||
if (out_file) {
|
||||
if (!show) {
|
||||
fprintf(out_file,
|
||||
"%s - hexdump_ascii(len=%lu): [REMOVED]\n",
|
||||
title, (unsigned long) len);
|
||||
return;
|
||||
}
|
||||
if (buf == NULL) {
|
||||
fprintf(out_file,
|
||||
"%s - hexdump_ascii(len=%lu): [NULL]\n",
|
||||
title, (unsigned long) len);
|
||||
return;
|
||||
}
|
||||
fprintf(out_file, "%s - hexdump_ascii(len=%lu):\n",
|
||||
title, (unsigned long) len);
|
||||
while (len) {
|
||||
llen = len > line_len ? line_len : len;
|
||||
fprintf(out_file, " ");
|
||||
for (i = 0; i < llen; i++)
|
||||
fprintf(out_file, " %02x", pos[i]);
|
||||
for (i = llen; i < line_len; i++)
|
||||
fprintf(out_file, " ");
|
||||
fprintf(out_file, " ");
|
||||
for (i = 0; i < llen; i++) {
|
||||
if (isprint(pos[i]))
|
||||
fprintf(out_file, "%c", pos[i]);
|
||||
else
|
||||
fprintf(out_file, "_");
|
||||
}
|
||||
for (i = llen; i < line_len; i++)
|
||||
fprintf(out_file, " ");
|
||||
fprintf(out_file, "\n");
|
||||
pos += llen;
|
||||
len -= llen;
|
||||
}
|
||||
} else {
|
||||
#endif /* CONFIG_DEBUG_FILE */
|
||||
if (!show) {
|
||||
printf("%s - hexdump_ascii(len=%lu): [REMOVED]\n",
|
||||
title, (unsigned long) len);
|
||||
return;
|
||||
}
|
||||
if (buf == NULL) {
|
||||
printf("%s - hexdump_ascii(len=%lu): [NULL]\n",
|
||||
title, (unsigned long) len);
|
||||
return;
|
||||
}
|
||||
printf("%s - hexdump_ascii(len=%lu):\n", title, (unsigned long) len);
|
||||
while (len) {
|
||||
llen = len > line_len ? line_len : len;
|
||||
printf(" ");
|
||||
for (i = 0; i < llen; i++)
|
||||
printf(" %02x", pos[i]);
|
||||
for (i = llen; i < line_len; i++)
|
||||
printf(" ");
|
||||
printf(" ");
|
||||
for (i = 0; i < llen; i++) {
|
||||
if (isprint(pos[i]))
|
||||
printf("%c", pos[i]);
|
||||
else
|
||||
printf("_");
|
||||
}
|
||||
for (i = llen; i < line_len; i++)
|
||||
printf(" ");
|
||||
printf("\n");
|
||||
pos += llen;
|
||||
len -= llen;
|
||||
}
|
||||
#ifdef CONFIG_DEBUG_FILE
|
||||
}
|
||||
#endif /* CONFIG_DEBUG_FILE */
|
||||
#endif /* CONFIG_ANDROID_LOG */
|
||||
}
|
||||
|
||||
|
||||
void wpa_hexdump_ascii(int level, const char *title, const void *buf,
|
||||
size_t len)
|
||||
{
|
||||
_wpa_hexdump_ascii(level, title, buf, len, 1);
|
||||
}
|
||||
|
||||
|
||||
void wpa_hexdump_ascii_key(int level, const char *title, const void *buf,
|
||||
size_t len)
|
||||
{
|
||||
_wpa_hexdump_ascii(level, title, buf, len, wpa_debug_show_keys);
|
||||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_DEBUG_FILE
|
||||
static char *last_path = NULL;
|
||||
#endif /* CONFIG_DEBUG_FILE */
|
||||
|
||||
int wpa_debug_reopen_file(void)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_FILE
|
||||
int rv;
|
||||
if (last_path) {
|
||||
char *tmp = os_strdup(last_path);
|
||||
wpa_debug_close_file();
|
||||
rv = wpa_debug_open_file(tmp);
|
||||
os_free(tmp);
|
||||
} else {
|
||||
wpa_printf(MSG_ERROR, "Last-path was not set, cannot "
|
||||
"re-open log file.");
|
||||
rv = -1;
|
||||
}
|
||||
return rv;
|
||||
#else /* CONFIG_DEBUG_FILE */
|
||||
return 0;
|
||||
#endif /* CONFIG_DEBUG_FILE */
|
||||
}
|
||||
|
||||
|
||||
int wpa_debug_open_file(const char *path)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_FILE
|
||||
if (!path)
|
||||
return 0;
|
||||
|
||||
if (last_path == NULL || os_strcmp(last_path, path) != 0) {
|
||||
/* Save our path to enable re-open */
|
||||
os_free(last_path);
|
||||
last_path = os_strdup(path);
|
||||
}
|
||||
|
||||
out_file = fopen(path, "a");
|
||||
if (out_file == NULL) {
|
||||
wpa_printf(MSG_ERROR, "wpa_debug_open_file: Failed to open "
|
||||
"output file, using standard output");
|
||||
return -1;
|
||||
}
|
||||
#ifndef _WIN32
|
||||
setvbuf(out_file, NULL, _IOLBF, 0);
|
||||
#endif /* _WIN32 */
|
||||
#else /* CONFIG_DEBUG_FILE */
|
||||
(void)path;
|
||||
#endif /* CONFIG_DEBUG_FILE */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void wpa_debug_close_file(void)
|
||||
{
|
||||
#ifdef CONFIG_DEBUG_FILE
|
||||
if (!out_file)
|
||||
return;
|
||||
fclose(out_file);
|
||||
out_file = NULL;
|
||||
os_free(last_path);
|
||||
last_path = NULL;
|
||||
#endif /* CONFIG_DEBUG_FILE */
|
||||
}
|
||||
|
||||
|
||||
void wpa_debug_setup_stdout(void)
|
||||
{
|
||||
#ifndef _WIN32
|
||||
setvbuf(stdout, NULL, _IOLBF, 0);
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
#endif /* CONFIG_NO_STDOUT_DEBUG */
|
||||
|
||||
|
||||
#ifndef CONFIG_NO_WPA_MSG
|
||||
static wpa_msg_cb_func wpa_msg_cb = NULL;
|
||||
|
||||
void wpa_msg_register_cb(wpa_msg_cb_func func)
|
||||
{
|
||||
wpa_msg_cb = func;
|
||||
}
|
||||
|
||||
|
||||
static wpa_msg_get_ifname_func wpa_msg_ifname_cb = NULL;
|
||||
|
||||
void wpa_msg_register_ifname_cb(wpa_msg_get_ifname_func func)
|
||||
{
|
||||
wpa_msg_ifname_cb = func;
|
||||
}
|
||||
|
||||
|
||||
void wpa_msg(void *ctx, int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *buf;
|
||||
int buflen;
|
||||
int len;
|
||||
char prefix[130];
|
||||
|
||||
va_start(ap, fmt);
|
||||
buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
|
||||
va_end(ap);
|
||||
|
||||
buf = os_malloc(buflen);
|
||||
if (buf == NULL) {
|
||||
wpa_printf(MSG_ERROR, "wpa_msg: Failed to allocate message "
|
||||
"buffer");
|
||||
return;
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
prefix[0] = '\0';
|
||||
if (wpa_msg_ifname_cb) {
|
||||
const char *ifname = wpa_msg_ifname_cb(ctx);
|
||||
if (ifname) {
|
||||
int res = os_snprintf(prefix, sizeof(prefix), "%s: ",
|
||||
ifname);
|
||||
if (os_snprintf_error(sizeof(prefix), res))
|
||||
prefix[0] = '\0';
|
||||
}
|
||||
}
|
||||
len = vsnprintf(buf, buflen, fmt, ap);
|
||||
va_end(ap);
|
||||
wpa_printf(level, "%s%s", prefix, buf);
|
||||
if (wpa_msg_cb)
|
||||
wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
|
||||
os_free(buf);
|
||||
}
|
||||
|
||||
|
||||
void wpa_msg_ctrl(void *ctx, int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *buf;
|
||||
int buflen;
|
||||
int len;
|
||||
|
||||
if (!wpa_msg_cb)
|
||||
return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
|
||||
va_end(ap);
|
||||
|
||||
buf = os_malloc(buflen);
|
||||
if (buf == NULL) {
|
||||
wpa_printf(MSG_ERROR, "wpa_msg_ctrl: Failed to allocate "
|
||||
"message buffer");
|
||||
return;
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
len = vsnprintf(buf, buflen, fmt, ap);
|
||||
va_end(ap);
|
||||
wpa_msg_cb(ctx, level, WPA_MSG_PER_INTERFACE, buf, len);
|
||||
os_free(buf);
|
||||
}
|
||||
|
||||
|
||||
void wpa_msg_global(void *ctx, int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *buf;
|
||||
int buflen;
|
||||
int len;
|
||||
|
||||
va_start(ap, fmt);
|
||||
buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
|
||||
va_end(ap);
|
||||
|
||||
buf = os_malloc(buflen);
|
||||
if (buf == NULL) {
|
||||
wpa_printf(MSG_ERROR, "wpa_msg_global: Failed to allocate "
|
||||
"message buffer");
|
||||
return;
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
len = vsnprintf(buf, buflen, fmt, ap);
|
||||
va_end(ap);
|
||||
wpa_printf(level, "%s", buf);
|
||||
if (wpa_msg_cb)
|
||||
wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
|
||||
os_free(buf);
|
||||
}
|
||||
|
||||
|
||||
void wpa_msg_global_ctrl(void *ctx, int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *buf;
|
||||
int buflen;
|
||||
int len;
|
||||
|
||||
if (!wpa_msg_cb)
|
||||
return;
|
||||
|
||||
va_start(ap, fmt);
|
||||
buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
|
||||
va_end(ap);
|
||||
|
||||
buf = os_malloc(buflen);
|
||||
if (buf == NULL) {
|
||||
wpa_printf(MSG_ERROR,
|
||||
"wpa_msg_global_ctrl: Failed to allocate message buffer");
|
||||
return;
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
len = vsnprintf(buf, buflen, fmt, ap);
|
||||
va_end(ap);
|
||||
wpa_msg_cb(ctx, level, WPA_MSG_GLOBAL, buf, len);
|
||||
os_free(buf);
|
||||
}
|
||||
|
||||
|
||||
void wpa_msg_no_global(void *ctx, int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *buf;
|
||||
int buflen;
|
||||
int len;
|
||||
|
||||
va_start(ap, fmt);
|
||||
buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
|
||||
va_end(ap);
|
||||
|
||||
buf = os_malloc(buflen);
|
||||
if (buf == NULL) {
|
||||
wpa_printf(MSG_ERROR, "wpa_msg_no_global: Failed to allocate "
|
||||
"message buffer");
|
||||
return;
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
len = vsnprintf(buf, buflen, fmt, ap);
|
||||
va_end(ap);
|
||||
wpa_printf(level, "%s", buf);
|
||||
if (wpa_msg_cb)
|
||||
wpa_msg_cb(ctx, level, WPA_MSG_NO_GLOBAL, buf, len);
|
||||
os_free(buf);
|
||||
}
|
||||
|
||||
void wpa_msg_global_only(void *ctx, int level, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *buf;
|
||||
int buflen;
|
||||
int len;
|
||||
|
||||
va_start(ap, fmt);
|
||||
buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
|
||||
va_end(ap);
|
||||
|
||||
buf = os_malloc(buflen);
|
||||
if (buf == NULL) {
|
||||
wpa_printf(MSG_ERROR, "wpa_msg_no_global: Failed to allocate "
|
||||
"message buffer");
|
||||
return;
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
len = vsnprintf(buf, buflen, fmt, ap);
|
||||
va_end(ap);
|
||||
wpa_printf(level, "%s", buf);
|
||||
if (wpa_msg_cb)
|
||||
wpa_msg_cb(ctx, level, WPA_MSG_ONLY_GLOBAL, buf, len);
|
||||
os_free(buf);
|
||||
}
|
||||
#endif /* CONFIG_NO_WPA_MSG */
|
||||
|
||||
|
||||
#ifndef CONFIG_NO_HOSTAPD_LOGGER
|
||||
static hostapd_logger_cb_func hostapd_logger_cb = NULL;
|
||||
|
||||
void hostapd_logger_register_cb(hostapd_logger_cb_func func)
|
||||
{
|
||||
hostapd_logger_cb = func;
|
||||
}
|
||||
|
||||
|
||||
void hostapd_logger(void *ctx, const u8 *addr, unsigned int module, int level,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *buf;
|
||||
int buflen;
|
||||
int len;
|
||||
|
||||
va_start(ap, fmt);
|
||||
buflen = vsnprintf(NULL, 0, fmt, ap) + 1;
|
||||
va_end(ap);
|
||||
|
||||
buf = os_malloc(buflen);
|
||||
if (buf == NULL) {
|
||||
wpa_printf(MSG_ERROR, "hostapd_logger: Failed to allocate "
|
||||
"message buffer");
|
||||
return;
|
||||
}
|
||||
va_start(ap, fmt);
|
||||
len = vsnprintf(buf, buflen, fmt, ap);
|
||||
va_end(ap);
|
||||
if (hostapd_logger_cb)
|
||||
hostapd_logger_cb(ctx, addr, module, level, buf, len);
|
||||
else if (addr)
|
||||
wpa_printf(MSG_DEBUG, "hostapd_logger: STA " MACSTR " - %s",
|
||||
MAC2STR(addr), buf);
|
||||
else
|
||||
wpa_printf(MSG_DEBUG, "hostapd_logger: %s", buf);
|
||||
os_free(buf);
|
||||
}
|
||||
#endif /* CONFIG_NO_HOSTAPD_LOGGER */
|
||||
82
qcom/opensource/fst-manager/fst_capconfigstore.cpp
Normal file
82
qcom/opensource/fst-manager/fst_capconfigstore.cpp
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Provides access to the capablity config store in Android
|
||||
*
|
||||
* Copyright (c) 2019, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include <vendor/qti/hardware/capabilityconfigstore/1.0/ICapabilityConfigStore.h>
|
||||
#include <vendor/qti/hardware/capabilityconfigstore/1.0/types.h>
|
||||
#define FST_MGR_COMPONENT "CCS"
|
||||
#include "fst_manager.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/os.h"
|
||||
#include "fst_capconfigstore.h"
|
||||
|
||||
using android::hardware::hidl_string;
|
||||
using namespace android;
|
||||
using CommandResult = ::vendor::qti::hardware::capabilityconfigstore::V1_0::CommandResult;
|
||||
using Result = ::vendor::qti::hardware::capabilityconfigstore::V1_0::Result;
|
||||
using ICapabilityConfigStore = ::vendor::qti::hardware::capabilityconfigstore::V1_0::ICapabilityConfigStore;
|
||||
|
||||
|
||||
#define WIGIG_CONFIG_STORE_AREA "wigig"
|
||||
|
||||
void fst_get_config_string(const char *key, const char *defvalue,
|
||||
char *buf, size_t len)
|
||||
{
|
||||
sp<ICapabilityConfigStore> service;
|
||||
CommandResult res;
|
||||
|
||||
res.result_type = Result::NOT_FOUND;
|
||||
|
||||
service = ICapabilityConfigStore::getService();
|
||||
if (!service) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"failed to get capconfigstore service");
|
||||
goto out;
|
||||
}
|
||||
|
||||
service->getConfig(WIGIG_CONFIG_STORE_AREA, key, [&](const CommandResult& res) {
|
||||
if(res.result_type == Result::SUCCESS) {
|
||||
fst_mgr_printf(MSG_DEBUG,
|
||||
"getConfig: key %s returned value %s",
|
||||
key, res.value.c_str());
|
||||
os_strlcpy(buf, res.value.c_str(), len);
|
||||
} else {
|
||||
fst_mgr_printf(MSG_DEBUG,
|
||||
"getConfig: failed to get key %s",
|
||||
key);
|
||||
}
|
||||
});
|
||||
|
||||
out:
|
||||
if (res.result_type != Result::SUCCESS) {
|
||||
fst_mgr_printf(MSG_DEBUG, "getConfig: use default value %s", defvalue);
|
||||
os_strlcpy(buf, defvalue, len);
|
||||
}
|
||||
}
|
||||
48
qcom/opensource/fst-manager/fst_capconfigstore.h
Normal file
48
qcom/opensource/fst-manager/fst_capconfigstore.h
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Provides access to the capablity config store in Android
|
||||
*
|
||||
* Copyright (c) 2019, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FST_CAPCONFIGSTORE_H__
|
||||
#define __FST_CAPCONFIGSTORE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void fst_get_config_string(const char *key, const char *defvalue,
|
||||
char *buf, size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* __FST_CAPCONFIGSTORE_H__ */
|
||||
964
qcom/opensource/fst-manager/fst_cfgmgr.c
Normal file
964
qcom/opensource/fst-manager/fst_cfgmgr.c
Normal file
@@ -0,0 +1,964 @@
|
||||
/*
|
||||
* FST Manager: FST Configuration Manager
|
||||
*
|
||||
* Copyright (c) 2015-2016,2019-2020, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_arp.h>
|
||||
#include <linux/sockios.h>
|
||||
#include "fst_cfgmgr.h"
|
||||
#include "fst_rateupg.h"
|
||||
#include "fst_ini_conf.h"
|
||||
|
||||
#define FST_MGR_COMPONENT "CFGMGR"
|
||||
#include "fst_manager.h"
|
||||
|
||||
static struct fst_config_ctx
|
||||
{
|
||||
enum fst_config_method method;
|
||||
struct fst_ini_config *handle;
|
||||
int skfd;
|
||||
} fstcfg = {FST_CONFIG_CLI, NULL, -1};
|
||||
|
||||
static int _get_iface_flags(int sock, const char *ifname, short int *flags)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
||||
os_memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
|
||||
|
||||
if (ioctl(sock, SIOCGIFFLAGS, &ifr) != 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Error getting interface %s flags", ifname);
|
||||
return -2;
|
||||
}
|
||||
*flags = ifr.ifr_flags;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_iface_flags(int sock, const char *ifname, short int flags)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
||||
os_memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
|
||||
ifr.ifr_flags = flags;
|
||||
|
||||
if (ioctl(sock, SIOCSIFFLAGS, &ifr) != 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Error setting interface %s flags", ifname);
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_iface_txqueuelen(int sock, const char *ifname, int txqueuelen)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
||||
os_memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, ifname, IFNAMSIZ);
|
||||
ifr.ifr_qlen = txqueuelen;
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "Setting %s txqueuelen %d", ifname, txqueuelen);
|
||||
|
||||
if (ioctl(sock, SIOCSIFTXQLEN, &ifr) != 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Error setting interface %s txqueuelen", ifname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _set_iface_up(int sock, const char *ifname, Boolean up)
|
||||
{
|
||||
short int flags;
|
||||
int ret;
|
||||
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
|
||||
ret = _get_iface_flags(sock, ifname, &flags);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (up) {
|
||||
if (flags & IFF_UP)
|
||||
return 0;
|
||||
flags |= IFF_UP;
|
||||
} else {
|
||||
if (!(flags & IFF_UP))
|
||||
return 0;
|
||||
flags &= ~IFF_UP;
|
||||
}
|
||||
|
||||
return set_iface_flags(sock, ifname, flags);
|
||||
}
|
||||
|
||||
int set_iface_up(const char *ifname, Boolean up)
|
||||
{
|
||||
return _set_iface_up(fstcfg.skfd, ifname, up);
|
||||
}
|
||||
|
||||
int get_iface_flags(const char *ifname, short int *flags)
|
||||
{
|
||||
return _get_iface_flags(fstcfg.skfd, ifname, flags);
|
||||
}
|
||||
|
||||
static int enslave_device(int sock, const char *bond, const char *ifname)
|
||||
{
|
||||
struct ifreq if_enslave;
|
||||
short int iface_flags;
|
||||
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
|
||||
if (_get_iface_flags(sock, ifname, &iface_flags) < 0)
|
||||
return -1;
|
||||
|
||||
if (iface_flags & IFF_SLAVE) {
|
||||
fst_mgr_printf(MSG_INFO, "Interface %s already enslaved", ifname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Device should be down before bonding in new kernels */
|
||||
iface_flags &= ~IFF_UP;
|
||||
if (set_iface_flags(sock, ifname, iface_flags) < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot down slave %s", ifname);
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Enslave the device */
|
||||
os_strlcpy(if_enslave.ifr_name, bond, IFNAMSIZ);
|
||||
os_strlcpy(if_enslave.ifr_slave, ifname, IFNAMSIZ);
|
||||
if ((ioctl(sock, SIOCBONDENSLAVE, &if_enslave) < 0)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Error enslaving %s to %s: %s",
|
||||
ifname, bond, strerror(errno));
|
||||
return -2;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int release_device(int sock, const char *bond, const char *ifname)
|
||||
{
|
||||
struct ifreq if_enslave;
|
||||
short int iface_flags;
|
||||
|
||||
if (sock < 0)
|
||||
return -1;
|
||||
|
||||
if (_get_iface_flags(sock, ifname, &iface_flags) < 0)
|
||||
return -1;
|
||||
|
||||
if (!(iface_flags & IFF_SLAVE)) {
|
||||
fst_mgr_printf(MSG_INFO, "Interface %s not enslaved", ifname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Release the device */
|
||||
os_strlcpy(if_enslave.ifr_name, bond, IFNAMSIZ);
|
||||
os_strlcpy(if_enslave.ifr_slave, ifname, IFNAMSIZ);
|
||||
if ((ioctl(sock, SIOCBONDRELEASE, &if_enslave) < 0)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Error releasing %s from %s: %s",
|
||||
ifname, bond, strerror(errno));
|
||||
return -2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fst_cfgmgr_get_txqueuelen(const char *gname)
|
||||
{
|
||||
int res = -1;
|
||||
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_get_txqueuelen(fstcfg.handle, gname);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
break;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_set_mac_address(struct fst_group_info *ginfo, const u8 *mac)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
int ret;
|
||||
char bond[80];
|
||||
|
||||
if (fst_cfgmgr_get_mux_ifname(ginfo->id, bond, sizeof(bond)-1) <= 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot get mux name for %s", ginfo->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_strlcpy(ifr.ifr_name, bond, IFNAMSIZ);
|
||||
memcpy(ifr.ifr_hwaddr.sa_data, mac, ETH_ALEN);
|
||||
ifr.ifr_hwaddr.sa_family = ARPHRD_ETHER;
|
||||
|
||||
ret = ioctl(fstcfg.skfd, SIOCSIFHWADDR, &ifr);
|
||||
if (ret < 0)
|
||||
fst_mgr_printf(MSG_ERROR, "SIOCSIFHWADDR failed on %s: %s",
|
||||
bond, strerror(errno));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int fst_iface_enslave(struct fst_group_info *ginfo, const char *ifname, Boolean enslave)
|
||||
{
|
||||
int res;
|
||||
char bond[80];
|
||||
|
||||
if (fst_cfgmgr_get_mux_ifname(ginfo->id, bond, sizeof(bond)-1) <= 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot get mux name for %s", ginfo->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fst_mgr_printf(MSG_DEBUG,
|
||||
"%s interface %s to mux %s (group %s)",
|
||||
enslave ? "Enslaving":"Releasing", ifname,
|
||||
bond, ginfo->id);
|
||||
|
||||
if (enslave)
|
||||
res = enslave_device(fstcfg.skfd, bond, ifname);
|
||||
else
|
||||
res = release_device(fstcfg.skfd, bond, ifname);
|
||||
if (res < 0)
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot enslave/release %s", ifname);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_update_txqueuelen(const struct fst_group_info *group)
|
||||
{
|
||||
int sock = fstcfg.skfd, txqueuelen, res = 0;
|
||||
char buf[80];
|
||||
|
||||
if (fst_cfgmgr_get_mux_ifname(group->id, buf, sizeof(buf)-1) <= 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot get mux name for %s",
|
||||
group->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
txqueuelen = fst_cfgmgr_get_txqueuelen(group->id);
|
||||
if (txqueuelen >= 0)
|
||||
res = set_iface_txqueuelen(sock, buf, txqueuelen);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_set_mux_iface_up(const struct fst_group_info *group, Boolean up)
|
||||
{
|
||||
int sock = fstcfg.skfd, res;
|
||||
char buf[80];
|
||||
|
||||
if (fst_cfgmgr_get_mux_ifname(group->id, buf, sizeof(buf)-1) <= 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot get mux name for %s",
|
||||
group->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = (_set_iface_up(sock, buf, up) < 0);
|
||||
if (res) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot set iface %s to state %s",
|
||||
buf, up ? "UP" : "DOWN");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static int do_bonding_operations(Boolean enslave)
|
||||
{
|
||||
struct fst_group_info *groups;
|
||||
struct fst_iface_info *ifaces;
|
||||
int gcnt, icnt, muxtype, sock = fstcfg.skfd, i, j, res;
|
||||
char buf[80];
|
||||
Boolean enslaved_any;
|
||||
|
||||
if (fstcfg.handle == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR, "Interfaces configuration not found");
|
||||
goto error_handle;
|
||||
}
|
||||
|
||||
gcnt = fst_ini_config_get_groups(fstcfg.handle, &groups);
|
||||
if (gcnt < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot read groups");
|
||||
goto error_groups;
|
||||
}
|
||||
|
||||
for (i = 0; i < gcnt; i++) {
|
||||
muxtype = fst_cfgmgr_get_mux_type(groups[i].id,
|
||||
buf, sizeof(buf)-1);
|
||||
if (muxtype && os_strncmp(buf, "bonding", sizeof(buf)-1) &&
|
||||
os_strncmp(buf, "bonding_l2da", sizeof(buf)-1)) {
|
||||
fst_mgr_printf(MSG_DEBUG,
|
||||
"Group %s mux type %s not supported, skipping",
|
||||
groups[i].id, buf);
|
||||
continue;
|
||||
}
|
||||
if (!fst_cfgmgr_is_mux_managed(groups[i].id)) {
|
||||
fst_mgr_printf(MSG_DEBUG,
|
||||
"Group %s mux is unmanaged, skipping",
|
||||
groups[i].id);
|
||||
continue;
|
||||
}
|
||||
if (fst_cfgmgr_get_mux_ifname(groups[i].id, buf, sizeof(buf)-1) <= 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot get mux name for %s",
|
||||
groups[i].id);
|
||||
goto error_muxname;
|
||||
}
|
||||
icnt = fst_ini_config_get_group_ifaces(fstcfg.handle,
|
||||
&groups[i], &ifaces);
|
||||
if (icnt < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot read interfaces for %s",
|
||||
groups[i].id);
|
||||
goto error_ifaces;
|
||||
}
|
||||
enslaved_any = FALSE;
|
||||
for (j = 0; j < icnt; j++) {
|
||||
if (enslave && ifaces[j].manual_enslave)
|
||||
continue;
|
||||
|
||||
res = fst_iface_enslave(&groups[i], ifaces[j].name, enslave);
|
||||
if (res < 0)
|
||||
goto error_enslave;
|
||||
enslaved_any = TRUE;
|
||||
}
|
||||
|
||||
if (enslaved_any) {
|
||||
res = fst_cfgmgr_update_txqueuelen(&groups[i]);
|
||||
if (res)
|
||||
goto error_set_iface;
|
||||
|
||||
fst_mgr_printf(MSG_DEBUG, "Setting bonding iface %s %s",
|
||||
buf, enslave ? "up":"down");
|
||||
if (_set_iface_up(sock, buf, enslave) < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot set iface %s",
|
||||
buf);
|
||||
goto error_set_iface;
|
||||
}
|
||||
}
|
||||
free(ifaces);
|
||||
}
|
||||
free(groups);
|
||||
return 0;
|
||||
error_set_iface:
|
||||
error_enslave:
|
||||
free(ifaces);
|
||||
error_ifaces:
|
||||
error_muxname:
|
||||
free(groups);
|
||||
error_groups:
|
||||
error_handle:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int bonding_ifaces_prepare()
|
||||
{
|
||||
return do_bonding_operations(TRUE);
|
||||
}
|
||||
|
||||
static int bonding_ifaces_cleanup()
|
||||
{
|
||||
return do_bonding_operations(FALSE);
|
||||
}
|
||||
|
||||
static int group_sessions_cleanup(const struct fst_group_info *gi)
|
||||
{
|
||||
uint32_t *sids = NULL;
|
||||
int n, i, res = 0;
|
||||
|
||||
n = fst_get_sessions(gi, &sids);
|
||||
if (n < 0) {
|
||||
fst_mgr_printf(MSG_WARNING, "cannot get sessions for group %s",
|
||||
gi->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if (fst_session_remove(sids[i])) {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot remove session %u",
|
||||
sids[i]);
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
fst_free(sids);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
static int group_detach_all(const struct fst_group_info *group)
|
||||
{
|
||||
struct fst_iface_info *ifaces;
|
||||
int i, res;
|
||||
|
||||
res = fst_get_group_ifaces(group, &ifaces);
|
||||
if (res < 0) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"Cannot get ifaces for group %s", group->id);
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < res; i++) {
|
||||
if (fst_detach_iface(&ifaces[i]))
|
||||
fst_mgr_printf(MSG_WARNING,
|
||||
"Error detaching interface %s", ifaces[i].name);
|
||||
}
|
||||
fst_free(ifaces);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_init(enum fst_config_method m, void *ctx)
|
||||
{
|
||||
if ((fstcfg.skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot open socket: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fstcfg.method = m;
|
||||
switch (m) {
|
||||
case FST_CONFIG_CLI:
|
||||
fstcfg.handle = NULL;
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
fstcfg.handle = fst_ini_config_init((const char*)ctx);
|
||||
if (fstcfg.handle == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot initialize config");
|
||||
return -1;
|
||||
}
|
||||
if(bonding_ifaces_prepare()) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot prepare bonding ifaces");
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Invalid config method %d", m);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fst_cfgmgr_deinit()
|
||||
{
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
bonding_ifaces_cleanup();
|
||||
fst_ini_config_deinit(fstcfg.handle);
|
||||
fstcfg.handle = NULL;
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
break;
|
||||
}
|
||||
|
||||
close(fstcfg.skfd);
|
||||
}
|
||||
|
||||
|
||||
int fst_cfgmgr_get_groups(struct fst_group_info **groups)
|
||||
{
|
||||
int res;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
res = fst_get_groups(groups);
|
||||
if (res < 0)
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot get groups");
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_get_groups(fstcfg.handle, groups);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot get groups in current config");
|
||||
res = -1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_get_ctrl_iface(char *buf, int size)
|
||||
{
|
||||
int res = -1;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_get_ctrl_iface(fstcfg.handle, buf, size);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"Cannot get ctrl_path in current config");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_get_group_ifaces(const struct fst_group_info *group,
|
||||
struct fst_iface_info **ifaces)
|
||||
{
|
||||
int res;
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "group: %s", group->id);
|
||||
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
res = fst_get_group_ifaces(group, ifaces);
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_get_group_ifaces(fstcfg.handle,
|
||||
group, ifaces);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot get ifaces in current config");
|
||||
res = -1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_get_iface_group_cipher(const struct fst_iface_info *iface,
|
||||
char *buf, int len)
|
||||
{
|
||||
int res = 0;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
res = 0;
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_get_iface_group_cipher(fstcfg.handle, iface,
|
||||
buf, len);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_get_iface_pairwise_cipher(const struct fst_iface_info *iface,
|
||||
char *buf, int len)
|
||||
{
|
||||
int res = 0;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
res = 0;
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_get_iface_pairwise_cipher(fstcfg.handle, iface,
|
||||
buf, len);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_get_iface_hw_mode(const struct fst_iface_info *iface,
|
||||
char *buf, int len)
|
||||
{
|
||||
int res = 0;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
res = 0;
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_get_iface_hw_mode(fstcfg.handle, iface,
|
||||
buf, len);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_get_iface_channel(const struct fst_iface_info *iface,
|
||||
char *buf, int len)
|
||||
{
|
||||
int res = 0;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
res = 0;
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_get_iface_channel(fstcfg.handle, iface,
|
||||
buf, len);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int fst_cfgmgr_on_iface_init(const struct fst_group_info *group,
|
||||
struct fst_iface_info *iface)
|
||||
{
|
||||
int res = 0;
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "group: %s", group->id);
|
||||
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_attach_iface(group, iface);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_on_iface_deinit(struct fst_iface_info *iface)
|
||||
{
|
||||
int res = 0;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_detach_iface(iface);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_on_global_init(void)
|
||||
{
|
||||
struct fst_group_info *groups;
|
||||
int i, res = 0;
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "enter");
|
||||
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
/* Remove existing configuration */
|
||||
res = fst_get_groups(&groups);
|
||||
if (res < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot get groups");
|
||||
return -1;
|
||||
}
|
||||
for (i=0; i < res; i++) {
|
||||
group_sessions_cleanup(&groups[i]);
|
||||
group_detach_all(&groups[i]);
|
||||
}
|
||||
if (res)
|
||||
fst_free(groups);
|
||||
res = fst_rate_upgrade_init(fstcfg.handle);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void fst_cfgmgr_on_global_deinit(void)
|
||||
{
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
fst_rate_upgrade_deinit();
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int fst_cfgmgr_on_group_init(const struct fst_group_info *group)
|
||||
{
|
||||
if (group_sessions_cleanup(group))
|
||||
return -1;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
if (fst_rate_upgrade_add_group(group))
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_on_group_deinit(const struct fst_group_info *group)
|
||||
{
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
if (fst_rate_upgrade_del_group(group))
|
||||
return -1;
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int fst_cfgmgr_on_connect(struct fst_group_info *group, const char *iface,
|
||||
const u8* addr)
|
||||
{
|
||||
int res = 0;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_rate_upgrade_on_connect(group, iface, addr);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_on_disconnect(struct fst_group_info *group, const char *iface,
|
||||
const u8* addr)
|
||||
{
|
||||
int res = 0;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_rate_upgrade_on_disconnect(group, iface, addr);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void fst_cfgmgr_on_switch_completed(const struct fst_group_info *group,
|
||||
const char *old_iface, const char *new_iface, const u8* peer_addr)
|
||||
{
|
||||
if (fstcfg.method != FST_CONFIG_INI)
|
||||
return;
|
||||
|
||||
fst_rate_upgrade_on_switch_completed(group, old_iface,
|
||||
new_iface, peer_addr);
|
||||
}
|
||||
|
||||
int fst_cfgmgr_get_mux_type(const char *gname, char *buf, int blen)
|
||||
{
|
||||
int res = 0;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
res = 0;
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_get_mux_type(fstcfg.handle, gname, buf, blen);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_get_mux_ifname(const char *gname, char *buf, int blen)
|
||||
{
|
||||
int res = 0;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
os_strlcpy(buf, gname, blen);
|
||||
res = os_strlen(buf);
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_get_mux_ifname(fstcfg.handle, gname,
|
||||
buf, blen);
|
||||
if (res == 0) {
|
||||
/* Fallback to mux==group_name if no mux name key */
|
||||
os_strlcpy(buf, gname, blen);
|
||||
res = os_strlen(buf);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_get_l2da_ap_default_ifname(const char *gname, char *buf,
|
||||
int blen)
|
||||
{
|
||||
int res = 0;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_get_l2da_ap_default_ifname(fstcfg.handle, gname,
|
||||
buf, blen);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
Boolean fst_cfgmgr_is_mux_managed(const char *gname)
|
||||
{
|
||||
Boolean res = FALSE;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
res = FALSE;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_is_mux_managed(fstcfg.handle, gname);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = FALSE;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_get_rate_upgrade_master(const char *gname, char *buf, int blen)
|
||||
{
|
||||
int res = 0;
|
||||
char *sres;
|
||||
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
sres = fst_ini_config_get_rate_upgrade_master(fstcfg.handle, gname);
|
||||
if (!sres)
|
||||
break;
|
||||
res = os_strlcpy(buf, sres, blen);
|
||||
free(sres);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_set_mux_ifname(const char *gname, const char *newname)
|
||||
{
|
||||
int res = 0;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
/* not supported */
|
||||
res = -1;
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_set_mux_ifname(fstcfg.handle, gname,
|
||||
newname);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_cfgmgr_rename_interface(const char *gname, const char *ifname, const char *newifname)
|
||||
{
|
||||
int res = 0;
|
||||
switch (fstcfg.method) {
|
||||
case FST_CONFIG_CLI:
|
||||
/* not supported */
|
||||
res = -1;
|
||||
break;
|
||||
case FST_CONFIG_INI:
|
||||
res = fst_ini_config_rename_interface(fstcfg.handle, gname, ifname, newifname);
|
||||
if (res)
|
||||
break;
|
||||
|
||||
fst_rate_upgrade_rename_interface(gname, ifname, newifname);
|
||||
break;
|
||||
default:
|
||||
fst_mgr_printf(MSG_ERROR, "Wrong config method");
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
void fst_cfgmgr_on_scan_started(const struct fst_group_info *group, const char *iface)
|
||||
{
|
||||
if (fstcfg.method != FST_CONFIG_INI)
|
||||
return;
|
||||
|
||||
fst_rate_upgrade_on_scan_started(group, iface);
|
||||
}
|
||||
|
||||
void fst_cfgmgr_on_scan_completed(const struct fst_group_info *group, const char *iface)
|
||||
{
|
||||
if (fstcfg.method != FST_CONFIG_INI)
|
||||
return;
|
||||
|
||||
fst_rate_upgrade_on_scan_completed(group, iface);
|
||||
}
|
||||
|
||||
void fst_cfgmgr_on_signal_change(const struct fst_group_info *group, const char *iface)
|
||||
{
|
||||
if (fstcfg.method != FST_CONFIG_INI)
|
||||
return;
|
||||
|
||||
fst_rate_upgrade_on_signal_change(group, iface);
|
||||
}
|
||||
105
qcom/opensource/fst-manager/fst_cfgmgr.h
Normal file
105
qcom/opensource/fst-manager/fst_cfgmgr.h
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* FST Manager: FST Configuration Manager
|
||||
*
|
||||
* Copyright (c) 2015-2016,2020 The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FST_FSTCFGMGR_H__
|
||||
#define __FST_FSTCFGMGR_H__
|
||||
#include "utils/common.h"
|
||||
#include "fst_ctrl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
enum fst_config_method {
|
||||
FST_CONFIG_CLI,
|
||||
FST_CONFIG_INI,
|
||||
FST_CONFIG_MAX
|
||||
};
|
||||
|
||||
|
||||
int fst_cfgmgr_init(enum fst_config_method m, void *ctx);
|
||||
void fst_cfgmgr_deinit();
|
||||
|
||||
int fst_cfgmgr_get_ctrl_iface(char *buf, int size);
|
||||
int fst_cfgmgr_get_group_ifaces(const struct fst_group_info *group,
|
||||
struct fst_iface_info **ifaces);
|
||||
int fst_cfgmgr_get_groups(struct fst_group_info **groups);
|
||||
int fst_cfgmgr_get_iface_group_cipher(const struct fst_iface_info *iface,
|
||||
char *buf, int len);
|
||||
int fst_cfgmgr_get_iface_pairwise_cipher(const struct fst_iface_info *iface,
|
||||
char *buf, int len);
|
||||
int fst_cfgmgr_get_iface_hw_mode(const struct fst_iface_info *iface,
|
||||
char *buf, int len);
|
||||
int fst_cfgmgr_get_iface_channel(const struct fst_iface_info *iface,
|
||||
char *buf, int len);
|
||||
|
||||
|
||||
int fst_cfgmgr_on_global_init(void);
|
||||
void fst_cfgmgr_on_global_deinit(void);
|
||||
int fst_cfgmgr_on_group_init(const struct fst_group_info *group);
|
||||
int fst_cfgmgr_on_group_deinit(const struct fst_group_info *group);
|
||||
int fst_cfgmgr_on_iface_init(const struct fst_group_info *group,
|
||||
struct fst_iface_info *iface);
|
||||
int fst_cfgmgr_on_iface_deinit(struct fst_iface_info *iface);
|
||||
int fst_cfgmgr_on_connect(struct fst_group_info *group, const char *iface,
|
||||
const u8* addr);
|
||||
int fst_cfgmgr_on_disconnect(struct fst_group_info *group, const char *iface,
|
||||
const u8* addr);
|
||||
void fst_cfgmgr_on_switch_completed(const struct fst_group_info *group,
|
||||
const char *old_iface, const char *new_iface, const u8* peer_addr);
|
||||
int fst_cfgmgr_get_mux_type(const char *gname, char *buf, int blen);
|
||||
int fst_cfgmgr_get_mux_ifname(const char *gname, char *buf, int blen);
|
||||
int fst_cfgmgr_get_l2da_ap_default_ifname(const char *gname, char *buf,
|
||||
int blen);
|
||||
Boolean fst_cfgmgr_is_mux_managed(const char *gname);
|
||||
int fst_cfgmgr_get_rate_upgrade_master(const char *gname, char *buf, int blen);
|
||||
|
||||
int fst_cfgmgr_set_mux_ifname(const char *gname, const char *newname);
|
||||
int fst_cfgmgr_rename_interface(const char *gname, const char *ifname, const char *newifname);
|
||||
|
||||
int set_iface_up(const char *ifname, Boolean up);
|
||||
int get_iface_flags(const char *ifname, short int *flags);
|
||||
int fst_iface_enslave(struct fst_group_info *ginfo, const char *ifname, Boolean enslave);
|
||||
int fst_set_mac_address(struct fst_group_info *ginfo, const u8 *mac);
|
||||
void fst_cfgmgr_on_scan_started(const struct fst_group_info *group, const char *iface);
|
||||
void fst_cfgmgr_on_scan_completed(const struct fst_group_info *group, const char *iface);
|
||||
void fst_cfgmgr_on_signal_change(const struct fst_group_info *group, const char *iface);
|
||||
int fst_cfgmgr_update_txqueuelen(const struct fst_group_info *group);
|
||||
int fst_cfgmgr_set_mux_iface_up(const struct fst_group_info *group, Boolean up);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* __FST_FSTCONF_H */
|
||||
|
||||
1301
qcom/opensource/fst-manager/fst_ctrl.c
Normal file
1301
qcom/opensource/fst-manager/fst_ctrl.c
Normal file
File diff suppressed because it is too large
Load Diff
281
qcom/opensource/fst-manager/fst_ctrl.h
Normal file
281
qcom/opensource/fst-manager/fst_ctrl.h
Normal file
@@ -0,0 +1,281 @@
|
||||
/*
|
||||
* FST Manager: hostapd/wpa_supplicant control interface wrapper definitions
|
||||
*
|
||||
* Copyright (c) 2015-2016, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FST_CTRL_H__
|
||||
#define __FST_CTRL_H__
|
||||
#include <errno.h>
|
||||
#include "fst/fst_ctrl_aux.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
/**
|
||||
* fst_notification_cb_func - FST notification callback function
|
||||
* @cb_ctx: %ntfy_cb_ctx as passed to fst_set_notify_cb()
|
||||
* @group_id: FST group ID
|
||||
* @session_id: FST session ID
|
||||
* @event_type: kind of FST event for the call
|
||||
* @extra: event-specific auxiliary information.
|
||||
* TODO: Define extra information for each event type
|
||||
*/
|
||||
typedef void (*fst_notification_cb_func)(void *cb_ctx,
|
||||
u32 session_id,
|
||||
enum fst_event_type event_type,
|
||||
void *extra);
|
||||
|
||||
/**
|
||||
* fst_set_notify_cb - set FST control callback
|
||||
* @ntfy_cb: FST notification callback function, %NULL to disable
|
||||
* @ntfy_cb_ctx: FST notification callback function's context to be passed to %ntfy_cb
|
||||
* Returns: 0 if success or negative error code
|
||||
*/
|
||||
int fst_set_notify_cb(fst_notification_cb_func ntfy_cb, void *ntfy_cb_ctx);
|
||||
|
||||
struct fst_group_info {
|
||||
char id[FST_MAX_GROUP_ID_SIZE];
|
||||
};
|
||||
|
||||
/**
|
||||
* fst_get_groups - get list of FST groups
|
||||
* @groups: Array of fst_group_info elements allocated by the function.
|
||||
* The array should be freed by caller.
|
||||
* Returns: Number of allocated elements if success or negative error code
|
||||
*/
|
||||
int fst_get_groups(struct fst_group_info **groups);
|
||||
|
||||
struct fst_iface_info{
|
||||
char name[FST_MAX_INTERFACE_SIZE];
|
||||
u8 addr[ETH_ALEN];
|
||||
u8 priority;
|
||||
u32 llt;
|
||||
u8 manual_enslave;
|
||||
};
|
||||
|
||||
/**
|
||||
* fst_get_iface_peers - get list of connected peers for this interface
|
||||
* @group: FST group info from fst_get_groups()
|
||||
* @iface: FST interface info fst_get_group_ifaces()
|
||||
* @peers: The list of peers MAC addresses allocated by the function.
|
||||
* The array should be freed by caller.
|
||||
* Returns: Number of allocated elements if success or negative error code
|
||||
*/
|
||||
int fst_get_iface_peers(const struct fst_group_info *group,
|
||||
struct fst_iface_info *iface, uint8_t **peers);
|
||||
|
||||
/**
|
||||
* fst_get_peer_mbies - get the hexadecimal dump of the peer's MBIEs on a given
|
||||
* interface
|
||||
* @ifname: FST interface name
|
||||
* @peer: The peer's MAC address
|
||||
* @mbies: The hexadecimal dump of the peer's MBIEs on the given interface
|
||||
* if not NULL. The array should be freed by caller.
|
||||
* Returns: Number of allocated bytes if success or negative error code
|
||||
*/
|
||||
int fst_get_peer_mbies(const char *ifname, const uint8_t *peer, char **mbies);
|
||||
|
||||
/**
|
||||
* fst_get_group_ifaces - get interfaces for the provided group
|
||||
* @group_id: FST group ID from fst_get_groups()
|
||||
* @ifaces: Array of fst_iface_info elements allocated by the function.
|
||||
* The array should be freed by caller.
|
||||
* Returns: Number of allocated elements if success or negative error code
|
||||
*/
|
||||
int fst_get_group_ifaces(const struct fst_group_info *group,
|
||||
struct fst_iface_info **ifaces);
|
||||
|
||||
/**
|
||||
* fst_detach_iface - Detaches FST interface
|
||||
* @iface: FST interface info for the interface to be detached
|
||||
*
|
||||
* Retunrs: 0 if success or a negative error code
|
||||
*/
|
||||
int fst_detach_iface(const struct fst_iface_info *iface);
|
||||
|
||||
/**
|
||||
* fst_attach_iface - Attaches FST interface
|
||||
* @group: FST group info for the group the interface to be attached to
|
||||
* @iface: FST interface info for the interface to be attached
|
||||
*
|
||||
* Retunrs: 0 if success or a negative error code
|
||||
*/
|
||||
int fst_attach_iface(const struct fst_group_info *group,
|
||||
const struct fst_iface_info *iface);
|
||||
|
||||
/**
|
||||
* fst_is_supplicant - Returns true if the hostap application is
|
||||
* the wpa_supplicant, FALSE - if the hostapd
|
||||
*/
|
||||
Boolean fst_is_supplicant(void);
|
||||
|
||||
/**
|
||||
* fst_add_iface - Add interfaces to Hostap
|
||||
* @master: Master interface name
|
||||
* @iface: Interface name
|
||||
* @acl_file: ACL file name for accept_mac_file (see hostapd.conf), can be NULL
|
||||
* @ctrl_interface: Control interface path, can be NULL
|
||||
*/
|
||||
int fst_add_iface(const char *master, const struct fst_iface_info *iface,
|
||||
const char *acl_file, const char *ctrl_interface);
|
||||
|
||||
/**
|
||||
* fst_del_iface - Delete interface from Hostap
|
||||
* @iface: Interface name
|
||||
*/
|
||||
int fst_del_iface(const struct fst_iface_info *iface);
|
||||
|
||||
/**
|
||||
* fst_dup_connection - Copy the connection params from master interface and
|
||||
* initiate a hostap connection for the interface iface
|
||||
* @iface: Interface info for the interface to connect
|
||||
* @master: Master interface name the connection parameters to be copied from
|
||||
* @addr: Address (BSSID) to connect to
|
||||
* @freq: Frequency to scan for the AP
|
||||
* @acl_file: ACL file name for accept_mac_file (see hostapd.conf), can be NULL
|
||||
*/
|
||||
int fst_dup_connection(const struct fst_iface_info *iface,
|
||||
const char *master, const u8 *addr, u32 freq, const char *acl_file);
|
||||
|
||||
/**
|
||||
* fst_dedup_connection - disallow connection on interface iface
|
||||
* @iface: Interface
|
||||
* @acl_file: ACL file name accept_mac_file (see hostapd.conf), can be NULL
|
||||
*/
|
||||
int fst_dedup_connection(const struct fst_iface_info *iface, const char *acl_file);
|
||||
|
||||
/**
|
||||
* fst_disconnect_peer - Disconnects from peer over specific interface
|
||||
* @ifname: Interface to disconnect
|
||||
* @peer_addr: peer to disconnect from
|
||||
*/
|
||||
int fst_disconnect_peer(const char *ifname, const u8 *peer_addr);
|
||||
|
||||
/**
|
||||
* fst_get_sessions - Iterate FST session within a group
|
||||
* @group_id: FST group ID from fst_get_groups()
|
||||
* @sessions: Array of fst_sessions allocated by the function.
|
||||
* The array should be freed by caller.
|
||||
* Returns: Number of allocated elements if success or negative error code
|
||||
*/
|
||||
int fst_get_sessions(const struct fst_group_info *group, u32 **sessions);
|
||||
|
||||
struct fst_session_info
|
||||
{
|
||||
u8 old_peer_addr[ETH_ALEN];
|
||||
u8 new_peer_addr[ETH_ALEN];
|
||||
char old_ifname[FST_MAX_INTERFACE_SIZE];
|
||||
char new_ifname[FST_MAX_INTERFACE_SIZE];
|
||||
u32 llt;
|
||||
enum fst_session_state state;
|
||||
u32 session_id;
|
||||
};
|
||||
|
||||
/**
|
||||
* fst_free - free an array allocated by fst_get_groups, fst_get_group_ifaces or
|
||||
* fst_get_sessions
|
||||
* @p: an array allocated by fst_get_groups, fst_get_group_ifaces,
|
||||
* fst_get_iface_peers or fst_get_sessions
|
||||
*/
|
||||
void fst_free(void *p);
|
||||
|
||||
/**
|
||||
* fst_session_get_info - Get FST session within a group
|
||||
* @session_id: FST Session id as received from fst_get_sessions.
|
||||
* @info: structure to fill if call succeeds
|
||||
* Returns: 0 on success, negative error codes on errors
|
||||
*/
|
||||
int fst_session_get_info(u32 session_id, struct fst_session_info *info);
|
||||
|
||||
/**
|
||||
* fst_session_add - Create FST session context
|
||||
* @session_id: FST Session id as received from fst_get_sessions.
|
||||
* Returns: 0 on success, negative error codes on errors
|
||||
*/
|
||||
int fst_session_add(const char * group_id, u32 * session_id);
|
||||
|
||||
/**
|
||||
* fst_session_remove - Remove FST session
|
||||
* @session_id: FST Session id as received from fst_get_sessions.
|
||||
* Returns: 0 on success, supported error codes on failure.
|
||||
*/
|
||||
int fst_session_remove(u32 session_id);
|
||||
|
||||
/**
|
||||
* fst_session_set - Set FST session parameter
|
||||
* @session_id: FST Session id as received from fst_get_sessions.
|
||||
* @pname: parameter name to set
|
||||
* @pval: parameter value to set
|
||||
* Returns: 0 on success, negative error codes on failures
|
||||
*/
|
||||
int fst_session_set(u32 session_id, const char *pname, const char * pval);
|
||||
|
||||
|
||||
/**
|
||||
* fst_session_initiate - Initiate FST session
|
||||
* @session_id: FST Session id as received from fst_get_sessions.
|
||||
* Returns: 0 on success, negative error code on failure
|
||||
*/
|
||||
int fst_session_initiate(u32 session_id);
|
||||
|
||||
/**
|
||||
* fst_session_respond - Respond to FST session request
|
||||
* @session_id: FST Session id as received from fst_get_sessions.
|
||||
* @response_status: response status string
|
||||
* Returns: 0 on success, supported error codes on failure.
|
||||
*/
|
||||
|
||||
int fst_session_respond(u32 session_id, const char *response_status);
|
||||
|
||||
/**
|
||||
* fst_session_transfer - Transfer established FST session
|
||||
* @session_id: FST Session id as received from fst_get_sessions.
|
||||
* Returns: 0 on success, supported error codes on failure.
|
||||
*/
|
||||
int fst_session_transfer(u32 session_id);
|
||||
|
||||
/**
|
||||
* fst_session_teardown - Tear down established FST session
|
||||
* @session_id: FST Session id as received from fst_get_sessions.
|
||||
* Returns: 0 on success, supported error codes on failure.
|
||||
*/
|
||||
int fst_session_teardown(u32 session_id);
|
||||
|
||||
int fst_signal_monitor(const char *iface, int thresh, int hyst);
|
||||
void fst_ctrl_bss_flush(const char *iface);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* __FST_CTRL_H__ */
|
||||
|
||||
1160
qcom/opensource/fst-manager/fst_ctrl_dbus.c
Normal file
1160
qcom/opensource/fst-manager/fst_ctrl_dbus.c
Normal file
File diff suppressed because it is too large
Load Diff
967
qcom/opensource/fst-manager/fst_ini_conf.c
Normal file
967
qcom/opensource/fst-manager/fst_ini_conf.c
Normal file
@@ -0,0 +1,967 @@
|
||||
/*
|
||||
* FST Manager: INI configuration file parser
|
||||
*
|
||||
* Copyright (c) 2015, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "utils/list.h"
|
||||
#include "fst_ini_conf.h"
|
||||
#include "ini.h"
|
||||
|
||||
#define FST_MGR_COMPONENT "INI_CONF"
|
||||
#include "fst_manager.h"
|
||||
|
||||
struct fst_ini_config
|
||||
{
|
||||
char *filename;
|
||||
struct cfg_cache *cache;
|
||||
};
|
||||
|
||||
struct cfg_ctx {
|
||||
const char *section;
|
||||
const char *name;
|
||||
char *buffer;
|
||||
int buflen;
|
||||
Boolean is_found;
|
||||
};
|
||||
|
||||
/*
|
||||
* FST Manager standalone configuration
|
||||
*/
|
||||
|
||||
/* matches the ini file limit */
|
||||
#define MAX_CFG_STRING 80
|
||||
|
||||
struct cfg_cache {
|
||||
char ctrl_iface[MAX_CFG_STRING];
|
||||
char slave_ctrl_interface[MAX_CFG_STRING];
|
||||
struct dl_list groups;
|
||||
};
|
||||
|
||||
struct cfg_group_info {
|
||||
char name[FST_MAX_GROUP_ID_SIZE];
|
||||
char rate_upgrade_master[MAX_CFG_STRING];
|
||||
char rate_upgrade_acl_fname[MAX_CFG_STRING];
|
||||
char mux_type[MAX_CFG_STRING];
|
||||
char mux_ifname[MAX_CFG_STRING];
|
||||
char l2da_ap_default_ifname[MAX_CFG_STRING];
|
||||
Boolean is_mux_managed;
|
||||
int txqueuelen;
|
||||
struct dl_list ifaces;
|
||||
struct dl_list list;
|
||||
};
|
||||
|
||||
struct cfg_iface_info {
|
||||
struct fst_iface_info info;
|
||||
char group_cipher[MAX_CFG_STRING];
|
||||
char pairwise_cipher[MAX_CFG_STRING];
|
||||
char hw_mode[MAX_CFG_STRING];
|
||||
char channel[MAX_CFG_STRING];
|
||||
struct dl_list list;
|
||||
};
|
||||
|
||||
int fst_ini_config_get_ctrl_iface(struct fst_ini_config *h, char *buf, int size)
|
||||
{
|
||||
if (!h->cache || !h->cache->ctrl_iface[0]) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"No ctrl_iface found in fst_manager config");
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_strlcpy(buf, h->cache->ctrl_iface, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct cfg_group_info *fst_ini_find_cfg_group(struct fst_ini_config *h,
|
||||
const char *id)
|
||||
{
|
||||
struct cfg_group_info *item;
|
||||
|
||||
if (!h->cache)
|
||||
return NULL;
|
||||
|
||||
dl_list_for_each(item, &h->cache->groups,
|
||||
struct cfg_group_info, list) {
|
||||
if (!strncmp(item->name, id, FST_MAX_GROUP_ID_SIZE))
|
||||
return item;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fst_ini_config_get_group_ifaces(struct fst_ini_config *h,
|
||||
const struct fst_group_info *group, struct fst_iface_info **ifaces)
|
||||
{
|
||||
struct cfg_group_info *cginfo = NULL;
|
||||
struct cfg_iface_info *item;
|
||||
int i, cnt;
|
||||
|
||||
if (!h->cache) {
|
||||
fst_mgr_printf(MSG_ERROR, "no config cache");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cginfo = fst_ini_find_cfg_group(h, group->id);
|
||||
if (!cginfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "group not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cnt = dl_list_len(&cginfo->ifaces);
|
||||
if (!cnt) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"No interfaces found for group %s", group->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ifaces = (struct fst_iface_info*)os_zalloc(
|
||||
sizeof(struct fst_iface_info) * cnt);
|
||||
if (*ifaces == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"Cannot allocate memory for interface");
|
||||
return -1;
|
||||
}
|
||||
item = dl_list_first(&cginfo->ifaces, struct cfg_iface_info, list);
|
||||
for (i = 0; i < cnt; i++) {
|
||||
(*ifaces)[i] = item->info;
|
||||
item = dl_list_entry(item->list.next, struct cfg_iface_info,
|
||||
list);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
int fst_ini_config_get_groups(struct fst_ini_config *h,
|
||||
struct fst_group_info **groups)
|
||||
{
|
||||
int i, cnt;
|
||||
struct cfg_group_info *item;
|
||||
|
||||
*groups = NULL;
|
||||
if (!h->cache) {
|
||||
fst_mgr_printf(MSG_ERROR, "no config cache");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cnt = dl_list_len(&h->cache->groups);
|
||||
if (cnt == 0) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"No groups defined in config");
|
||||
return -1;
|
||||
}
|
||||
*groups = (struct fst_group_info*)malloc(
|
||||
sizeof(struct fst_group_info) * cnt);
|
||||
if (*groups == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR,"Cannot allocate memory for groups");
|
||||
return -1;
|
||||
}
|
||||
|
||||
item = dl_list_first(&h->cache->groups, struct cfg_group_info, list);
|
||||
for (i = 0; i < cnt; i++) {
|
||||
os_strlcpy((*groups)[i].id, item->name,
|
||||
sizeof((*groups)[i].id));
|
||||
item = dl_list_entry(item->list.next, struct cfg_group_info,
|
||||
list);
|
||||
}
|
||||
|
||||
return cnt;
|
||||
}
|
||||
|
||||
char *fst_ini_config_get_rate_upgrade_master(struct fst_ini_config *h,
|
||||
const char *groupname)
|
||||
{
|
||||
struct cfg_group_info *cginfo;
|
||||
|
||||
cginfo = fst_ini_find_cfg_group(h, groupname);
|
||||
if (!cginfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "group not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!cginfo->rate_upgrade_master[0])
|
||||
return NULL;
|
||||
|
||||
return strdup(cginfo->rate_upgrade_master);
|
||||
}
|
||||
|
||||
char *fst_ini_config_get_rate_upgrade_acl_fname(struct fst_ini_config *h,
|
||||
const char *groupname)
|
||||
{
|
||||
struct cfg_group_info *cginfo;
|
||||
|
||||
cginfo = fst_ini_find_cfg_group(h, groupname);
|
||||
if (!cginfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "group not found");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!cginfo->rate_upgrade_acl_fname[0])
|
||||
return NULL;
|
||||
|
||||
return strdup(cginfo->rate_upgrade_acl_fname);
|
||||
}
|
||||
|
||||
int fst_ini_config_get_mux_type(struct fst_ini_config *h,
|
||||
const char *gname, char *buf, int buflen)
|
||||
{
|
||||
struct cfg_group_info *cginfo;
|
||||
|
||||
cginfo = fst_ini_find_cfg_group(h, gname);
|
||||
if (!cginfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "group not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
os_strlcpy(buf, cginfo->mux_type, buflen);
|
||||
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
|
||||
int fst_ini_config_get_mux_ifname(struct fst_ini_config *h,
|
||||
const char *gname, char *buf, int buflen)
|
||||
{
|
||||
struct cfg_group_info *cginfo;
|
||||
|
||||
cginfo = fst_ini_find_cfg_group(h, gname);
|
||||
if (!cginfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "group not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
os_strlcpy(buf, cginfo->mux_ifname, buflen);
|
||||
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
int fst_ini_config_get_l2da_ap_default_ifname(struct fst_ini_config *h,
|
||||
const char *gname, char *buf, int buflen)
|
||||
{
|
||||
struct cfg_group_info *cginfo;
|
||||
|
||||
cginfo = fst_ini_find_cfg_group(h, gname);
|
||||
if (!cginfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "group not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
os_strlcpy(buf, cginfo->l2da_ap_default_ifname, buflen);
|
||||
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
Boolean fst_ini_config_is_mux_managed(struct fst_ini_config *h, const char *gname)
|
||||
{
|
||||
struct cfg_group_info *cginfo;
|
||||
|
||||
cginfo = fst_ini_find_cfg_group(h, gname);
|
||||
if (!cginfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "group not found");
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return cginfo->is_mux_managed;
|
||||
}
|
||||
|
||||
static struct cfg_iface_info *fst_ini_find_cfg_iface(struct fst_ini_config *h,
|
||||
const char *ifname)
|
||||
{
|
||||
struct cfg_group_info *cginfo;
|
||||
struct cfg_iface_info *ifinfo;
|
||||
|
||||
if (!h->cache)
|
||||
return NULL;
|
||||
|
||||
dl_list_for_each(cginfo, &h->cache->groups,
|
||||
struct cfg_group_info, list) {
|
||||
dl_list_for_each(ifinfo, &cginfo->ifaces,
|
||||
struct cfg_iface_info, list) {
|
||||
if (!strncmp(ifname, ifinfo->info.name,
|
||||
FST_MAX_INTERFACE_SIZE))
|
||||
return ifinfo;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fst_ini_config_get_iface_group_cipher(struct fst_ini_config *h,
|
||||
const struct fst_iface_info *iface, char *buf, int len)
|
||||
{
|
||||
struct cfg_iface_info *ifinfo;
|
||||
|
||||
ifinfo = fst_ini_find_cfg_iface(h, iface->name);
|
||||
if (!ifinfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "interface not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
os_strlcpy(buf, ifinfo->group_cipher, len);
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
int fst_ini_config_get_iface_pairwise_cipher(struct fst_ini_config *h,
|
||||
const struct fst_iface_info *iface, char *buf, int len)
|
||||
{
|
||||
struct cfg_iface_info *ifinfo;
|
||||
|
||||
ifinfo = fst_ini_find_cfg_iface(h, iface->name);
|
||||
if (!ifinfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "interface not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
os_strlcpy(buf, ifinfo->pairwise_cipher, len);
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
int fst_ini_config_get_iface_hw_mode(struct fst_ini_config *h,
|
||||
const struct fst_iface_info *iface, char *buf, int len)
|
||||
{
|
||||
struct cfg_iface_info *ifinfo;
|
||||
|
||||
ifinfo = fst_ini_find_cfg_iface(h, iface->name);
|
||||
if (!ifinfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "interface not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
os_strlcpy(buf, ifinfo->hw_mode, len);
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
int fst_ini_config_get_iface_channel(struct fst_ini_config *h,
|
||||
const struct fst_iface_info *iface, char *buf, int len)
|
||||
{
|
||||
struct cfg_iface_info *ifinfo;
|
||||
|
||||
ifinfo = fst_ini_find_cfg_iface(h, iface->name);
|
||||
if (!ifinfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "interface not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
os_strlcpy(buf, ifinfo->channel, len);
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
int fst_ini_config_get_txqueuelen(struct fst_ini_config *h, const char *gname)
|
||||
{
|
||||
struct cfg_group_info *cginfo;
|
||||
|
||||
cginfo = fst_ini_find_cfg_group(h, gname);
|
||||
if (!cginfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "group not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return cginfo->txqueuelen;
|
||||
}
|
||||
|
||||
int fst_ini_config_get_slave_ctrl_interface(struct fst_ini_config *h, char *buf, int len)
|
||||
{
|
||||
if (!h->cache || !h->cache->ctrl_iface[0]) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"No slave_ctrl_iface found in fst_manager config");
|
||||
return 0;
|
||||
}
|
||||
|
||||
os_strlcpy(buf, h->cache->slave_ctrl_interface, len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fst_ini_config_set_mux_ifname(struct fst_ini_config *h,
|
||||
const char *gname, const char *newname)
|
||||
{
|
||||
struct cfg_group_info *cginfo;
|
||||
|
||||
cginfo = fst_ini_find_cfg_group(h, gname);
|
||||
if (!cginfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "group not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_strlcpy(cginfo->mux_ifname, newname, sizeof(cginfo->mux_ifname));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fst_ini_config_rename_interface(struct fst_ini_config *h,
|
||||
const char *gname, const char *ifname, const char *newname)
|
||||
{
|
||||
struct cfg_iface_info *ifinfo;
|
||||
struct cfg_group_info *cginfo;
|
||||
|
||||
cginfo = fst_ini_find_cfg_group(h, gname);
|
||||
if (!cginfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "group not found");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ifinfo = fst_ini_find_cfg_iface(h, newname);
|
||||
if (ifinfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "new interface %s already exists",
|
||||
newname);
|
||||
return -1;
|
||||
}
|
||||
ifinfo = fst_ini_find_cfg_iface(h, ifname);
|
||||
if (!ifinfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "interface %s not found", ifname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_strlcpy(ifinfo->info.name, newname, sizeof(ifinfo->info.name));
|
||||
if (!os_strcmp(cginfo->rate_upgrade_master, ifname)) {
|
||||
os_strlcpy(cginfo->rate_upgrade_master, newname, sizeof(cginfo->rate_upgrade_master));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reading the INI file
|
||||
*/
|
||||
|
||||
static int ini_handler(void* user, const char* section, const char* name,
|
||||
const char* value)
|
||||
{
|
||||
struct cfg_ctx *ctx = (struct cfg_ctx*)user;
|
||||
if (!ctx->is_found) {
|
||||
if (strncmp(section, ctx->section, strlen(section)) == 0 &&
|
||||
strncmp(name, ctx->name, strlen(name)) == 0) {
|
||||
ctx->is_found = TRUE;
|
||||
if (ctx->buffer && ctx->buflen) {
|
||||
os_strlcpy(ctx->buffer, value, ctx->buflen);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int parse_csv(char *string, char **tokens, int tokenslen)
|
||||
{
|
||||
const char *delim = " ,\t";
|
||||
char *tokbuf;
|
||||
int count = 0;
|
||||
char *token = strtok_r(string, delim, &tokbuf);
|
||||
while (token != NULL && count < tokenslen) {
|
||||
count++;
|
||||
*tokens++ = token;
|
||||
token = strtok_r(NULL, delim, &tokbuf);
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static Boolean fst_ini_config_read(struct fst_ini_config *h, const char *s,
|
||||
const char *k, char *buf, int buflen)
|
||||
{
|
||||
struct cfg_ctx ctx;
|
||||
ctx.section = s;
|
||||
ctx.name = k;
|
||||
ctx.buffer = buf;
|
||||
ctx.buflen = buflen;
|
||||
ctx.is_found = FALSE;
|
||||
|
||||
if (ini_parse(h->filename, ini_handler, &ctx) < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Error parsing configuration file %s",
|
||||
h->filename);
|
||||
}
|
||||
return ctx.is_found;
|
||||
}
|
||||
|
||||
static int fst_ini_cache_config(struct fst_ini_config *h);
|
||||
static void fst_ini_free_config_cache(struct cfg_cache *cache);
|
||||
|
||||
struct fst_ini_config *fst_ini_config_init(const char *filename)
|
||||
{
|
||||
struct fst_ini_config *h = (struct fst_ini_config*)os_zalloc(
|
||||
sizeof(struct fst_ini_config));
|
||||
if (h == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot allocate memory for config");
|
||||
return NULL;
|
||||
}
|
||||
h->filename = strdup(filename);
|
||||
if (h->filename == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot allocate memory for filename");
|
||||
goto out_err;
|
||||
}
|
||||
if (fst_ini_cache_config(h) < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot cache ini configuration");
|
||||
goto out_err;
|
||||
}
|
||||
|
||||
return h;
|
||||
|
||||
out_err:
|
||||
fst_ini_config_deinit(h);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void fst_ini_config_deinit(struct fst_ini_config *h)
|
||||
{
|
||||
if (!h)
|
||||
return;
|
||||
|
||||
fst_ini_free_config_cache(h->cache);
|
||||
free(h->filename);
|
||||
free(h);
|
||||
}
|
||||
|
||||
/*
|
||||
* FST Manager standalone configuration - used for caching only
|
||||
*/
|
||||
#define INI_MAX_STRING 80
|
||||
#define INI_MAX_TOKENS 16
|
||||
|
||||
static int __fst_ini_config_get_ctrl_iface(struct fst_ini_config *h,
|
||||
char *buf, int size)
|
||||
{
|
||||
if (!fst_ini_config_read(h, "fst_manager", "ctrl_iface",
|
||||
buf, size)) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"No ctrl_iface found in fst_manager config");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __fst_ini_config_get_group_ifaces(struct fst_ini_config *h,
|
||||
const struct fst_group_info *group, struct fst_iface_info **ifaces)
|
||||
{
|
||||
char buf[INI_MAX_STRING+1], buf_ifaces[INI_MAX_STRING+1];
|
||||
char *tokens[INI_MAX_TOKENS];
|
||||
int i, cnt;
|
||||
|
||||
if (!fst_ini_config_read(h, (const char*)group->id, "interfaces",
|
||||
buf_ifaces, INI_MAX_STRING)) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"No interfaces key for group %s", group->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cnt = parse_csv(buf_ifaces, tokens, INI_MAX_TOKENS);
|
||||
if (cnt == 0) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"No interfaces found for group %s", group->id);
|
||||
return -1;
|
||||
}
|
||||
fst_mgr_printf(MSG_INFO,"%d interfaces found", cnt);
|
||||
|
||||
*ifaces = (struct fst_iface_info*)os_zalloc(
|
||||
sizeof(struct fst_iface_info) * cnt);
|
||||
if (*ifaces == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"Cannot allocate memory for interface");
|
||||
return -1;
|
||||
}
|
||||
for (i = 0; i < cnt; i++) {
|
||||
os_strlcpy((*ifaces)[i].name, tokens[i], sizeof((*ifaces)[i].name));
|
||||
if (fst_ini_config_read(h, (const char*)tokens[i], "priority",
|
||||
buf, INI_MAX_STRING))
|
||||
(*ifaces)[i].priority = strtoul(buf, NULL, 0);
|
||||
if (fst_ini_config_read(h, (const char*)tokens[i], "default_llt",
|
||||
buf, INI_MAX_STRING))
|
||||
(*ifaces)[i].llt = strtoul(buf, NULL, 0);
|
||||
if (fst_ini_config_read(h, (const char*)tokens[i], "manual_enslave",
|
||||
buf, INI_MAX_STRING))
|
||||
(*ifaces)[i].manual_enslave = strtoul(buf, NULL, 0);
|
||||
fst_mgr_printf(MSG_DEBUG,
|
||||
"iface %s (pri=%d, llt=%d manual_enslave=%d) has been parsed",
|
||||
(*ifaces)[i].name, (*ifaces)[i].priority, (*ifaces)[i].llt, (*ifaces)[i].manual_enslave);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static int __fst_ini_config_get_groups(struct fst_ini_config *h,
|
||||
struct fst_group_info **groups)
|
||||
{
|
||||
char buf[INI_MAX_STRING+1];
|
||||
char *tokens[INI_MAX_TOKENS];
|
||||
int i, cnt;
|
||||
|
||||
*groups = NULL;
|
||||
if (!fst_ini_config_read(h, "fst_manager", "groups",
|
||||
buf, INI_MAX_STRING)) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"No groups key found in fst_manager config");
|
||||
return -1;
|
||||
}
|
||||
|
||||
cnt = parse_csv(buf, tokens, INI_MAX_TOKENS);
|
||||
if (cnt == 0) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"No groups defined in config");
|
||||
return -1;
|
||||
}
|
||||
*groups = (struct fst_group_info*)malloc(
|
||||
sizeof(struct fst_group_info) * cnt);
|
||||
if (*groups == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR,"Cannot allocate memory for groups");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < cnt; i++) {
|
||||
os_strlcpy((*groups)[i].id, tokens[i], sizeof((*groups)[i].id));
|
||||
fst_mgr_printf(MSG_DEBUG,"Config: group %s has been parsed", tokens[i]);
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static char *__fst_ini_config_get_rate_upgrade_master(struct fst_ini_config *h,
|
||||
const char *groupname)
|
||||
{
|
||||
char buf[INI_MAX_STRING+1];
|
||||
if(!fst_ini_config_read(h, groupname, "rate_upgrade_master", buf,
|
||||
INI_MAX_STRING))
|
||||
return NULL;
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
static char *__fst_ini_config_get_rate_upgrade_acl_fname(struct fst_ini_config *h,
|
||||
const char *groupname)
|
||||
{
|
||||
char buf[INI_MAX_STRING+1];
|
||||
if(!fst_ini_config_read(h, groupname, "rate_upgrade_acl_file", buf,
|
||||
INI_MAX_STRING))
|
||||
return NULL;
|
||||
return strdup(buf);
|
||||
}
|
||||
|
||||
/* this is part of the public API, it does not access the INI directly */
|
||||
int fst_ini_config_get_group_slave_ifaces(struct fst_ini_config *h,
|
||||
const struct fst_group_info *group, const char *master,
|
||||
struct fst_iface_info **ifaces)
|
||||
{
|
||||
int i, cnt;
|
||||
|
||||
fst_mgr_printf(MSG_INFO,"group %s master %s", group->id, master);
|
||||
|
||||
cnt = fst_ini_config_get_group_ifaces(h, group, ifaces);
|
||||
if (cnt < 0)
|
||||
return cnt;
|
||||
|
||||
for (i=0; i < cnt; i++) {
|
||||
if (!strncmp((*ifaces)[i].name, master, strlen(master))) {
|
||||
/* Skip the master interface */
|
||||
cnt--;
|
||||
if (i < cnt)
|
||||
os_memmove(&(*ifaces)[i], &(*ifaces)[i+1],
|
||||
(cnt-i) * sizeof(struct fst_iface_info));
|
||||
return cnt;
|
||||
}
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
static int __fst_ini_config_get_mux_type(struct fst_ini_config *h,
|
||||
const char *gname, char *buf, int buflen)
|
||||
{
|
||||
if(!fst_ini_config_read(h, gname, "mux_type", buf, buflen))
|
||||
return 0;
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
|
||||
static int __fst_ini_config_get_mux_ifname(struct fst_ini_config *h,
|
||||
const char *gname, char *buf, int buflen)
|
||||
{
|
||||
if(!fst_ini_config_read(h, gname, "mux_ifname", buf, buflen))
|
||||
return 0;
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static int __fst_ini_config_get_l2da_ap_default_ifname(struct fst_ini_config *h,
|
||||
const char *gname, char *buf, int buflen)
|
||||
{
|
||||
if(!fst_ini_config_read(h, gname, "l2da_ap_default_ifname", buf, buflen))
|
||||
return 0;
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static Boolean __fst_ini_config_is_mux_managed(struct fst_ini_config *h, const char *gname)
|
||||
{
|
||||
char buf[INI_MAX_STRING+1];
|
||||
if(!fst_ini_config_read(h, gname, "mux_managed", buf,
|
||||
INI_MAX_STRING))
|
||||
return FALSE;
|
||||
if (buf[0] == '1' || buf[0] == 'y' || buf[0] == 'Y')
|
||||
return TRUE;
|
||||
else if (buf[0] == '0' || buf[0] == 'n' || buf[0] == 'N')
|
||||
return FALSE;
|
||||
else {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"mux_managed wrong boolean %s, assuming false", buf);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
static int __fst_ini_config_get_iface_group_cipher(struct fst_ini_config *h,
|
||||
const struct fst_iface_info *iface, char *buf, int len)
|
||||
{
|
||||
if(!fst_ini_config_read(h, iface->name, "wpa_group", buf, len))
|
||||
return 0;
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static int __fst_ini_config_get_iface_pairwise_cipher(struct fst_ini_config *h,
|
||||
const struct fst_iface_info *iface, char *buf, int len)
|
||||
{
|
||||
if(!fst_ini_config_read(h, iface->name, "wpa_pairwise", buf, len))
|
||||
return 0;
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static int __fst_ini_config_get_iface_hw_mode(struct fst_ini_config *h,
|
||||
const struct fst_iface_info *iface, char *buf, int len)
|
||||
{
|
||||
if(!fst_ini_config_read(h, iface->name, "hw_mode", buf, len))
|
||||
return 0;
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static int __fst_ini_config_get_iface_channel(struct fst_ini_config *h,
|
||||
const struct fst_iface_info *iface, char *buf, int len)
|
||||
{
|
||||
if(!fst_ini_config_read(h, iface->name, "channel", buf, len))
|
||||
return 0;
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
static int __fst_ini_config_get_txqueuelen(struct fst_ini_config *h, const char *gname)
|
||||
{
|
||||
char buf[INI_MAX_STRING + 1];
|
||||
|
||||
if (!fst_ini_config_read(h, gname, "txqueuelen", buf, INI_MAX_STRING))
|
||||
return -1;
|
||||
|
||||
return atoi(buf);
|
||||
}
|
||||
|
||||
static int __fst_ini_config_get_slave_ctrl_interface(struct fst_ini_config *h,
|
||||
char *buf, int len)
|
||||
{
|
||||
if(!fst_ini_config_read(h, "fst_manager", "slave_ctrl_iface_dir", buf, len))
|
||||
return 0;
|
||||
return strlen(buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Caching the INI file
|
||||
*/
|
||||
|
||||
static int fst_ini_cache_iface(struct fst_ini_config *h,
|
||||
struct fst_iface_info *fiinfo, struct cfg_iface_info **out_ciinfo)
|
||||
{
|
||||
struct cfg_iface_info *ciinfo;
|
||||
|
||||
ciinfo = (struct cfg_iface_info *)os_zalloc(
|
||||
sizeof(struct cfg_iface_info));
|
||||
if (!ciinfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "cache_iface: fail to allocate cfg_iface_info");
|
||||
return -1;
|
||||
}
|
||||
|
||||
ciinfo->info = *fiinfo;
|
||||
__fst_ini_config_get_iface_group_cipher(h, fiinfo, ciinfo->group_cipher,
|
||||
sizeof(ciinfo->group_cipher));
|
||||
__fst_ini_config_get_iface_pairwise_cipher(h, fiinfo,
|
||||
ciinfo->pairwise_cipher, sizeof(ciinfo->pairwise_cipher));
|
||||
__fst_ini_config_get_iface_hw_mode(h, fiinfo, ciinfo->hw_mode, sizeof(ciinfo->hw_mode));
|
||||
__fst_ini_config_get_iface_channel(h, fiinfo, ciinfo->channel, sizeof(ciinfo->channel));
|
||||
|
||||
*out_ciinfo = ciinfo;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fst_ini_cache_ifaces(struct fst_ini_config *h,
|
||||
struct fst_group_info *fginfo, struct cfg_group_info *cginfo)
|
||||
{
|
||||
struct fst_iface_info *ifaces = NULL;
|
||||
int nof_ifaces, i, res;
|
||||
struct cfg_iface_info *ifinfo = NULL;
|
||||
|
||||
res = __fst_ini_config_get_group_ifaces(h, fginfo, &ifaces);
|
||||
if (res < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "cache_ifaces: fail to get ifaces");
|
||||
return -1;
|
||||
}
|
||||
|
||||
nof_ifaces = res;
|
||||
res = 0;
|
||||
for (i = 0; i < nof_ifaces; i++) {
|
||||
if (fst_ini_cache_iface(h, &ifaces[i], &ifinfo) < 0) {
|
||||
res = -1;
|
||||
break;
|
||||
}
|
||||
dl_list_add_tail(&cginfo->ifaces, &ifinfo->list);
|
||||
}
|
||||
|
||||
free(ifaces);
|
||||
/* on error, anything already added to cache will be freed by caller */
|
||||
return res;
|
||||
}
|
||||
|
||||
static void fst_ini_free_group_info(struct cfg_group_info *cginfo)
|
||||
{
|
||||
struct cfg_iface_info *ifinfo, *tmp;
|
||||
|
||||
if (!cginfo)
|
||||
return;
|
||||
|
||||
dl_list_for_each_safe(ifinfo, tmp, &cginfo->ifaces,
|
||||
struct cfg_iface_info, list) {
|
||||
dl_list_del(&ifinfo->list);
|
||||
free(ifinfo);
|
||||
}
|
||||
free(cginfo);
|
||||
}
|
||||
|
||||
static int fst_ini_cache_group(
|
||||
struct fst_ini_config *h, struct fst_group_info *fginfo,
|
||||
struct cfg_group_info **out_cginfo)
|
||||
{
|
||||
struct cfg_group_info *cginfo;
|
||||
char *str;
|
||||
|
||||
cginfo = (struct cfg_group_info *)os_zalloc(
|
||||
sizeof(struct cfg_group_info));
|
||||
if (!cginfo) {
|
||||
fst_mgr_printf(MSG_ERROR, "fail to allocate cfg_group_info");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dl_list_init(&cginfo->ifaces);
|
||||
|
||||
os_strlcpy(cginfo->name, fginfo->id, sizeof(cginfo->name));
|
||||
|
||||
str = __fst_ini_config_get_rate_upgrade_master(h, cginfo->name);
|
||||
if (str) {
|
||||
os_strlcpy(cginfo->rate_upgrade_master, str,
|
||||
sizeof(cginfo->rate_upgrade_master));
|
||||
free(str);
|
||||
}
|
||||
str = __fst_ini_config_get_rate_upgrade_acl_fname(h, cginfo->name);
|
||||
if (str) {
|
||||
os_strlcpy(cginfo->rate_upgrade_acl_fname, str,
|
||||
sizeof(cginfo->rate_upgrade_acl_fname));
|
||||
free(str);
|
||||
}
|
||||
__fst_ini_config_get_mux_type(h, cginfo->name, cginfo->mux_type,
|
||||
sizeof(cginfo->mux_type));
|
||||
__fst_ini_config_get_mux_ifname(h, cginfo->name, cginfo->mux_ifname,
|
||||
sizeof(cginfo->mux_ifname));
|
||||
__fst_ini_config_get_l2da_ap_default_ifname(h, cginfo->name,
|
||||
cginfo->l2da_ap_default_ifname,
|
||||
sizeof(cginfo->l2da_ap_default_ifname));
|
||||
cginfo->is_mux_managed = __fst_ini_config_is_mux_managed(h, cginfo->name);
|
||||
cginfo->txqueuelen = __fst_ini_config_get_txqueuelen(h, cginfo->name);
|
||||
|
||||
if (fst_ini_cache_ifaces(h, fginfo, cginfo) < 0)
|
||||
goto out_err;
|
||||
|
||||
*out_cginfo = cginfo;
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
fst_ini_free_group_info(cginfo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int fst_ini_cache_groups(struct fst_ini_config *h, struct cfg_cache *cache)
|
||||
{
|
||||
struct fst_group_info *groups = NULL;
|
||||
struct cfg_group_info *ginfo = NULL;
|
||||
int res, nof_groups, i;
|
||||
|
||||
res = __fst_ini_config_get_groups(h, &groups);
|
||||
if (res < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "fail to get groups");
|
||||
return -1;
|
||||
}
|
||||
|
||||
nof_groups = res;
|
||||
res = 0;
|
||||
for (i = 0; i < nof_groups; i++) {
|
||||
res = fst_ini_cache_group(h, &groups[i], &ginfo);
|
||||
if (res < 0)
|
||||
break;
|
||||
dl_list_add_tail(&cache->groups, &ginfo->list);
|
||||
}
|
||||
|
||||
free(groups);
|
||||
/* on error, anything already added to cache will be freed by caller */
|
||||
return res;
|
||||
}
|
||||
|
||||
static void fst_ini_free_config_cache(struct cfg_cache *cache)
|
||||
{
|
||||
struct cfg_group_info *cginfo, *tmp;
|
||||
|
||||
if (!cache)
|
||||
return;
|
||||
|
||||
dl_list_for_each_safe(cginfo, tmp, &cache->groups,
|
||||
struct cfg_group_info, list) {
|
||||
dl_list_del(&cginfo->list);
|
||||
fst_ini_free_group_info(cginfo);
|
||||
}
|
||||
free(cache);
|
||||
}
|
||||
|
||||
static int fst_ini_cache_config(struct fst_ini_config *h)
|
||||
{
|
||||
struct cfg_cache *cache;
|
||||
|
||||
cache = (struct cfg_cache *)os_zalloc(sizeof(struct cfg_cache));
|
||||
if (!cache) {
|
||||
fst_mgr_printf(MSG_ERROR, "fail to allocate cfg_cache");
|
||||
return -1;
|
||||
}
|
||||
|
||||
dl_list_init(&cache->groups);
|
||||
|
||||
__fst_ini_config_get_ctrl_iface(h, cache->ctrl_iface,
|
||||
sizeof(cache->ctrl_iface));
|
||||
|
||||
__fst_ini_config_get_slave_ctrl_interface(h,
|
||||
cache->slave_ctrl_interface,
|
||||
sizeof(cache->slave_ctrl_interface));
|
||||
|
||||
if (fst_ini_cache_groups(h, cache) < 0)
|
||||
goto out_err;
|
||||
|
||||
h->cache = cache;
|
||||
return 0;
|
||||
|
||||
out_err:
|
||||
fst_ini_free_config_cache(cache);
|
||||
return -1;
|
||||
}
|
||||
83
qcom/opensource/fst-manager/fst_ini_conf.h
Normal file
83
qcom/opensource/fst-manager/fst_ini_conf.h
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* FST Manager: INI configuration file parser
|
||||
*
|
||||
* Copyright (c) 2015, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FST_INI_CONF_H__
|
||||
#define __FST_INI_CONF_H__
|
||||
#include "utils/common.h"
|
||||
#include "fst_ctrl.h"
|
||||
|
||||
struct fst_ini_config;
|
||||
|
||||
struct fst_ini_config *fst_ini_config_init(const char *filename);
|
||||
void fst_ini_config_deinit(struct fst_ini_config *h);
|
||||
|
||||
int fst_ini_config_get_ctrl_iface(struct fst_ini_config *h,
|
||||
char *buf, int size);
|
||||
int fst_ini_config_get_group_ifaces(struct fst_ini_config *h,
|
||||
const struct fst_group_info *group,
|
||||
struct fst_iface_info **ifaces);
|
||||
int fst_ini_config_get_groups(struct fst_ini_config *h,
|
||||
struct fst_group_info **groups);
|
||||
char *fst_ini_config_get_rate_upgrade_master(struct fst_ini_config *h,
|
||||
const char *groupname);
|
||||
char *fst_ini_config_get_rate_upgrade_acl_fname(struct fst_ini_config *h,
|
||||
const char *groupname);
|
||||
int fst_ini_config_get_group_slave_ifaces(struct fst_ini_config *h,
|
||||
const struct fst_group_info *group, const char *master,
|
||||
struct fst_iface_info **ifaces);
|
||||
int fst_ini_config_get_mux_type(struct fst_ini_config *h,
|
||||
const char *gname, char *buf, int buflen);
|
||||
int fst_ini_config_get_mux_ifname(struct fst_ini_config *h,
|
||||
const char *gname, char *buf, int buflen);
|
||||
int fst_ini_config_get_l2da_ap_default_ifname(struct fst_ini_config *h,
|
||||
const char *gname, char *buf, int buflen);
|
||||
Boolean fst_ini_config_is_mux_managed(struct fst_ini_config *h,
|
||||
const char *gname);
|
||||
int fst_ini_config_get_iface_group_cipher(struct fst_ini_config *h,
|
||||
const struct fst_iface_info *iface, char *buf, int len);
|
||||
int fst_ini_config_get_iface_pairwise_cipher(struct fst_ini_config *h,
|
||||
const struct fst_iface_info *iface, char *buf, int len);
|
||||
int fst_ini_config_get_iface_hw_mode(struct fst_ini_config *h,
|
||||
const struct fst_iface_info *iface, char *buf, int len);
|
||||
int fst_ini_config_get_iface_channel(struct fst_ini_config *h,
|
||||
const struct fst_iface_info *iface, char *buf, int len);
|
||||
int fst_ini_config_get_txqueuelen(struct fst_ini_config *h, const char *gname);
|
||||
int fst_ini_config_get_slave_ctrl_interface(struct fst_ini_config *h,
|
||||
char *buf, int len);
|
||||
|
||||
int fst_ini_config_set_mux_ifname(struct fst_ini_config *h,
|
||||
const char *gname, const char *newname);
|
||||
int fst_ini_config_rename_interface(struct fst_ini_config *h,
|
||||
const char *gname, const char *ifname, const char *newname);
|
||||
|
||||
#endif /* __FST_INI_CONF_H__ */
|
||||
|
||||
1944
qcom/opensource/fst-manager/fst_manager.c
Normal file
1944
qcom/opensource/fst-manager/fst_manager.c
Normal file
File diff suppressed because it is too large
Load Diff
93
qcom/opensource/fst-manager/fst_manager.h
Normal file
93
qcom/opensource/fst-manager/fst_manager.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* FST Manager interface definitions
|
||||
*
|
||||
* Copyright (c) 2015, 2019 The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FST_MANAGER_H__
|
||||
#define __FST_MANAGER_H__
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/defs.h"
|
||||
|
||||
#ifndef FST_MGR_COMPONENT
|
||||
#error "FST_MGR_COMPONENT has to be defined"
|
||||
#endif
|
||||
|
||||
#define FST_MANAGER_VERSION "0.02"
|
||||
|
||||
#ifdef CONFIG_DBUS
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#define _fst_mgr_printf g_printerr
|
||||
#else
|
||||
#define _fst_mgr_printf(format, ...) wpa_printf(MSG_ERROR, format, ##__VA_ARGS__)
|
||||
#endif
|
||||
|
||||
extern unsigned int fst_debug_level;
|
||||
|
||||
#include <sys/time.h>
|
||||
|
||||
#define fst_mgr_printf(level, format, ...) \
|
||||
do { \
|
||||
if ((level) >= fst_debug_level) { \
|
||||
struct timeval tv = {}; \
|
||||
gettimeofday(&tv, NULL); \
|
||||
_fst_mgr_printf("[%08lu.%06lu] FST: " FST_MGR_COMPONENT \
|
||||
": %s: " format "\n", \
|
||||
(unsigned long)tv.tv_sec, \
|
||||
(unsigned long)tv.tv_usec, \
|
||||
__func__, ##__VA_ARGS__); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
int fst_manager_init(void);
|
||||
void fst_manager_deinit(void);
|
||||
const u8 *fst_mgr_get_addr_from_mbie(struct multi_band_ie *mbie);
|
||||
void fst_manager_terminate(void);
|
||||
int fst_manager_enslave(const char *gname, const char* ifname, Boolean enslave);
|
||||
int fst_manager_is_enslaved(const char *gname, const char* ifname,
|
||||
Boolean *isEnslaved);
|
||||
int fst_manager_set_mac_address(const char *ifname, const u8 *mac);
|
||||
int fst_manager_set_mux_iface_name(const char *gname, const char *ifname);
|
||||
int fst_manager_rename_group_interface(const char *gname, const char *ifname,
|
||||
const char *newifname);
|
||||
int fst_manager_session_transfer(const char *old_ifname, const u8 *peer_addr);
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* __FST_MANAGER_H__ */
|
||||
52
qcom/opensource/fst-manager/fst_mux.h
Normal file
52
qcom/opensource/fst-manager/fst_mux.h
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* FST mux interface definitions
|
||||
*
|
||||
* Copyright (c) 2015, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FST_MUX_H__
|
||||
#define __FST_MUX_H__
|
||||
|
||||
#include "utils/common.h"
|
||||
|
||||
struct fst_mux;
|
||||
|
||||
struct fst_mux *fst_mux_init(const char *drv_iface_name);
|
||||
int fst_mux_start(struct fst_mux *ctx);
|
||||
int fst_mux_register_iface(struct fst_mux *ctx, const char *iface_name,
|
||||
u8 priority);
|
||||
int fst_mux_add_map_entry(struct fst_mux *ctx, const u8 *da,
|
||||
const char *iface_name);
|
||||
int fst_mux_del_map_entry(struct fst_mux *ctx, const u8 *da);
|
||||
void fst_mux_unregister_iface(struct fst_mux *ctx, const char *iface_name);
|
||||
void fst_mux_stop(struct fst_mux *ctx);
|
||||
void fst_mux_cleanup(struct fst_mux *ctx);
|
||||
|
||||
|
||||
#endif /* __FST_MUX_H__ */
|
||||
482
qcom/opensource/fst-manager/fst_mux_bonding.c
Normal file
482
qcom/opensource/fst-manager/fst_mux_bonding.c
Normal file
@@ -0,0 +1,482 @@
|
||||
/*
|
||||
* FST bonding + TC based mux implementation
|
||||
*
|
||||
* Copyright (c) 2015, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/list.h"
|
||||
#include "common/defs.h"
|
||||
#include "fst_mux.h"
|
||||
#include "fst_tc.h"
|
||||
#include "fst_cfgmgr.h"
|
||||
#include <sys/ioctl.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/if_bonding.h>
|
||||
#include <linux/sockios.h>
|
||||
#include <linux/ethtool.h>
|
||||
|
||||
#define FST_MGR_COMPONENT "MUX"
|
||||
#include "fst_manager.h"
|
||||
|
||||
#define BOND_ABI_VERSION 2
|
||||
#define BOND_SYSFS_ROOT "/sys/class/net"
|
||||
#define BOND_SYSFS_QUEUEID "bonding/queue_id"
|
||||
|
||||
struct fst_mux_iface
|
||||
{
|
||||
char ifname[IFNAMSIZ + 1];
|
||||
u8 priority;
|
||||
int queue_id;
|
||||
struct dl_list filters;
|
||||
struct dl_list lentry;
|
||||
};
|
||||
|
||||
struct fst_mux_filter
|
||||
{
|
||||
u8 da[ETH_ALEN];
|
||||
struct fst_tc_filter_handle filter_handle;
|
||||
struct fst_mux_iface *iface;
|
||||
struct dl_list lentry;
|
||||
};
|
||||
|
||||
struct fst_mux
|
||||
{
|
||||
char bond_ifname[IFNAMSIZ + 1];
|
||||
struct dl_list ifaces;
|
||||
int skfd;
|
||||
int queue_id;
|
||||
struct fst_tc *tc;
|
||||
};
|
||||
|
||||
struct fst_mux_iface * _drv_get_iface_by_name(struct fst_mux *ctx,
|
||||
const char *ifname)
|
||||
{
|
||||
struct fst_mux_iface *i;
|
||||
dl_list_for_each(i, &ctx->ifaces, struct fst_mux_iface, lentry) {
|
||||
if (!os_strcmp(i->ifname, ifname))
|
||||
return i;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct fst_mux_filter *_drv_get_filter_by_da(struct fst_mux *ctx, const u8 *da)
|
||||
{
|
||||
struct fst_mux_iface *i;
|
||||
dl_list_for_each(i, &ctx->ifaces, struct fst_mux_iface, lentry) {
|
||||
struct fst_mux_filter *f;
|
||||
dl_list_for_each(f, &i->filters, struct fst_mux_filter, lentry) {
|
||||
if (os_memcmp(f->da, da, ETH_ALEN) == 0) {
|
||||
return f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
__mux_bond_get_info(struct fst_mux *ctx)
|
||||
{
|
||||
struct ifreq ifr;
|
||||
struct ethtool_drvinfo info;
|
||||
char *endptr;
|
||||
int abi_ver;
|
||||
|
||||
os_memset(&ifr, 0, sizeof(ifr));
|
||||
os_strlcpy(ifr.ifr_name, ctx->bond_ifname, IFNAMSIZ);
|
||||
ifr.ifr_data = (caddr_t)&info;
|
||||
|
||||
info.cmd = ETHTOOL_GDRVINFO;
|
||||
os_strlcpy(info.driver, "ifenslave", 32);
|
||||
os_snprintf(info.fw_version, 32, "%d", BOND_ABI_VERSION);
|
||||
|
||||
if (ioctl(ctx->skfd, SIOCETHTOOL, &ifr) < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "SIOCETHTOOL failed on %s: %s",
|
||||
ctx->bond_ifname, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
abi_ver = strtoul(info.fw_version, &endptr, 0);
|
||||
if (*endptr) {
|
||||
fst_mgr_printf(MSG_ERROR, "Invalid ABI version arrived from %s",
|
||||
ctx->bond_ifname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fst_mgr_printf(MSG_DEBUG, "ABI ver is %d", abi_ver);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _mux_bond_assign_queue_id(struct fst_mux *ctx,
|
||||
const char *slave_ifname, int queue_id)
|
||||
{
|
||||
FILE *f;
|
||||
char fname[256];
|
||||
snprintf(fname, sizeof(fname), BOND_SYSFS_ROOT "/%s/" BOND_SYSFS_QUEUEID,
|
||||
ctx->bond_ifname);
|
||||
f = fopen(fname, "w");
|
||||
if (!f) {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot open queu_id file: %s",
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
fprintf(f, "%s:%d", slave_ifname, queue_id);
|
||||
fclose(f);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _mux_bond_connect(struct fst_mux *ctx)
|
||||
{
|
||||
short ifru_flags;
|
||||
|
||||
if ((ctx->skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot open socket: %s",
|
||||
strerror(errno));
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (__mux_bond_get_info(ctx)) {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot get bond info");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (get_iface_flags(ctx->bond_ifname, &ifru_flags)) {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot get bond flags");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(ifru_flags & IFF_MASTER)) {
|
||||
fst_mgr_printf(MSG_ERROR, "%s isn't a master",
|
||||
ctx->bond_ifname);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!(ifru_flags & IFF_UP)) {
|
||||
fst_mgr_printf(MSG_ERROR, "%s is down",
|
||||
ctx->bond_ifname);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int _drv_del_filter(struct fst_mux *ctx, struct fst_mux_filter *filter,
|
||||
Boolean force_removal)
|
||||
{
|
||||
if (!fst_tc_del_l2da_filter(ctx->tc, &filter->filter_handle))
|
||||
fst_mgr_printf(MSG_DEBUG,
|
||||
"TC filter deleted for [" MACSTR "]",
|
||||
MAC2STR(filter->da));
|
||||
else {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"Cannot delete TC filter for [" MACSTR "]",
|
||||
MAC2STR(filter->da));
|
||||
if (!force_removal)
|
||||
return -1;
|
||||
}
|
||||
|
||||
dl_list_del(&filter->lentry);
|
||||
|
||||
/* STA can only have 1 peer (AP), so it should have no filters
|
||||
* installed after we removed the previous one */
|
||||
WPA_ASSERT(!fst_is_supplicant() ||
|
||||
dl_list_empty(&filter->iface->filters));
|
||||
|
||||
os_free(filter);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void _drv_purge_iface_filters(struct fst_mux *ctx,
|
||||
struct fst_mux_iface *iface)
|
||||
{
|
||||
while (1) {
|
||||
struct fst_mux_filter *filter =
|
||||
dl_list_first(&iface->filters, struct fst_mux_filter, lentry);
|
||||
if (!filter)
|
||||
break;
|
||||
_drv_del_filter(ctx, filter, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
static void _drv_purge_filters(struct fst_mux *ctx)
|
||||
{
|
||||
struct fst_mux_iface *iface;
|
||||
dl_list_for_each(iface, &ctx->ifaces, struct fst_mux_iface, lentry)
|
||||
_drv_purge_iface_filters(ctx, iface);
|
||||
}
|
||||
|
||||
void _drv_del_iface(struct fst_mux *ctx, struct fst_mux_iface *iface)
|
||||
{
|
||||
dl_list_del(&iface->lentry);
|
||||
_drv_purge_iface_filters(ctx, iface);
|
||||
os_free(iface);
|
||||
}
|
||||
|
||||
static void _drv_bond_disconnect(struct fst_mux *ctx)
|
||||
{
|
||||
close(ctx->skfd);
|
||||
ctx->skfd = -1;
|
||||
}
|
||||
|
||||
struct fst_mux *fst_mux_init(const char *group_name)
|
||||
{
|
||||
struct fst_mux *ctx = NULL;
|
||||
int len;
|
||||
char buf[80];
|
||||
|
||||
len = fst_cfgmgr_get_mux_type(group_name, buf, sizeof(buf)-1);
|
||||
if (len) {
|
||||
if (os_strcmp(buf, "bonding")) {
|
||||
fst_mgr_printf(MSG_ERROR, "Unsupported mux type: %s", buf);
|
||||
goto fail_mux_type;
|
||||
}
|
||||
}
|
||||
|
||||
ctx = os_zalloc(sizeof(*ctx));
|
||||
if (!ctx) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot allocate driver for %s",
|
||||
group_name);
|
||||
goto fail_no_ctx;
|
||||
}
|
||||
|
||||
len = fst_cfgmgr_get_mux_ifname(group_name, ctx->bond_ifname,
|
||||
sizeof(ctx->bond_ifname)-1);
|
||||
if (len == 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot get mux ifname");
|
||||
goto fail_mux_name;
|
||||
}
|
||||
|
||||
dl_list_init(&ctx->ifaces);
|
||||
ctx->skfd = -1;
|
||||
ctx->queue_id = 0;
|
||||
|
||||
if (_mux_bond_connect(ctx)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot connect to bond#%s",
|
||||
ctx->bond_ifname);
|
||||
goto fail_connect;
|
||||
}
|
||||
|
||||
ctx->tc = fst_tc_create(fst_is_supplicant());
|
||||
if (!ctx->tc) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot create FST TC bond#%s",
|
||||
ctx->bond_ifname);
|
||||
goto fail_tc_create;
|
||||
}
|
||||
|
||||
fst_mgr_printf(MSG_DEBUG, "driver initialized for %s",
|
||||
ctx->bond_ifname);
|
||||
|
||||
return ctx;
|
||||
|
||||
fail_tc_create:
|
||||
_drv_bond_disconnect(ctx);
|
||||
fail_connect:
|
||||
fail_mux_name:
|
||||
os_free(ctx);
|
||||
fail_no_ctx:
|
||||
fail_mux_type:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fst_mux_start(struct fst_mux *ctx)
|
||||
{
|
||||
struct fst_mux_iface *i;
|
||||
|
||||
dl_list_for_each(i, &ctx->ifaces, struct fst_mux_iface, lentry) {
|
||||
i->queue_id = ++ctx->queue_id;
|
||||
|
||||
if (_mux_bond_assign_queue_id(ctx, i->ifname, i->queue_id)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot assign queue_id#%d for %s",
|
||||
i->queue_id, i->ifname);
|
||||
goto fail;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if (fst_tc_start(ctx->tc, ctx->bond_ifname) != 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot start FST TC bond#%s",
|
||||
ctx->bond_ifname);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
fst_mgr_printf(MSG_DEBUG, "%s initialized",
|
||||
ctx->bond_ifname);
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
dl_list_for_each(i, &ctx->ifaces, struct fst_mux_iface, lentry)
|
||||
_mux_bond_assign_queue_id(ctx, i->ifname, 0);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fst_mux_register_iface(struct fst_mux *ctx, const char *iface_name,
|
||||
u8 priority)
|
||||
{
|
||||
struct fst_mux_iface *iface;
|
||||
|
||||
iface = _drv_get_iface_by_name(ctx, iface_name);
|
||||
if (iface) {
|
||||
fst_mgr_printf(MSG_ERROR, "Slave (%s) already regirestred with bond#%s",
|
||||
iface_name, ctx->bond_ifname);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
iface = os_zalloc(sizeof(*iface));
|
||||
if (!iface) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot allocate object for %s",
|
||||
iface_name);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fst_tc_register_iface(ctx->tc, iface_name)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot register TC for %s",
|
||||
iface_name);
|
||||
goto fail_tc_register;
|
||||
}
|
||||
|
||||
iface->priority = priority;
|
||||
|
||||
dl_list_init(&iface->filters);
|
||||
os_strlcpy(iface->ifname, iface_name, sizeof(iface->ifname));
|
||||
|
||||
dl_list_add_tail(&ctx->ifaces, &iface->lentry);
|
||||
|
||||
fst_mgr_printf(MSG_DEBUG, "interface %s registered with %s",
|
||||
iface_name, ctx->bond_ifname);
|
||||
|
||||
return 0;
|
||||
|
||||
fail_tc_register:
|
||||
os_free(iface);
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fst_mux_add_map_entry(struct fst_mux *ctx, const u8 *da,
|
||||
const char *iface_name)
|
||||
{
|
||||
struct fst_mux_iface *iface;
|
||||
struct fst_mux_filter *filter;
|
||||
|
||||
iface = _drv_get_iface_by_name(ctx, iface_name);
|
||||
if (!iface) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot find interface %s", iface_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
fst_mux_del_map_entry(ctx, da);
|
||||
|
||||
filter = os_zalloc(sizeof(*filter));
|
||||
if (!filter) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot allocate filter "
|
||||
"for [" MACSTR ",%s]",
|
||||
MAC2STR(da), iface_name);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fst_tc_add_l2da_filter(ctx->tc, da, iface->queue_id, iface_name,
|
||||
&filter->filter_handle)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot add TC filter for [" MACSTR ",%s]",
|
||||
MAC2STR(da), iface_name);
|
||||
os_free(filter);
|
||||
return -1;
|
||||
}
|
||||
|
||||
os_memcpy(filter->da, da, ETH_ALEN);
|
||||
filter->iface = iface;
|
||||
dl_list_add_tail(&iface->filters, &filter->lentry);
|
||||
|
||||
fst_mgr_printf(MSG_DEBUG, "TC filter added for [" MACSTR ",%s]",
|
||||
MAC2STR(da), iface_name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fst_mux_del_map_entry(struct fst_mux *ctx, const u8 *da)
|
||||
{
|
||||
struct fst_mux_filter *filter;
|
||||
|
||||
filter = _drv_get_filter_by_da(ctx, da);
|
||||
if (!filter) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot find TC filter for [" MACSTR "]",
|
||||
MAC2STR(da));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return _drv_del_filter(ctx, filter, FALSE);
|
||||
}
|
||||
|
||||
void fst_mux_unregister_iface(struct fst_mux *ctx, const char *iface_name)
|
||||
{
|
||||
struct fst_mux_iface *iface;
|
||||
|
||||
fst_tc_unregister_iface(ctx->tc, iface_name);
|
||||
|
||||
iface = _drv_get_iface_by_name(ctx, iface_name);
|
||||
if (iface) {
|
||||
_drv_del_iface(ctx, iface);
|
||||
fst_mgr_printf(MSG_DEBUG, "interface %s unregistered with %s",
|
||||
iface_name, ctx->bond_ifname);
|
||||
}
|
||||
}
|
||||
|
||||
void fst_mux_stop(struct fst_mux *ctx)
|
||||
{
|
||||
struct fst_mux_iface *i;
|
||||
_drv_purge_filters(ctx);
|
||||
fst_tc_stop(ctx->tc);
|
||||
dl_list_for_each(i, &ctx->ifaces, struct fst_mux_iface, lentry) {
|
||||
_mux_bond_assign_queue_id(ctx, i->ifname, 0);
|
||||
}
|
||||
ctx->queue_id = 0;
|
||||
}
|
||||
|
||||
void fst_mux_cleanup(struct fst_mux *ctx)
|
||||
{
|
||||
while (TRUE) {
|
||||
struct fst_mux_iface *iface =
|
||||
dl_list_first(&ctx->ifaces, struct fst_mux_iface, lentry);
|
||||
if (!iface)
|
||||
break;
|
||||
_drv_del_iface(ctx, iface);
|
||||
}
|
||||
fst_tc_delete(ctx->tc);
|
||||
_drv_bond_disconnect(ctx);
|
||||
fst_mgr_printf(MSG_DEBUG, "driver cleaned up for %s",
|
||||
ctx->bond_ifname);
|
||||
os_free(ctx);
|
||||
}
|
||||
359
qcom/opensource/fst-manager/fst_mux_l2da.c
Normal file
359
qcom/opensource/fst-manager/fst_mux_l2da.c
Normal file
@@ -0,0 +1,359 @@
|
||||
/*
|
||||
* FST L2DA + NETLINK based mux implementation
|
||||
*
|
||||
* Copyright (c) 2015, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <netlink/socket.h>
|
||||
#include <netlink/attr.h>
|
||||
#include <netlink/msg.h>
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/list.h"
|
||||
#include <linux/if_bonding_genl.h>
|
||||
#include "common/defs.h"
|
||||
#include "fst_mux.h"
|
||||
#include "fst_cfgmgr.h"
|
||||
|
||||
#define FST_MGR_COMPONENT "MUX"
|
||||
#include "fst_manager.h"
|
||||
|
||||
struct fst_mux
|
||||
{
|
||||
char bond_ifname[IFNAMSIZ + 1];
|
||||
char *ap_default_ifname;
|
||||
struct nl_sock *nl;
|
||||
int fam_id;
|
||||
};
|
||||
|
||||
#define BOND_L2DA_STA_OPTS (BOND_L2DA_OPT_DEDUP_RX | \
|
||||
BOND_L2DA_OPT_REPLACE_MAC | \
|
||||
BOND_L2DA_OPT_AUTO_ARP_ANNOUNCE )
|
||||
#define BOND_L2DA_AP_OPTS (BOND_L2DA_OPT_DUP_MC_TX | \
|
||||
BOND_L2DA_OPT_FORWARD_RX)
|
||||
|
||||
static struct nl_msg * _init_genl_msg(struct fst_mux *ctx, int cmd)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
void *hdr;
|
||||
int res;
|
||||
|
||||
msg = nlmsg_alloc();
|
||||
if(msg == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot allocate nlmsg");
|
||||
goto fail_nlmsg;
|
||||
}
|
||||
|
||||
hdr = genlmsg_put(msg, NL_AUTO_PORT, NL_AUTO_SEQ, ctx->fam_id,
|
||||
0, NLM_F_REQUEST | NLM_F_ACK, cmd, BOND_GENL_VERSION);
|
||||
if (hdr == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR, "genlmsg_put failed");
|
||||
goto fail_nlmsg_put;
|
||||
}
|
||||
|
||||
res = nla_put_string(msg, BOND_GENL_ATTR_BOND_NAME, ctx->bond_ifname);
|
||||
if (res != 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot put bond: %s", nl_geterror(res));
|
||||
goto fail_nlmsg_put;
|
||||
}
|
||||
|
||||
fst_mgr_printf(MSG_DEBUG, " _init_genl_msg created msg for %d cmd", cmd);
|
||||
|
||||
return msg;
|
||||
|
||||
fail_nlmsg_put:
|
||||
nlmsg_free(msg);
|
||||
fail_nlmsg:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _send_and_free_genl_msg(struct fst_mux *ctx, struct nl_msg *msg)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = nl_send_auto(ctx->nl, msg);
|
||||
nlmsg_free(msg);
|
||||
if (res < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot nl_send: %s", nl_geterror(res));
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int _send_genl_reset_map_msg(struct fst_mux *ctx)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
int res;
|
||||
|
||||
msg = _init_genl_msg(ctx, BOND_GENL_CMD_L2DA_RESET_MAP);
|
||||
if (msg == NULL)
|
||||
return -1;
|
||||
|
||||
res = _send_and_free_genl_msg(ctx, msg);
|
||||
if (!res)
|
||||
fst_mgr_printf(MSG_INFO, "L2DA map reset");
|
||||
else
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot reset L2DA map");
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _send_genl_set_opts_msg(struct fst_mux *ctx, u32 opts)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
int res;
|
||||
|
||||
msg = _init_genl_msg(ctx, BOND_GENL_CMD_L2DA_SET_OPTS);
|
||||
if (msg == NULL)
|
||||
return -1;
|
||||
|
||||
res = nla_put_u32(msg, BOND_GENL_ATTR_L2DA_OPTS, opts);
|
||||
if (res != 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot put opts: %s",
|
||||
nl_geterror(res));
|
||||
nlmsg_free(msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = _send_and_free_genl_msg(ctx, msg);
|
||||
if (!res)
|
||||
fst_mgr_printf(MSG_INFO, "L2DA opts set to 0x%08x", opts);
|
||||
else
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot set L2DA opts");
|
||||
return res;
|
||||
}
|
||||
|
||||
static int _send_genl_set_def_slave_msg(struct fst_mux *ctx, const char *ifname)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
int res;
|
||||
|
||||
msg = _init_genl_msg(ctx, BOND_GENL_CMD_L2DA_SET_DEFAULT);
|
||||
if (msg == NULL)
|
||||
return -1;
|
||||
|
||||
res = nla_put_string(msg, BOND_GENL_ATTR_SLAVE_NAME, ifname);
|
||||
if (res != 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot put slave: %s",
|
||||
nl_geterror(res));
|
||||
nlmsg_free(msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
res = _send_and_free_genl_msg(ctx, msg);
|
||||
if (!res)
|
||||
fst_mgr_printf(MSG_INFO, "L2DA default slave set to %s",
|
||||
ifname);
|
||||
else
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot set L2DA default slave");
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
static int _send_genl_set_change_map_msg(struct fst_mux *ctx, const u8 *da,
|
||||
const char *ifname)
|
||||
{
|
||||
struct nl_msg *msg;
|
||||
int res;
|
||||
|
||||
res = ifname ? BOND_GENL_CMD_L2DA_ADD_MAP_ENTRY :
|
||||
BOND_GENL_CMD_L2DA_DEL_MAP_ENTRY;
|
||||
|
||||
msg = _init_genl_msg(ctx, res);
|
||||
if (msg == NULL)
|
||||
return -1;
|
||||
|
||||
res = nla_put(msg, BOND_GENL_ATTR_MAC, ETH_ALEN, da);
|
||||
if (res != 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot put address: %s", nl_geterror(res));
|
||||
goto fail_nlmsg_put;
|
||||
}
|
||||
|
||||
if (ifname) {
|
||||
res = nla_put_string(msg, BOND_GENL_ATTR_SLAVE_NAME, ifname);
|
||||
if (res != 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot put slave: %s",
|
||||
nl_geterror(res));
|
||||
goto fail_nlmsg_put;
|
||||
}
|
||||
}
|
||||
|
||||
res = _send_and_free_genl_msg(ctx, msg);
|
||||
if (!res)
|
||||
fst_mgr_printf(MSG_INFO, "L2DA map entry changed ["MACSTR",%s]",
|
||||
MAC2STR(da), ifname ? ifname : "NULL");
|
||||
else
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"Cannot change L2DA map entry ["MACSTR", %s]",
|
||||
MAC2STR(da), ifname ? ifname : "NULL");
|
||||
return res;
|
||||
|
||||
|
||||
fail_nlmsg_put:
|
||||
nlmsg_free(msg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct fst_mux *fst_mux_init(const char *group_name)
|
||||
{
|
||||
struct fst_mux *ctx = NULL;
|
||||
int len;
|
||||
char buf[80];
|
||||
char ifname[IFNAMSIZ + 1];
|
||||
|
||||
len = fst_cfgmgr_get_mux_type(group_name, buf, sizeof(buf)-1);
|
||||
if (len) {
|
||||
if (os_strcmp(buf, "bonding_l2da")) {
|
||||
fst_mgr_printf(MSG_ERROR, "Unsupported mux type: %s", buf);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ctx = os_zalloc(sizeof(*ctx));
|
||||
if (!ctx) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot allocate driver for %s",
|
||||
group_name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
len = fst_cfgmgr_get_mux_ifname(group_name, ctx->bond_ifname,
|
||||
sizeof(ctx->bond_ifname)-1);
|
||||
if (len == 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot get mux ifname");
|
||||
goto fail_mux_name;
|
||||
}
|
||||
|
||||
if (!fst_is_supplicant() &&
|
||||
fst_cfgmgr_get_l2da_ap_default_ifname(group_name, ifname,
|
||||
sizeof(ifname)-1) > 0) {
|
||||
ctx->ap_default_ifname = os_strdup(ifname);
|
||||
if (!ctx->ap_default_ifname) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot dup ap default ifname");
|
||||
goto fail_ap_default_name;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->nl = nl_socket_alloc();
|
||||
if (!ctx->nl) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot alloc nl socket");
|
||||
goto fail_nl_socket;
|
||||
}
|
||||
|
||||
if (genl_connect(ctx->nl)) {
|
||||
fst_mgr_printf(MSG_ERROR, "genl_connect failed");
|
||||
goto fail_nl_connect;
|
||||
}
|
||||
|
||||
nl_socket_disable_seq_check(ctx->nl);
|
||||
|
||||
ctx->fam_id = genl_ctrl_resolve(ctx->nl, BOND_GENL_NAME);
|
||||
if (ctx->fam_id < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot get nl family id");
|
||||
goto fail_nl_famid;
|
||||
}
|
||||
|
||||
fst_mgr_printf(MSG_DEBUG, "mux_l2da initialized for %s",
|
||||
ctx->bond_ifname);
|
||||
|
||||
return ctx;
|
||||
|
||||
fail_nl_famid:
|
||||
fail_nl_connect:
|
||||
nl_socket_free(ctx->nl);
|
||||
fail_nl_socket:
|
||||
os_free(ctx->ap_default_ifname);
|
||||
fail_ap_default_name:
|
||||
fail_mux_name:
|
||||
os_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fst_mux_start(struct fst_mux *ctx)
|
||||
{
|
||||
u32 opts;
|
||||
|
||||
if(_send_genl_reset_map_msg(ctx) != 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Error starting mux: reset map");
|
||||
return -1;
|
||||
}
|
||||
|
||||
opts = fst_is_supplicant() ? BOND_L2DA_STA_OPTS : BOND_L2DA_AP_OPTS;
|
||||
if (_send_genl_set_opts_msg(ctx, opts)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Error starting mux: set opts");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!fst_is_supplicant() && ctx->ap_default_ifname &&
|
||||
_send_genl_set_def_slave_msg(ctx, ctx->ap_default_ifname)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Error starting mux: set ap default iface");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fst_mux_add_map_entry(struct fst_mux *ctx, const u8 *da,
|
||||
const char *iface_name)
|
||||
{
|
||||
return fst_is_supplicant() ?
|
||||
_send_genl_set_def_slave_msg(ctx, iface_name) :
|
||||
_send_genl_set_change_map_msg(ctx, da, iface_name);
|
||||
}
|
||||
|
||||
int fst_mux_del_map_entry(struct fst_mux *ctx, const u8 *da)
|
||||
{
|
||||
/* "No need to del map entry for STA as we use default slave */
|
||||
return fst_is_supplicant() ?
|
||||
0 : _send_genl_set_change_map_msg(ctx, da, NULL);
|
||||
}
|
||||
|
||||
int fst_mux_register_iface(struct fst_mux *ctx, const char *iface_name,
|
||||
u8 priority)
|
||||
{
|
||||
return 0; /* Left for mux API compatibility */
|
||||
}
|
||||
|
||||
void fst_mux_unregister_iface(struct fst_mux *ctx, const char *iface_name)
|
||||
{
|
||||
/* Left for mux API compatibility */
|
||||
}
|
||||
|
||||
void fst_mux_stop(struct fst_mux *ctx)
|
||||
{
|
||||
if(_send_genl_reset_map_msg(ctx) != 0)
|
||||
fst_mgr_printf(MSG_WARNING, "Error stopping mux");
|
||||
}
|
||||
|
||||
void fst_mux_cleanup(struct fst_mux *ctx)
|
||||
{
|
||||
nl_socket_free(ctx->nl);
|
||||
os_free(ctx->ap_default_ifname);
|
||||
os_free(ctx);
|
||||
}
|
||||
808
qcom/opensource/fst-manager/fst_rateupg.c
Normal file
808
qcom/opensource/fst-manager/fst_rateupg.c
Normal file
@@ -0,0 +1,808 @@
|
||||
/*
|
||||
* FST Manager: Rate Upgrade
|
||||
*
|
||||
* Copyright (c) 2015-2016, 2019, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "utils/list.h"
|
||||
#include "fst_rateupg.h"
|
||||
#include "fst_tpoll.h"
|
||||
#include "fst_capconfigstore.h"
|
||||
|
||||
#define FST_MGR_COMPONENT "RATEUPG"
|
||||
#include "fst_manager.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
|
||||
#define FST_MAX_MCS 15
|
||||
#define FST_SIGNAL_MONITOR_DEFAULT_RSSI -55
|
||||
#define FST_SIGNAL_MONITOR_DEFAULT_HYST 5
|
||||
|
||||
static const char FST_CONFIG_SENSITIVITY_LEVEL_KEY_NAME[] = "fst.config.sensitivity.level";
|
||||
#define FST_CONFIG_SENSITIVITY_LEVEL "1" /* Medium */
|
||||
static const char FST_CONFIG_ENTRY_MCS_KEY_NAME[] = "fst.config.entry.mcs";
|
||||
#define FST_CONFIG_ENTRY_MCS "9"
|
||||
static const char FST_CONFIG_EXIT_MCS_KEY_NAME[] = "fst.config.exit.mcs";
|
||||
#define FST_CONFIG_EXIT_MCS "3"
|
||||
|
||||
enum wmi_fst_switch_sensitivity_level {
|
||||
WMI_FST_SWITCH_SENSITIVITY_LOW = 0x00,
|
||||
WMI_FST_SWITCH_SENSITIVITY_MED = 0x01,
|
||||
WMI_FST_SWITCH_SENSITIVITY_HIGH = 0x02,
|
||||
};
|
||||
|
||||
struct rate_upgrade_mac {
|
||||
u8 addr[ETH_ALEN];
|
||||
struct dl_list lentry;
|
||||
};
|
||||
|
||||
struct rate_upgrade_group {
|
||||
char *groupname;
|
||||
char *master;
|
||||
char *acl_fname;
|
||||
struct fst_iface_info *slaves;
|
||||
int slave_cnt;
|
||||
struct dl_list acl_macs;
|
||||
Boolean is_duped;
|
||||
struct dl_list lentry;
|
||||
};
|
||||
|
||||
struct rate_upgrade_manager {
|
||||
struct fst_ini_config *iniconf;
|
||||
struct dl_list groups;
|
||||
|
||||
/* FST config from xml */
|
||||
int sensitivity_level;
|
||||
int entryMCS;
|
||||
int exitMCS;
|
||||
int tpoll_interval;
|
||||
int tpoll_alpha;
|
||||
};
|
||||
|
||||
static struct rate_upgrade_manager g_rateupg_mgr;
|
||||
static int g_rateupg_mgr_initialized = 0;
|
||||
|
||||
static struct rate_upgrade_mac *find_rate_upgrade_mac(
|
||||
struct rate_upgrade_group *g, const u8 *addr)
|
||||
{
|
||||
struct rate_upgrade_mac *p;
|
||||
|
||||
if (!addr)
|
||||
return dl_list_first(&g->acl_macs, struct rate_upgrade_mac, lentry);
|
||||
|
||||
dl_list_for_each(p, &g->acl_macs, struct rate_upgrade_mac, lentry)
|
||||
if (!os_memcmp(p->addr, addr, ETH_ALEN))
|
||||
return p;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct rate_upgrade_mac *add_rate_upgrade_mac(
|
||||
struct rate_upgrade_group *g, const u8 *addr)
|
||||
{
|
||||
struct rate_upgrade_mac *p = os_malloc(sizeof(*p));
|
||||
if (p) {
|
||||
os_memcpy(p->addr, addr, ETH_ALEN);
|
||||
dl_list_add_tail(&g->acl_macs, &p->lentry);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
static void del_rate_upgrade_mac(struct rate_upgrade_mac *p)
|
||||
{
|
||||
dl_list_del(&p->lentry);
|
||||
os_free(p);
|
||||
}
|
||||
|
||||
static int update_acl_file(struct rate_upgrade_group *g)
|
||||
{
|
||||
struct rate_upgrade_mac *p;
|
||||
int res = -1;
|
||||
FILE *f;
|
||||
|
||||
if (!g->acl_fname)
|
||||
return 0;
|
||||
|
||||
f = fopen(g->acl_fname, "w");
|
||||
if (!f) {
|
||||
fst_mgr_printf(MSG_ERROR, "group %s: cannot open acl file: %s",
|
||||
g->groupname, g->acl_fname);
|
||||
goto error_file;
|
||||
}
|
||||
|
||||
dl_list_for_each(p, &g->acl_macs, struct rate_upgrade_mac, lentry)
|
||||
if (fprintf(f, MACSTR "\n", MAC2STR(p->addr)) <= 0) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"group %s: cannot fill acl file: %s",
|
||||
g->groupname, g->acl_fname);
|
||||
goto error_fprintf;
|
||||
}
|
||||
|
||||
res = 0;
|
||||
|
||||
error_fprintf:
|
||||
fclose(f);
|
||||
error_file:
|
||||
return res;
|
||||
}
|
||||
|
||||
static struct rate_upgrade_group *find_rate_upgrade_group(const char *name)
|
||||
{
|
||||
struct rate_upgrade_group *g;
|
||||
dl_list_for_each(g, &g_rateupg_mgr.groups, struct rate_upgrade_group, lentry) {
|
||||
if(!strncmp(g->groupname, name, strlen(name)))
|
||||
return g;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void deinit_rate_upgrade_group(struct rate_upgrade_group *g)
|
||||
{
|
||||
free(g->slaves);
|
||||
free(g->master);
|
||||
free(g->groupname);
|
||||
free(g->acl_fname);
|
||||
dl_list_del(&g->lentry);
|
||||
free(g);
|
||||
}
|
||||
|
||||
int fst_rate_upgrade_init(struct fst_ini_config *h)
|
||||
{
|
||||
int res;
|
||||
char buf[64] = { '\0' };
|
||||
|
||||
os_memset(&g_rateupg_mgr, 0, sizeof(g_rateupg_mgr));
|
||||
dl_list_init(&g_rateupg_mgr.groups);
|
||||
g_rateupg_mgr.iniconf = h;
|
||||
|
||||
fst_get_config_string(FST_CONFIG_SENSITIVITY_LEVEL_KEY_NAME,
|
||||
FST_CONFIG_SENSITIVITY_LEVEL, buf, sizeof(buf));
|
||||
g_rateupg_mgr.sensitivity_level = strtoul(buf, NULL, 0);
|
||||
|
||||
switch (g_rateupg_mgr.sensitivity_level) {
|
||||
case WMI_FST_SWITCH_SENSITIVITY_LOW:
|
||||
g_rateupg_mgr.tpoll_interval = 200;
|
||||
g_rateupg_mgr.tpoll_alpha = 20;
|
||||
break;
|
||||
case WMI_FST_SWITCH_SENSITIVITY_MED:
|
||||
g_rateupg_mgr.tpoll_interval = 100;
|
||||
g_rateupg_mgr.tpoll_alpha = 40;
|
||||
break;
|
||||
case WMI_FST_SWITCH_SENSITIVITY_HIGH:
|
||||
g_rateupg_mgr.tpoll_interval = 50;
|
||||
g_rateupg_mgr.tpoll_alpha = 50;
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
fst_get_config_string(FST_CONFIG_ENTRY_MCS_KEY_NAME,
|
||||
FST_CONFIG_ENTRY_MCS, buf, sizeof(buf));
|
||||
g_rateupg_mgr.entryMCS = strtoul(buf, NULL, 0);
|
||||
if (g_rateupg_mgr.entryMCS < 0 || g_rateupg_mgr.entryMCS > FST_MAX_MCS)
|
||||
return -1;
|
||||
|
||||
fst_get_config_string(FST_CONFIG_EXIT_MCS_KEY_NAME,
|
||||
FST_CONFIG_EXIT_MCS, buf, sizeof(buf));
|
||||
g_rateupg_mgr.exitMCS = strtoul(buf, NULL, 0);
|
||||
if (g_rateupg_mgr.exitMCS < 0 || g_rateupg_mgr.exitMCS > FST_MAX_MCS)
|
||||
return -1;
|
||||
if (g_rateupg_mgr.entryMCS <= g_rateupg_mgr.exitMCS)
|
||||
return -1;
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "sensitivity_level %d entry/exit MCS %d/%d",
|
||||
g_rateupg_mgr.sensitivity_level, g_rateupg_mgr.entryMCS, g_rateupg_mgr.exitMCS);
|
||||
|
||||
res = fst_tpoll_init(g_rateupg_mgr.tpoll_interval, g_rateupg_mgr.tpoll_alpha);
|
||||
if (res)
|
||||
return res;
|
||||
|
||||
g_rateupg_mgr_initialized = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fst_rate_upgrade_deinit()
|
||||
{
|
||||
if (g_rateupg_mgr_initialized) {
|
||||
while (!dl_list_empty(&g_rateupg_mgr.groups)) {
|
||||
struct rate_upgrade_group *g = dl_list_first(&g_rateupg_mgr.groups,
|
||||
struct rate_upgrade_group, lentry);
|
||||
deinit_rate_upgrade_group(g);
|
||||
}
|
||||
g_rateupg_mgr_initialized = 0;
|
||||
}
|
||||
|
||||
fst_tpoll_deinit();
|
||||
}
|
||||
|
||||
int fst_rate_upgrade_add_group(const struct fst_group_info *group)
|
||||
{
|
||||
struct rate_upgrade_group *g;
|
||||
struct fst_iface_info *ifaces;
|
||||
int i;
|
||||
char *master = NULL;
|
||||
char *acl_fname = NULL;
|
||||
char ctrl_iface_dir[256];
|
||||
int ctrl_iface_dir_len;
|
||||
|
||||
if (find_rate_upgrade_group(group->id)) {
|
||||
fst_mgr_printf(MSG_WARNING, "Group %s already added", group->id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
master = fst_ini_config_get_rate_upgrade_master(
|
||||
g_rateupg_mgr.iniconf, group->id);
|
||||
if (!master)
|
||||
return 0;
|
||||
|
||||
if (!fst_is_supplicant()) {
|
||||
acl_fname = fst_ini_config_get_rate_upgrade_acl_fname(
|
||||
g_rateupg_mgr.iniconf, group->id);
|
||||
if (acl_fname != NULL)
|
||||
fst_mgr_printf(MSG_INFO, "Using ACL file %s", acl_fname);
|
||||
}
|
||||
|
||||
g = malloc(sizeof(struct rate_upgrade_group));
|
||||
if (!g) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot alloc group %s",
|
||||
group->id);
|
||||
goto error_group;
|
||||
}
|
||||
|
||||
memset(g, 0, sizeof(struct rate_upgrade_group));
|
||||
g->master = master;
|
||||
g->groupname = strdup(group->id);
|
||||
if (g->groupname == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot alloc groupname %s",
|
||||
group->id);
|
||||
goto error_groupname;
|
||||
}
|
||||
g->slave_cnt = fst_ini_config_get_group_slave_ifaces(
|
||||
g_rateupg_mgr.iniconf, group, master, &ifaces);
|
||||
if (g->slave_cnt < 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot add group %s", group->id);
|
||||
goto error_get_slave;
|
||||
}
|
||||
else if (g->slave_cnt == 0) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"No slave ifaces found in group %s", group->id);
|
||||
goto error_get_slave;
|
||||
}
|
||||
g->slaves = ifaces;
|
||||
dl_list_init(&g->acl_macs);
|
||||
g->acl_fname = acl_fname;
|
||||
|
||||
if (update_acl_file(g)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot update ACL file");
|
||||
goto error_acl_file;
|
||||
}
|
||||
|
||||
ctrl_iface_dir_len = fst_ini_config_get_slave_ctrl_interface(
|
||||
g_rateupg_mgr.iniconf, ctrl_iface_dir, sizeof(ctrl_iface_dir));
|
||||
for (i = 0; i < g->slave_cnt; i++) {
|
||||
if (ifaces[i].manual_enslave)
|
||||
continue;
|
||||
|
||||
if (fst_add_iface(master, &ifaces[i], g->acl_fname,
|
||||
(ctrl_iface_dir_len > 0) ? ctrl_iface_dir : NULL)) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"Cannot add slave interface %s", ifaces[i].name);
|
||||
goto error_add;
|
||||
}
|
||||
}
|
||||
|
||||
dl_list_add_tail(&g_rateupg_mgr.groups, &g->lentry);
|
||||
|
||||
return 0;
|
||||
|
||||
error_add:
|
||||
while(i-- > 0)
|
||||
fst_del_iface(&ifaces[i]);
|
||||
error_acl_file:
|
||||
free(ifaces);
|
||||
error_get_slave:
|
||||
free(g->groupname);
|
||||
error_groupname:
|
||||
free(g);
|
||||
error_group:
|
||||
free(acl_fname);
|
||||
free(master);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fst_rate_upgrade_del_group(const struct fst_group_info *group)
|
||||
{
|
||||
struct rate_upgrade_group *g;
|
||||
int i;
|
||||
|
||||
g = find_rate_upgrade_group(group->id);
|
||||
if (g == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR, "No group exists %s", group->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < g->slave_cnt; i++) {
|
||||
if (fst_del_iface(&g->slaves[i])) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot delete iface %s",
|
||||
g->slaves[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
deinit_rate_upgrade_group(g);
|
||||
return 0;
|
||||
}
|
||||
static int fst_dup_connection_sta(struct rate_upgrade_group *g,
|
||||
const char *iface, const u8* addr)
|
||||
{
|
||||
int i;
|
||||
char *str_mbies = NULL;
|
||||
int str_mbies_size;
|
||||
int mbies_size;
|
||||
u8 *mbies = NULL, *mbies_iter;
|
||||
|
||||
str_mbies_size = fst_get_peer_mbies(iface, addr, &str_mbies);
|
||||
if (str_mbies_size < 2 || str_mbies_size & 1) {
|
||||
fst_mgr_printf(MSG_INFO, "invalid mbies size %d",
|
||||
str_mbies_size);
|
||||
for (i = 0; i < g->slave_cnt; i++) {
|
||||
if (fst_dup_connection(&g->slaves[i], g->master, addr, 0,
|
||||
g->acl_fname)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot connect iface %s",
|
||||
g->slaves[i].name);
|
||||
goto error_connect;
|
||||
}
|
||||
}
|
||||
os_free(str_mbies);
|
||||
return 0;
|
||||
}
|
||||
|
||||
mbies_size = str_mbies_size / 2;
|
||||
mbies = os_malloc(mbies_size);
|
||||
if (!mbies) {
|
||||
fst_mgr_printf(MSG_ERROR, "mbies allocation failed");
|
||||
goto error_mbie;
|
||||
}
|
||||
if (hexstr2bin(str_mbies, mbies, mbies_size)) {
|
||||
fst_mgr_printf(MSG_ERROR, "failed converting hex mbie to bin");
|
||||
goto error_mbie;
|
||||
}
|
||||
|
||||
/* for each slave duplicate the addresses from all bands */
|
||||
for (i = 0; i < g->slave_cnt; i++) {
|
||||
mbies_iter = mbies;
|
||||
while (mbies_size >= 2) {
|
||||
struct multi_band_ie *mbie = (struct multi_band_ie *) mbies_iter;
|
||||
const u8 *addr_on_other_band;
|
||||
u32 freq = 0;
|
||||
|
||||
if (mbie->eid != WLAN_EID_MULTI_BAND ||
|
||||
(size_t) 2 + mbie->len < sizeof(*mbie))
|
||||
break;
|
||||
|
||||
addr_on_other_band = fst_mgr_get_addr_from_mbie(mbie);
|
||||
if (!addr_on_other_band)
|
||||
continue;
|
||||
|
||||
if (mbie->band_id == MB_BAND_ID_WIFI_60GHZ)
|
||||
freq = 56160 + mbie->chan * 2160;
|
||||
if (fst_dup_connection(&g->slaves[i], g->master,
|
||||
addr_on_other_band, freq,
|
||||
g->acl_fname))
|
||||
goto error_connect;
|
||||
|
||||
mbies_iter += mbie->len + 2;
|
||||
mbies_size -= mbie->len + 2;
|
||||
}
|
||||
}
|
||||
|
||||
g->is_duped = TRUE;
|
||||
|
||||
os_free(str_mbies);
|
||||
os_free(mbies);
|
||||
return 0;
|
||||
|
||||
error_connect:
|
||||
while (i-- > 0)
|
||||
fst_dedup_connection(&g->slaves[i], g->acl_fname);
|
||||
error_mbie:
|
||||
os_free(str_mbies);
|
||||
os_free(mbies);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int fst_dup_connection_ap(struct rate_upgrade_group *g,
|
||||
const u8* addr)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < g->slave_cnt; i++) {
|
||||
if (fst_dup_connection(&g->slaves[i], g->master, addr, 0,
|
||||
g->acl_fname)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot connect iface %s",
|
||||
g->slaves[i].name);
|
||||
goto error_connect;
|
||||
}
|
||||
}
|
||||
|
||||
g->is_duped = TRUE;
|
||||
|
||||
return 0;
|
||||
|
||||
error_connect:
|
||||
while (i-- > 0)
|
||||
fst_dedup_connection(&g->slaves[i], g->acl_fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int
|
||||
fst_rate_upgrade_config_device(struct rate_upgrade_group *g, const u8 *peer, int enabled)
|
||||
{
|
||||
int res = 0, i;
|
||||
|
||||
for (i = 0; i < g->slave_cnt; i++) {
|
||||
char fname[128];
|
||||
FILE *f;
|
||||
|
||||
if (snprintf(fname, sizeof(fname), "/sys/class/net/%s/device/wil6210/fst_config",
|
||||
g->slaves[i].name) < 0) {
|
||||
res = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
f = fopen(fname, "w");
|
||||
if (!f) {
|
||||
fst_mgr_printf(MSG_ERROR, "failed to open: %s", fname);
|
||||
res = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* <ap_bssid> <enabled> <entry_mcs> <exit_mcs> <sensitivity_level> */
|
||||
if (fprintf(f, MACSTR " %d %d %d %d\n", MAC2STR(peer), enabled, g_rateupg_mgr.entryMCS,
|
||||
g_rateupg_mgr.exitMCS, g_rateupg_mgr.sensitivity_level) < 0) {
|
||||
res = -1;
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
out:
|
||||
if (res < 0)
|
||||
fst_mgr_printf(MSG_WARNING, "failed to set fst config %s",
|
||||
enabled ? "On" : "Off");
|
||||
else
|
||||
fst_mgr_printf(MSG_INFO, "fst config %s for peer " MACSTR,
|
||||
enabled ? "enabled" : "disabled",
|
||||
MAC2STR(peer));
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int fst_rate_upgrade_on_connect(const struct fst_group_info *group,
|
||||
const char *iface, const u8* addr)
|
||||
{
|
||||
int res;
|
||||
struct rate_upgrade_group *g;
|
||||
struct rate_upgrade_mac *p;
|
||||
|
||||
g = find_rate_upgrade_group(group->id);
|
||||
if (!g)
|
||||
return 0;
|
||||
|
||||
if (os_strcmp(iface, g->master)) {
|
||||
/* slave iface connect - trigger link monitoring */
|
||||
res = fst_signal_monitor(iface, FST_SIGNAL_MONITOR_DEFAULT_RSSI, FST_SIGNAL_MONITOR_DEFAULT_HYST);
|
||||
if (res) {
|
||||
fst_mgr_printf(MSG_ERROR, "setting signal monitor failed on iface %s", iface);
|
||||
/* continue without signal monitor */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* else - master iface connect */
|
||||
|
||||
if (find_rate_upgrade_mac(g, addr)) {
|
||||
fst_mgr_printf(MSG_WARNING, "MAC " MACSTR
|
||||
" is already connected", MAC2STR(addr));
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = add_rate_upgrade_mac(g, addr);
|
||||
if (!p) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot add MAC " MACSTR,
|
||||
MAC2STR(addr));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (update_acl_file(g)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot update ACL file");
|
||||
goto error_acl_file;
|
||||
}
|
||||
|
||||
if (fst_is_supplicant()) {
|
||||
res = fst_rate_upgrade_config_device(g, addr, TRUE);
|
||||
if (res)
|
||||
goto error_acl_file;
|
||||
|
||||
/* for STA start traffic poller. dup connection takes place
|
||||
* upon high tput on master.
|
||||
*/
|
||||
res = fst_tpoll_start(group);
|
||||
} else {
|
||||
res = fst_dup_connection_ap(g, addr);
|
||||
}
|
||||
|
||||
if (!res)
|
||||
return res;
|
||||
|
||||
error_acl_file:
|
||||
fst_rate_upgrade_config_device(g, addr, FALSE);
|
||||
fst_tpoll_stop();
|
||||
del_rate_upgrade_mac(p);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int fst_rate_upgrade_on_disconnect(const struct fst_group_info *group,
|
||||
const char *iface, const u8* addr)
|
||||
{
|
||||
int i, res = 0;
|
||||
struct rate_upgrade_group *g;
|
||||
struct rate_upgrade_mac *p;
|
||||
|
||||
g = find_rate_upgrade_group(group->id);
|
||||
if (!g)
|
||||
return 0;
|
||||
|
||||
if (os_strcmp(iface, g->master)) {
|
||||
/* slave iface disconnect - flush BSS cache to prevent supplicant
|
||||
* from trying to reconnect due to cached scan result which leads
|
||||
* to temp-disable situation.
|
||||
*/
|
||||
fst_ctrl_bss_flush(iface);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* else - master iface disconnect */
|
||||
|
||||
p = find_rate_upgrade_mac(g, addr);
|
||||
if (!p) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot find master peer");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fst_rate_upgrade_config_device(g, addr, FALSE);
|
||||
fst_tpoll_stop();
|
||||
|
||||
del_rate_upgrade_mac(p);
|
||||
|
||||
if (update_acl_file(g)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot update ACL file");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < g->slave_cnt; i++) {
|
||||
if (fst_dedup_connection(&g->slaves[i], g->acl_fname)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot disconnect iface %s",
|
||||
g->slaves[i].name);
|
||||
res = -1;
|
||||
}
|
||||
}
|
||||
|
||||
g->is_duped = FALSE;
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
void fst_rate_upgrade_on_release(const struct fst_group_info *group,
|
||||
const char *iface)
|
||||
{
|
||||
int i;
|
||||
struct rate_upgrade_group *g = find_rate_upgrade_group(group->id);
|
||||
|
||||
if (!g)
|
||||
return;
|
||||
|
||||
for (i = 0; i < g->slave_cnt; i++) {
|
||||
if (os_strcmp(g->slaves[i].name, iface))
|
||||
continue;
|
||||
|
||||
if (fst_dedup_connection(&g->slaves[i], g->acl_fname))
|
||||
fst_mgr_printf(MSG_ERROR, "failed to disconnect iface %s", g->slaves[i].name);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
g->is_duped = FALSE;
|
||||
}
|
||||
|
||||
void fst_rate_upgrade_on_switch_completed(const struct fst_group_info *group,
|
||||
const char *old_iface, const char *new_iface, const u8* old_peer_addr)
|
||||
{
|
||||
struct rate_upgrade_group *g;
|
||||
int ret;
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "%s=>%s, old peer address " MACSTR,
|
||||
old_iface, new_iface, MAC2STR(old_peer_addr));
|
||||
|
||||
if (fst_is_supplicant())
|
||||
/* do nothing for STA mode */
|
||||
return;
|
||||
|
||||
g = find_rate_upgrade_group(group->id);
|
||||
if (!g) {
|
||||
fst_mgr_printf(MSG_INFO, "%s is not a rate upgrade group", group->id);
|
||||
return;
|
||||
}
|
||||
|
||||
if (os_strcmp(old_iface, g->master) == 0) {
|
||||
fst_mgr_printf(MSG_INFO, "switching from master, do nothing");
|
||||
return;
|
||||
}
|
||||
|
||||
/* old_iface is not master, disconnect from peer */
|
||||
ret = fst_disconnect_peer(old_iface, old_peer_addr);
|
||||
if (ret)
|
||||
fst_mgr_printf(MSG_ERROR, "failed to disconnect peer");
|
||||
}
|
||||
|
||||
void fst_rate_upgrade_rename_interface(const char *gname, const char *ifname, const char *newifname)
|
||||
{
|
||||
struct rate_upgrade_group *g;
|
||||
int i;
|
||||
|
||||
g = find_rate_upgrade_group(gname);
|
||||
if (!g) {
|
||||
fst_mgr_printf(MSG_INFO, "%s is not a rate upgrade group", gname);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!os_strcmp(g->master, ifname))
|
||||
os_strlcpy(g->master, newifname, sizeof(g->master));
|
||||
for (i = 0; i < g->slave_cnt; i++) {
|
||||
if (!os_strcmp(g->slaves[i].name, ifname)) {
|
||||
os_strlcpy(g->slaves[i].name, newifname, sizeof(g->slaves[i].name));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fst_rate_upgrade_high_traffic(const struct fst_group_info *group)
|
||||
{
|
||||
int res;
|
||||
struct rate_upgrade_group *g;
|
||||
struct rate_upgrade_mac *peer;
|
||||
|
||||
g = find_rate_upgrade_group(group->id);
|
||||
if (!g)
|
||||
return;
|
||||
|
||||
if (g->is_duped) {
|
||||
fst_mgr_printf(MSG_INFO, "connection already duplicated, ignore");
|
||||
return;
|
||||
}
|
||||
|
||||
peer = find_rate_upgrade_mac(g, NULL);
|
||||
if (peer == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR, "peer address not found");
|
||||
return;
|
||||
}
|
||||
|
||||
res = fst_dup_connection_sta(g, g->master, peer->addr);
|
||||
if (res) {
|
||||
fst_mgr_printf(MSG_ERROR, "dup connection failed, addr " MACSTR, MAC2STR(peer->addr));
|
||||
}
|
||||
}
|
||||
|
||||
void fst_rate_upgrade_low_traffic(const struct fst_group_info *group)
|
||||
{
|
||||
int i, res;
|
||||
struct rate_upgrade_group *g;
|
||||
struct rate_upgrade_mac *peer;
|
||||
|
||||
g = find_rate_upgrade_group(group->id);
|
||||
if (!g)
|
||||
return;
|
||||
|
||||
if (!g->is_duped) {
|
||||
fst_mgr_printf(MSG_INFO, "connection not duplicated, ignore");
|
||||
return;
|
||||
}
|
||||
|
||||
peer = find_rate_upgrade_mac(g, NULL);
|
||||
if (peer == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR, "peer address not found");
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < g->slave_cnt; i++) {
|
||||
res = fst_manager_session_transfer(g->slaves[i].name, peer->addr);
|
||||
if (res) {
|
||||
fst_mgr_printf(MSG_ERROR, "session transfer failed");
|
||||
}
|
||||
|
||||
if (fst_dedup_connection(&g->slaves[i], g->acl_fname)) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot dedup iface %s", g->slaves[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
g->is_duped = FALSE;
|
||||
}
|
||||
|
||||
void fst_rate_upgrade_on_scan_started(const struct fst_group_info *group,
|
||||
const char *iface)
|
||||
{
|
||||
struct rate_upgrade_group *g;
|
||||
|
||||
g = find_rate_upgrade_group(group->id);
|
||||
if (!g)
|
||||
return;
|
||||
|
||||
if (!os_strcmp(iface, g->master))
|
||||
return;
|
||||
|
||||
/* pause traffic poller upon scan on slave interface */
|
||||
fst_tpoll_pause();
|
||||
}
|
||||
|
||||
void fst_rate_upgrade_on_scan_completed(const struct fst_group_info *group,
|
||||
const char *iface)
|
||||
{
|
||||
struct rate_upgrade_group *g;
|
||||
|
||||
g = find_rate_upgrade_group(group->id);
|
||||
if (!g)
|
||||
return;
|
||||
|
||||
if (!os_strcmp(iface, g->master))
|
||||
return;
|
||||
|
||||
/* resume traffic poller upon scan complete on slave interface */
|
||||
fst_tpoll_resume();
|
||||
}
|
||||
|
||||
void fst_rate_upgrade_on_signal_change(const struct fst_group_info *group,
|
||||
const char *iface)
|
||||
{
|
||||
struct rate_upgrade_group *g;
|
||||
|
||||
g = find_rate_upgrade_group(group->id);
|
||||
if (!g)
|
||||
return;
|
||||
|
||||
if (!os_strcmp(iface, g->master))
|
||||
return;
|
||||
|
||||
/* it is assumed that slave sends this event upon signal low. Trigger session switch to master */
|
||||
fst_rate_upgrade_low_traffic(group);
|
||||
|
||||
/* restart traffic poller so it can re-trigger high traffic callback when needed */
|
||||
fst_tpoll_pause();
|
||||
fst_tpoll_resume();
|
||||
}
|
||||
70
qcom/opensource/fst-manager/fst_rateupg.h
Normal file
70
qcom/opensource/fst-manager/fst_rateupg.h
Normal file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* FST Manager: Rate Upgrade
|
||||
*
|
||||
* Copyright (c) 2015-2016, 2019, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FST_RATEUPG_H__
|
||||
#define __FST_RATEUPG_H__
|
||||
#include "fst_ini_conf.h"
|
||||
|
||||
int fst_rate_upgrade_init(struct fst_ini_config *h);
|
||||
void fst_rate_upgrade_deinit();
|
||||
int fst_rate_upgrade_add_group(const struct fst_group_info *group);
|
||||
int fst_rate_upgrade_del_group(const struct fst_group_info *group);
|
||||
int fst_rate_upgrade_on_connect(const struct fst_group_info *group,
|
||||
const char *iface, const u8* addr);
|
||||
int fst_rate_upgrade_on_disconnect(const struct fst_group_info *group,
|
||||
const char *iface, const u8* addr);
|
||||
/**
|
||||
* fst_rate_upgrade_on_switch_completed - called after successful session
|
||||
* switch. This function will trigger disconnect from peer on old_iface if it's
|
||||
* not the group's master interface
|
||||
*
|
||||
* @group: FST group of the session
|
||||
* @old_iface: interface that we switch from
|
||||
* @new_iface: interface that we switch to
|
||||
* @old_peer_addr: peer's MAC address on old_iface
|
||||
*/
|
||||
void fst_rate_upgrade_on_switch_completed(const struct fst_group_info *group,
|
||||
const char *old_iface, const char *new_iface, const u8* old_peer_addr);
|
||||
|
||||
void fst_rate_upgrade_on_release(const struct fst_group_info *group,
|
||||
const char *iface);
|
||||
void fst_rate_upgrade_rename_interface(const char *gname, const char *ifname, const char *newifname);
|
||||
void fst_rate_upgrade_high_traffic(const struct fst_group_info *group);
|
||||
void fst_rate_upgrade_low_traffic(const struct fst_group_info *group);
|
||||
void fst_rate_upgrade_on_scan_started(const struct fst_group_info *group,
|
||||
const char *iface);
|
||||
void fst_rate_upgrade_on_scan_completed(const struct fst_group_info *group,
|
||||
const char *iface);
|
||||
void fst_rate_upgrade_on_signal_change(const struct fst_group_info *group,
|
||||
const char *iface);
|
||||
|
||||
#endif /* __FST_RATEUPG_H */
|
||||
1090
qcom/opensource/fst-manager/fst_tc.c
Normal file
1090
qcom/opensource/fst-manager/fst_tc.c
Normal file
File diff suppressed because it is too large
Load Diff
59
qcom/opensource/fst-manager/fst_tc.h
Normal file
59
qcom/opensource/fst-manager/fst_tc.h
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* FST TC related routines definitions
|
||||
*
|
||||
* Copyright (c) 2015, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FST_TC_H__
|
||||
#define __FST_TC_H__
|
||||
|
||||
#include "common/defs.h"
|
||||
|
||||
struct fst_tc;
|
||||
|
||||
struct fst_tc * fst_tc_create(Boolean is_sta);
|
||||
int fst_tc_start(struct fst_tc *f, const char *ifname);
|
||||
void fst_tc_stop(struct fst_tc *f);
|
||||
void fst_tc_delete(struct fst_tc *f);
|
||||
|
||||
int fst_tc_register_iface(struct fst_tc *f, const char *ifname);
|
||||
void fst_tc_unregister_iface(struct fst_tc *f, const char *ifname);
|
||||
|
||||
struct fst_tc_filter_handle {
|
||||
u16 prio;
|
||||
char ifname[IFNAMSIZ + 1];
|
||||
struct dl_list filters_lentry;
|
||||
};
|
||||
|
||||
int fst_tc_add_l2da_filter(struct fst_tc *f, const u8 *mac, int queue_id,
|
||||
const char *ifname, struct fst_tc_filter_handle *filter_handle);
|
||||
int fst_tc_del_l2da_filter(struct fst_tc *f,
|
||||
struct fst_tc_filter_handle *filter_handle);
|
||||
|
||||
#endif /* __FST_TC_H__ */
|
||||
293
qcom/opensource/fst-manager/fst_tpoll.c
Normal file
293
qcom/opensource/fst-manager/fst_tpoll.c
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
* FST Manager traffic poller implementation
|
||||
*
|
||||
* Copyright (c) 2019, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "utils/includes.h"
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#define FST_MGR_COMPONENT "TPOLL"
|
||||
#include "fst_manager.h"
|
||||
#include "fst_tpoll.h"
|
||||
#include "fst_cfgmgr.h"
|
||||
#include "fst_rateupg.h"
|
||||
#include "fst_capconfigstore.h"
|
||||
|
||||
#define FST_TPOLL_MIN_SAMPLES 5
|
||||
#define Mbps2Bpms(t) (t * 1000 * 1000 / 1000 / 8)
|
||||
#define OS_RELTIME2MS(t) (t.sec * 1000 + t.usec / 1000)
|
||||
|
||||
static const char FST_TPOLL_LOW_THRESH_KEY_NAME[] = "fst.tpoll.low.thresh.mbps";
|
||||
#define FST_TPOLL_LOW_TRAFFIC_THRESH "10"
|
||||
static const char FST_TPOLL_HIGH_THRESH_KEY_NAME[] = "fst.tpoll.high.thresh.mbps";
|
||||
#define FST_TPOLL_HIGH_TRAFFIC_THRESH "40"
|
||||
|
||||
enum fst_tpoll_state {
|
||||
FST_TPOLL_STATE_DETECTED_NONE,
|
||||
FST_TPOLL_STATE_DETECTED_HIGH,
|
||||
FST_TPOLL_STATE_DETECTED_LOW,
|
||||
};
|
||||
|
||||
struct fst_tpoll
|
||||
{
|
||||
const struct fst_group_info *group;
|
||||
char mux_ifname[IFNAMSIZ + 1];
|
||||
int interval_ms;
|
||||
int alpha;
|
||||
int low_thresh_Bpms;
|
||||
int high_thresh_Bpms;
|
||||
|
||||
enum fst_tpoll_state state;
|
||||
|
||||
struct os_reltime prev_sample_time;
|
||||
unsigned long long prev_total_bytes;
|
||||
int prev_avg; /* bytes/ms */
|
||||
size_t num_samples;
|
||||
};
|
||||
|
||||
static struct fst_tpoll g_fst_tpoll;
|
||||
|
||||
static int fst_tpoll_read_bytes(unsigned long long *total_bytes)
|
||||
{
|
||||
char fname[128];
|
||||
FILE *f;
|
||||
unsigned long long rx_bytes, tx_bytes;
|
||||
int res = -1;
|
||||
|
||||
if (snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/rx_bytes", g_fst_tpoll.mux_ifname) < 0)
|
||||
return -1;
|
||||
|
||||
f = fopen(fname, "r");
|
||||
if (!f) {
|
||||
fst_mgr_printf(MSG_ERROR, "failed to open %s", fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fscanf(f, "%llu", &rx_bytes) != 1) {
|
||||
fst_mgr_printf(MSG_ERROR, "failed to read %s", fname);
|
||||
goto out;
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
|
||||
if (snprintf(fname, sizeof(fname), "/sys/class/net/%s/statistics/tx_bytes", g_fst_tpoll.mux_ifname) < 0)
|
||||
return -1;
|
||||
|
||||
f = fopen(fname, "r");
|
||||
if (!f) {
|
||||
fst_mgr_printf(MSG_ERROR, "failed to open %s", fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fscanf(f, "%llu", &tx_bytes) != 1) {
|
||||
fst_mgr_printf(MSG_ERROR, "failed to read %s", fname);
|
||||
goto out;
|
||||
}
|
||||
|
||||
*total_bytes = rx_bytes + tx_bytes;
|
||||
res = 0;
|
||||
|
||||
out:
|
||||
fclose(f);
|
||||
return res;
|
||||
}
|
||||
|
||||
static void fst_tpoll_timer(void *eloop_ctx, void *timeout_ctx)
|
||||
{
|
||||
unsigned long long total_bytes;
|
||||
int res, tput, new_avg = g_fst_tpoll.prev_avg;
|
||||
Boolean detected_high = FALSE, detected_low = FALSE;
|
||||
|
||||
res = fst_tpoll_read_bytes(&total_bytes);
|
||||
if (res)
|
||||
goto out;
|
||||
|
||||
if (total_bytes < g_fst_tpoll.prev_total_bytes) {
|
||||
fst_mgr_printf(MSG_WARNING, "invalid sample, total_bytes (%llu) < prev_total_bytes (%llu)", total_bytes, g_fst_tpoll.prev_total_bytes);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (g_fst_tpoll.num_samples > 0) {
|
||||
struct os_reltime age;
|
||||
|
||||
os_reltime_age(&g_fst_tpoll.prev_sample_time, &age);
|
||||
/* bytes/ms */
|
||||
tput = (total_bytes - g_fst_tpoll.prev_total_bytes) / OS_RELTIME2MS(age);
|
||||
} else {
|
||||
/* in 1st sample, "prev" fields are uninitialized */
|
||||
tput = 0;
|
||||
}
|
||||
|
||||
/* Exponential Filtering */
|
||||
new_avg = (g_fst_tpoll.alpha * tput + (100 - g_fst_tpoll.alpha) * g_fst_tpoll.prev_avg) / 100;
|
||||
|
||||
|
||||
if (++g_fst_tpoll.num_samples < FST_TPOLL_MIN_SAMPLES) {
|
||||
/* not enough samples to make decisions */
|
||||
goto out;
|
||||
}
|
||||
|
||||
switch (g_fst_tpoll.state) {
|
||||
case FST_TPOLL_STATE_DETECTED_NONE:
|
||||
if (new_avg > g_fst_tpoll.high_thresh_Bpms)
|
||||
detected_high = TRUE;
|
||||
else if (new_avg < g_fst_tpoll.low_thresh_Bpms)
|
||||
detected_low = TRUE;
|
||||
break;
|
||||
case FST_TPOLL_STATE_DETECTED_HIGH:
|
||||
if (new_avg < g_fst_tpoll.low_thresh_Bpms)
|
||||
detected_low = TRUE;
|
||||
break;
|
||||
case FST_TPOLL_STATE_DETECTED_LOW:
|
||||
if (new_avg > g_fst_tpoll.high_thresh_Bpms)
|
||||
detected_high = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
if (detected_high) {
|
||||
fst_mgr_printf(MSG_INFO, "detected high traffic, bytes %llu => %llu, tput %d, avg %d => %d",
|
||||
g_fst_tpoll.prev_total_bytes, total_bytes, tput * 8 / 1000,
|
||||
g_fst_tpoll.prev_avg * 8 / 1000, new_avg * 8 / 1000);
|
||||
fst_rate_upgrade_high_traffic(g_fst_tpoll.group);
|
||||
g_fst_tpoll.state = FST_TPOLL_STATE_DETECTED_HIGH;
|
||||
} else if (detected_low) {
|
||||
fst_mgr_printf(MSG_INFO, "detected low traffic, bytes %llu => %llu, tput %d, avg %d => %d",
|
||||
g_fst_tpoll.prev_total_bytes, total_bytes, tput * 8 / 1000,
|
||||
g_fst_tpoll.prev_avg * 8 / 1000, new_avg * 8 / 1000);
|
||||
fst_rate_upgrade_low_traffic(g_fst_tpoll.group);
|
||||
g_fst_tpoll.state = FST_TPOLL_STATE_DETECTED_LOW;
|
||||
}
|
||||
|
||||
out:
|
||||
os_get_reltime(&g_fst_tpoll.prev_sample_time);
|
||||
g_fst_tpoll.prev_total_bytes = total_bytes;
|
||||
g_fst_tpoll.prev_avg = new_avg;
|
||||
eloop_register_timeout(0, g_fst_tpoll.interval_ms * 1000, fst_tpoll_timer, NULL, NULL);
|
||||
}
|
||||
|
||||
int fst_tpoll_start(const struct fst_group_info *group)
|
||||
{
|
||||
int len;
|
||||
|
||||
if (g_fst_tpoll.group != NULL) {
|
||||
fst_mgr_printf(MSG_ERROR, "tpoll already started for group %s", g_fst_tpoll.group->id);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len = fst_cfgmgr_get_mux_ifname(group->id, g_fst_tpoll.mux_ifname, sizeof(g_fst_tpoll.mux_ifname)-1);
|
||||
if (len == 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "Cannot get mux ifname");
|
||||
return -1;
|
||||
}
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "starting");
|
||||
|
||||
g_fst_tpoll.group = group;
|
||||
g_fst_tpoll.num_samples = 0;
|
||||
g_fst_tpoll.state = FST_TPOLL_STATE_DETECTED_NONE;
|
||||
g_fst_tpoll.prev_sample_time.sec = g_fst_tpoll.prev_sample_time.usec = 0;
|
||||
g_fst_tpoll.prev_total_bytes = 0;
|
||||
g_fst_tpoll.prev_avg = 0;
|
||||
|
||||
eloop_register_timeout(0, 0, fst_tpoll_timer, NULL, NULL);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fst_tpoll_stop()
|
||||
{
|
||||
fst_mgr_printf(MSG_INFO, "stopping");
|
||||
|
||||
g_fst_tpoll.group = NULL;
|
||||
eloop_cancel_timeout(fst_tpoll_timer, NULL, NULL);
|
||||
}
|
||||
|
||||
void fst_tpoll_pause()
|
||||
{
|
||||
if (g_fst_tpoll.group == NULL)
|
||||
return;
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "pausing");
|
||||
|
||||
eloop_cancel_timeout(fst_tpoll_timer, NULL, NULL);
|
||||
}
|
||||
|
||||
void fst_tpoll_resume()
|
||||
{
|
||||
if (g_fst_tpoll.group == NULL)
|
||||
return;
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "resuming");
|
||||
|
||||
g_fst_tpoll.num_samples = 0;
|
||||
g_fst_tpoll.state = FST_TPOLL_STATE_DETECTED_NONE;
|
||||
g_fst_tpoll.prev_sample_time.sec = g_fst_tpoll.prev_sample_time.usec = 0;
|
||||
g_fst_tpoll.prev_total_bytes = 0;
|
||||
g_fst_tpoll.prev_avg = 0;
|
||||
|
||||
eloop_register_timeout(0, 0, fst_tpoll_timer, NULL, NULL);
|
||||
}
|
||||
|
||||
int fst_tpoll_init(int interval, int alpha)
|
||||
{
|
||||
char buf[64] = { '\0' };
|
||||
|
||||
os_memset(&g_fst_tpoll, 0, sizeof(g_fst_tpoll));
|
||||
|
||||
g_fst_tpoll.interval_ms = interval;
|
||||
if (g_fst_tpoll.interval_ms <= 0)
|
||||
return -1;
|
||||
|
||||
g_fst_tpoll.alpha = alpha;
|
||||
if (g_fst_tpoll.alpha <= 0 || g_fst_tpoll.alpha > 100)
|
||||
return -1;
|
||||
|
||||
fst_get_config_string(FST_TPOLL_LOW_THRESH_KEY_NAME,
|
||||
FST_TPOLL_LOW_TRAFFIC_THRESH, buf, sizeof(buf));
|
||||
g_fst_tpoll.low_thresh_Bpms = Mbps2Bpms(strtoul(buf, NULL, 0));
|
||||
if (g_fst_tpoll.low_thresh_Bpms <= 0)
|
||||
return -1;
|
||||
|
||||
fst_get_config_string(FST_TPOLL_HIGH_THRESH_KEY_NAME,
|
||||
FST_TPOLL_HIGH_TRAFFIC_THRESH, buf, sizeof(buf));
|
||||
g_fst_tpoll.high_thresh_Bpms = Mbps2Bpms(strtoul(buf, NULL, 0));
|
||||
if (g_fst_tpoll.high_thresh_Bpms <= g_fst_tpoll.low_thresh_Bpms)
|
||||
return -1;
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "interval %d, alpha %d, thresh (Bpms) low %d high %d",
|
||||
g_fst_tpoll.interval_ms, g_fst_tpoll.alpha, g_fst_tpoll.low_thresh_Bpms, g_fst_tpoll.high_thresh_Bpms);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fst_tpoll_deinit()
|
||||
{
|
||||
eloop_cancel_timeout(fst_tpoll_timer, NULL, NULL);
|
||||
}
|
||||
45
qcom/opensource/fst-manager/fst_tpoll.h
Normal file
45
qcom/opensource/fst-manager/fst_tpoll.h
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* FST Manager traffic poller interface definitions
|
||||
*
|
||||
* Copyright (c) 2019, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FST_TPOLL_H__
|
||||
#define __FST_TPOLL_H__
|
||||
|
||||
#include "fst_ctrl.h"
|
||||
|
||||
int fst_tpoll_init(int interval, int alpha);
|
||||
void fst_tpoll_deinit();
|
||||
int fst_tpoll_start(const struct fst_group_info *group);
|
||||
void fst_tpoll_stop();
|
||||
void fst_tpoll_pause();
|
||||
void fst_tpoll_resume();
|
||||
|
||||
#endif /* __FST_TPOLL_H__ */
|
||||
24
qcom/opensource/fst-manager/fstman.ini
Normal file
24
qcom/opensource/fst-manager/fstman.ini
Normal file
@@ -0,0 +1,24 @@
|
||||
[fst_manager]
|
||||
ctrl_iface=/data/vendor/wifi/hostapd/global
|
||||
groups=bond0
|
||||
|
||||
[bond0]
|
||||
interfaces=wlan0,wigig0
|
||||
mux_type=bonding
|
||||
mux_ifname=bond0
|
||||
mux_managed=1
|
||||
mac_address_by=wlan0
|
||||
rate_upgrade_master=wlan0
|
||||
txqueuelen=100
|
||||
rate_upgrade_acl_file=/data/vendor/wifi/fst_rate_upgrade.accept
|
||||
|
||||
[wlan0]
|
||||
priority=100
|
||||
default_llt=3600
|
||||
|
||||
[wigig0]
|
||||
priority=110
|
||||
wpa_group=GCMP
|
||||
wpa_pairwise=GCMP
|
||||
hw_mode=ad
|
||||
channel=2
|
||||
325
qcom/opensource/fst-manager/hidl/FstGroup.cpp
Normal file
325
qcom/opensource/fst-manager/hidl/FstGroup.cpp
Normal file
@@ -0,0 +1,325 @@
|
||||
/*
|
||||
* hidl interface for fst manager
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
|
||||
*
|
||||
* 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
#include "hidl_manager.h"
|
||||
#include "hidl_return_util.h"
|
||||
#include "FstGroup.h"
|
||||
|
||||
#define FST_MGR_COMPONENT "HIDL"
|
||||
#include "fst_manager.h"
|
||||
#include "fst_cfgmgr.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "utils/eloop.h"
|
||||
}
|
||||
|
||||
namespace vendor {
|
||||
namespace qti {
|
||||
namespace hardware {
|
||||
namespace fstman {
|
||||
namespace V1_0 {
|
||||
namespace implementation {
|
||||
using hidl_return_util::validateAndCall;
|
||||
|
||||
using namespace vendor::qti::hardware::fstman::V1_0;
|
||||
using V1_0::IFstGroupCallback;
|
||||
|
||||
FstGroup::FstGroup(const char groupName[])
|
||||
: groupName_(groupName), is_valid_(true)
|
||||
{}
|
||||
|
||||
void FstGroup::invalidate() { is_valid_ = false; }
|
||||
bool FstGroup::isValid()
|
||||
{
|
||||
return is_valid_;
|
||||
}
|
||||
|
||||
Return<void> FstGroup::getName(getName_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstGroup::getNameInternal, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<void> FstGroup::registerCallback(
|
||||
const sp<IFstGroupCallback> &callback,
|
||||
registerCallback_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstGroup::registerCallbackInternal, _hidl_cb, callback);
|
||||
}
|
||||
|
||||
Return<void> FstGroup::listInterfaces(listInterfaces_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstGroup::listInterfacesInternal, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<void> FstGroup::isFstModeSupported(isFstModeSupported_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstGroup::isFstModeSupportedInternal, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<void> FstGroup::isWifiSonModeSupported(
|
||||
isWifiSonModeSupported_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstGroup::isWifiSonModeSupportedInternal, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<void> FstGroup::getMuxInterfaceName(
|
||||
getMuxInterfaceName_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstGroup::getMuxInterfaceNameInternal, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<void> FstGroup::setMuxInterfaceName(
|
||||
const hidl_string& name, setMuxInterfaceName_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstGroup::setMuxInterfaceNameInternal, _hidl_cb, name);
|
||||
}
|
||||
|
||||
Return<void> FstGroup::enslave(
|
||||
const hidl_string& ifname, bool enslave,
|
||||
enslave_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstGroup::enslaveInternal, _hidl_cb, ifname, enslave);
|
||||
}
|
||||
|
||||
Return<void> FstGroup::isEnslaved(
|
||||
const hidl_string& ifname, isEnslaved_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstGroup::isEnslavedInternal, _hidl_cb, ifname);
|
||||
}
|
||||
|
||||
Return<void> FstGroup::setMacAddress(
|
||||
const hidl_array<uint8_t, 6>& mac,
|
||||
setMacAddress_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstGroup::setMacAddressInternal, _hidl_cb, mac);
|
||||
}
|
||||
|
||||
Return<void> FstGroup::isRateUpgradeMaster(
|
||||
const hidl_string& ifname, isRateUpgradeMaster_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstGroup::isRateUpgradeMasterInternal, _hidl_cb, ifname);
|
||||
}
|
||||
|
||||
Return<void> FstGroup::renameInterface(const hidl_string& ifname,
|
||||
const hidl_string& newifname,
|
||||
renameInterface_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstGroup::renameInterfaceInternal, _hidl_cb, ifname, newifname);
|
||||
}
|
||||
|
||||
std::pair<FstManagerStatus, std::string> FstGroup::getNameInternal()
|
||||
{
|
||||
return {{FstManagerStatusCode::SUCCESS, ""}, groupName_};
|
||||
}
|
||||
|
||||
FstManagerStatus FstGroup::registerCallbackInternal(
|
||||
const sp<IFstGroupCallback> &callback)
|
||||
{
|
||||
HidlManager *hidl_manager = HidlManager::getInstance();
|
||||
if (!hidl_manager ||
|
||||
hidl_manager->addFstGroupCallbackHidlObject(groupName_, callback)) {
|
||||
return {FstManagerStatusCode::FAILURE_UNKNOWN, ""};
|
||||
}
|
||||
return {FstManagerStatusCode::SUCCESS, ""};
|
||||
}
|
||||
|
||||
std::pair<FstManagerStatus, std::vector<hidl_string>>
|
||||
FstGroup::listInterfacesInternal()
|
||||
{
|
||||
std::vector<hidl_string> ifaceNames;
|
||||
struct fst_group_info gi = {0};
|
||||
struct fst_iface_info *ifaces = NULL;
|
||||
int nof_ifaces, i;
|
||||
|
||||
os_strlcpy(gi.id, groupName_.c_str(), sizeof(gi.id));
|
||||
|
||||
nof_ifaces = fst_cfgmgr_get_group_ifaces(&gi, &ifaces);
|
||||
if (nof_ifaces < 0)
|
||||
goto finish;
|
||||
|
||||
for (i = 0; i < nof_ifaces; i++)
|
||||
ifaceNames.emplace_back(ifaces[i].name);
|
||||
finish:
|
||||
fst_free(ifaces);
|
||||
return {{FstManagerStatusCode::SUCCESS, ""}, std::move(ifaceNames)};
|
||||
}
|
||||
|
||||
std::pair<FstManagerStatus, bool> FstGroup::isFstModeSupportedInternal()
|
||||
{
|
||||
return {{FstManagerStatusCode::SUCCESS, ""}, true};
|
||||
}
|
||||
|
||||
std::pair<FstManagerStatus, bool> FstGroup::isWifiSonModeSupportedInternal()
|
||||
{
|
||||
return {{FstManagerStatusCode::SUCCESS, ""}, false};
|
||||
}
|
||||
|
||||
std::pair<FstManagerStatus, std::string>
|
||||
FstGroup::getMuxInterfaceNameInternal()
|
||||
{
|
||||
char buf[IFNAMSIZ + 1];
|
||||
FstManagerStatus status = {FstManagerStatusCode::SUCCESS, ""};
|
||||
int res;
|
||||
std::string muxIfname;
|
||||
|
||||
res = fst_cfgmgr_get_mux_ifname(groupName_.c_str(), buf, sizeof(buf));
|
||||
if (res <= 0)
|
||||
status = {FstManagerStatusCode::FAILURE_UNKNOWN, ""};
|
||||
else
|
||||
muxIfname = buf;
|
||||
|
||||
return {status, muxIfname};
|
||||
}
|
||||
|
||||
FstManagerStatus FstGroup::setMuxInterfaceNameInternal(const hidl_string& name)
|
||||
{
|
||||
int res;
|
||||
|
||||
res = fst_manager_set_mux_iface_name(groupName_.c_str(), name.c_str());
|
||||
if (res < 0)
|
||||
return {FstManagerStatusCode::FAILURE_UNKNOWN, ""};
|
||||
|
||||
return {FstManagerStatusCode::SUCCESS, ""};
|
||||
}
|
||||
|
||||
FstManagerStatus FstGroup::enslaveInternal(
|
||||
const hidl_string& ifname, bool enslave)
|
||||
{
|
||||
int res;
|
||||
FstManagerStatus status = {FstManagerStatusCode::SUCCESS, ""};
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "%s interface %s", enslave ? "enslave" : "release",
|
||||
ifname.c_str());
|
||||
|
||||
res = fst_manager_enslave(groupName_.c_str(), ifname.c_str(), enslave ? TRUE : FALSE);
|
||||
if (res)
|
||||
status = {FstManagerStatusCode::FAILURE_UNKNOWN, ""};
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
std::pair<FstManagerStatus, bool> FstGroup::isEnslavedInternal(
|
||||
const hidl_string& ifname)
|
||||
{
|
||||
Boolean isEnslaved = FALSE;
|
||||
FstManagerStatus status = {FstManagerStatusCode::SUCCESS, ""};
|
||||
int res;
|
||||
|
||||
res = fst_manager_is_enslaved(groupName_.c_str(), ifname.c_str(),
|
||||
&isEnslaved);
|
||||
if (res < 0)
|
||||
status = {FstManagerStatusCode::FAILURE_UNKNOWN, ""};
|
||||
|
||||
return {status, (isEnslaved == TRUE)};
|
||||
}
|
||||
|
||||
FstManagerStatus FstGroup::setMacAddressInternal(
|
||||
const hidl_array<uint8_t, 6>& mac)
|
||||
{
|
||||
int res;
|
||||
FstManagerStatus status = {FstManagerStatusCode::SUCCESS, ""};
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "%s new mac address " MACSTR, groupName_.c_str(), MAC2STR(mac.data()));
|
||||
|
||||
res = fst_manager_set_mac_address(groupName_.c_str(), mac.data());
|
||||
if (res)
|
||||
status = {FstManagerStatusCode::FAILURE_UNKNOWN, ""};
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
std::pair<FstManagerStatus, bool> FstGroup::isRateUpgradeMasterInternal(
|
||||
const hidl_string& ifname)
|
||||
{
|
||||
char buf[IFNAMSIZ + 1];
|
||||
FstManagerStatus status = {FstManagerStatusCode::SUCCESS, ""};
|
||||
int res;
|
||||
bool isMaster = false;
|
||||
|
||||
res = fst_cfgmgr_get_rate_upgrade_master(groupName_.c_str(), buf,
|
||||
sizeof(buf));
|
||||
if (res > 0) {
|
||||
isMaster = !strncmp(ifname.c_str(), buf, IFNAMSIZ);
|
||||
} else {
|
||||
status = {FstManagerStatusCode::FAILURE_UNKNOWN, ""};
|
||||
}
|
||||
|
||||
return {status, isMaster};
|
||||
}
|
||||
|
||||
FstManagerStatus FstGroup::renameInterfaceInternal(const hidl_string& ifname,
|
||||
const hidl_string& newifname)
|
||||
{
|
||||
int res;
|
||||
FstManagerStatus status = {FstManagerStatusCode::SUCCESS, ""};
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "rename group %s interface %s to %s ",
|
||||
groupName_.c_str(), ifname.c_str(), newifname.c_str());
|
||||
|
||||
res = fst_manager_rename_group_interface(groupName_.c_str(),
|
||||
ifname.c_str(), newifname.c_str());
|
||||
if (res)
|
||||
status = {FstManagerStatusCode::FAILURE_UNKNOWN, ""};
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace fstman
|
||||
} // namespace hardware
|
||||
} // namespace qti
|
||||
} // namespace vendor
|
||||
148
qcom/opensource/fst-manager/hidl/FstGroup.h
Normal file
148
qcom/opensource/fst-manager/hidl/FstGroup.h
Normal file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* hidl interface for fst manager
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
|
||||
*
|
||||
* 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef FST_MANAGER_HIDL_FST_GROUP_H
|
||||
#define FST_MANAGER_HIDL_FST_GROUP_H
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
#include <android-base/macros.h>
|
||||
|
||||
#include <vendor/qti/hardware/fstman/1.0/IFstGroup.h>
|
||||
#include <vendor/qti/hardware/fstman/1.0/IFstGroupCallback.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "utils/common.h"
|
||||
}
|
||||
|
||||
namespace vendor {
|
||||
namespace qti {
|
||||
namespace hardware {
|
||||
namespace fstman {
|
||||
namespace V1_0 {
|
||||
namespace implementation {
|
||||
using namespace vendor::qti::hardware::fstman::V1_0;
|
||||
using android::hardware::hidl_array;
|
||||
|
||||
/**
|
||||
* Implementation of FstGroup hidl object. Each unique hidl
|
||||
* object is used for control operations on a specific group
|
||||
* controlled by fst-manager.
|
||||
*/
|
||||
class FstGroup : public IFstGroup
|
||||
{
|
||||
public:
|
||||
FstGroup(const char groupName[]);
|
||||
~FstGroup() override = default;
|
||||
// HIDL does not provide a built-in mechanism to let the server
|
||||
// invalidate a HIDL interface object after creation. If any client
|
||||
// process holds onto a reference to the object in their context,
|
||||
// any method calls on that reference will continue to be directed to
|
||||
// the server.
|
||||
// However FstManager HAL needs to control the lifetime of these
|
||||
// objects. So, add a public |invalidate| method to all |FstGroup| and
|
||||
// |FstIface| objects.
|
||||
// This will be used to mark an object invalid when the corresponding
|
||||
// iface or network is removed.
|
||||
// All HIDL method implementations should check if the object is still
|
||||
// marked valid before processing them.
|
||||
void invalidate();
|
||||
bool isValid();
|
||||
|
||||
// Hidl methods exposed.
|
||||
Return<void> getName(getName_cb _hidl_cb) override;
|
||||
Return<void> registerCallback(
|
||||
const sp<IFstGroupCallback>& callback,
|
||||
registerCallback_cb _hidl_cb) override;
|
||||
Return<void> listInterfaces(listInterfaces_cb _hidl_cb) override;
|
||||
Return<void> isFstModeSupported(
|
||||
isFstModeSupported_cb _hidl_cb) override;
|
||||
Return<void> isWifiSonModeSupported(
|
||||
isWifiSonModeSupported_cb _hidl_cb) override;
|
||||
Return<void> getMuxInterfaceName(
|
||||
getMuxInterfaceName_cb _hidl_cb) override;
|
||||
Return<void> setMuxInterfaceName(
|
||||
const hidl_string& name, setMuxInterfaceName_cb _hidl_cb) override;
|
||||
Return<void> enslave(
|
||||
const hidl_string& ifname,
|
||||
bool enslave,
|
||||
enslave_cb _hidl_cb) override;
|
||||
Return<void> isEnslaved(
|
||||
const hidl_string& ifname, isEnslaved_cb _hidl_cb) override;
|
||||
Return<void> setMacAddress(
|
||||
const hidl_array<uint8_t, 6>& mac,
|
||||
setMacAddress_cb _hidl_cb) override;
|
||||
Return<void> isRateUpgradeMaster(
|
||||
const hidl_string& ifname,
|
||||
isRateUpgradeMaster_cb _hidl_cb) override;
|
||||
Return<void> renameInterface(const hidl_string& ifname,
|
||||
const hidl_string& newifname,
|
||||
renameInterface_cb _hidl_cb) override;
|
||||
private:
|
||||
// Corresponding worker functions for the HIDL methods.
|
||||
std::pair<FstManagerStatus, std::string> getNameInternal();
|
||||
FstManagerStatus registerCallbackInternal(
|
||||
const sp<IFstGroupCallback>& callback);
|
||||
std::pair<FstManagerStatus, std::vector<hidl_string>>
|
||||
listInterfacesInternal();
|
||||
std::pair<FstManagerStatus, bool> isFstModeSupportedInternal();
|
||||
std::pair<FstManagerStatus, bool> isWifiSonModeSupportedInternal();
|
||||
std::pair<FstManagerStatus, std::string> getMuxInterfaceNameInternal();
|
||||
FstManagerStatus setMuxInterfaceNameInternal(const hidl_string& name);
|
||||
FstManagerStatus enslaveInternal(
|
||||
const hidl_string& ifname, bool enslave);
|
||||
std::pair<FstManagerStatus, bool> isEnslavedInternal(
|
||||
const hidl_string& ifname);
|
||||
FstManagerStatus setMacAddressInternal(
|
||||
const hidl_array<uint8_t, 6>& mac);
|
||||
std::pair<FstManagerStatus, bool> isRateUpgradeMasterInternal(
|
||||
const hidl_string& ifname);
|
||||
FstManagerStatus renameInterfaceInternal(const hidl_string& ifname,
|
||||
const hidl_string& newifname);
|
||||
|
||||
// Name of the group this hidl object controls
|
||||
const std::string groupName_;
|
||||
bool is_valid_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(FstGroup);
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace fstman
|
||||
} // namespace hardware
|
||||
} // namespace qti
|
||||
} // namespace vendor
|
||||
|
||||
#endif // FST_MANAGER_HIDL_FST_GROUP_H
|
||||
187
qcom/opensource/fst-manager/hidl/FstManager.cpp
Normal file
187
qcom/opensource/fst-manager/hidl/FstManager.cpp
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* hidl interface for fst manager
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
|
||||
*
|
||||
* 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include "hidl_manager.h"
|
||||
#include "hidl_return_util.h"
|
||||
#include "FstManager.h"
|
||||
|
||||
#define FST_MGR_COMPONENT "HIDL"
|
||||
#include "fst_manager.h"
|
||||
#include "fst_cfgmgr.h"
|
||||
#include "fst_ctrl.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "utils/eloop.h"
|
||||
}
|
||||
|
||||
namespace vendor {
|
||||
namespace qti {
|
||||
namespace hardware {
|
||||
namespace fstman {
|
||||
namespace V1_0 {
|
||||
namespace implementation {
|
||||
using hidl_return_util::validateAndCall;
|
||||
|
||||
FstManager::FstManager() {}
|
||||
|
||||
bool FstManager::isValid()
|
||||
{
|
||||
// This top level object cannot be invalidated.
|
||||
return true;
|
||||
}
|
||||
|
||||
Return<void> FstManager::getGroup(
|
||||
const hidl_string& groupName, getGroup_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstManager::getGroupInternal, _hidl_cb, groupName);
|
||||
}
|
||||
|
||||
Return<void> FstManager::listGroups(listGroups_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstManager::listGroupsInternal, _hidl_cb);
|
||||
}
|
||||
|
||||
Return<void> FstManager::setDebugParams(
|
||||
IFstManager::DebugLevel level, bool show_timestamp,
|
||||
setDebugParams_cb _hidl_cb)
|
||||
{
|
||||
return validateAndCall(
|
||||
this, FstManagerStatusCode::FAILURE_UNKNOWN,
|
||||
&FstManager::setDebugParamsInternal, _hidl_cb, level,
|
||||
show_timestamp);
|
||||
}
|
||||
|
||||
Return<IFstManager::DebugLevel> FstManager::getDebugLevel()
|
||||
{
|
||||
// TODO: Add FstManagerStatus in this method return for uniformity with
|
||||
// the other methods in FstManager HIDL interface.
|
||||
return (IFstManager::DebugLevel)wpa_debug_level;
|
||||
}
|
||||
|
||||
Return<bool> FstManager::isDebugShowTimestampEnabled()
|
||||
{
|
||||
// TODO: Add FstManagerStatus in this method return for uniformity with
|
||||
// the other methods in FstManager HIDL interface.
|
||||
return ((wpa_debug_timestamp != 0) ? true : false);
|
||||
}
|
||||
|
||||
Return<void> FstManager::terminate()
|
||||
{
|
||||
fst_mgr_printf(MSG_INFO, "Terminating...");
|
||||
fst_manager_terminate();
|
||||
return Void();
|
||||
}
|
||||
|
||||
std::pair<FstManagerStatus, sp<IFstGroup>>
|
||||
FstManager::getGroupInternal(const hidl_string& groupName)
|
||||
{
|
||||
if (!isGroupExists(groupName.c_str())) {
|
||||
return {{FstManagerStatusCode::FAILURE_GROUP_UNKNOWN, ""},
|
||||
nullptr};
|
||||
}
|
||||
HidlManager* hidl_manager = HidlManager::getInstance();
|
||||
android::sp<IFstGroup> group;
|
||||
if (!hidl_manager ||
|
||||
hidl_manager->getFstGroupHidlObjectByName(
|
||||
groupName, &group)) {
|
||||
return {{FstManagerStatusCode::FAILURE_UNKNOWN, ""}, group};
|
||||
}
|
||||
return {{FstManagerStatusCode::SUCCESS, ""}, group};
|
||||
}
|
||||
|
||||
std::pair<FstManagerStatus, std::vector<hidl_string>>
|
||||
FstManager::listGroupsInternal()
|
||||
{
|
||||
std::vector<hidl_string> groupNames;
|
||||
struct fst_group_info *groups = NULL;
|
||||
int res, nof_groups, i;
|
||||
|
||||
res = fst_cfgmgr_get_groups(&groups);
|
||||
if (res < 0) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
nof_groups = res;
|
||||
for (i = 0; i < nof_groups; i++) {
|
||||
groupNames.emplace_back(groups[i].id);
|
||||
}
|
||||
finish:
|
||||
fst_free(groups);
|
||||
return {{FstManagerStatusCode::SUCCESS, ""}, std::move(groupNames)};
|
||||
}
|
||||
|
||||
FstManagerStatus FstManager::setDebugParamsInternal(
|
||||
IFstManager::DebugLevel level, bool show_timestamp)
|
||||
{
|
||||
wpa_debug_level = static_cast<uint32_t>(level);
|
||||
wpa_debug_timestamp = show_timestamp ? 1 : 0;
|
||||
return {FstManagerStatusCode::SUCCESS, ""};
|
||||
}
|
||||
|
||||
bool FstManager::isGroupExists(const char *groupName)
|
||||
{
|
||||
struct fst_group_info *groups = NULL;
|
||||
int res, nof_groups, i;
|
||||
bool found;
|
||||
|
||||
if (!groupName)
|
||||
return false;
|
||||
|
||||
res = fst_cfgmgr_get_groups(&groups);
|
||||
if (res < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
nof_groups = res;
|
||||
found = false;
|
||||
for (i = 0; i < nof_groups; i++) {
|
||||
if (!strcmp(groupName, groups[i].id)) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
fst_free(groups);
|
||||
return found;
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace fstman
|
||||
} // namespace hardware
|
||||
} // namespace qti
|
||||
} // namespace vendor
|
||||
98
qcom/opensource/fst-manager/hidl/FstManager.h
Normal file
98
qcom/opensource/fst-manager/hidl/FstManager.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* hidl interface for fst manager
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
|
||||
*
|
||||
* 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef FST_MANAGER_HIDL_FSTMANAGER_H
|
||||
#define FST_MANAGER_HIDL_FSTMANAGER_H
|
||||
|
||||
#include <vendor/qti/hardware/fstman/1.0/IFstGroupCallback.h>
|
||||
#include <vendor/qti/hardware/fstman/1.0/IFstManager.h>
|
||||
#include <vendor/qti/hardware/fstman/1.0/types.h>
|
||||
#include <android-base/macros.h>
|
||||
#include <hidl/Status.h>
|
||||
|
||||
namespace vendor {
|
||||
namespace qti {
|
||||
namespace hardware {
|
||||
namespace fstman {
|
||||
namespace V1_0 {
|
||||
namespace implementation {
|
||||
using namespace vendor::qti::hardware::fstman::V1_0;
|
||||
using android::hardware::Return;
|
||||
using android::hardware::Void;
|
||||
using android::hardware::hidl_string;
|
||||
using android::sp;
|
||||
|
||||
/**
|
||||
* Implementation of the fst manager hidl object. This hidl
|
||||
* object is used core for global control operations on
|
||||
* fst manager.
|
||||
*/
|
||||
class FstManager : public V1_0::IFstManager
|
||||
{
|
||||
public:
|
||||
FstManager();
|
||||
~FstManager() override = default;
|
||||
bool isValid();
|
||||
|
||||
// Hidl methods exposed.
|
||||
Return<void> getGroup(
|
||||
const hidl_string& groupName, getGroup_cb _hidl_cb) override;
|
||||
Return<void> listGroups(listGroups_cb _hidl_cb) override;
|
||||
Return<void> setDebugParams(
|
||||
IFstManager::DebugLevel level, bool show_timestamp,
|
||||
setDebugParams_cb _hidl_cb) override;
|
||||
Return<IFstManager::DebugLevel> getDebugLevel() override;
|
||||
Return<bool> isDebugShowTimestampEnabled() override;
|
||||
Return<void> terminate() override;
|
||||
|
||||
private:
|
||||
// Corresponding worker functions for the HIDL methods.
|
||||
std::pair<FstManagerStatus, sp<IFstGroup>> getGroupInternal(
|
||||
const hidl_string& groupName);
|
||||
std::pair<FstManagerStatus, std::vector<hidl_string>>
|
||||
listGroupsInternal();
|
||||
FstManagerStatus setDebugParamsInternal(
|
||||
IFstManager::DebugLevel level, bool show_timestamp);
|
||||
|
||||
bool isGroupExists(const char *groupName);
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(FstManager);
|
||||
};
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace fstman
|
||||
} // namespace hardware
|
||||
} // namespace qti
|
||||
} // namespace vendor
|
||||
|
||||
#endif // FST_MANAGER_HIDL_FSTMANAGER_H
|
||||
145
qcom/opensource/fst-manager/hidl/fst_hidl.cpp
Normal file
145
qcom/opensource/fst-manager/hidl/fst_hidl.cpp
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Implements HIDL communication channel for fst manager
|
||||
*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
|
||||
*
|
||||
* 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
#include <vendor/qti/hardware/fstman/1.0/IFstManager.h>
|
||||
#include <vendor/qti/hardware/fstman/1.0/types.h>
|
||||
#include <hwbinder/IPCThreadState.h>
|
||||
#include <hwbinder/ProcessState.h>
|
||||
#include <cutils/properties.h>
|
||||
#include <hidl/HidlTransportSupport.h>
|
||||
|
||||
#define FST_MGR_COMPONENT "HIDL"
|
||||
#include "fst_manager.h"
|
||||
#include "fst_cfgmgr.h"
|
||||
#include "hidl_manager.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "utils/common.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "utils/os.h"
|
||||
}
|
||||
#include "fst_hidl.h"
|
||||
|
||||
using android::hardware::hidl_string;
|
||||
using namespace android;
|
||||
using android::hardware::configureRpcThreadpool;
|
||||
using android::hardware::handleTransportPoll;
|
||||
using android::hardware::setupTransportPolling;
|
||||
using vendor::qti::hardware::fstman::V1_0::implementation::HidlManager;
|
||||
using FstManagerStatus = ::vendor::qti::hardware::fstman::V1_0::FstManagerStatus;
|
||||
using FstManagerStatusCode = ::vendor::qti::hardware::fstman::V1_0::FstManagerStatusCode;
|
||||
using IFstManager = ::vendor::qti::hardware::fstman::V1_0::IFstManager;
|
||||
|
||||
struct fst_hidl_priv {
|
||||
int hidl_fd;
|
||||
};
|
||||
|
||||
static void fst_hidl_sock_handler(
|
||||
int sock, void * /* eloop_ctx */, void * /* sock_ctx */)
|
||||
{
|
||||
handleTransportPoll(sock);
|
||||
}
|
||||
|
||||
void *fst_hidl_init(void)
|
||||
{
|
||||
struct fst_hidl_priv *priv;
|
||||
HidlManager *hidl_manager;
|
||||
struct fst_group_info *groups = NULL;
|
||||
int nof_groups, i;
|
||||
|
||||
priv = (fst_hidl_priv *)os_zalloc(sizeof(*priv));
|
||||
if (!priv) {
|
||||
fst_mgr_printf(MSG_ERROR, "failed to allocate hidl area");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "initializing hidl control");
|
||||
|
||||
configureRpcThreadpool(1, true /* callerWillJoin */);
|
||||
priv->hidl_fd = setupTransportPolling();
|
||||
if (priv->hidl_fd < 0)
|
||||
goto err;
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "Processing hidl events on FD %d", priv->hidl_fd);
|
||||
// Look for read events from the hidl socket in the eloop.
|
||||
if (eloop_register_read_sock(
|
||||
priv->hidl_fd, fst_hidl_sock_handler, NULL, priv) < 0)
|
||||
goto err;
|
||||
|
||||
hidl_manager = HidlManager::getInstance();
|
||||
if (!hidl_manager)
|
||||
goto err;
|
||||
hidl_manager->registerHidlService();
|
||||
|
||||
nof_groups = fst_cfgmgr_get_groups(&groups);
|
||||
|
||||
if (nof_groups > 0) {
|
||||
for (i = 0; i < nof_groups; i++)
|
||||
hidl_manager->registerGroup(groups[i].id);
|
||||
fst_free(groups);
|
||||
}
|
||||
|
||||
return priv;
|
||||
err:
|
||||
fst_hidl_deinit(priv);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void fst_hidl_deinit(void *handle)
|
||||
{
|
||||
HidlManager *hidl_manager;
|
||||
struct fst_group_info *groups = NULL;
|
||||
int nof_groups, i;
|
||||
|
||||
if (!handle)
|
||||
return;
|
||||
hidl_manager = HidlManager::getInstance();
|
||||
if (!hidl_manager)
|
||||
return;
|
||||
|
||||
struct fst_hidl_priv *priv = (struct fst_hidl_priv *)handle;
|
||||
fst_mgr_printf(MSG_INFO, "Deiniting hidl control");
|
||||
|
||||
nof_groups = fst_cfgmgr_get_groups(&groups);
|
||||
|
||||
if (nof_groups > 0) {
|
||||
for (i = 0; i < nof_groups; i++)
|
||||
hidl_manager->unregisterGroup(groups[i].id);
|
||||
fst_free(groups);
|
||||
}
|
||||
|
||||
HidlManager::destroyInstance();
|
||||
eloop_unregister_read_sock(priv->hidl_fd);
|
||||
os_free(priv);
|
||||
}
|
||||
55
qcom/opensource/fst-manager/hidl/fst_hidl.h
Normal file
55
qcom/opensource/fst-manager/hidl/fst_hidl.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Implements HIDL communication channel for fst manager
|
||||
*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
|
||||
*
|
||||
* 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FST_HIDL_H__
|
||||
#define __FST_HIDL_H__
|
||||
|
||||
#include "fst_ctrl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
void *fst_hidl_init(void);
|
||||
void fst_hidl_deinit(void *handle);
|
||||
|
||||
void fst_hidl_notify_group_init(const struct fst_group_info *group);
|
||||
void fst_hidl_notify_group_deinit(const struct fst_group_info *group);
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
||||
#endif /* __FST_CAPCONFIGSTORE_H__ */
|
||||
355
qcom/opensource/fst-manager/hidl/hidl_manager.cpp
Normal file
355
qcom/opensource/fst-manager/hidl/hidl_manager.cpp
Normal file
@@ -0,0 +1,355 @@
|
||||
/*
|
||||
* hidl interface for fst manager
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
|
||||
*
|
||||
* 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "hidl_manager.h"
|
||||
|
||||
#define FST_MGR_COMPONENT "HIDL"
|
||||
#include "fst_manager.h"
|
||||
|
||||
namespace {
|
||||
using android::hardware::hidl_array;
|
||||
using namespace vendor::qti::hardware::fstman::V1_0;
|
||||
|
||||
/**
|
||||
* Add callback to the corresponding list after linking to death on the
|
||||
* corresponding hidl object reference.
|
||||
*/
|
||||
template <class CallbackType>
|
||||
int registerForDeathAndAddCallbackHidlObjectToList(
|
||||
const android::sp<CallbackType> &callback,
|
||||
const std::function<void(const android::sp<CallbackType> &)>
|
||||
&on_hidl_died_fctor,
|
||||
std::vector<android::sp<CallbackType>> &callback_list)
|
||||
{
|
||||
// TODO link to death
|
||||
callback_list.push_back(callback);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class ObjectType>
|
||||
int addHidlObjectToMap(
|
||||
const std::string &key, const android::sp<ObjectType> object,
|
||||
std::map<const std::string, android::sp<ObjectType>> &object_map)
|
||||
{
|
||||
// Return failure if we already have an object for that |key|.
|
||||
if (object_map.find(key) != object_map.end())
|
||||
return 1;
|
||||
object_map[key] = object;
|
||||
if (!object_map[key].get())
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class ObjectType>
|
||||
int removeHidlObjectFromMap(
|
||||
const std::string &key,
|
||||
std::map<const std::string, android::sp<ObjectType>> &object_map)
|
||||
{
|
||||
// Return failure if we dont have an object for that |key|.
|
||||
const auto &object_iter = object_map.find(key);
|
||||
if (object_iter == object_map.end())
|
||||
return 1;
|
||||
object_iter->second->invalidate();
|
||||
object_map.erase(object_iter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class CallbackType>
|
||||
int addGroupCallbackHidlObjectToMap(
|
||||
const std::string &groupName, const android::sp<CallbackType> &callback,
|
||||
const std::function<void(const android::sp<CallbackType> &)>
|
||||
&on_hidl_died_fctor,
|
||||
std::map<const std::string, std::vector<android::sp<CallbackType>>>
|
||||
&callbacks_map)
|
||||
{
|
||||
if (groupName.empty())
|
||||
return 1;
|
||||
|
||||
auto group_callback_map_iter = callbacks_map.find(groupName);
|
||||
if (group_callback_map_iter == callbacks_map.end())
|
||||
return 1;
|
||||
auto &group_callback_list = group_callback_map_iter->second;
|
||||
|
||||
// Register for death notification before we add it to our list.
|
||||
return registerForDeathAndAddCallbackHidlObjectToList<CallbackType>(
|
||||
callback, on_hidl_died_fctor, group_callback_list);
|
||||
}
|
||||
|
||||
template <class CallbackType>
|
||||
void removeGroupCallbackHidlObjectFromMap(
|
||||
const std::string &groupName, const android::sp<CallbackType> &callback,
|
||||
std::map<const std::string, std::vector<android::sp<CallbackType>>>
|
||||
&callbacks_map)
|
||||
{
|
||||
if (groupName.empty())
|
||||
return;
|
||||
|
||||
auto group_callback_map_iter = callbacks_map.find(groupName);
|
||||
if (group_callback_map_iter == callbacks_map.end())
|
||||
return;
|
||||
|
||||
auto &group_callback_list = group_callback_map_iter->second;
|
||||
group_callback_list.erase(
|
||||
std::remove(
|
||||
group_callback_list.begin(), group_callback_list.end(),
|
||||
callback),
|
||||
group_callback_list.end());
|
||||
}
|
||||
|
||||
template <class CallbackType>
|
||||
int removeAllGroupCallbackHidlObjectsFromMap(
|
||||
const std::string &groupName,
|
||||
std::map<const std::string, std::vector<android::sp<CallbackType>>>
|
||||
&callbacks_map)
|
||||
{
|
||||
auto group_callback_map_iter = callbacks_map.find(groupName);
|
||||
if (group_callback_map_iter == callbacks_map.end())
|
||||
return 1;
|
||||
// TODO unlink to death
|
||||
callbacks_map.erase(group_callback_map_iter);
|
||||
return 0;
|
||||
}
|
||||
|
||||
template <class CallbackType>
|
||||
void callWithEachGroupCallback(
|
||||
const std::string &groupName,
|
||||
const std::function<
|
||||
android::hardware::Return<void>(android::sp<CallbackType>)> &method,
|
||||
const std::map<const std::string, std::vector<android::sp<CallbackType>>>
|
||||
&callbacks_map)
|
||||
{
|
||||
if (groupName.empty())
|
||||
return;
|
||||
|
||||
auto group_callback_map_iter = callbacks_map.find(groupName);
|
||||
if (group_callback_map_iter == callbacks_map.end())
|
||||
return;
|
||||
const auto &group_callback_list = group_callback_map_iter->second;
|
||||
for (const auto &callback : group_callback_list) {
|
||||
if (!method(callback).isOk()) {
|
||||
fst_mgr_printf(
|
||||
MSG_ERROR, "Failed to invoke HIDL group callback");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace vendor {
|
||||
namespace qti {
|
||||
namespace hardware {
|
||||
namespace fstman {
|
||||
namespace V1_0 {
|
||||
namespace implementation {
|
||||
|
||||
using namespace vendor::qti::hardware::fstman::V1_0;
|
||||
using V1_0::IFstGroupCallback;
|
||||
|
||||
HidlManager *HidlManager::instance_ = NULL;
|
||||
|
||||
HidlManager *HidlManager::getInstance()
|
||||
{
|
||||
if (!instance_)
|
||||
instance_ = new HidlManager();
|
||||
return instance_;
|
||||
}
|
||||
|
||||
void HidlManager::destroyInstance()
|
||||
{
|
||||
if (instance_)
|
||||
delete instance_;
|
||||
instance_ = NULL;
|
||||
}
|
||||
|
||||
int HidlManager::registerHidlService()
|
||||
{
|
||||
::android::status_t status;
|
||||
|
||||
// Create the main hidl service object and register it.
|
||||
fstman_object_ = new FstManager();
|
||||
status = fstman_object_->registerAsService();
|
||||
|
||||
if (status != android::NO_ERROR) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register a group to hidl manager.
|
||||
*
|
||||
* @param groupName the FST group name
|
||||
*
|
||||
* @return 0 on success, 1 on failure.
|
||||
*/
|
||||
int HidlManager::registerGroup(const char *groupName)
|
||||
{
|
||||
if (!groupName)
|
||||
return 1;
|
||||
|
||||
if (addHidlObjectToMap<FstGroup>(
|
||||
groupName,
|
||||
new FstGroup(groupName),
|
||||
fst_group_object_map_)) {
|
||||
fst_mgr_printf(
|
||||
MSG_ERROR,
|
||||
"Failed to register FST group with HIDL "
|
||||
"control: %s",
|
||||
groupName);
|
||||
return 1;
|
||||
}
|
||||
fst_group_callbacks_map_[groupName] =
|
||||
std::vector<android::sp<IFstGroupCallback>>();
|
||||
|
||||
// TODO send callback when group created? Currently fst-manager
|
||||
// does not support dynamic group add/remove.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregister a group from hidl manager.
|
||||
*
|
||||
* @param groupName the FST group name
|
||||
*
|
||||
* @return 0 on success, 1 on failure.
|
||||
*/
|
||||
int HidlManager::unregisterGroup(const char *groupName)
|
||||
{
|
||||
if (!groupName)
|
||||
return 1;
|
||||
|
||||
int success = !removeHidlObjectFromMap(
|
||||
groupName, fst_group_object_map_);
|
||||
if (success) {
|
||||
success = !removeAllGroupCallbackHidlObjectsFromMap(
|
||||
groupName, fst_group_callbacks_map_);
|
||||
}
|
||||
if (!success) {
|
||||
fst_mgr_printf(
|
||||
MSG_ERROR,
|
||||
"Failed to unregister group with HIDL "
|
||||
"control: %s",
|
||||
groupName);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// TODO send callback when group removed? Currently fst-manager
|
||||
// does not support dynamic group add/remove.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new iface callback hidl object reference to our
|
||||
* interface callback list.
|
||||
*
|
||||
* @param ifname Name of the corresponding interface.
|
||||
* @param callback Hidl reference of the callback object.
|
||||
*
|
||||
* @return 0 on success, 1 on failure.
|
||||
*/
|
||||
int HidlManager::addFstGroupCallbackHidlObject(
|
||||
const std::string &groupName,
|
||||
const android::sp<IFstGroupCallback> &callback)
|
||||
{
|
||||
const std::function<void(
|
||||
const android::sp<IFstGroupCallback> &)>
|
||||
on_hidl_died_fctor = std::bind(
|
||||
&HidlManager::removeFstGroupCallbackHidlObject, this, groupName,
|
||||
std::placeholders::_1);
|
||||
return addGroupCallbackHidlObjectToMap(
|
||||
groupName, callback, on_hidl_died_fctor, fst_group_callbacks_map_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the |IFstGroup| hidl object reference using the provided
|
||||
* group name.
|
||||
*
|
||||
* @param groupName Name of the corresponding interface.
|
||||
* @param group_object Hidl reference corresponding to the group.
|
||||
*
|
||||
* @return 0 on success, 1 on failure.
|
||||
*/
|
||||
int HidlManager::getFstGroupHidlObjectByName(
|
||||
const std::string &groupName, android::sp<IFstGroup> *group_object)
|
||||
{
|
||||
if (groupName.empty() || !group_object)
|
||||
return 1;
|
||||
|
||||
auto group_object_iter = fst_group_object_map_.find(groupName);
|
||||
if (group_object_iter == fst_group_object_map_.end())
|
||||
return 1;
|
||||
|
||||
*group_object = group_object_iter->second;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the provided FST group callback hidl object reference from
|
||||
* our group callback list.
|
||||
*
|
||||
* @param groupName Name of the corresponding FST group.
|
||||
* @param callback Hidl reference of the callback object.
|
||||
*/
|
||||
void HidlManager::removeFstGroupCallbackHidlObject(
|
||||
const std::string &groupName,
|
||||
const android::sp<IFstGroupCallback> &callback)
|
||||
{
|
||||
return removeGroupCallbackHidlObjectFromMap(
|
||||
groupName, callback, fst_group_callbacks_map_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper fucntion to invoke the provided callback method on all the
|
||||
* registered FST group callback hidl objects for the specified
|
||||
* |groupName|.
|
||||
*
|
||||
* @param groupName Name of the corresponding FST group.
|
||||
* @param method Pointer to the required hidl method from
|
||||
* |IFstGroupCallback|.
|
||||
*/
|
||||
void HidlManager::callWithEachFstGroupCallback(
|
||||
const std::string &groupName,
|
||||
const std::function<Return<void>(android::sp<IFstGroupCallback>)>
|
||||
&method)
|
||||
{
|
||||
callWithEachGroupCallback(groupName, method, fst_group_callbacks_map_);
|
||||
}
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace fstman
|
||||
} // namespace hardware
|
||||
} // namespace qti
|
||||
} // namespace vendor
|
||||
|
||||
135
qcom/opensource/fst-manager/hidl/hidl_manager.h
Normal file
135
qcom/opensource/fst-manager/hidl/hidl_manager.h
Normal file
@@ -0,0 +1,135 @@
|
||||
/*
|
||||
* hidl interface for fst manager
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
|
||||
*
|
||||
* 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef FST_MANAGER_HIDL_HIDL_MANAGER_H
|
||||
#define FST_MANAGER_HIDL_HIDL_MANAGER_H
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "FstManager.h"
|
||||
#include "FstGroup.h"
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "utils/common.h"
|
||||
}
|
||||
|
||||
namespace vendor {
|
||||
namespace qti {
|
||||
namespace hardware {
|
||||
namespace fstman {
|
||||
namespace V1_0 {
|
||||
namespace implementation {
|
||||
using namespace vendor::qti::hardware::fstman::V1_0;
|
||||
using V1_0::IFstManager;
|
||||
using V1_0::IFstGroupCallback;
|
||||
|
||||
/**
|
||||
* HidlManager is responsible for managing the lifetime of all
|
||||
* hidl objects created by the fst manager. This is a singleton
|
||||
* class which is created by the fstman core and can be used
|
||||
* to get references to the hidl objects.
|
||||
*/
|
||||
class HidlManager
|
||||
{
|
||||
public:
|
||||
static HidlManager *getInstance();
|
||||
static void destroyInstance();
|
||||
|
||||
// Methods called from fstman core.
|
||||
int registerHidlService();
|
||||
int registerGroup(const char *groupName);
|
||||
int unregisterGroup(const char *groupName);
|
||||
void notifyTest(const char *groupName, const char *msg); // DEBUGGING
|
||||
|
||||
// Methods called from hidl objects.
|
||||
int addFstGroupCallbackHidlObject(
|
||||
const std::string &groupName,
|
||||
const android::sp<IFstGroupCallback> &callback);
|
||||
|
||||
int getFstGroupHidlObjectByName(
|
||||
const std::string &groupName,
|
||||
android::sp<IFstGroup> *group_object);
|
||||
private:
|
||||
HidlManager() = default;
|
||||
~HidlManager() = default;
|
||||
HidlManager(const HidlManager &) = default;
|
||||
HidlManager &operator=(const HidlManager &) = default;
|
||||
|
||||
void removeFstGroupCallbackHidlObject(
|
||||
const std::string &groupName,
|
||||
const android::sp<IFstGroupCallback> &callback);
|
||||
|
||||
void callWithEachFstGroupCallback(
|
||||
const std::string &groupName,
|
||||
const std::function<android::hardware::Return<void>(
|
||||
android::sp<IFstGroupCallback>)> &method);
|
||||
|
||||
// Singleton instance of this class.
|
||||
static HidlManager *instance_;
|
||||
// The main hidl service object.
|
||||
android::sp<FstManager> fstman_object_;
|
||||
|
||||
// Map of all the FST group specific hidl objects controlled by
|
||||
// fst-manager. This map is keyed in by the corresponding
|
||||
// |groupName|.
|
||||
std::map<const std::string, android::sp<FstGroup>>
|
||||
fst_group_object_map_;
|
||||
// Map of all the callbacks registered for FST group specific
|
||||
// hidl objects controlled by fst-manager. This map is keyed in by
|
||||
// the corresponding |groupName|.
|
||||
std::map<
|
||||
const std::string,
|
||||
std::vector<android::sp<IFstGroupCallback>>>
|
||||
fst_group_callbacks_map_;
|
||||
|
||||
};
|
||||
|
||||
// The hidl interface uses some values which are the same as internal ones to
|
||||
// avoid nasty runtime conversion functions. So, adding compile time asserts
|
||||
// to guard against any internal changes breaking the hidl interface.
|
||||
static_assert(
|
||||
static_cast<uint32_t>(IFstManager::DebugLevel::EXCESSIVE) == MSG_EXCESSIVE,
|
||||
"Debug level value mismatch");
|
||||
static_assert(
|
||||
static_cast<uint32_t>(IFstManager::DebugLevel::ERROR) == MSG_ERROR,
|
||||
"Debug level value mismatch");
|
||||
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace fstman
|
||||
} // namespace hardware
|
||||
} // namespace qti
|
||||
} // namespace vendor
|
||||
|
||||
#endif // WPA_SUPPLICANT_HIDL_HIDL_MANAGER_H
|
||||
124
qcom/opensource/fst-manager/hidl/hidl_return_util.h
Normal file
124
qcom/opensource/fst-manager/hidl/hidl_return_util.h
Normal file
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
* hidl interface for fst manager
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
|
||||
* Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
|
||||
*
|
||||
* 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef HIDL_RETURN_UTIL_H_
|
||||
#define HIDL_RETURN_UTIL_H_
|
||||
|
||||
namespace vendor {
|
||||
namespace qti {
|
||||
namespace hardware {
|
||||
namespace fstman {
|
||||
namespace V1_0 {
|
||||
namespace implementation {
|
||||
namespace hidl_return_util {
|
||||
|
||||
/**
|
||||
* These utility functions are used to invoke a method on the provided
|
||||
* HIDL interface object.
|
||||
* These functions checks if the provided HIDL interface object is valid.
|
||||
* a) if valid, Invokes the corresponding internal implementation function of
|
||||
* the HIDL method. It then invokes the HIDL continuation callback with
|
||||
* the status and any returned values.
|
||||
* b) if invalid, invokes the HIDL continuation callback with the
|
||||
* provided error status and default values.
|
||||
*/
|
||||
// Use for HIDL methods which return only an instance of FstManagerStatus.
|
||||
template <typename ObjT, typename WorkFuncT, typename... Args>
|
||||
Return<void> validateAndCall(
|
||||
ObjT* obj, FstManagerStatusCode status_code_if_invalid, WorkFuncT&& work,
|
||||
const std::function<void(const FstManagerStatus&)>& hidl_cb, Args&&... args)
|
||||
{
|
||||
if (obj->isValid()) {
|
||||
hidl_cb((obj->*work)(std::forward<Args>(args)...));
|
||||
} else {
|
||||
hidl_cb({status_code_if_invalid, ""});
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
// Use for HIDL methods which return instance of FstManagerStatus and a single
|
||||
// return value.
|
||||
template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
|
||||
Return<void> validateAndCall(
|
||||
ObjT* obj, FstManagerStatusCode status_code_if_invalid, WorkFuncT&& work,
|
||||
const std::function<void(const FstManagerStatus&, ReturnT)>& hidl_cb,
|
||||
Args&&... args)
|
||||
{
|
||||
if (obj->isValid()) {
|
||||
const auto& ret_pair =
|
||||
(obj->*work)(std::forward<Args>(args)...);
|
||||
const FstManagerStatus& status = std::get<0>(ret_pair);
|
||||
const auto& ret_value = std::get<1>(ret_pair);
|
||||
hidl_cb(status, ret_value);
|
||||
} else {
|
||||
hidl_cb(
|
||||
{status_code_if_invalid, ""},
|
||||
typename std::remove_reference<ReturnT>::type());
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
// Use for HIDL methods which return instance of FstManagerStatus and 2 return
|
||||
// values.
|
||||
template <
|
||||
typename ObjT, typename WorkFuncT, typename ReturnT1, typename ReturnT2,
|
||||
typename... Args>
|
||||
Return<void> validateAndCall(
|
||||
ObjT* obj, FstManagerStatusCode status_code_if_invalid, WorkFuncT&& work,
|
||||
const std::function<void(const FstManagerStatus&, ReturnT1, ReturnT2)>&
|
||||
hidl_cb,
|
||||
Args&&... args)
|
||||
{
|
||||
if (obj->isValid()) {
|
||||
const auto& ret_tuple =
|
||||
(obj->*work)(std::forward<Args>(args)...);
|
||||
const FstManagerStatus& status = std::get<0>(ret_tuple);
|
||||
const auto& ret_value1 = std::get<1>(ret_tuple);
|
||||
const auto& ret_value2 = std::get<2>(ret_tuple);
|
||||
hidl_cb(status, ret_value1, ret_value2);
|
||||
} else {
|
||||
hidl_cb(
|
||||
{status_code_if_invalid, ""},
|
||||
typename std::remove_reference<ReturnT1>::type(),
|
||||
typename std::remove_reference<ReturnT2>::type());
|
||||
}
|
||||
return Void();
|
||||
}
|
||||
|
||||
} // namespace hidl_return_util
|
||||
} // namespace implementation
|
||||
} // namespace V1_0
|
||||
} // namespace fstman
|
||||
} // namespace hardware
|
||||
} // namespace qti
|
||||
} // namespace vendor
|
||||
#endif // HIDL_RETURN_UTIL_H_
|
||||
458
qcom/opensource/fst-manager/main.c
Normal file
458
qcom/opensource/fst-manager/main.c
Normal file
@@ -0,0 +1,458 @@
|
||||
/*
|
||||
* FST CLI based main
|
||||
*
|
||||
* Copyright (c) 2015,2019, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/os.h"
|
||||
#include "utils/eloop.h"
|
||||
#include "common/defs.h"
|
||||
|
||||
#define FST_MGR_COMPONENT "MAINCLI"
|
||||
#include "fst_manager.h"
|
||||
#include "fst_ctrl.h"
|
||||
#include "fst_cfgmgr.h"
|
||||
#ifdef ANDROID
|
||||
#include "fst_capconfigstore.h"
|
||||
#include "fst_hidl.h"
|
||||
#endif
|
||||
|
||||
#define DEFAULT_FST_INIT_RETRY_PERIOD_SEC 1
|
||||
#define MAX_CTRL_IFACE_SIZE 256
|
||||
|
||||
extern Boolean fst_ctrl_create(const char *ctrl_iface,
|
||||
unsigned int ping_interval);
|
||||
extern void fst_ctrl_free(void);
|
||||
|
||||
/* globals */
|
||||
unsigned int fst_debug_level = MSG_INFO;
|
||||
unsigned int fst_num_of_retries = 20;
|
||||
unsigned int fst_ping_interval = 1;
|
||||
Boolean fst_force_nc = FALSE;
|
||||
static Boolean fst_main_do_loop = FALSE;
|
||||
static Boolean fst_continuous_loop = FALSE;
|
||||
static Boolean terminate_signalled = FALSE;
|
||||
static Boolean init_done = FALSE;
|
||||
|
||||
static void fst_manager_signal_terminate(int sig)
|
||||
{
|
||||
fst_mgr_printf(MSG_INFO, "termination signal arrived (%d)",
|
||||
sig);
|
||||
terminate_signalled = TRUE;
|
||||
}
|
||||
|
||||
static void fst_manager_eloop_terminate(int sig, void *signal_ctx)
|
||||
{
|
||||
eloop_terminate();
|
||||
fst_manager_signal_terminate(sig);
|
||||
}
|
||||
|
||||
void fst_manager_terminate(void)
|
||||
{
|
||||
fst_main_do_loop = FALSE;
|
||||
eloop_terminate();
|
||||
}
|
||||
|
||||
static void usage(const char *prog)
|
||||
{
|
||||
printf("Usage: %s [options] [<ctrl_interace_name>]\n", prog);
|
||||
printf(", where options are:\n"
|
||||
"\t--version, -V - show version.\n"
|
||||
"\t--daemon, -B - run in daemon mode. Exit after "
|
||||
"wpa_supplicant/hostapd quits\n"
|
||||
"\t--daemonex, -b - continuous daemon mode. Wait for a next "
|
||||
"wpa_supplicant/hostapd\n"
|
||||
"\t--config, -c <file> - read the FST configuration from the file\n"
|
||||
"\t--retries -r <int> - number of session setup retries.\n"
|
||||
"\t--ping-int -p <int> - CLI ping interval in sec, 0 to disable\n"
|
||||
"\t--force-nc -n - force non-compliant mode.\n"
|
||||
"\t--debug, -d - increase debugging verbosity (-dd - more, "
|
||||
"-ddd - even more)\n"
|
||||
"\t--logfile, -f <file>- log output to specified file\n"
|
||||
#ifdef ANDROID
|
||||
"\t--autogen, -a <mode>- auto-generate fstman.ini for android "
|
||||
" (mode: 0=supplicant 1=softap)\n"
|
||||
#endif
|
||||
"\t--usage, -u - this message\n"
|
||||
"\t--help, -h - this message\n");
|
||||
exit(2);
|
||||
|
||||
}
|
||||
|
||||
void try_to_init(void *eloop_ctx, void *ctx)
|
||||
{
|
||||
const char *ctrl_iface = (const char *)ctx;
|
||||
|
||||
if (!fst_ctrl_create(ctrl_iface, fst_ping_interval)) {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot create fst_ctrl");
|
||||
goto again;
|
||||
}
|
||||
|
||||
if (fst_manager_init()) {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot init fst manager");
|
||||
goto error_init;
|
||||
}
|
||||
|
||||
init_done = TRUE;
|
||||
|
||||
return;
|
||||
|
||||
error_init:
|
||||
fst_ctrl_free();
|
||||
again:
|
||||
eloop_register_timeout(DEFAULT_FST_INIT_RETRY_PERIOD_SEC, 0, try_to_init, NULL, (void*)ctrl_iface);
|
||||
}
|
||||
|
||||
void main_loop(const char *ctrl_iface)
|
||||
{
|
||||
if (eloop_register_signal_terminate(fst_manager_eloop_terminate, NULL)) {
|
||||
fst_mgr_printf(MSG_ERROR, "eloop_register_signal_terminate");
|
||||
return;
|
||||
}
|
||||
|
||||
eloop_run();
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "eloop finished");
|
||||
if (!fst_continuous_loop)
|
||||
fst_main_do_loop = FALSE;
|
||||
|
||||
if (init_done) {
|
||||
fst_manager_deinit();
|
||||
fst_ctrl_free();
|
||||
init_done = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
|
||||
static const char FSTMAN_IFNAME[] = "wlan0";
|
||||
static const char FSTMAN_WIGIG_IFNAME[] = "wigig0";
|
||||
static const char FSTMAN_DATA_IFNAME[] = "bond0";
|
||||
static const char FSTMAN_SAP_IFNAME[] = "wlan0";
|
||||
static const char FSTMAN_WIGIG_IF_CHANNEL[] = "2";
|
||||
static const char FST_STA_INTERFACE_KEY_NAME[] =
|
||||
"fst.wifi.sta.interface";
|
||||
static const char FST_SAP_INTERFACE_KEY_NAME[] =
|
||||
"fst.wifi.sap.interface";
|
||||
static const char FST_DATA_INTERFACE_KEY_NAME[] =
|
||||
"fst.data.interface";
|
||||
static const char FST_WIGIG_INTERFACE_KEY_NAME[] =
|
||||
"fst.wigig.interface";
|
||||
static const char FST_WIGIG_INTERFACE_CHANNEL_KEY_NAME[] =
|
||||
"fst.wigig.interface.channel";
|
||||
|
||||
static int create_fstman_ini_file(int softap_mode, char *buf, int len)
|
||||
{
|
||||
char fst_iface1[64] = { '\0' };
|
||||
char fst_iface2[64] = { '\0' };
|
||||
char fst_data_iface[64] = { '\0' };
|
||||
char fst_wigig_channel[64] = { '\0' };
|
||||
int result;
|
||||
|
||||
if (softap_mode)
|
||||
fst_get_config_string(FST_SAP_INTERFACE_KEY_NAME,
|
||||
FSTMAN_SAP_IFNAME,
|
||||
fst_iface1, sizeof(fst_iface1));
|
||||
else
|
||||
fst_get_config_string(FST_STA_INTERFACE_KEY_NAME,
|
||||
FSTMAN_IFNAME,
|
||||
fst_iface1, sizeof(fst_iface1));
|
||||
fst_get_config_string(FST_WIGIG_INTERFACE_KEY_NAME, FSTMAN_WIGIG_IFNAME,
|
||||
fst_iface2, sizeof(fst_iface2));
|
||||
fst_get_config_string(FST_DATA_INTERFACE_KEY_NAME, FSTMAN_DATA_IFNAME,
|
||||
fst_data_iface, sizeof(fst_data_iface));
|
||||
fst_get_config_string(FST_WIGIG_INTERFACE_CHANNEL_KEY_NAME,
|
||||
FSTMAN_WIGIG_IF_CHANNEL,
|
||||
fst_wigig_channel, sizeof(fst_wigig_channel));
|
||||
|
||||
result = snprintf(buf, len,
|
||||
"[fst_manager]\n"
|
||||
"ctrl_iface=/data/vendor/wifi/hostapd/global\n"
|
||||
"groups=%s\n" /* bond0 */
|
||||
"\n"
|
||||
"[%s]\n" /* bond0 */
|
||||
"interfaces=%s,%s\n" /* wlan0,wigig0 */
|
||||
"mux_type=bonding\n"
|
||||
"mux_ifname=%s\n" /* bond0 */
|
||||
"mux_managed=1\n"
|
||||
"mac_address_by=%s\n" /* wlan0 */
|
||||
"rate_upgrade_master=%s\n" /* wlan0 */
|
||||
"txqueuelen=100\n"
|
||||
"rate_upgrade_acl_file=/data/vendor/wifi/fst_rate_upgrade.accept\n"
|
||||
"\n"
|
||||
"[%s]\n" /* wlan0 */
|
||||
"manual_enslave=1\n"
|
||||
"priority=100\n"
|
||||
"default_llt=3600\n"
|
||||
"\n"
|
||||
"[%s]\n" /* wigig0 */
|
||||
"manual_enslave=1\n"
|
||||
"priority=110\n"
|
||||
"wpa_group=GCMP\n"
|
||||
"wpa_pairwise=GCMP\n"
|
||||
"hw_mode=ad\n"
|
||||
"channel=%s\n",
|
||||
fst_data_iface,
|
||||
fst_data_iface,
|
||||
fst_iface1, fst_iface2,
|
||||
fst_data_iface,
|
||||
fst_iface1,
|
||||
fst_iface1,
|
||||
fst_iface1,
|
||||
fst_iface2,
|
||||
fst_wigig_channel
|
||||
);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static bool write_fstman_ini_file(const char *fname, const char *contents, int len)
|
||||
{
|
||||
FILE *f;
|
||||
int written;
|
||||
|
||||
f = fopen(fname, "w");
|
||||
if (!f) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"fail to open %s for writing\n", fname);
|
||||
return false;
|
||||
}
|
||||
written = fwrite(contents, 1, len, f);
|
||||
fclose(f);
|
||||
if (written != len) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"fail to write to %s\n", fname);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int fst_manager_gen_fstman_ini(const char *fname, int softap_mode)
|
||||
{
|
||||
char cfg[2048];
|
||||
int len;
|
||||
|
||||
len = create_fstman_ini_file(softap_mode, cfg, sizeof(cfg));
|
||||
if (len <= 0)
|
||||
return -1;
|
||||
if (!write_fstman_ini_file(fname, cfg, len))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* ANDROID */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
const struct option long_opts[] = {
|
||||
{"version", no_argument, NULL, 'V'},
|
||||
{"daemon", no_argument, NULL, 'B'},
|
||||
{"daemonex", no_argument, NULL, 'b'},
|
||||
{"config", required_argument, NULL, 'c'},
|
||||
{"retries", required_argument, NULL, 'r'},
|
||||
{"ping-int", required_argument, NULL, 'p'},
|
||||
{"force-nc", no_argument, NULL, 'n'},
|
||||
{"debug", optional_argument, NULL, 'd'},
|
||||
{"logfile", required_argument, NULL, 'f'},
|
||||
{"autogen", required_argument, NULL, 'a'},
|
||||
{"usage", no_argument, NULL, 'u'},
|
||||
{"help", no_argument, NULL, 'h'},
|
||||
{}
|
||||
};
|
||||
int res = -1;
|
||||
char short_opts[] = "VBbc:r:nd::f:a:uh";
|
||||
const char *ctrl_iface = NULL;
|
||||
char *fstman_config_file = NULL;
|
||||
int opt, i, mode;
|
||||
char buf[MAX_CTRL_IFACE_SIZE];
|
||||
#ifdef ANDROID
|
||||
void *priv;
|
||||
#endif
|
||||
|
||||
while ((opt = getopt_long_only(argc, argv, short_opts, long_opts, NULL))
|
||||
!= -1) {
|
||||
switch (opt) {
|
||||
case 'V':
|
||||
printf("FST Manager, version "
|
||||
FST_MANAGER_VERSION "\n");
|
||||
exit(0);
|
||||
break;
|
||||
case 'B':
|
||||
fst_main_do_loop = TRUE;
|
||||
break;
|
||||
case 'b':
|
||||
fst_main_do_loop = TRUE;
|
||||
fst_continuous_loop = TRUE;
|
||||
break;
|
||||
case 'c':
|
||||
if (fstman_config_file != NULL) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"Multiple configurations not allowed\n");
|
||||
goto error_cfmgr_params;
|
||||
}
|
||||
if (optarg != NULL)
|
||||
fstman_config_file=os_strdup(optarg);
|
||||
if (fstman_config_file == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"Filename memory allocation error\n");
|
||||
goto error_cfmgr_params;
|
||||
}
|
||||
break;
|
||||
case 'r':
|
||||
if (optarg != NULL)
|
||||
fst_num_of_retries = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'p':
|
||||
if (optarg != NULL)
|
||||
fst_ping_interval = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'n':
|
||||
fst_force_nc = TRUE;
|
||||
fst_mgr_printf(MSG_INFO, "Non-compliant FST mode forced\n");
|
||||
break;
|
||||
case 'd':
|
||||
fst_debug_level = MSG_DEBUG;
|
||||
if (optarg && optarg[0] == 'd') {
|
||||
fst_debug_level = MSG_MSGDUMP;
|
||||
if (optarg[1] == 'd')
|
||||
fst_debug_level = MSG_EXCESSIVE;
|
||||
}
|
||||
break;
|
||||
case 'f':
|
||||
if (wpa_debug_open_file(optarg)) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"Cannot open log file: %s", optarg);
|
||||
goto error_cfmgr_params;
|
||||
}
|
||||
break;
|
||||
#ifdef ANDROID
|
||||
case 'a':
|
||||
if (fstman_config_file == NULL) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"Config file must be specified\n");
|
||||
goto error_cfmgr_params;
|
||||
}
|
||||
mode = optarg ? strtoul(optarg, NULL, 0) : 0;
|
||||
res = fst_manager_gen_fstman_ini(
|
||||
fstman_config_file, mode);
|
||||
if (res < 0) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"fstman.ini gen failure, err: %d\n",
|
||||
res);
|
||||
goto error_cfmgr_params;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 'u':
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!fstman_config_file && argc - optind != 1) {
|
||||
fst_mgr_printf(MSG_ERROR,
|
||||
"either ctrl_interace_name or config has to be specified");
|
||||
usage(argv[0]);
|
||||
goto error_cfmgr_params;
|
||||
}
|
||||
|
||||
if (fstman_config_file)
|
||||
i = fst_cfgmgr_init(FST_CONFIG_INI, (void*)fstman_config_file);
|
||||
else
|
||||
i = fst_cfgmgr_init(FST_CONFIG_CLI, NULL);
|
||||
if (i != 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "FST Configuration error");
|
||||
goto error_cfmgr_init;
|
||||
}
|
||||
|
||||
if (argc - optind == 1)
|
||||
ctrl_iface = argv[optind];
|
||||
else if (!fst_cfgmgr_get_ctrl_iface(buf, sizeof(buf)))
|
||||
ctrl_iface = buf;
|
||||
else {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot get ctrl_iface");
|
||||
goto error_ctrl_iface;
|
||||
}
|
||||
|
||||
if (eloop_init() != 0) {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot init eloop");
|
||||
goto error_eloop_init;
|
||||
}
|
||||
|
||||
#ifdef ANDROID
|
||||
priv = fst_hidl_init();
|
||||
if (!priv) {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot init HIDL");
|
||||
goto error_hidl_init;
|
||||
}
|
||||
#endif
|
||||
|
||||
signal(SIGINT, fst_manager_signal_terminate);
|
||||
signal(SIGTERM, fst_manager_signal_terminate);
|
||||
while (TRUE) {
|
||||
eloop_cancel_timeout(try_to_init, NULL, NULL);
|
||||
eloop_register_timeout(0, 0, try_to_init, NULL, (void*)ctrl_iface);
|
||||
main_loop(ctrl_iface);
|
||||
if (!fst_main_do_loop || terminate_signalled)
|
||||
break;
|
||||
signal(SIGINT, fst_manager_signal_terminate);
|
||||
signal(SIGTERM, fst_manager_signal_terminate);
|
||||
os_sleep(DEFAULT_FST_INIT_RETRY_PERIOD_SEC, 0);
|
||||
}
|
||||
|
||||
res = 0;
|
||||
#ifdef ANDROID
|
||||
fst_hidl_deinit(priv);
|
||||
#endif
|
||||
|
||||
error_hidl_init:
|
||||
eloop_destroy();
|
||||
error_eloop_init:
|
||||
error_ctrl_iface:
|
||||
fst_cfgmgr_deinit();
|
||||
error_cfmgr_init:
|
||||
error_cfmgr_params:
|
||||
wpa_debug_close_file();
|
||||
os_free(fstman_config_file);
|
||||
return res;
|
||||
}
|
||||
164
qcom/opensource/fst-manager/main_dbus.c
Normal file
164
qcom/opensource/fst-manager/main_dbus.c
Normal file
@@ -0,0 +1,164 @@
|
||||
/*
|
||||
* FST Dbus based main
|
||||
*
|
||||
* Copyright (c) 2015, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
* 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.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
|
||||
#define FST_MGR_COMPONENT "MDBS"
|
||||
#include "fst_manager.h"
|
||||
|
||||
#include "utils/common.h"
|
||||
#include "utils/os.h"
|
||||
#include "common/defs.h"
|
||||
|
||||
#include "fst_ctrl.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-unix.h>
|
||||
|
||||
struct wpa_ctrl;
|
||||
extern Boolean fst_ctrl_create(void);
|
||||
extern void fst_ctrl_free(void);
|
||||
|
||||
/* globals */
|
||||
unsigned int fst_debug_level = MSG_INFO;
|
||||
unsigned int fst_num_of_retries = 3;
|
||||
Boolean fst_force_nc = FALSE;
|
||||
|
||||
static gboolean register_signal_terminate(GSourceFunc handler,
|
||||
gpointer user_data)
|
||||
{
|
||||
guint id = g_unix_signal_add(SIGINT, handler, user_data);
|
||||
if (id > 0) {
|
||||
id = g_unix_signal_add(SIGTERM, handler, user_data);
|
||||
if (id > 0)
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean fst_manager_terminate(gpointer user_data)
|
||||
{
|
||||
GMainLoop *loop = user_data;
|
||||
fst_mgr_printf(MSG_INFO, "termination signal arrived");
|
||||
g_main_loop_quit(loop);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void usage(const char *prog)
|
||||
{
|
||||
g_print("Usage: %s [options] <ctrl_interace_name>\n", prog);
|
||||
g_print(", where options are:\n"
|
||||
"\t--version, -V - show version.\n"
|
||||
"\t--retries -r - number of session setup retries.\n"
|
||||
"\t--debug, -d - debug output\n"
|
||||
"\t--usage, -u - this message\n"
|
||||
"\t--help, -h - this message\n");
|
||||
exit(2);
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
GMainLoop *loop;
|
||||
const struct option long_opts[] = {
|
||||
{"version", 0, NULL, 'V'},
|
||||
{"retries", 1, NULL, 'r'},
|
||||
{"force-nc", 0, NULL, 'n'},
|
||||
{"debug", 2, NULL, 'd'},
|
||||
{"usage", 0, NULL, 'u'},
|
||||
{"help", 0, NULL, 'h'},
|
||||
{}
|
||||
};
|
||||
char short_opts[] = "vr:nd::uh";
|
||||
int opt;
|
||||
|
||||
while ((opt = getopt_long_only(argc, argv, short_opts, long_opts, NULL))
|
||||
!= -1) {
|
||||
switch (opt) {
|
||||
case 'V':
|
||||
printf("FST Manager, version "
|
||||
FST_MANAGER_VERSION "\n");
|
||||
exit(0);
|
||||
break;
|
||||
case 'r':
|
||||
fst_num_of_retries = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'n':
|
||||
fst_force_nc = TRUE;
|
||||
fst_mgr_printf(MSG_INFO,
|
||||
"Non-compliant FST mode forced\n");
|
||||
break;
|
||||
case 'd':
|
||||
fst_debug_level = MSG_EXCESSIVE;
|
||||
if (optarg)
|
||||
fst_debug_level = strtoul(optarg, NULL, 0);
|
||||
break;
|
||||
case 'u':
|
||||
case 'h':
|
||||
case '?':
|
||||
default:
|
||||
usage(argv[0]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
loop = g_main_loop_new(NULL, FALSE);
|
||||
if (!loop) {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot create main loop");
|
||||
goto error_g_main_loop_new;
|
||||
}
|
||||
|
||||
if (!fst_ctrl_create()) {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot create fst_ctrl");
|
||||
goto error_fst_ctrl_create;
|
||||
}
|
||||
|
||||
if (!register_signal_terminate(fst_manager_terminate, loop)) {
|
||||
fst_mgr_printf(MSG_ERROR, "cannot register termination signal handler");
|
||||
goto error_register_signal_terminate;
|
||||
}
|
||||
|
||||
g_main_loop_run(loop);
|
||||
|
||||
fst_mgr_printf(MSG_INFO, "main loop finished");
|
||||
|
||||
error_register_signal_terminate:
|
||||
fst_ctrl_free();
|
||||
error_fst_ctrl_create:
|
||||
g_main_loop_unref(loop);
|
||||
error_g_main_loop_new:
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
# Copyright (c) 2019, The Linux Foundation. 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 Linux Foundation 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 "AS IS" AND ANY EXPRESS OR IMPLIED
|
||||
# WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
||||
# 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.
|
||||
|
||||
# FST Manager with hostapd (softap) - all settings inside ini file
|
||||
service fstman /vendor/bin/fstman -B -ddd -c /data/vendor/wifi/fstman.ini -a 1
|
||||
user wifi
|
||||
group wifi
|
||||
capabilities NET_ADMIN NET_RAW
|
||||
class main
|
||||
disabled
|
||||
oneshot
|
||||
|
||||
# FST Manager with supplicant - connect to supplicant socket
|
||||
service fstman_wlan0 /vendor/bin/fstman -B -ddd -c /data/vendor/wifi/fstman.ini \
|
||||
-a 0 @android:vendor_wpa_wlan0
|
||||
user wifi
|
||||
group wifi
|
||||
capabilities NET_ADMIN NET_RAW
|
||||
interface vendor.qti.hardware.fstman@1.0::IFstManager default
|
||||
class main
|
||||
disabled
|
||||
oneshot
|
||||
Reference in New Issue
Block a user