replace common qcom sources with samsung ones

This commit is contained in:
SaschaNes
2025-08-12 22:13:00 +02:00
parent ba24dcded9
commit 6f7753de11
5682 changed files with 2450203 additions and 103634 deletions

View File

@@ -0,0 +1,116 @@
OBJS=sigma_dut.c
OBJS += utils.c
OBJS += wpa_ctrl.c
OBJS += wpa_helpers.c
OBJS += cmds_reg.c
OBJS += basic.c
OBJS += sta.c
OBJS += traffic.c
OBJS += p2p.c
OBJS += dev.c
OBJS += ap.c
OBJS += powerswitch.c
OBJS += atheros.c
OBJS += ftm.c
OBJS += dpp.c
OBJS += dhcp.c
# Initialize CFLAGS to limit to local module
CFLAGS =
ifndef NO_TRAFFIC_AGENT
CFLAGS += -DCONFIG_TRAFFIC_AGENT -DCONFIG_WFA_WMM_AC
OBJS += traffic_agent.c
OBJS += uapsd_stream.c
endif
ifndef NO_WLANTEST
CFLAGS += -DCONFIG_WLANTEST
OBJS += wlantest.c
endif
### MIRACAST ###
OBJS += miracast.c
CFLAGS += -DMIRACAST
CFLAGS += -DCONFIG_CTRL_IFACE_CLIENT_DIR=\"/data/misc/wifi/sockets\"
CFLAGS += -DSIGMA_TMPDIR=\"/data\"
CFLAGS += -DNL80211_SUPPORT
LOCAL_PATH := $(call my-dir)
FRAMEWORK_GIT_VER := $(shell cd $(ANDROID_BUILD_TOP/)frameworks/base && git describe)
SIGMA_GIT_VER := $(shell cd $(LOCAL_PATH) && git describe --dirty=+)
ifeq ($(SIGMA_GIT_VER),)
ifeq ($(FRAMEWORK_GIT_VER),)
SIGMA_VER := android-$(PLATFORM_VERSION)-$(TARGET_BOARD_PLATFORM)-$(BUILD_ID)
else
SIGMA_VER := framework-$(FRAMEWORK_VER)
endif
else
ifeq ($(FRAMEWORK_GIT_VER),)
SIGMA_VER := android-$(PLATFORM_VERSION)-$(TARGET_BOARD_PLATFORM)-$(BUILD_ID)-sigma-$(SIGMA_GIT_VER)
else
SIGMA_VER := framework-$(FRAMEWORK_GIT_VER)-sigma-$(SIGMA_GIT_VER)
endif
endif
CFLAGS += -DSIGMA_DUT_VER=\"$(SIGMA_VER)\"
include $(CLEAR_VARS)
LOCAL_MODULE := sigma_dut
QCOM_WLAN_ROOT ?= hardware/qcom/wlan
ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED), true)
LOCAL_VENDOR_MODULE := true
endif
LOCAL_CLANG := true
LOCAL_MODULE_TAGS := optional
LOCAL_C_INCLUDES += \
$(LOCAL_PATH) frameworks/base/cmds/keystore system/security/keystore \
$(LOCAL_PATH) frameworks/opt/net/wifi/libwifi_hal/include/ \
$(LOCAL_PATH) $(QCOM_WLAN_ROOT)/qcwcn/wifi_hal \
$(LOCAL_PATH) system/core/include/cutils \
$(LOCAL_PATH) hardware/libhardware_legacy/include/hardware_legacy \
$(LOCAL_PATH) hardware/interfaces/wifi/legacy_headers/include/hardware_legacy \
$(LOCAL_PATH) external/libpcap \
$(LOCAL_PATH) external/libnl/include
LOCAL_SHARED_LIBRARIES := libc libcutils libnl
ifneq ($(BUILD_QEMU_IMAGES),true)
LOCAL_STATIC_LIBRARIES := libpcap.vendor
endif
LOCAL_SHARED_LIBRARIES += libnetutils
LOCAL_C_INCLUDES += $(LOCAL_PATH) system/core/include/netutils
ifeq ($(BOARD_WLAN_DEVICE),qcwcn)
ifneq ($(wildcard hardware/qcom/wlan/qcwcn/wifi_hal/nan_cert.h),)
LOCAL_SHARED_LIBRARIES += libwifi-hal-qcom
OBJS += nan.c
CFLAGS += -DANDROID_NAN
CFLAGS += -DANDROID_WIFI_HAL
endif
ifneq ($(wildcard external/mdnsresponder/mDNSShared/dns_sd.h),)
CFLAGS += -DANDROID_MDNS
LOCAL_C_INCLUDES += external/mdnsresponder/mDNSShared
OBJS += dnssd.c
LOCAL_SHARED_LIBRARIES += libdl
endif
endif
CFLAGS += -Wno-unused-parameter
LOCAL_C_INCLUDES += system/security/keystore/include/keystore
LOCAL_SHARED_LIBRARIES += liblog
ifeq ($(PRODUCT_VENDOR_MOVE_ENABLED), true)
LOCAL_SHARED_LIBRARIES += libkeystore-engine-wifi-hidl libkeystore-wifi-hidl
else
LOCAL_SHARED_LIBRARIES += libkeystore_binder
endif
LOCAL_SRC_FILES := $(OBJS)
LOCAL_HEADER_LIBRARIES := libcutils_headers
LOCAL_CFLAGS := $(CFLAGS)
include $(BUILD_EXECUTABLE)
# Add building of e_loop
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= e_loop.c
LOCAL_MODULE := e_loop
LOCAL_VENDOR_MODULE := true
LOCAL_CFLAGS := -DWITHOUT_IFADDRS -Wno-sign-compare
include $(BUILD_EXECUTABLE)

View File

@@ -0,0 +1,108 @@
Contributions to sigma_dut
--------------------------
This software is distributed under a permissive open source license to
allow it to be used in any projects, whether open source or proprietary.
Contributions to the project are welcome and it is important to maintain
clear record of contributions and terms under which they are licensed.
To help with this, following procedure is used to allow acceptance and
recording of the terms.
All contributions are expected to be licensed under the Clear BSD
license (see below) and will not be accepted if any contrary licensing
which could affect the license of this project are submitted.
Acknowledgment of the terms is tracked through inclusion of
Signed-off-by tag in the contributions at the end of the commit log
message. This tag indicates that the contributor agrees with the
Developer Certificate of Origin (DCO) version 1.1 terms (see below; also
available from http://developercertificate.org/).
To indicate your acceptance of Developer's Certificate of Origin 1.1
terms and licensing of the contribution under the Clear BSD license
terms, please add the following line to the end of the commit message
for each contribution you make to the project:
Signed-off-by: Your Name <your@email.example.org>
using your real name. Pseudonyms or anonymous contributions cannot
unfortunately be accepted.
===[ start quote from http://developercertificate.org/ ]=======================
Developer Certificate of Origin
Version 1.1
Copyright (C) 2004, 2006 The Linux Foundation and its contributors.
660 York Street, Suite 102,
San Francisco, CA 94110 USA
Everyone is permitted to copy and distribute verbatim copies of this
license document, but changing it is not allowed.
Developer's Certificate of Origin 1.1
By making a contribution to this project, I certify that:
(a) The contribution was created in whole or in part by me and I
have the right to submit it under the open source license
indicated in the file; or
(b) The contribution is based upon previous work that, to the best
of my knowledge, is covered under an appropriate open source
license and I have the right under that license to submit that
work with modifications, whether created in whole or in part
by me, under the same open source license (unless I am
permitted to submit under a different license), as indicated
in the file; or
(c) The contribution was provided directly to me by some other
person who certified (a), (b) or (c) and I have not modified
it.
(d) I understand and agree that this project and the contribution
are public and that a record of the contribution (including all
personal information I submit with it, including my sign-off) is
maintained indefinitely and may be redistributed consistent with
this project or the open source license(s) involved.
===[ end quote from http://developercertificate.org/ ]=========================
The license terms used for sigma_dut files
------------------------------------------
Copyright (c) 2010-2011, Atheros Communications, Inc.
Copyright (c) 2011-2017, Qualcomm Atheros, Inc.
Copyright (c) 2018-2021, The Linux Foundation
All Rights Reserved.
Licensed under the Clear BSD license.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Atheros, Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER 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.

View File

@@ -0,0 +1,10 @@
DPP bootstrapping services
On the device that provides bootstrapping services, the following
processes needs to be started:
# stunnel to handle HTTPS(TLS-PSK)
stunnel stunnel-server.conf
# local-only HTTP server to handle the core DPP REST API
./dpp-rest-server.py

View File

@@ -0,0 +1,111 @@
#!/usr/bin/env python3
#
# Sigma Control API DUT (DPP REST API server)
# Copyright (c) 2022, Qualcomm Innovation Center, Inc.
# All Rights Reserved.
# Licensed under the Clear BSD license. See README for more details.
from http.server import HTTPServer, BaseHTTPRequestHandler
import json
import os
import wpaspy
wpas_ctrl = '/var/run/wpa_supplicant'
ifname = None
def wpas_connect():
ifaces = []
if os.path.isdir(wpas_ctrl):
try:
ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
except OSError as error:
print("Could not find wpa_supplicant: %s", str(error))
return None
if len(ifaces) < 1:
print("No wpa_supplicant control interface found")
return None
for ctrl in ifaces:
if ifname and ifname not in ctrl:
continue
if os.path.basename(ctrl).startswith("p2p-dev-"):
# skip P2P management interface
continue
try:
print("Trying to use control interface " + ctrl)
wpas = wpaspy.Ctrl(ctrl)
return wpas
except Exception as e:
pass
print("Could not connect to wpa_supplicant")
return None
class DPP_REST_HTTPRequestHandler(BaseHTTPRequestHandler):
def do_POST(self):
if self.path != "/dpp/bskey":
self.send_response(404)
self.end_headers()
return
if 'Content-Length' not in self.headers:
self.send_response(411)
self.end_headers()
return
content_len = int(self.headers['Content-Length'])
body = self.rfile.read(content_len)
try:
data = json.loads(body)
except:
self.send_response(400)
self.end_headers()
self.wfile.write("Invalid JSON data".encode("ascii"))
return
if 'dppUri' not in data:
print("Missing dppUri")
self.send_response(400)
self.end_headers()
self.wfile.write("Missing dppUri".encode("ascii"))
return
wpas = wpas_connect()
if wpas is None:
self.send_response(503)
self.end_headers()
self.wfile.write("DPP Configurator not available".encode("ascii"))
return
res = wpas.request("DPP_QR_CODE " + data['dppUri'])
if "UNKNOWN COMMAND" in res:
self.send_response(503)
self.end_headers()
self.wfile.write("DPP Configurator not available".encode("ascii"))
return
if "FAIL" in res:
self.send_response(400)
self.end_headers()
self.wfile.write("Invalid DPP URI".encode("ascii"))
return
id = int(res)
with open("/tmp/dpp-rest-server.id", "w") as f:
f.write(str(id))
with open("/tmp/dpp-rest-server.uri", "w") as f:
f.write(data['dppUri'])
self.send_response(200)
self.end_headers()
def main():
# Bind to localhost only and use an external stunnel proxy to handle
# TLS-PSK.
httpd = HTTPServer(('localhost', 44444), DPP_REST_HTTPRequestHandler)
httpd.serve_forever()
if __name__ == "__main__":
main()

View File

@@ -0,0 +1,9 @@
debug=debug
foreground=yes
pid = /tmp/stunnel-dpp-rest-server.pid
[PSK server]
accept = 8908
connect = 44444
ciphers = PSK
PSKsecrets = stunnel-server.psk

View File

@@ -0,0 +1 @@
dpp-rest:00112233445566778899aabbccddeeff

View File

@@ -0,0 +1,103 @@
ALL=sigma_dut
all: $(ALL)
ifdef UBSAN
CC=clang
CHECKS=undefined,unsigned-integer-overflow
CFLAGS += -fsanitize=$(CHECKS)
CFLAGS += -fno-sanitize-recover=all
LDFLAGS += -fsanitize=$(CHECKS)
LDFLAGS += -fno-sanitize-recover=all
endif
ifdef CFI
CC=clang-6.0
CFLAGS += -MMD -O2 -Wall -g
CFLAGS += -flto -fvisibility=hidden -fsanitize=cfi -fno-sanitize-trap=cfi
LDFLAGS += -flto -fvisibility=hidden -fsanitize=cfi -fno-sanitize-trap=cfi
endif
ifndef CC
CC=gcc
endif
ifndef LDO
LDO=$(CC)
endif
ifndef CFLAGS
CFLAGS = -MMD -O2 -Wall -g
endif
GITVER := $(shell git describe --dirty=+)
ifneq ($(GITVER),)
CFLAGS += -DSIGMA_DUT_VER=\"$(GITVER)\"
endif
export BINDIR ?= /usr/local/bin/
OBJS=sigma_dut.o
OBJS += utils.o
OBJS += wpa_ctrl.o
OBJS += wpa_helpers.o
OBJS += cmds_reg.o
OBJS += basic.o
OBJS += sta.o
OBJS += traffic.o
OBJS += p2p.o
OBJS += dev.o
OBJS += ap.o
OBJS += powerswitch.o
OBJS += atheros.o
OBJS += ftm.o
OBJS += dpp.o
ifndef NO_TRAFFIC_AGENT
CFLAGS += -DCONFIG_TRAFFIC_AGENT -DCONFIG_WFA_WMM_AC
OBJS += traffic_agent.o
OBJS += uapsd_stream.o
endif
LIBS += -lpthread
ifndef NO_WLANTEST
CFLAGS += -DCONFIG_WLANTEST
OBJS += wlantest.o
endif
ifndef NO_SNIFFER
CFLAGS += -DCONFIG_SNIFFER
OBJS += sniffer.o
endif
ifdef SERVER
CFLAGS += -DCONFIG_SERVER
OBJS += server.o
LIBS += -lsqlite3
endif
ifdef MIRACAST
OBJS += miracast.o
CFLAGS += -DMIRACAST
LIBS += -ldl
endif
ifdef NL80211_SUPPORT
CFLAGS += -DNL80211_SUPPORT -I /usr/include/libnl3
LIBS += -lnl-3 -lnl-genl-3
endif
sigma_dut: $(OBJS)
$(LDO) $(LDFLAGS) -o sigma_dut $(OBJS) $(LIBS)
clean:
rm -f core *~ *.o *.d sigma_dut
$(DESTDIR)$(BINDIR)/%: %
install -D $(<) $(@)
install: $(addprefix $(DESTDIR)$(BINDIR)/,$(ALL))
-include $(OBJS:%.o=%.d)

View File

@@ -0,0 +1,31 @@
#### template frame for P2P device discovery request ####
# Frame control - type management(0) and subtype action(13)
d000
# Duration
d004
# DA (destination address)
001500f86819
# SA (source address)
001500f8b05b
# BSSID
001500f86819
# Fragment number and sequence number
a0b0
# Category - 4 (public action) and action field - 9 (vendor specific)
0409
# WFA OUI (506f9a) and OUI type - 9 (P2P)
506f9a09
# OUI subtype - 5 (Device discoveribility)
05
# Dialog token
05
### P2P IE ###
# Element type - 221 (vendor element) and length (0x29)
dd29
# OUI - WFA (506f9a) and OUI type - 9 (P2P)
506f9a09
$1 P2P device ID attribute
#030600001500f8caf
030600001500f8caf5
$2 P2P group ID attribute
0f1900001500f868194449524543542d373600000000000000000000

View File

@@ -0,0 +1,122 @@
sigma_dut - WFA Sigma DUT/CA
----------------------------
Copyright (c) 2010-2011, Atheros Communications, Inc.
Copyright (c) 2011-2017, Qualcomm Atheros, Inc.
Copyright (c) 2018-2021, The Linux Foundation
All Rights Reserved.
Licensed under the Clear BSD license.
Redistribution and use in source and binary forms, with or without
modification, are permitted (subject to the limitations in the
disclaimer below) 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 Qualcomm Atheros, Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED
BY THIS LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT HOLDER 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.
See the CONTRIBUTIONS file for requirements for contributions to this
open source project.
This README file contains certain notices of software components
included with the software that Qualcomm Atheros, Inc. ("Qualcomm
Atheros") is required to provide you. Except where prohibited by the
open source license, the content of these notices is only provided to
satisfy Qualcomm Atheros's attribution and notice requirement.
Compliance with all copyright laws and software license agreements
included in the notice section of this file are the responsibility of
the user. Except as may be granted by separate express written
agreement, this file provides no license to any patents, trademarks,
copyrights, or other intellectual property of Qualcomm Incorporated or
any of its subsidiaries.
Qualcomm is a trademark of Qualcomm Incorporated, registered in the
United States and other countries. All Qualcomm Incorporated trademarks
are used with permission. Atheros is a trademark of Qualcomm Atheros,
Inc., registered in the United States and other countries. Other
products and brand names may be trademarks or registered trademarks of
their respective owners.
The following files are from the open source wpa_supplicant/hostapd
project (git://w1.fi/srv/git/hostap.git)
wlantest_ctrl.h
wpa_ctrl.c
wpa_ctrl.h
These are redistributed using the BSD license:
Copyright (c) 2003-2012, Jouni Malinen <j@w1.fi> and contributors
All Rights Reserved.
This software may be distributed, used, and modified under the terms of
BSD license:
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. 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.
3. Neither the name(s) of the above-listed copyright holder(s) nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
uapsd_stream.c is based on source code released by Wi-Fi Alliance under
the following terms:
* Copyright (c) 2014 Wi-Fi Alliance
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
* SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE
* USE OR PERFORMANCE OF THIS SOFTWARE.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,123 @@
/*
* Sigma Control API DUT (station/AP)
* Copyright (c) 2010, Atheros Communications, Inc.
* Copyright (c) 2019, The Linux Foundation
* All Rights Reserved.
* Licensed under the Clear BSD license. See README for more details.
*/
#include "sigma_dut.h"
#include "wpa_helpers.h"
static enum sigma_cmd_result cmd_sta_atheros(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
char buf[2048], *pos;
int i;
const char *intf, *c;
char resp[200];
intf = get_param(cmd, "interface");
c = get_param(cmd, "cmd");
if (c == NULL)
return INVALID_SEND_STATUS;
buf[0] = '\0';
if (strncmp(c, "ctrl=", 5) == 0) {
size_t rlen;
c += 5;
if (wpa_command_resp(intf, c, buf, sizeof(buf)) < 0)
return ERROR_SEND_STATUS;
rlen = strlen(buf);
if (rlen > 0 && buf[rlen - 1] == '\n')
buf[rlen - 1] = '\0';
} else if (strncmp(c, "timeout=", 8) == 0) {
unsigned int timeout;
timeout = atoi(c + 8);
if (timeout == 0)
return INVALID_SEND_STATUS;
dut->default_timeout = timeout;
sigma_dut_print(dut, DUT_MSG_INFO, "Set DUT default timeout "
"to %u seconds", dut->default_timeout);
snprintf(buf, sizeof(buf), "OK");
} else
return ERROR_SEND_STATUS;
i = snprintf(resp, sizeof(resp), "resp,");
if (i < 0)
return ERROR_SEND_STATUS;
pos = buf;
while (*pos && i + 1 < (int) sizeof(resp)) {
char c = *pos++;
if (c == '\n' || c == '\r' || c == ',')
c = '^';
resp[i++] = c;
}
resp[i] = '\0';
send_resp(dut, conn, SIGMA_COMPLETE, resp);
return STATUS_SENT;
}
static int req_intf(struct sigma_cmd *cmd)
{
return get_param(cmd, "interface") == NULL ? -1 : 0;
}
#ifdef NL80211_SUPPORT
static enum sigma_cmd_result cmd_atheros_config_scan(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
struct nl_msg *msg;
int ret;
struct nlattr *params;
const char *val;
int ifindex;
val = get_param(cmd, "enable");
if (!val)
return INVALID_SEND_STATUS;
ifindex = if_nametoindex("wlan0");
if (!(msg = nl80211_drv_msg(dut, dut->nl_ctx, ifindex, 0,
NL80211_CMD_VENDOR)) ||
nla_put_u32(msg, NL80211_ATTR_IFINDEX, ifindex) ||
nla_put_u32(msg, NL80211_ATTR_VENDOR_ID, OUI_QCA) ||
nla_put_u32(msg, NL80211_ATTR_VENDOR_SUBCMD,
QCA_NL80211_VENDOR_SUBCMD_SET_WIFI_CONFIGURATION) ||
!(params = nla_nest_start(msg, NL80211_ATTR_VENDOR_DATA)) ||
nla_put_u8(msg,
QCA_WLAN_VENDOR_ATTR_CONFIG_SCAN_ENABLE,
atoi(val))) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"%s: err in adding vendor_cmd and vendor_data",
__func__);
nlmsg_free(msg);
return ERROR_SEND_STATUS;
}
nla_nest_end(msg, params);
ret = send_and_recv_msgs(dut, dut->nl_ctx, msg, NULL, NULL);
if (ret) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"%s: err in send_and_recv_msgs, ret=%d",
__func__, ret);
return ERROR_SEND_STATUS;
}
return STATUS_SENT;
}
#endif /* NL80211_SUPPORT */
void atheros_register_cmds(void)
{
sigma_dut_reg_cmd("sta_atheros", req_intf, cmd_sta_atheros);
#ifdef NL80211_SUPPORT
sigma_dut_reg_cmd("atheros_config_scan", NULL, cmd_atheros_config_scan);
#endif /* NL80211_SUPPORT */
}

View File

@@ -0,0 +1,268 @@
/*
* Sigma Control API DUT (station/AP)
* Copyright (c) 2010, Atheros Communications, Inc.
* Copyright (c) 2011-2014, 2016-2017, Qualcomm Atheros, Inc.
* Copyright (c) 2019-2020, The Linux Foundation
* All Rights Reserved.
* Licensed under the Clear BSD license. See README for more details.
*/
#include "sigma_dut.h"
#ifdef __linux__
#include <sys/stat.h>
#include <linux/ethtool.h>
#include <linux/netlink.h>
#include <linux/sockios.h>
#endif /* __linux__ */
#include "wpa_helpers.h"
#include <sys/ioctl.h>
static enum sigma_cmd_result cmd_ca_get_version(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *info;
info = get_param(cmd, "TestInfo");
if (info) {
char buf[200];
snprintf(buf, sizeof(buf), "NOTE CAPI:TestInfo:%s", info);
wpa_command(get_main_ifname(dut), buf);
}
send_resp(dut, conn, SIGMA_COMPLETE, "version,1.0");
return STATUS_SENT;
}
#ifdef __linux__
static void first_line(char *s)
{
while (*s) {
if (*s == '\r' || *s == '\n') {
*s = '\0';
return;
}
s++;
}
}
void get_ver(const char *cmd, char *buf, size_t buflen)
{
FILE *f;
char *pos;
buf[0] = '\0';
f = popen(cmd, "r");
if (f == NULL)
return;
if (fgets(buf, buflen, f))
first_line(buf);
pclose(f);
pos = strstr(buf, " v");
if (pos == NULL)
buf[0] = '\0';
else
memmove(buf, pos + 1, strlen(pos));
}
#endif /* __linux__ */
static enum sigma_cmd_result cmd_device_get_info(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *vendor = "Qualcomm Atheros";
const char *model = "N/A";
const char *version = "N/A";
#ifdef __linux__
char model_buf[128];
char ver_buf[512];
#endif /* __linux__ */
int res;
char resp[512];
#ifdef __linux__
{
char fname[128], path[128];
struct stat s;
FILE *f;
char compat_ver[128];
char wpa_supplicant_ver[128];
char hostapd_ver[128];
char host_fw_ver[128];
snprintf(path, sizeof(path), "/sys/class/net/%s/phy80211",
get_main_ifname(dut));
if (stat(path, &s) == 0) {
ssize_t res;
char *pos;
res = snprintf(fname, sizeof(fname),
"/sys/class/net/%s/device/driver",
get_main_ifname(dut));
if (res < 0 || res >= sizeof(fname)) {
model = "Linux/";
} else if ((res = readlink(fname, path,
sizeof(path))) < 0) {
model = "Linux/";
} else {
if (res >= (int) sizeof(path))
res = sizeof(path) - 1;
path[res] = '\0';
pos = strrchr(path, '/');
if (pos == NULL)
pos = path;
else
pos++;
res = snprintf(model_buf, sizeof(model_buf),
"Linux/%s", pos);
if (res >= 0 && res < sizeof(model_buf))
model = model_buf;
}
} else
model = "Linux";
/* TODO: get version from wpa_supplicant (+ driver via wpa_s)
*/
f = fopen("/sys/module/compat/parameters/"
"backported_kernel_version", "r");
if (f == NULL)
f = fopen("/sys/module/compat/parameters/"
"compat_version", "r");
if (f) {
if (fgets(compat_ver, sizeof(compat_ver), f) == NULL)
compat_ver[0] = '\0';
else
first_line(compat_ver);
fclose(f);
} else
compat_ver[0] = '\0';
get_ver("./hostapd -v 2>&1", hostapd_ver, sizeof(hostapd_ver));
if (hostapd_ver[0] == '\0')
get_ver("hostapd -v 2>&1", hostapd_ver,
sizeof(hostapd_ver));
get_ver("./wpa_supplicant -v", wpa_supplicant_ver,
sizeof(wpa_supplicant_ver));
if (wpa_supplicant_ver[0] == '\0')
get_ver("wpa_supplicant -v", wpa_supplicant_ver,
sizeof(wpa_supplicant_ver));
host_fw_ver[0] = '\0';
if (get_driver_type(dut) == DRIVER_WCN ||
get_driver_type(dut) == DRIVER_LINUX_WCN) {
get_ver("iwpriv wlan0 version", host_fw_ver,
sizeof(host_fw_ver));
} else if (get_driver_type(dut) == DRIVER_WIL6210) {
struct ethtool_drvinfo drvinfo;
struct ifreq ifr; /* ifreq suitable for ethtool ioctl */
int fd; /* socket suitable for ethtool ioctl */
memset(&drvinfo, 0, sizeof(drvinfo));
drvinfo.cmd = ETHTOOL_GDRVINFO;
memset(&ifr, 0, sizeof(ifr));
strlcpy(ifr.ifr_name, get_main_ifname(dut),
sizeof(ifr.ifr_name));
fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fd < 0)
fd = socket(AF_NETLINK, SOCK_RAW,
NETLINK_GENERIC);
if (fd >= 0) {
ifr.ifr_data = (void *) &drvinfo;
if (ioctl(fd, SIOCETHTOOL, &ifr) == 0)
strlcpy(host_fw_ver, drvinfo.fw_version,
sizeof(host_fw_ver));
close(fd);
}
}
res = snprintf(ver_buf, sizeof(ver_buf),
"drv=%s%s%s%s%s%s%s/sigma=" SIGMA_DUT_VER "%s%s",
compat_ver,
wpa_supplicant_ver[0] ? "/wpas=" : "",
wpa_supplicant_ver,
hostapd_ver[0] ? "/hapd=" : "",
hostapd_ver,
host_fw_ver[0] ? "/wlan=" : "",
host_fw_ver,
dut->version ? "@" : "",
dut->version ? dut->version : "");
if (res < 0 || res >= sizeof(ver_buf))
return ERROR_SEND_STATUS;
version = ver_buf;
}
#endif /* __linux__ */
if (dut->vendor_name)
vendor = dut->vendor_name;
if (dut->model_name)
model = dut->model_name;
if (dut->version_name)
version = dut->version_name;
res = snprintf(resp, sizeof(resp), "vendor,%s,model,%s,version,%s",
vendor, model, version);
if (res < 0 || res >= sizeof(resp))
return ERROR_SEND_STATUS;
send_resp(dut, conn, SIGMA_COMPLETE, resp);
return STATUS_SENT;
}
static int check_device_list_interfaces(struct sigma_cmd *cmd)
{
if (get_param(cmd, "interfaceType") == NULL)
return -1;
return 0;
}
static enum sigma_cmd_result cmd_device_list_interfaces(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *type, *band;
char resp[200];
type = get_param(cmd, "interfaceType");
if (type == NULL)
return -1;
sigma_dut_print(dut, DUT_MSG_DEBUG, "device_list_interfaces - "
"interfaceType=%s", type);
if (strcmp(type, "802.11") != 0)
return ERROR_SEND_STATUS;
band = get_param(cmd, "band");
if (!band) {
} else if (strcasecmp(band, "24g") == 0) {
dut->use_5g = 0;
} else if (strcasecmp(band, "5g") == 0) {
dut->use_5g = 1;
} else {
send_resp(dut, conn, SIGMA_COMPLETE,
"errorCode,Unsupported band value");
return STATUS_SENT_ERROR;
}
snprintf(resp, sizeof(resp), "interfaceType,802.11,interfaceID,%s",
get_main_ifname(dut));
send_resp(dut, conn, SIGMA_COMPLETE, resp);
return STATUS_SENT;
}
void basic_register_cmds(void)
{
sigma_dut_reg_cmd("ca_get_version", NULL, cmd_ca_get_version);
sigma_dut_reg_cmd("device_get_info", NULL, cmd_device_get_info);
sigma_dut_reg_cmd("device_list_interfaces",
check_device_list_interfaces,
cmd_device_list_interfaces);
}

View File

@@ -0,0 +1,37 @@
/*
* Sigma Control API DUT (station/AP)
* Copyright (c) 2010, Atheros Communications, Inc.
* Copyright (c) 2011-2014, 2017, Qualcomm Atheros, Inc.
* Copyright (c) 2019, The Linux Foundation
* All Rights Reserved.
* Licensed under the Clear BSD license. See README for more details.
*/
#include "sigma_dut.h"
void sigma_dut_register_cmds(void)
{
basic_register_cmds();
sta_register_cmds();
traffic_register_cmds();
#ifdef CONFIG_TRAFFIC_AGENT
traffic_agent_register_cmds();
#endif /* CONFIG_TRAFFIC_AGENT */
p2p_register_cmds();
ap_register_cmds();
powerswitch_register_cmds();
atheros_register_cmds();
#ifdef CONFIG_WLANTEST
wlantest_register_cmds();
#endif /* CONFIG_WLANTEST */
dev_register_cmds();
#ifdef CONFIG_SNIFFER
sniffer_register_cmds();
#endif /* CONFIG_SNIFFER */
#ifdef CONFIG_SERVER
server_register_cmds();
#endif /* CONFIG_SERVER */
#ifdef MIRACAST
miracast_register_cmds();
#endif /* MIRACAST */
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,270 @@
/*
* Sigma Control API DUT (station/AP)
* Copyright (c) 2018-2019, The Linux Foundation
* All Rights Reserved.
* Licensed under the Clear BSD license. See README for more details.
*/
#include "sigma_dut.h"
#include "wpa_helpers.h"
#include <netinet/if_ether.h>
#include <netinet/ip.h>
#include <netinet/udp.h>
#include <pcap.h>
#include <signal.h>
#define DHCP_SERVER_PORT 67
#define DHCP_CLIENT_PORT 68
#define DHCP_ACK 5
#define UDP_PROTOCOL 17
static pcap_t *pcap = NULL;
struct dhcp_pkt {
struct iphdr iph;
struct udphdr udph;
u8 op;
u8 htype;
u8 hlen;
u8 hops;
u32 xid;
u16 secs;
u16 flags;
u32 client_ip;
u32 your_ip;
u32 server_ip;
u32 relay_ip;
u8 hw_addr[16];
u8 serv_name[64];
u8 boot_file[128];
u32 magic_cookie;
u8 options[314];
} __attribute__ ((packed));
enum dhcp_options {
DHCP_OPT_SUBNET_MASK = 1,
DHCP_OPT_ROUTER = 3,
DHCP_OPT_MSG_TYPE = 53,
DHCP_OPT_END = 255
};
static u8 * get_dhcp_option(u8 *options, u8 type, int len)
{
u8 *pos = options;
u8 *end = pos + len;
while (pos < end && pos + 1 < end && pos + 2 + pos[1] <= end) {
if (*pos == type)
return pos;
pos += 2 + pos[1];
}
return NULL;
}
/**
* 1. Open UDP socket
* 2. read_msg
* 3. Process DHCP_ACK
*/
static void * process_dhcp_ack(void *ptr)
{
struct bpf_program pcap_fp;
char pcap_filter[200], pcap_err[PCAP_ERRBUF_SIZE];
struct sigma_dut *dut = ptr;
int nbytes = 0;
u8 buf[1024];
struct dhcp_pkt *dhcp;
int option_len;
u8 *msg_type, *val;
struct in_addr ip;
char your_ip[16], mask[16], router[16];
unsigned short protocol, port_no;
bpf_u_int32 pcap_maskp, pcap_netp;
char ifname[20];
protocol = UDP_PROTOCOL;
port_no = DHCP_SERVER_PORT;
strlcpy(ifname, get_main_ifname(dut), sizeof(ifname));
/* gives the network mask for ifname essential for applying filter */
pcap_lookupnet(ifname, &pcap_netp, &pcap_maskp, pcap_err);
sigma_dut_print(dut, DUT_MSG_INFO, "DHCP: ifname = %s", ifname);
/* creates a session for sniffing */
pcap = pcap_open_live(ifname, 2500, 0, 10, pcap_err);
if (!pcap) {
sigma_dut_print(dut, DUT_MSG_INFO, "pcap_open_live: %s",
pcap_err);
goto exit;
}
snprintf(pcap_filter, sizeof(pcap_filter),
"ip proto 0x%x and udp src port 0x%x",
protocol, port_no);
sigma_dut_print(dut, DUT_MSG_INFO, "pcap_flter %s", pcap_filter);
if (pcap_compile(pcap, &pcap_fp, pcap_filter, 1, pcap_netp) < 0)
sigma_dut_print(dut, DUT_MSG_INFO, "pcap_compile: %s",
pcap_geterr(pcap));
if (pcap_setfilter(pcap, &pcap_fp) < 0)
sigma_dut_print(dut, DUT_MSG_INFO, "pcap_setfilter: %s",
pcap_geterr(pcap));
pcap_freecode(&pcap_fp);
while (1) {
memset(buf, 0, sizeof(buf));
sigma_dut_print(dut, DUT_MSG_DEBUG,
"HLP: Waiting for message to receive");
nbytes = recvfrom(pcap_get_selectable_fd(pcap), &buf,
sizeof(buf), 0, NULL, NULL);
if (nbytes == -1) {
sigma_dut_print(dut, DUT_MSG_ERROR, "HLP: failed: %s",
strerror(errno));
goto exit;
}
sigma_dut_print(dut, DUT_MSG_INFO, "HLP: Received %d bytes",
nbytes);
hex_dump(dut, buf, nbytes);
if (nbytes < 314) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"HLP: Ignore MSG, Too short message received");
continue;
}
nbytes -= 14;
/*
* Process DHCP packet
* skip ethernet header from buf and then process the ack
*/
dhcp = (struct dhcp_pkt *) (buf + ETH_HLEN);
option_len = nbytes - ((char *) dhcp->options - (char *) dhcp);
sigma_dut_print(dut, DUT_MSG_DEBUG,
"option_len %d, First option : %02x",
option_len, *(dhcp->options));
/* Check for DHCP_ACK */
msg_type = get_dhcp_option(dhcp->options, DHCP_OPT_MSG_TYPE,
option_len);
if (!msg_type) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Ignore MSG, DHCP OPT MSG_TYPE missing");
continue;
}
if (msg_type[2] != DHCP_ACK) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Ignore MSG, DHCP message type : %02x",
msg_type[2]);
continue;
}
ip.s_addr = dhcp->your_ip;
strlcpy(your_ip, inet_ntoa(ip), sizeof(your_ip));
val = get_dhcp_option(dhcp->options, DHCP_OPT_SUBNET_MASK,
option_len);
if (!val) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"DHCP option SUBNET_MASK missing");
continue;
}
memcpy(&(ip.s_addr), (val + 2), val[1]);
strlcpy(mask, inet_ntoa(ip), sizeof(mask));
val = get_dhcp_option(dhcp->options, DHCP_OPT_ROUTER,
option_len);
if (!val) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"DHCP option DHCP_OPT_ROUTER missing");
continue;
}
memcpy(&(ip.s_addr), val + 2, val[1]);
strlcpy(router, inet_ntoa(ip), sizeof(router));
sigma_dut_print(dut, DUT_MSG_DEBUG,
"OP: %d, your_ip: %s, netmask: %s, router: %s",
dhcp->op, your_ip, mask, router);
/* set ip configuration */
if (!set_ipv4_addr(dut, ifname, your_ip, mask)) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set IP address");
continue;
}
if (set_ipv4_gw(dut, router) < 1) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to set Gateway address");
continue;
}
sigma_dut_print(dut, DUT_MSG_DEBUG,
"IP configuration completed");
}
exit:
sigma_dut_print(dut, DUT_MSG_INFO, "HLP: Received failed in exit");
if (pcap) {
pcap_close(pcap);
pcap = NULL;
}
dut->hlp_thread = 0;
return NULL;
}
static void hlp_thread_exit(int signum)
{
pthread_exit(0);
}
void hlp_thread_cleanup(struct sigma_dut *dut)
{
if (pcap) {
pcap_close(pcap);
pcap = NULL;
}
if (dut->hlp_thread) {
sigma_dut_print(dut, DUT_MSG_DEBUG, "Kill thread: %ld",
dut->hlp_thread);
pthread_kill(dut->hlp_thread, SIGUSR1);
dut->hlp_thread = 0;
}
}
void process_fils_hlp(struct sigma_dut *dut)
{
static pthread_t hlp_thread;
if (dut->hlp_thread) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"FILS-HLP DHCP thread already running");
return;
}
signal(SIGUSR1, hlp_thread_exit);
sigma_dut_print(dut, DUT_MSG_DEBUG, "Creating FILS_HLP thread-->");
/* create FILS_HLP thread */
if (!pthread_create(&hlp_thread, NULL, &process_dhcp_ack,
(void *) dut)) {
dut->hlp_thread = hlp_thread;
} else {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"FILS_HLP thread creation failed");
}
}

View File

@@ -0,0 +1,90 @@
/*
* Sigma Control API DUT (DNS service discovery functionality)
* Copyright (c) 2023, Qualcomm Innovation Center, Inc.
* All Rights Reserved.
* Licensed under the Clear BSD license. See README for more details.
*/
#include "sigma_dut.h"
#include <dlfcn.h>
static void * get_dl_sym(struct sigma_dut *dut, void *handle,
const char *symbol)
{
void *sym = dlsym(handle, symbol);
if (!sym)
sigma_dut_print(dut, DUT_MSG_ERROR, "Could not resolve %s",
symbol);
return sym;
}
int mdnssd_init(struct sigma_dut *dut)
{
dut->mdnssd_so = dlopen("/vendor/lib64/libmdnssd.so", RTLD_NOW);
if (!dut->mdnssd_so) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Could not open libmdnssd.so");
return -1;
}
dut->mdnssd.service_create_connection = get_dl_sym(
dut, dut->mdnssd_so, "DNSServiceCreateConnection");
dut->mdnssd.service_socket_fd = get_dl_sym(dut, dut->mdnssd_so,
"DNSServiceRefSockFD");
dut->mdnssd.service_process_result = get_dl_sym(
dut, dut->mdnssd_so, "DNSServiceProcessResult");
dut->mdnssd.service_register = get_dl_sym(dut, dut->mdnssd_so,
"DNSServiceRegister");
dut->mdnssd.service_deallocate = get_dl_sym(dut, dut->mdnssd_so,
"DNSServiceRefDeallocate");
dut->mdnssd.service_browse = get_dl_sym(dut, dut->mdnssd_so,
"DNSServiceBrowse");
dut->mdnssd.service_resolve = get_dl_sym(dut, dut->mdnssd_so,
"DNSServiceResolve");
dut->mdnssd.get_addr_info = get_dl_sym(dut, dut->mdnssd_so,
"DNSServiceGetAddrInfo");
dut->mdnssd.txt_create = get_dl_sym(dut, dut->mdnssd_so,
"TXTRecordCreate");
dut->mdnssd.txt_set_value = get_dl_sym(dut, dut->mdnssd_so,
"TXTRecordSetValue");
dut->mdnssd.txt_deallocate = get_dl_sym(dut, dut->mdnssd_so,
"TXTRecordDeallocate");
dut->mdnssd.txt_contains_key = get_dl_sym(dut, dut->mdnssd_so,
"TXTRecordContainsKey");
dut->mdnssd.txt_get_value = get_dl_sym(dut, dut->mdnssd_so,
"TXTRecordGetValuePtr");
dut->mdnssd.txt_get_length = get_dl_sym(dut, dut->mdnssd_so,
"TXTRecordGetLength");
dut->mdnssd.txt_get_bytes = get_dl_sym(dut, dut->mdnssd_so,
"TXTRecordGetBytesPtr");
if (!dut->mdnssd.service_create_connection ||
!dut->mdnssd.service_socket_fd ||
!dut->mdnssd.service_process_result ||
!dut->mdnssd.service_register ||
!dut->mdnssd.service_deallocate ||
!dut->mdnssd.service_browse ||
!dut->mdnssd.service_resolve ||
!dut->mdnssd.get_addr_info ||
!dut->mdnssd.txt_create ||
!dut->mdnssd.txt_set_value ||
!dut->mdnssd.txt_deallocate ||
!dut->mdnssd.txt_contains_key ||
!dut->mdnssd.txt_get_value ||
!dut->mdnssd.txt_get_length ||
!dut->mdnssd.txt_get_bytes) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Could not resolve needed symbol from libmdnssd.so");
memset(&dut->mdnssd, 0, sizeof(dut->mdnssd));
dlclose(dut->mdnssd_so);
dut->mdnssd_so = NULL;
return -1;
}
sigma_dut_print(dut, DUT_MSG_INFO, "Successfully loaded libmdnssd.so");
return 0;
}

View File

@@ -0,0 +1,88 @@
#!/usr/bin/env python3
#
# Sigma Control API DUT (DPP CA)
# Copyright (c) 2020, The Linux Foundation
# All Rights Reserved.
# Licensed under the Clear BSD license. See README for more details.
import base64
import OpenSSL
import os
import subprocess
import sys
def dpp_sign_cert(cacert, cakey, csr_der):
csr = OpenSSL.crypto.load_certificate_request(OpenSSL.crypto.FILETYPE_ASN1,
csr_der)
cert = OpenSSL.crypto.X509()
cert.set_serial_number(12345)
cert.gmtime_adj_notBefore(-10)
cert.gmtime_adj_notAfter(100000)
cert.set_pubkey(csr.get_pubkey())
dn = csr.get_subject()
cert.set_subject(dn)
cert.set_version(2)
cert.add_extensions([
OpenSSL.crypto.X509Extension(b"basicConstraints", True,
b"CA:FALSE"),
OpenSSL.crypto.X509Extension(b"subjectKeyIdentifier", False,
b"hash", subject=cert),
OpenSSL.crypto.X509Extension(b"authorityKeyIdentifier", False,
b"keyid:always", issuer=cacert),
])
cert.set_issuer(cacert.get_subject())
cert.sign(cakey, "sha256")
return cert
def main():
if len(sys.argv) < 2:
print("No certificate directory path provided")
sys.exit(-1)
cert_dir = sys.argv[1]
cacert_file = os.path.join(cert_dir, "dpp-ca.pem")
cakey_file = os.path.join(cert_dir, "dpp-ca.key")
csr_file = os.path.join(cert_dir, "dpp-ca-csr")
cert_file = os.path.join(cert_dir, "dpp-ca-cert")
pkcs7_file = os.path.join(cert_dir, "dpp-ca-pkcs7")
certbag_file = os.path.join(cert_dir, "dpp-ca-certbag")
with open(cacert_file, "rb") as f:
res = f.read()
cacert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM,
res)
with open(cakey_file, "rb") as f:
res = f.read()
cakey = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, res)
if not os.path.exists(csr_file):
print("No CSR file: %s" % csr_file)
sys.exit(-1)
with open(csr_file) as f:
csr_b64 = f.read()
csr = base64.b64decode(csr_b64)
if not csr:
print("Could not base64 decode CSR")
sys.exit(-1)
cert = dpp_sign_cert(cacert, cakey, csr)
with open(cert_file, 'wb') as f:
f.write(OpenSSL.crypto.dump_certificate(OpenSSL.crypto.FILETYPE_PEM,
cert))
subprocess.check_call(['openssl', 'crl2pkcs7', '-nocrl',
'-certfile', cert_file,
'-certfile', cacert_file,
'-outform', 'DER', '-out', pkcs7_file])
with open(pkcs7_file, 'rb') as f:
pkcs7_der = f.read()
certbag = base64.b64encode(pkcs7_der)
with open(certbag_file, 'wb') as f:
f.write(certbag)
if __name__ == "__main__":
main()

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,144 @@
/*
* e_loop helper program
* Copyright (c) 2015, Qualcomm Atheros, Inc.
* All Rights Reserved.
* Licensed under the Clear BSD license. See README for more details.
*/
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <unistd.h>
#include <sys/wait.h>
char *e_loop_cmd_file = "/data/local/hs2/To_Phone/tag_file";
char *e_loop_log_file = "/data/local/hs2/To_Phone/Logs/e_loop.log";
static const char *log_file = NULL;
static const char *tag_file = NULL;
int main(int argc, char *argv[])
{
char *buf = NULL;
char *cmd = NULL;
long pos;
int c, ret;
size_t len = 0;
FILE *f, *f2 = NULL;
/* Set the defaults */
log_file = e_loop_log_file;
tag_file = e_loop_cmd_file;
for (;;) {
c = getopt(argc, argv, "l:t:");
if (c < 0)
break;
switch (c) {
case 'l':
log_file = optarg;
break;
case 't':
tag_file = optarg;
break;
default:
printf("usage: e_loop [-l<log_filename>] [-t<tag_filename>]\n");
exit(0);
break;
}
}
/* Main command event loop */
while (1) {
/* Wait for a tag_file with a command to process */
while (!(f = fopen(tag_file, "rb")))
sleep(1);
len = 80;
/* Figure out how long the file is */
if (fseek(f, 0, SEEK_END) < 0 || (pos = ftell(f)) < 0) {
fclose(f);
return -1;
}
len = pos;
if (fseek(f, 0, SEEK_SET) < 0) {
fclose(f);
return -1;
}
buf = malloc(len);
if (!buf) {
fclose(f);
return -1;
}
/* Read up the command line */
if (fread(buf, 1, len, f) != len) {
fclose(f);
free(buf);
return -1;
}
fclose(f);
buf[len - 1] = '\0';
if (log_file) {
len = strlen(buf) + strlen(log_file) + 7;
cmd = malloc(len);
if (cmd == NULL) {
free(buf);
return -1;
}
ret = snprintf(cmd, len, "%s > %s", buf, log_file);
if (ret < 0 || (size_t) ret >= len) {
free(buf);
free(cmd);
return -1;
}
free(buf);
buf = NULL;
} else {
cmd = buf;
}
cmd[len - 1] = '\0';
/*
* This string "cmd" will contain the command passed in by
* hs20-action.sh. And the name of the "logfile". Which can be
* monitored for the result.
*/
ret = system(cmd);
if (WIFEXITED(ret)) {
ret = WEXITSTATUS(ret);
}
if ((f2 = fopen(log_file, "a")) == NULL) {
free(cmd);
return -1;
}
if (fprintf(f2,"\nELOOP_CMD : %s\n", cmd) <= 0) {
fclose(f2);
free(cmd);
return -1;
}
if (fprintf(f2,"\nELOOP_CMD_STATUS : %d\n", ret) <= 0) {
fclose(f2);
free(cmd);
return -1;
}
/* Only free the cmd buffer. It is all that is left allocated */
free(cmd);
fclose(f2);
/* Clean up */
unlink(tag_file);
}
return ret;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,57 @@
/*
* Sigma Control API DUT - Miracast interface
* Copyright (c) 2017, Qualcomm Atheros, Inc.
* All Rights Reserved.
* Licensed under the Clear BSD license. See README for more details.
*/
#ifndef SIGMA_MIRACAST_H
#define SIGMA_MIRACAST_H
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <time.h>
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#ifdef ANDROID
#include "properties.h"
#endif /* ANDROID */
struct sigma_dut;
struct sigma_conn;
struct sigma_cmd;
void miracast_init(struct sigma_dut *sigma_dut);
void miracast_deinit(struct sigma_dut *sigma_dut);
void miracast_start_autonomous_go(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd, char *ifname);
int miracast_dev_send_frame(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd);
int miracast_dev_exec_action(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd);
int miracast_preset_testparameters(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd);
int miracast_cmd_sta_get_parameter(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd);
void miracast_sta_reset_default(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd);
#endif /* SIGMA_MIRACAST_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,40 @@
#!/bin/sh
STATE=$1
shift
OPER=$*
play()
{
canberra-gtk-play --file=$1 &
}
if [ "$STATE" = "START" ]; then
zenity --title="NFC operation" --info --text="$OPER" &
echo $! > nfc-status.pid
play /usr/share/sounds/ubuntu/stereo/system-ready.ogg
#espeak "NFC $OPER"
fi
if [ "$STATE" = "SUCCESS" -o "$STATE" = "FAIL" ]; then
if [ -r nfc-status.pid ]; then
pid=`cat nfc-status.pid`
rm nfc-status.pid
if [ $pid -gt 0 ]; then
if ps -o command $pid | grep -q zenity; then
kill $pid
fi
fi
fi
fi
if [ "$STATE" = "SUCCESS" ]; then
play /usr/share/sounds/freedesktop/stereo/complete.oga
#espeak "Success"
fi
if [ "$STATE" = "FAIL" ]; then
play /usr/share/sounds/freedesktop/stereo/bell.oga
#espeak "Failed"
fi

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,52 @@
/*
* Sigma Control API DUT (station/AP)
* Copyright (c) 2010, Atheros Communications, Inc.
* Copyright (c) 2019, The Linux Foundation
* All Rights Reserved.
* Licensed under the Clear BSD license. See README for more details.
*/
#include "sigma_dut.h"
static enum sigma_cmd_result cmd_power_switch_ctrl(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
return SUCCESS_SEND_STATUS;
}
static enum sigma_cmd_result cmd_power_switch_reset(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
if (system("killall hostapd") == 0) {
int i;
/* Wait some time to allow hostapd to complete cleanup before
* starting a new process */
for (i = 0; i < 10; i++) {
usleep(500000);
if (system("pidof hostapd") != 0)
break;
}
}
return SUCCESS_SEND_STATUS;
}
static enum sigma_cmd_result cmd_powerswitch(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
return SUCCESS_SEND_STATUS;
}
void powerswitch_register_cmds(void)
{
sigma_dut_reg_cmd("power_switch_ctrl", NULL, cmd_power_switch_ctrl);
sigma_dut_reg_cmd("power_switch_reset", NULL, cmd_power_switch_reset);
sigma_dut_reg_cmd("PowerSwitch", NULL, cmd_powerswitch);
}

View File

@@ -0,0 +1,23 @@
#### Probe request frame for P2P devices (using P2P wildcard as SSID - "DIRECT-") ####
# Frame control - type management(0) and subtype probe request(4)
4000
# Duration
a104
# DA (destination address)
001500f8b3c1
# SA (source address)
04ce14000704
# BSSID
ffffffffffff
# Fragment number and sequence number
7000
### IEs ###
# SSID IE
00074449524543542d
# DMG capabilities IE
941104ce140007040110d1b706000040000000
# WPS IE
dd7e0050f204104a000110103a0001011008000231081047001028dc5a4aa4b9590e829f8feaaef981e61054000800010050f2040001103c000104100200020000100900020000101200020000102100012010230001201024000120101100135175616c636f6d6d5f313161645f74657374311049000900372a000120030101
# P2P IE
dd3c506f9a090202002100060500585804b4020d280004ce14000704110800010050f204000100101100135175616c636f6d6d5f313161645f7465737431

View File

@@ -0,0 +1,22 @@
#### Probe request frame for all devices (wildcard SSID) ####
# Frame control - type management(0) and subtype probe request(4)
4000
# Duration
cc04
# DA (destination address)
04ce14000704
# SA (source address)
001500f8b3c1
# BSSID
04ce14000704
# Fragment number and sequence number
1000
### IEs ###
# SSID IE
0000
# DMG capabilities
9411001500f8b3c100c18e53c5000342101308
# WPS IE
dd800050f204104a000110103a00010010080002400810470010001500f8b3c10000000000000000000010540008000c0050f2040001103c0001041002000200001009000200001012000200001021000a496e74656c20436f72701023000a4d61706c65205065616b1024000831333130304e475710110002696910490003000120
# P2P IE
dd43506f9a090202003106060500888804b4020d2700001500f8b3c14008000c0050f204000102000c00d45c700003000c00d45c700005101100026969110500888804b402

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,228 @@
#!/system/bin/sh
# HotSpot2.0 Release 2 action script - hs20-action.sh
# Supports the testing of wpa_supplicant and wlan driver
# support for HotSpot2.0 Release 2 on Android.
# It assumes that busybox is installed.
# Copyright (c) 2014, Qualcomm Atheros, Inc.
# All Rights Reserved.
# Licensed under the Clear BSD license. See README for more details.
BASEDIR=$(busybox dirname $0)
date >> $BASEDIR/Logs/hs20-action.log
echo "$*" >> $BASEDIR/Logs/hs20-action.log
if [ -e $BASEDIR/summary ]; then
echo "$*" >> $BASEDIR/summary
fi
IFNAME=$1
CMD=$2
echo "CMD=$CMD"
echo "CMD=$CMD" >> $BASEDIR/Logs/hs20-action.log
if [ -e /data/vendor/wifi/wpa/sockets/$IFNAME ]; then
IFACE_DIR=/data/vendor/wifi/wpa/sockets/
else
IFACE_DIR=/data/misc/wifi/sockets/
fi
run_eloop_cmd()
{
rm -f $BASEDIR/Logs/e_loop.log
echo "$1" > $BASEDIR/tag_file
# Read back the status of the command issued to e_loop
i=1
while [ ! -e $BASEDIR/Logs/e_loop.log ]
do
sleep 1
echo "Waiting $i second(s) for result..." >> $BASEDIR/Logs/hs20-action.log
if [ "$i" = "30" ] ; then
echo "Something went wrong with e_loop, exiting" >> $BASEDIR/Logs/hs20-action.log
exit 0
fi
i=$(($i + 1))
done
cmd=$(grep "ELOOP_CMD :" $BASEDIR/Logs/e_loop.log)
status=$(grep "ELOOP_CMD_STATUS :" $BASEDIR/Logs/e_loop.log)
echo "Eloop: $cmd ; $status" >> $BASEDIR/Logs/hs20-action.log
}
# generated cleanup url for system() command
cleanup_url()
{
sp_str="&"
mod_str="\\\\&"
URL="${1//$sp_str/$mod_str}"
}
if [ "$CMD" = "HS20-SUBSCRIPTION-REMEDIATION" ]; then
METHOD="$3"
cleanup_url "$4"
cd $BASEDIR
date >> Logs/hs20-osu-client.txt
echo "METHOD=$METHOD" >> Logs/hs20-osu-client.txt
echo "URL=$URL" >> Logs/hs20-osu-client.txt
if [ -e $BASEDIR/SP/wi-fi.org/pps.xml ]; then
run_eloop_cmd "nohup hs20-osu-client -w $IFACE_DIR -r hs20-osu-client.res -s summary -dddKt -f Logs/hs20-osu-client.txt sub_rem $URL SP/wi-fi.org/pps.xml SP/wi-fi.org/ca.pem >> Logs/browser.txt 2>&1 &"
else
if [ "$METHOD" = "0" ]; then
run_eloop_cmd "hs20-osu-client -w $IFACE_DIR -r hs20-osu-client.res -s summary -dddKt -f Logs/hs20-osu-client.txt oma_dm_sim_prov $URL osu-ca.pem"
else
run_eloop_cmd "hs20-osu-client -w $IFACE_DIR -r hs20-osu-client.res -s summary -dddKt -f Logs/hs20-osu-client.txt sim_prov $URL osu-ca.pem"
fi
fi
RES=$?
if [ -r hs20-osu-client.res ]; then
# notify-send "'cat hs20-osu-client.res'"
echo "hs20-osu-client: 'cat hs20-osu-client.res'" >> summary
elif [ "$RES" = "0" ]; then
echo "hs20-osu-client success" >> summary
else
echo "hs20-osu-client error" >> summary
fi
date >> Logs/hs20-osu-client.txt
fi
if [ "$CMD" = "CONNECTED" ]; then
if [ -e $BASEDIR/static-ip ]; then
if read ver addr mask gw < $BASEDIR/static-ip; then
echo "ver=$ver addr=$addr mask=$mask gw=$gw" >> $BASEDIR/Logs/hs20-action.log
if [ "$ver" = "6" ]; then
run_eloop_cmd "busybox sysctl -w net.ipv6.conf.$IFNAME.accept_dad=2 net.ipv6.conf.$IFNAME.dad_transmits=4 net.ipv6.conf.$IFNAME.autoconf=0 net.ipv6.conf.$IFNAME.ndisc_notify=1"
run_eloop_cmd "ip -6 addr del $addr/$mask dev $IFNAME"
run_eloop_cmd "busybox sysctl -w net.ipv6.conf.$IFNAME.disable_ipv6=0"
run_eloop_cmd "ip -6 addr add $addr/$mask dev $IFNAME"
sleep 4
run_eloop_cmd "ip addr show dev $IFNAME"
if [[ ! -z $(busybox grep -i $addr $BASEDIR/Logs/e_loop.log | grep -i dadfailed ) ]] ; then
echo "Duplicate IPv6 address $addr found on $IFNAME" >> $BASEDIR/Logs/hs20-action.log
#I need a version of the "notify-send" command that works in Android
#notify-send "Duplicate IPv6 address $addr found on $IFNAME"
exit 0
fi
if [[ -z $(grep -i $addr $BASEDIR/Logs/e_loop.log) ]] ; then
echo "Could not assign the requested IPv6 address $addr on $IFNAME" >> $BASEDIR/Logs/hs20-action.log
#notify-send "Could not assign the requested IPv6 address $addr on $IFNAME"
exit 0
fi
else
echo "Cleaning up and Sleeping 4 seconds..." >> $BASEDIR/Logs/hs20-action.log
rm -f $BASEDIR/Logs/e_loop.log
sleep 4
echo "Waking up..." >> $BASEDIR/Logs/hs20-action.log
run_eloop_cmd "busybox arping -c 4 -D -I $IFNAME -s 0.0.0.0 $addr"
#Search for the string "Unicast reply". Then you know you have a duplicate IP address...
if [[ ! -z $(grep Unicast $BASEDIR/Logs/e_loop.log) ]] ; then
echo "Duplicate IPv4 address $addr found on $IFNAME" >> $BASEDIR/Logs/hs20-action.log
#notify-send "Duplicate IPv4 address $addr found on $IFNAME"
exit 0
else
echo "Duplicate IPv4 address $addr NOT found on $IFNAME. Configuring address." >> $BASEDIR/Logs/hs20-action.log
fi
ifconfig $IFNAME $addr netmask $mask
run_eloop_cmd "busybox arping -c 4 -I $IFNAME -s $addr $addr"
if [ "$gw" != "N/A" ]; then
route add default gw "$gw"
ip ro re default via "$gw"
fi
fi
else
echo "Could not parse static-ip" >> $BASEDIR/Logs/hs20-action.log
fi
exit
fi
run_eloop_cmd "busybox sysctl -w net.ipv6.conf.$IFNAME.disable_ipv6=1 net.ipv6.conf.$IFNAME.autoconf=1 net.ipv6.conf.$IFNAME.accept_ra=1 net.ipv6.conf.$IFNAME.ndisc_notify=1 net.ipv6.conf.$IFNAME.disable_ipv6=0"
# Do not run dhcpcd from here as sigma_dut is already starting appropriate
# dhcp binary on CTRL-EVENT-CONNECTED.
fi
if [ "$CMD" = "ESS-DISASSOC-IMMINENT" ]; then
cd $BASEDIR
PMF="$3"
TIME_IN_MS="$4"
cleanup_url "$5"
count=1
if [ "$PMF" = "0" ]; then
echo "Disassociation imminent notification received without PMF - ignored" >> summary
exit 0
fi
echo "Disassociation imminent notification received - URL: $URL" >> summary
case "$URL" in
http*)
while [ $count -le 10 ]
do
sleep 1
addr=$(busybox ip addr show dev $IFNAME | grep "inet ")
if [ -n "$addr" ]; then
if ! busybox pidof hs20-osu-client; then
run_eloop_cmd "nohup hs20-osu-client -w $IFACE_DIR -f Logs/hs20-osu-client.txt browser $URL > Logs/browser.txt 2>&1 &"
fi
break
else
echo "waiting $count seconds"
fi
count=$(($count + 1))
done
;;
esac
# notify-send "Disassociation imminent"
fi
if [ "$CMD" = "HS20-DEAUTH-IMMINENT-NOTICE" ]; then
cd $BASEDIR
CODE="$3"
DELAY="$4"
cleanup_url "$5"
count=1
echo "HS 2.0 Deauthentication Imminent notification received - code=$CODE reauth_delay=$DELAY URL: $URL" >> summary
case "$URL" in
http*)
while [ $count -le 10 ]
do
sleep 1
addr=$(busybox ip addr show dev $IFNAME | grep "inet ")
if [ -n "$addr" ]; then
if ! busybox pidof hs20-osu-client; then
run_eloop_cmd "nohup hs20-osu-client -w $IFACE_DIR -f Logs/hs20-osu-client.txt browser $URL > Logs/browser.txt 2>&1 &"
fi
break
else
echo "waiting $count seconds"
fi
count=$(($count + 1))
done
;;
esac
# notify-send "HS 2.0 Deauthentication imminent"
fi
if [ "$CMD" = "HS20-T-C-ACCEPTANCE" ]; then
cd $BASEDIR
cleanup_url "$3"
count=1
echo "HS 2.0 Terms and Conditions notification received - URL: $URL" >> summary
case "$URL" in
http*)
while [ $count -le 10 ]
do
sleep 1
addr=$(busybox ip addr show dev $IFNAME | grep "inet ")
if [ -n "$addr" ]; then
if ! busybox pidof hs20-osu-client; then
run_eloop_cmd "nohup hs20-osu-client -w $IFACE_DIR -f Logs/hs20-osu-client.txt browser $URL > Logs/browser.txt 2>&1 &"
fi
break
else
echo "waiting $count seconds"
fi
count=$(($count + 1))
done
;;
esac
fi

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,79 @@
#!/usr/bin/python
#
# Sigma Control API DUT (sniffer - P2P NoA check)
# Copyright (c) 2014, Qualcomm Atheros, Inc.
# All Rights Reserved.
# Licensed under the Clear BSD license. See README for more details.
import sys
import subprocess
infile = sys.argv[1]
bssid = sys.argv[2]
srcmac = sys.argv[3]
destmac = sys.argv[4]
tshark = subprocess.Popen(['tshark', '-r', infile,
'-c', '1',
'-R', 'wlan.sa==' + bssid + " and wlan.fc.type_subtype==8",
'-Tfields',
'-e', 'radiotap.mactime',
'-e', 'wlan_mgt.fixed.timestamp',
'-e', 'wifi_p2p.noa.duration',
'-e', 'wifi_p2p.noa.interval',
'-e', 'wifi_p2p.noa.start_time',
'-e', 'frame.time_relative'],
stdout=subprocess.PIPE)
noa_data = tshark.stdout.read()
vals = noa_data.rstrip().split('\t')
mactime = int(vals[0])
timestamp = int(vals[1], 16)
noa_duration = int(vals[2])
noa_interval = int(vals[3])
noa_start = int(vals[4])
frame_time = float(vals[5])
if noa_start > timestamp:
print "FilterStatus,FAIL,reasonCode,Unexpected NoA Start Time after Beacon timestamp"
sys.exit()
noa_start_mactime = mactime - (timestamp - noa_start)
noa_start_frame_time = frame_time - (timestamp - noa_start) / 1000000.0
debug = open(infile + ".txt", "w")
debug.write("mactime={}\ntimestamp={}\nnoa_duration={}\nnoa_interval={}\nnoa_start={}\nnoa_start_mactime={}\nnoa_start_frame_time={}\n".format(mactime, timestamp, noa_duration, noa_interval, noa_start, noa_start_mactime, noa_start_frame_time))
tshark = subprocess.Popen(['tshark', '-r', infile,
'-R', 'wlan.da==' + destmac + " and wlan.sa==" + srcmac,
'-Tfields',
'-e', 'frame.number',
'-e', 'radiotap.mactime',
'-e', 'frame.time_relative'],
stdout=subprocess.PIPE)
frames = tshark.stdout.read()
error_frame = None
debug.write("\nframenum mactime offset(mactime) offset(frametime)\n")
for f in frames.splitlines():
vals = f.rstrip().split('\t')
framenum = int(vals[0])
mactime = int(vals[1])
frametime = float(vals[2])
if mactime < noa_start_mactime:
print "FilterStatus,FAIL,reasonCode,Unexpected mactime before NoA Start Time"
sys.exit()
offset = (mactime - noa_start_mactime) % noa_interval
offset_t = ((frametime - noa_start_frame_time) * 1000000) % noa_interval
debug.write("{} {} {} {}\n".format(framenum, mactime, offset, offset_t))
# allow 200 us as extra buffer to compensate for sniffer inaccuracy
allow_buffer = 200
if offset > allow_buffer and offset + allow_buffer < noa_duration:
debug.write("Frame {} during GO absence (mactime) (mactime={}, offset={} usec, NoA-duration={} usec)\n".format(framenum, mactime, offset, noa_duration))
error_frame = framenum
if offset_t > allow_buffer and offset_t + allow_buffer < noa_duration:
debug.write("Frame {} during GO absence (frametime) (frametime={}, offset={} usec, NoA-duration={} usec)\n".format(framenum, frametime, offset_t, noa_duration))
#error_frame = framenum
if error_frame:
print "FilterStatus,FAILURE,frameNumber," + str(error_frame)
else:
print "FilterStatus,SUCCESS"

View File

@@ -0,0 +1,69 @@
#!/usr/bin/python
#
# Sigma Control API DUT (sniffer_control_field_check)
# Copyright (c) 2014, Qualcomm Atheros, Inc.
# All Rights Reserved.
# Licensed under the Clear BSD license. See README for more details.
import sys
import subprocess
import tshark
framename = None
wsc_state = None
pvb_bit = None
moredata_bit = None
eosp_bit = None
for arg in sys.argv:
if arg.startswith("FileName="):
infile = arg.split("=", 1)[1]
elif arg.startswith("SrcMac="):
srcmac = arg.split("=", 1)[1]
elif arg.startswith("FrameName="):
framename = arg.split("=", 1)[1].lower()
elif arg.startswith("WSC_State="):
wsc_state = arg.split("=", 1)[1]
elif arg.startswith("pvb_bit="):
pvb_bit = arg.split("=", 1)[1]
elif arg.startswith("MoreData_bit="):
moredata_bit = arg.split("=", 1)[1]
elif arg.startswith("EOSP_bit="):
eosp_bit = arg.split("=", 1)[1]
filter = 'wlan.sa==' + srcmac
if framename:
frame_filters = tshark.tshark_framenames()
if framename not in frame_filters:
print "errorCode,Unsupported FrameName"
sys.exit()
filter = filter + " and " + frame_filters[framename]
if wsc_state:
filter = filter + " and wps.wifi_protected_setup_state == " + wsc_state
if pvb_bit:
val = int(pvb_bit)
if val == 1:
filter = filter + " and wlan_mgt.tim.partial_virtual_bitmap != 0"
elif val == 0:
filter = filter + " and wlan_mgt.tim.partial_virtual_bitmap == 0"
else:
filter = filter + " and wlan_mgt.tim.partial_virtual_bitmap == " + pvb_bit
if moredata_bit:
filter = filter + " and wlan.fc.moredata == " + moredata_bit
if eosp_bit:
filter = filter + " and wlan.qos.eosp == " + eosp_bit
cmd = ['tshark', '-r', infile, '-c', '1', '-R', filter,
'-Tfields', '-e', 'frame.number']
tshark = subprocess.Popen(cmd, stdout=subprocess.PIPE)
data = tshark.stdout.read()
frames = data.splitlines()
if len(frames) == 0:
print "CheckResult,FAIL"
else:
print "CheckResult,SUCCESS"

View File

@@ -0,0 +1,77 @@
#!/usr/bin/python
#
# Sigma Control API DUT (sniffer_control_filter_capture)
# Copyright (c) 2014, Qualcomm Atheros, Inc.
# All Rights Reserved.
# Licensed under the Clear BSD license. See README for more details.
import sys
import subprocess
import tshark
framename = None
hasfield = None
datalen = None
for arg in sys.argv:
if arg.startswith("InFile="):
infile = arg.split("=", 1)[1]
elif arg.startswith("OutFile="):
outfile = arg.split("=", 1)[1]
elif arg.startswith("SrcMac="):
srcmac = arg.split("=", 1)[1]
elif arg.startswith("FrameName="):
framename = arg.split("=", 1)[1].lower()
elif arg.startswith("HasField="):
hasfield = arg.split("=", 1)[1].lower()
elif arg.startswith("Nframes="):
nframes = arg.split("=", 1)[1]
elif arg.startswith("Datalen="):
datalen = arg.split("=", 1)[1]
filter = 'wlan.sa==' + srcmac
if framename:
frame_filters = tshark.tshark_framenames()
if framename not in frame_filters:
print "errorCode,Unsupported FrameName"
sys.exit()
filter = filter + " and " + frame_filters[framename]
if hasfield:
fields = tshark.tshark_hasfields()
if hasfield not in fields:
print "errorCode,Unsupported HasField"
sys.exit()
filter = filter + " and " + fields[hasfield]
if datalen:
filter = filter + " and wlan.fc.type == 2 and data.len == " + datalen
if nframes == "last":
cmd = ['tshark', '-r', infile, '-R', filter,
'-Tfields', '-e', 'frame.number']
tshark = subprocess.Popen(cmd, stdout=subprocess.PIPE)
data = tshark.stdout.read()
frames = data.splitlines()
if len(frames) == 0:
print "CheckResult,NoPacketsFound"
sys.exit()
filter = "frame.number == " + frames[-1]
nframes = "1"
elif nframes == "all":
nframes = "9999999"
cmd = ['tshark', '-r', infile, '-w', outfile,
'-c', nframes,
'-R', filter]
tshark = subprocess.Popen(cmd, stdout=subprocess.PIPE)
data = tshark.stdout.read()
cmd = ['tshark', '-r', outfile, '-c', '1', '-Tfields', '-e', 'frame.number']
tshark = subprocess.Popen(cmd, stdout=subprocess.PIPE)
data = tshark.stdout.read().rstrip()
result = "SUCCESS" if len(data) > 0 else "NoPacketsFound"
print "CheckResult,%s" % (result)

View File

@@ -0,0 +1,40 @@
#!/usr/bin/python
#
# Sigma Control API DUT (sniffer_get_field_value)
# Copyright (c) 2014, Qualcomm Atheros, Inc.
# All Rights Reserved.
# Licensed under the Clear BSD license. See README for more details.
import sys
import subprocess
import tshark
for arg in sys.argv:
if arg.startswith("FileName="):
filename = arg.split("=", 1)[1]
elif arg.startswith("SrcMac="):
srcmac = arg.split("=", 1)[1]
elif arg.startswith("FrameName="):
framename = arg.split("=", 1)[1].lower()
elif arg.startswith("FieldName="):
fieldname = arg.split("=", 1)[1].lower()
frame_filters = tshark.tshark_framenames()
if framename not in frame_filters:
print "errorCode,Unsupported FrameName"
sys.exit()
fields = tshark.tshark_fieldnames()
if fieldname not in fields:
print "errorCode,Unsupported FieldName"
sys.exit()
cmd = ['tshark', '-r', filename,
'-c', '1',
'-R', 'wlan.sa==' + srcmac + " and " + frame_filters[framename],
'-Tfields',
'-e', fields[fieldname]]
tshark = subprocess.Popen(cmd, stdout=subprocess.PIPE)
data = tshark.stdout.read().rstrip()
result = "SUCCESS" if len(data) > 0 else "FAIL"
print "CheckResult,%s,ReturnValue,%s" % (result, data)

View File

@@ -0,0 +1 @@
NoA_Duration wifi_p2p.noa.duration

View File

@@ -0,0 +1,11 @@
assocreq wlan.fc.type_subtype == 0
assoreq wlan.fc.type_subtype == 0
assocresp wlan.fc.type_subtype == 1
assoresp wlan.fc.type_subtype == 1
assocreassocreq (wlan.fc.type_subtype == 0 or wlan.fc.type_subtype == 2)
assocreassocresp (wlan.fc.type_subtype == 1 or wlan.fc.type_subtype == 3)
probereq wlan.fc.type_subtype == 4
proberesp wlan.fc.type_subtype == 5
beacon wlan.fc.type_subtype == 8
QoSNULL wlan.fc.type_subtype == 0x2c
qosdata wlan.fc.type_subtype == 0x28

View File

@@ -0,0 +1 @@
NoA wifi_p2p.type == 12

View File

@@ -0,0 +1,391 @@
/*
* Sigma Control API DUT (sniffer)
* Copyright (c) 2013-2014, Qualcomm Atheros, Inc.
* Copyright (c) 2019, The Linux Foundation
* All Rights Reserved.
* Licensed under the Clear BSD license. See README for more details.
*/
#include "sigma_dut.h"
#include <signal.h>
#include <sys/stat.h>
#include <sys/wait.h>
static void capture_process(const char *ifname, const char *filename)
{
char *env[] = { NULL };
char *argv[] = { "sigma_dut[capture]", "-i", strdup(ifname),
"-w", strdup(filename), NULL };
execve("/usr/bin/dumpcap", argv, env);
perror("execve");
exit(EXIT_FAILURE);
}
static enum sigma_cmd_result cmd_sniffer_control_start(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *filename = get_param(cmd, "filename");
enum sigma_cmd_result res;
pid_t pid;
if (dut->sniffer_pid) {
sigma_dut_print(dut, DUT_MSG_INFO, "Sniffer was already capturing - restart based on new parameters");
sniffer_close(dut);
}
if (filename == NULL) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Missing filename argument");
return STATUS_SENT;
}
if (strchr(filename, '/')) {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,Invalid filename");
return STATUS_SENT;
}
res = cmd_wlantest_set_channel(dut, conn, cmd);
if (res != SUCCESS_SEND_STATUS)
return res;
mkdir("Captures", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
sigma_dut_print(dut, DUT_MSG_INFO, "Starting sniffer process");
snprintf(dut->sniffer_filename, sizeof(dut->sniffer_filename),
"Captures/%s", filename);
pid = fork();
if (pid < 0) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed to fork sniffer process");
return STATUS_SENT;
}
if (pid == 0) {
capture_process(dut->sniffer_ifname, dut->sniffer_filename);
return SUCCESS_SEND_STATUS;
}
dut->sniffer_pid = pid;
return SUCCESS_SEND_STATUS;
}
void sniffer_close(struct sigma_dut *dut)
{
if (!dut->sniffer_pid)
return;
if (kill(dut->sniffer_pid, SIGTERM) < 0) {
printf("Failed to kill sniffer process: %s\n", strerror(errno));
dut->sniffer_pid = 0;
return;
}
waitpid(dut->sniffer_pid, NULL, 0);
if (dut->sniffer_filename[0]) {
chmod(dut->sniffer_filename,
S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
dut->sniffer_filename[0] = '\0';
}
dut->sniffer_pid = 0;
}
static enum sigma_cmd_result cmd_sniffer_control_stop(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
if (!dut->sniffer_pid) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Sniffer was not capturing");
return STATUS_SENT;
}
sniffer_close(dut);
return SUCCESS_SEND_STATUS;
}
static enum sigma_cmd_result
cmd_sniffer_control_field_check(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *filename = get_param(cmd, "filename");
const char *framename = get_param(cmd, "framename");
const char *srcmac = get_param(cmd, "srcmac");
const char *wsc_state = get_param(cmd, "WSC_State");
const char *pvb_bit = get_param(cmd, "pvb_bit");
const char *moredata_bit = get_param(cmd, "MoreData_bit");
const char *eosp_bit = get_param(cmd, "EOSP_bit");
char buf[2000], *pos;
FILE *f;
if (filename == NULL || srcmac == NULL)
return INVALID_SEND_STATUS;
if (strchr(filename, '/')) {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,Invalid filename");
return STATUS_SENT;
}
if (!file_exists("sniffer-control-field-check.py")) {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-control-field-check.py not found");
return STATUS_SENT;
}
snprintf(buf, sizeof(buf),
"./sniffer-control-field-check.py FileName=Captures/%s SrcMac=%s%s%s%s%s%s%s%s%s%s%s",
filename, srcmac,
framename ? " FrameName=" : "", framename ? framename : "",
wsc_state ? " WSC_State=" : "", wsc_state ? wsc_state : "",
moredata_bit ? " MoreData_bit=" : "",
moredata_bit ? moredata_bit : "",
eosp_bit ? " EOSP_bit=" : "", eosp_bit ? eosp_bit : "",
pvb_bit ? " pvb_bit=" : "", pvb_bit ? pvb_bit : "");
sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
f = popen(buf, "r");
if (f == NULL) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed to run sniffer helper");
return STATUS_SENT;
}
if (!fgets(buf, sizeof(buf), f)) {
pclose(f);
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed extract response from sniffer helper");
return STATUS_SENT;
}
pos = strchr(buf, '\n');
if (pos)
*pos = '\0';
pclose(f);
send_resp(dut, conn, SIGMA_COMPLETE, buf);
return STATUS_SENT;
}
static enum sigma_cmd_result cmd_sniffer_get_info(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
char buf[200];
snprintf(buf, sizeof(buf), "WfaSnifferVersion,SigmaSniffer-foo,SnifferSTA,foo,DeviceSwInfo,foo,WiresharkVersion,foo");
send_resp(dut, conn, SIGMA_COMPLETE, buf);
return STATUS_SENT;
}
static enum sigma_cmd_result
cmd_sniffer_control_filter_capture(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *infile = get_param(cmd, "InFile");
const char *outfile = get_param(cmd, "OutFile");
const char *srcmac = get_param(cmd, "SrcMac");
const char *framename = get_param(cmd, "FrameName");
const char *nframes = get_param(cmd, "Nframes");
const char *hasfield = get_param(cmd, "HasField");
const char *datalen = get_param(cmd, "Datalen");
char buf[500], *pos;
FILE *f;
if (infile == NULL || outfile == NULL || srcmac == NULL ||
nframes == NULL)
return INVALID_SEND_STATUS;
if (strchr(infile, '/') || strchr(outfile, '/'))
return INVALID_SEND_STATUS;
if (!file_exists("sniffer-control-filter-capture.py")) {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-control-filter-capture.py not found");
return STATUS_SENT;
}
snprintf(buf, sizeof(buf),
"./sniffer-control-filter-capture.py InFile=Captures/%s OutFile=Captures/%s SrcMac=%s%s%s Nframes=%s%s%s%s%s",
infile, outfile, srcmac,
framename ? " FrameName=" : "", framename ? framename : "",
nframes,
hasfield ? " HasField=" : "", hasfield ? hasfield : "",
datalen ? " Datalen=" : "", datalen ? datalen : "");
sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
f = popen(buf, "r");
if (f == NULL) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed to run sniffer helper");
return STATUS_SENT;
}
if (!fgets(buf, sizeof(buf), f)) {
pclose(f);
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed extract response from sniffer helper");
return STATUS_SENT;
}
pos = strchr(buf, '\n');
if (pos)
*pos = '\0';
pclose(f);
send_resp(dut, conn, SIGMA_COMPLETE, buf);
return STATUS_SENT;
}
static enum sigma_cmd_result
cmd_sniffer_get_field_value(struct sigma_dut *dut, struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *infile = get_param(cmd, "FileName");
const char *srcmac = get_param(cmd, "SrcMac");
const char *framename = get_param(cmd, "FrameName");
const char *fieldname = get_param(cmd, "FieldName");
char buf[500], *pos;
FILE *f;
if (infile == NULL || srcmac == NULL || framename == NULL ||
fieldname == NULL)
return INVALID_SEND_STATUS;
if (!file_exists("sniffer-get-field-value.py")) {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-get-field-value.py not found");
return STATUS_SENT;
}
snprintf(buf, sizeof(buf),
"./sniffer-get-field-value.py FileName=Captures/%s SrcMac=%s FrameName=%s FieldName=%s",
infile, srcmac, framename, fieldname);
sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
f = popen(buf, "r");
if (f == NULL) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed to run sniffer helper");
return STATUS_SENT;
}
if (!fgets(buf, sizeof(buf), f)) {
pclose(f);
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed extract response from sniffer helper");
return STATUS_SENT;
}
pos = strchr(buf, '\n');
if (pos)
*pos = '\0';
pclose(f);
send_resp(dut, conn, SIGMA_COMPLETE, buf);
return STATUS_SENT;
}
static enum sigma_cmd_result
cmd_sniffer_check_p2p_noa_duration(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
FILE *f;
char buf[200], *pos;
const char *infile = get_param(cmd, "FileName");
const char *bssid = get_param(cmd, "bssid");
const char *srcmac = get_param(cmd, "srcmac");
const char *destmac = get_param(cmd, "destmac");
if (infile == NULL || bssid == NULL || srcmac == NULL ||
destmac == NULL)
return INVALID_SEND_STATUS;
if (!file_exists("sniffer-check-p2p-noa-duration.py")) {
send_resp(dut, conn, SIGMA_ERROR, "errorCode,sniffer-check-p2p-noa-duration.py not found");
return STATUS_SENT;
}
snprintf(buf, sizeof(buf),
"./sniffer-check-p2p-noa-duration.py Captures/%s %s %s %s",
infile, bssid, srcmac, destmac);
sigma_dut_print(dut, DUT_MSG_INFO, "Run: %s", buf);
f = popen(buf, "r");
if (f == NULL) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed to run sniffer check");
return STATUS_SENT;
}
if (!fgets(buf, sizeof(buf), f)) {
pclose(f);
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed extract response from sniffer check");
return STATUS_SENT;
}
pos = strchr(buf, '\n');
if (pos)
*pos = '\0';
pclose(f);
send_resp(dut, conn, SIGMA_COMPLETE, buf);
return STATUS_SENT;
}
static enum sigma_cmd_result
cmd_sniffer_check_p2p_opps_client(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
char buf[200];
/* TODO */
snprintf(buf, sizeof(buf), "FilterStatus,SUCCESS");
send_resp(dut, conn, SIGMA_COMPLETE, buf);
return STATUS_SENT;
}
static enum sigma_cmd_result
cmd_sniffer_check_frame_field(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
char buf[200];
/* TODO */
snprintf(buf, sizeof(buf), "FilterStatus,SUCCESS");
send_resp(dut, conn, SIGMA_COMPLETE, buf);
return STATUS_SENT;
}
void sniffer_register_cmds(void)
{
sigma_dut_reg_cmd("sniffer_control_start", NULL,
cmd_sniffer_control_start);
sigma_dut_reg_cmd("sniffer_control_stop", NULL,
cmd_sniffer_control_stop);
sigma_dut_reg_cmd("sniffer_control_field_check", NULL,
cmd_sniffer_control_field_check);
sigma_dut_reg_cmd("sniffer_get_info", NULL, cmd_sniffer_get_info);
sigma_dut_reg_cmd("sniffer_control_filter_capture", NULL,
cmd_sniffer_control_filter_capture);
sigma_dut_reg_cmd("wfa_sniffer_control_filter_capture", NULL,
cmd_sniffer_control_filter_capture);
sigma_dut_reg_cmd("sniffer_get_field_value", NULL,
cmd_sniffer_get_field_value);
sigma_dut_reg_cmd("sniffer_check_p2p_NoA_duration", NULL,
cmd_sniffer_check_p2p_noa_duration);
sigma_dut_reg_cmd("sniffer_check_p2p_opps_client", NULL,
cmd_sniffer_check_p2p_opps_client);
sigma_dut_reg_cmd("sniffer_check_frame_field", NULL,
cmd_sniffer_check_frame_field);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,970 @@
/*
* Sigma Control API DUT (station/AP)
* Copyright (c) 2010, Atheros Communications, Inc.
* Copyright (c) 2011-2013, 2016-2017 Qualcomm Atheros, Inc.
* Copyright (c) 2018-2021, The Linux Foundation
* All Rights Reserved.
* Licensed under the Clear BSD license. See README for more details.
*/
#include "sigma_dut.h"
#include <sys/types.h>
#include <sys/stat.h>
#include <dirent.h>
#include <fcntl.h>
#include <signal.h>
#include <ctype.h>
#include <ifaddrs.h>
#include <netdb.h>
#include "wpa_helpers.h"
#ifdef ANDROID
#define SHELL "/system/bin/sh"
#else /* ANDROID */
#define SHELL "/bin/sh"
#endif /* ANDROID */
static enum sigma_cmd_result cmd_traffic_send_ping(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *dst, *val;
int size, dur, pkts;
int id;
char resp[100];
float interval;
double rate;
FILE *f;
char buf[100];
int type = 1;
int dscp = 0, use_dscp = 0;
char extra[100], int_arg[100], intf_arg[100], ip_dst[100], ping[100];
struct in6_addr ip6_addr;
bool broadcast = false;
val = get_param(cmd, "Type");
if (!val)
val = get_param(cmd, "IPType");
if (val)
type = atoi(val);
if (type != 1 && type != 2) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Unsupported address type");
return STATUS_SENT;
}
dst = get_param(cmd, "destination");
if (dst == NULL || (type == 1 && !is_ip_addr(dst)) ||
(type == 2 && !is_ipv6_addr(dst)))
return INVALID_SEND_STATUS;
if (dut->ndp_enable && type == 2) {
snprintf(ip_dst, sizeof(ip_dst), "%s%%nan0", dst);
dst = ip_dst;
} else if (type == 2) {
if (inet_pton(AF_INET6, dst, &ip6_addr) <= 0) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Unsupported address type");
return STATUS_SENT;
}
if (IN6_IS_ADDR_LINKLOCAL(&ip6_addr)) {
snprintf(ip_dst, sizeof(ip_dst), "%s%%%s", dst,
get_station_ifname(dut));
dst = ip_dst;
}
}
val = get_param(cmd, "frameSize");
if (val == NULL)
return INVALID_SEND_STATUS;
size = atoi(val);
if (type != 2 && strcmp(dst, BROADCAST_ADDR) == 0) {
if (size > 1472) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Unsupported broadcast ping frame size");
return STATUS_SENT;
}
broadcast = true;
snprintf(buf, sizeof(buf),
"ip route add 255.255.255.255 dev %s",
get_station_ifname(dut));
run_system(dut, buf);
}
val = get_param(cmd, "frameRate");
if (val == NULL)
return INVALID_SEND_STATUS;
rate = atof(val);
if (rate <= 0)
return INVALID_SEND_STATUS;
val = get_param(cmd, "duration");
if (val == NULL)
return INVALID_SEND_STATUS;
dur = atoi(val);
if (dur <= 0 || dur > 3600)
dur = 3600;
pkts = dur * rate;
interval = (float) 1 / rate;
if (interval > 100000)
return INVALID_SEND_STATUS;
val = get_param(cmd, "DSCP");
if (val) {
dscp = atoi(val);
if (dscp < 0 || dscp > 63) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Invalid DSCP value");
return STATUS_SENT;
}
use_dscp = 1;
}
id = dut->next_streamid++;
snprintf(buf, sizeof(buf), "%s/sigma_dut-ping.%d",
dut->sigma_tmpdir, id);
unlink(buf);
snprintf(buf, sizeof(buf), "%s/sigma_dut-ping-pid.%d",
dut->sigma_tmpdir, id);
unlink(buf);
sigma_dut_print(dut, DUT_MSG_DEBUG, "Send ping: pkts=%d interval=%f "
"streamid=%d",
pkts, interval, id);
f = fopen(concat_sigma_tmpdir(dut, "/sigma_dut-ping.sh", ping,
sizeof(ping)), "w");
if (f == NULL)
return ERROR_SEND_STATUS;
extra[0] = '\0';
if (use_dscp) {
snprintf(extra, sizeof(extra), " -Q 0x%02x",
dscp << 2);
}
int_arg[0] = '\0';
if (rate != 1)
snprintf(int_arg, sizeof(int_arg), " -i %f", interval);
if (!dut->ndp_enable && type == 2)
snprintf(intf_arg, sizeof(intf_arg), " -I %s",
get_station_ifname(dut));
else
intf_arg[0] = '\0';
fprintf(f, "#!" SHELL "\n"
"ping%s%s -c %d%s -s %d%s -q%s %s > %s"
"/sigma_dut-ping.%d &\n"
"echo $! > %s/sigma_dut-ping-pid.%d\n",
type == 2 ? "6" : "", broadcast ? " -b" : "",
pkts, int_arg, size, extra,
intf_arg, dst, dut->sigma_tmpdir, id, dut->sigma_tmpdir, id);
fclose(f);
if (chmod(concat_sigma_tmpdir(dut, "/sigma_dut-ping.sh", ping,
sizeof(ping)),
S_IRUSR | S_IWUSR | S_IXUSR) < 0)
return ERROR_SEND_STATUS;
if (system(concat_sigma_tmpdir(dut, "/sigma_dut-ping.sh", ping,
sizeof(ping))) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to start ping");
return ERROR_SEND_STATUS;
}
unlink(concat_sigma_tmpdir(dut, "/sigma_dut-ping.sh", ping,
sizeof(ping)));
snprintf(resp, sizeof(resp), "streamID,%d", id);
send_resp(dut, conn, SIGMA_COMPLETE, resp);
return STATUS_SENT;
}
static enum sigma_cmd_result cmd_traffic_stop_ping(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *val;
int id, pid;
FILE *f;
char buf[100];
int res_found = 0, sent = 0, received = 0;
val = get_param(cmd, "streamID");
if (val == NULL)
return INVALID_SEND_STATUS;
id = atoi(val);
snprintf(buf, sizeof(buf), "%s/sigma_dut-ping-pid.%d",
dut->sigma_tmpdir, id);
f = fopen(buf, "r");
if (f == NULL) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Unknown streamID");
return STATUS_SENT;
}
if (fscanf(f, "%d", &pid) != 1 || pid <= 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "No PID for ping process");
fclose(f);
unlink(buf);
return ERROR_SEND_STATUS;
}
fclose(f);
unlink(buf);
sigma_dut_print(dut, DUT_MSG_DEBUG, "Ping process pid %d", pid);
if (kill(pid, SIGINT) < 0 && errno != ESRCH) {
sigma_dut_print(dut, DUT_MSG_DEBUG, "kill failed: %s",
strerror(errno));
}
usleep(250000);
snprintf(buf, sizeof(buf), "%s/sigma_dut-ping.%d",
dut->sigma_tmpdir, id);
f = fopen(buf, "r");
if (f == NULL) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"No ping result file found");
send_resp(dut, conn, SIGMA_COMPLETE, "sent,0,replies,0");
return STATUS_SENT;
}
while (fgets(buf, sizeof(buf), f)) {
char *pos;
pos = strstr(buf, " packets transmitted");
if (pos) {
pos--;
while (pos > buf && isdigit(pos[-1]))
pos--;
sent = atoi(pos);
res_found = 1;
}
pos = strstr(buf, " packets received");
if (pos == NULL)
pos = strstr(buf, " received");
if (pos) {
pos--;
while (pos > buf && isdigit(pos[-1]))
pos--;
received = atoi(pos);
res_found = 1;
}
}
fclose(f);
snprintf(buf, sizeof(buf), "%s/sigma_dut-ping.%d",
dut->sigma_tmpdir, id);
unlink(buf);
if (!res_found) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"No ping results found");
send_resp(dut, conn, SIGMA_COMPLETE, "sent,0,replies,0");
return STATUS_SENT;
}
snprintf(buf, sizeof(buf), "sent,%d,replies,%d", sent, received);
send_resp(dut, conn, SIGMA_COMPLETE, buf);
return STATUS_SENT;
}
int get_ip_addr(const char *ifname, int ipv6, char *buf, size_t len)
{
struct ifaddrs *ifa, *ifa_tmp;
bool non_ll_addr_found = false;
if (getifaddrs(&ifa) == -1)
return -1;
for (ifa_tmp = ifa; ifa_tmp; ifa_tmp = ifa_tmp->ifa_next) {
if (!ifa_tmp->ifa_addr ||
strcasecmp(ifname, ifa_tmp->ifa_name) != 0)
continue;
if (!ipv6 && ifa_tmp->ifa_addr->sa_family == AF_INET) {
struct sockaddr_in *in;
in = (struct sockaddr_in *) ifa_tmp->ifa_addr;
if (!inet_ntop(AF_INET, &in->sin_addr, buf, len))
return -1;
return 0;
}
if (ipv6 && ifa_tmp->ifa_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *in6;
in6 = (struct sockaddr_in6 *) ifa_tmp->ifa_addr;
/* get link local address if available */
if (IN6_IS_ADDR_LINKLOCAL(&in6->sin6_addr)) {
if (!inet_ntop(AF_INET6, &in6->sin6_addr, buf,
len))
return -1;
return 0;
}
if (!non_ll_addr_found &&
inet_ntop(AF_INET6, &in6->sin6_addr, buf, len))
non_ll_addr_found = true;
}
}
return non_ll_addr_found ? 0 : -1;
}
static int get_dscp_from_policy_table(struct sigma_dut *dut, int ip_version,
const char *domain_name,
const char *src_ip, int dst_port,
int src_port)
{
struct dscp_policy_data *policy;
char *suffix;
int dscp = -1, max_score = 0, max_suffix_length = 0;
int score, suffix_length;
for (policy = dut->dscp_policy_table; policy; policy = policy->next) {
if (strlen(policy->domain_name) == 0)
continue;
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Found policy with domain name %s, ipver %d start_port %d, end_port %d, dst_port %d src_port %d, src_ip %s, dscp %d",
policy->domain_name, policy->ip_version,
policy->start_port, policy->end_port,
policy->dst_port, policy->src_port,
policy->src_ip, policy->dscp);
/*
* Discard if suffix is not found or suffix is not in the end of
* the complete domain name.
*/
suffix = strstr(domain_name, policy->domain_name);
if (!suffix)
continue;
suffix_length = strlen(suffix);
if (suffix_length != strlen(policy->domain_name))
continue;
/* Calculate granularity score */
score = 0;
if (policy->ip_version) {
if (ip_version == policy->ip_version)
score++;
else
continue;
}
if (policy->start_port && policy->end_port) {
if (dst_port >= policy->start_port &&
dst_port <= policy->end_port)
score++;
else
continue;
}
if (policy->dst_port) {
if (dst_port == policy->dst_port)
score++;
else
continue;
}
if (policy->src_port) {
if (src_port == policy->src_port)
score++;
else
continue;
}
if (strlen(policy->src_ip)) {
if (!strcmp(src_ip, policy->src_ip))
score++;
else
continue;
}
if (score > max_score) {
max_score = score;
max_suffix_length = suffix_length;
dscp = policy->dscp;
} else if (score == max_score &&
suffix_length > max_suffix_length) {
max_suffix_length = suffix_length;
dscp = policy->dscp;
}
}
if (dscp == -1)
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Policy not found for %s", domain_name);
else
sigma_dut_print(dut, DUT_MSG_DEBUG,
"DSCP for %s is %d", domain_name, dscp);
return dscp;
}
static enum sigma_cmd_result cmd_traffic_start_iperf(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
const char *val, *dst, *domain_name = NULL;
const char *iptype;
int duration, dst_port = 0, src_port = 0;
const char *proto;
char buf[256];
const char *ifname;
char port_str[20], iperf[100], src_ip[100];
FILE *f;
int server, ipv6 = 0;
char *pos;
int dscp, reverse = 0, rate;
char tos[20], client_port_str[100], bitrate[30], burst_size_str[50];
struct hostent *host_addr;
char ip_addr[INET6_ADDRSTRLEN];
bool iperf_v2 = false;
char iperf_result_file[50], iperf_pid_file[50], latency_str[50];
int res;
char iperf_cmd[300];
val = get_param(cmd, "iperfversion");
if (val && atoi(val) == 2)
iperf_v2 = true;
val = get_param(cmd, "mode");
if (!val) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Missing mode parameter");
return STATUS_SENT;
}
server = strcasecmp(val, "server") == 0;
iptype = "";
val = get_param(cmd, "iptype");
if (val) {
if (strcasecmp(val, "ipv6") == 0 ||
strcasecmp(val, "version6") == 0) {
iptype = "-6";
ipv6 = 1;
} else {
iptype = "-4";
ipv6 = 0;
}
}
port_str[0] = '\0';
val = get_param(cmd, "port");
if (val) {
dst_port = atoi(val);
snprintf(port_str, sizeof(port_str), "-p %d", dst_port);
}
rate = 1024 * 1024 * 1024; /* default rate: 1 Gbps */
bitrate[0] = '\0';
val = get_param(cmd, "bitrate");
if (val) {
int ret = snprintf(bitrate, sizeof(bitrate), " -b %s", val);
size_t len;
char rate_factor;
if (ret < 0 || ret >= sizeof(bitrate))
return ERROR_SEND_STATUS;
rate = atoi(val);
len = strlen(val);
rate_factor = len > 0 ? val[len - 1] : 0;
if (rate_factor == 'G')
rate *= 1024 * 1024 * 1024;
else if (rate_factor == 'M')
rate *= 1024 * 1024;
else if (rate_factor == 'K')
rate *= 1024;
}
burst_size_str[0] = '\0';
val = get_param(cmd, "burstsize");
if (!iperf_v2 && val) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid Iperf3 option BurstSize");
return ERROR_SEND_STATUS;
}
if (val && atoi(val) > 0) {
int fps, ret;
fps = rate / (atoi(val) * 8);
/* Use --isochronous to allow lower burst size. */
ret = snprintf(burst_size_str, sizeof(burst_size_str),
" --isochronous=%d:%d,0 -w 2M", fps, rate);
if (ret < 0 || ret >= sizeof(burst_size_str))
return ERROR_SEND_STATUS;
/* Isochronous and bitrate don't get configured together */
bitrate[0] = '\0';
}
dst = get_param(cmd, "destination");
pos = dst ? strchr(dst, '%') : NULL;
if (pos) {
*pos++ = '\0';
ifname = pos;
} else if (dut->ndpe || dut->program == PROGRAM_NAN) {
ifname = "nan0";
} else {
ifname = get_station_ifname(dut);
}
if (dst && !ipv6 && !is_ip_addr(dst)) {
domain_name = dst;
host_addr = gethostbyname2(dst, AF_INET);
if (!host_addr) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid IPv4 address/domain name");
return STATUS_SENT;
}
dst = inet_ntop(AF_INET, host_addr->h_addr_list[0], ip_addr,
sizeof(ip_addr));
} else if (dst && ipv6 && !is_ipv6_addr(dst)) {
domain_name = dst;
host_addr = gethostbyname2(dst, AF_INET6);
if (!host_addr) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid IPv6 address/domain name");
return STATUS_SENT;
}
dst = inet_ntop(AF_INET6, host_addr->h_addr_list[0], ip_addr,
sizeof(ip_addr));
}
if (!server && !dst) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Invalid destination address");
return STATUS_SENT;
}
val = get_param(cmd, "duration");
if (val)
duration = atoi(val);
else
duration = 0;
client_port_str[0] = '\0';
src_ip[0] = '\0';
val = get_param(cmd, "clientport");
if (val) {
src_port = atoi(val);
if (get_ip_addr(ifname, ipv6, src_ip, sizeof(src_ip))) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Cannot get own IP address");
return STATUS_SENT;
}
if (ipv6)
snprintf(buf, sizeof(buf), "%s%%%s", src_ip, ifname);
else
snprintf(buf, sizeof(buf), "%s", src_ip);
res = snprintf(client_port_str, sizeof(client_port_str),
" -B %s%s%d", buf,
iperf_v2 ? ":" : " --cport ",
src_port);
if (res < 0 || res >= sizeof(client_port_str))
return ERROR_SEND_STATUS;
}
val = get_param(cmd, "reverse");
if (val)
reverse = atoi(val);
latency_str[0] = '\0';
val = get_param(cmd, "latency");
if (!iperf_v2 && val) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode, Iperf3 doesn't support latency params");
return STATUS_SENT_ERROR;
}
if (val && atoi(val)) {
const char *lower_ci, *upper_ci;
val = get_param(cmd, "LowerCI");
lower_ci = val ? val : "95";
val = get_param(cmd, "UpperCI");
upper_ci = val ? val : "99.9";
if (server)
res = snprintf(latency_str, sizeof(latency_str),
" --realtime --histograms=1m,1000000,%s,%s ",
lower_ci, upper_ci);
else
res = snprintf(latency_str, sizeof(latency_str),
" --realtime --trip-times ");
if (res < 0 || res >= sizeof(latency_str))
return ERROR_SEND_STATUS;
}
tos[0] = '\0';
val = get_param(cmd, "DSCP");
if (val) {
dscp = atoi(val);
if (dscp < 0 || dscp > 63) {
send_resp(dut, conn, SIGMA_ERROR,
"ErrorCode,Invalid DSCP value");
return STATUS_SENT_ERROR;
}
snprintf(tos, sizeof(tos), " -S 0x%02x", dscp << 2);
}
if (domain_name) {
dscp = get_dscp_from_policy_table(dut, ipv6 ? IPV6 : IPV4,
domain_name, src_ip, dst_port,
src_port);
if (dscp != -1)
snprintf(tos, sizeof(tos), " -S 0x%02x", dscp << 2);
}
res = snprintf(iperf_result_file, sizeof(iperf_result_file),
"/sigma_dut-iperf-res-%d-%d", server, dst_port);
if (res < 0 || res >= sizeof(iperf_result_file))
return ERROR_SEND_STATUS;
res = snprintf(iperf_pid_file, sizeof(iperf_pid_file),
"/sigma_dut-iperf-pid-%d-%d", server, dst_port);
if (res < 0 || res >= sizeof(iperf_pid_file))
return ERROR_SEND_STATUS;
unlink(concat_sigma_tmpdir(dut, iperf_result_file, iperf,
sizeof(iperf)));
unlink(concat_sigma_tmpdir(dut, iperf_pid_file, iperf,
sizeof(iperf)));
/* open IPv6 multicast socket using iperf v2 */
if (ipv6 && dst && (strncmp(dst, "ff", 2) == 0))
iperf_v2 = true;
if (iperf_v2)
iptype = ipv6 ? "-V" : "";
proto = "";
val = get_param(cmd, "transproto");
/* proto -u is not applicable for iperf3 server */
if (val && strcasecmp(val, "udp") == 0 && !(!iperf_v2 && server))
proto = "-u";
if (server) {
/* write server side command to shell file */
if (ipv6 && dst && (strncmp(dst, "ff", 2) == 0)) {
/* open IPv6 multicast server socket using iperf */
snprintf(buf, sizeof(buf), "-B %s%%%s", dst, ifname);
} else if (dst) {
/* open IPv4 multicast server socket using iperf3 */
snprintf(buf, sizeof(buf), "-B %s", dst);
} else {
buf[0] = '\0';
}
res = snprintf(iperf_cmd, sizeof(iperf_cmd),
"iperf%s -s %s %s %s %s -i 1 %s > %s%s &\n",
iperf_v2 ? "" : "3", port_str, iptype, proto,
buf, latency_str, dut->sigma_tmpdir, iperf_result_file);
} else {
/* write client side command to shell file */
if (!dst)
return INVALID_SEND_STATUS;
if (ipv6)
snprintf(buf, sizeof(buf), "%s%%%s", dst, ifname);
else
snprintf(buf, sizeof(buf), "%s", dst);
res = snprintf(iperf_cmd, sizeof(iperf_cmd),
"iperf%s -c %s -t %d %s %s%s %s%s%s%s%s -i 1 %s > %s%s &\n",
iperf_v2 ? "" : "3",
buf, duration, iptype, proto, bitrate, port_str,
client_port_str, tos, reverse ? " -R" : "",
burst_size_str, latency_str, dut->sigma_tmpdir,
iperf_result_file);
}
if (res < 0 || res >= sizeof(iperf_cmd))
return ERROR_SEND_STATUS;
f = fopen(concat_sigma_tmpdir(dut, "/sigma_dut-iperf.sh", iperf,
sizeof(iperf)), "w");
if (!f) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Can not write sigma_dut-iperf.sh");
return STATUS_SENT;
}
fprintf(f, "#!" SHELL "\n%s"
"echo $! > %s%s\n",
iperf_cmd, dut->sigma_tmpdir, iperf_pid_file);
fclose(f);
if (chmod(concat_sigma_tmpdir(dut, "/sigma_dut-iperf.sh", iperf,
sizeof(iperf)),
S_IRUSR | S_IWUSR | S_IXUSR) < 0) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Can not chmod sigma_dut-iperf.sh");
return STATUS_SENT;
}
sigma_dut_print(dut, DUT_MSG_DEBUG, "Starting iperf. cmd: %s",
iperf_cmd);
if (system(concat_sigma_tmpdir(dut, "/sigma_dut-iperf.sh", iperf,
sizeof(iperf))) != 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "Failed to start iperf");
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,Failed to run sigma_dut-iperf.sh");
return STATUS_SENT;
}
unlink(concat_sigma_tmpdir(dut, "/sigma_dut-iperf.sh", iperf,
sizeof(iperf)));
return SUCCESS_SEND_STATUS;
}
static enum sigma_cmd_result cmd_traffic_stop_iperf(struct sigma_dut *dut,
struct sigma_conn *conn,
struct sigma_cmd *cmd)
{
int pid;
FILE *f;
char buf[1024], summary_buf[1024], iperf[100], histogram_buf[1024];
float bandwidth, totalbytes, factor;
char *pos;
long l_bandwidth, l_totalbytes;
const char *val;
const size_t max_fname = 50;
char iperf_result_file[max_fname], iperf_pid_file[max_fname];
DIR *dir;
struct dirent *entry;
int res, server;
bool latency_expected = false;
char *latency;
val = get_param(cmd, "mode");
server = val && strcasecmp(val, "server") == 0;
val = get_param(cmd, "port");
if (val) {
int dst_port;
dst_port = atoi(val);
res = snprintf(iperf_result_file, sizeof(iperf_result_file),
"/sigma_dut-iperf-res-%d-%d", server, dst_port);
if (res < 0 || res >= sizeof(iperf_result_file))
return ERROR_SEND_STATUS;
res = snprintf(iperf_pid_file, sizeof(iperf_pid_file),
"/sigma_dut-iperf-pid-%d-%d", server, dst_port);
if (res < 0 || res >= sizeof(iperf_pid_file))
return ERROR_SEND_STATUS;
} else {
/* Assume single instance and find the file using opendir(). */
iperf_result_file[0] = '\0';
iperf_pid_file[0] = '\0';
dir = opendir(dut->sigma_tmpdir);
if (!dir)
return ERROR_SEND_STATUS;
while ((entry = readdir(dir))) {
if (strncmp(entry->d_name, "sigma_dut-iperf-res-",
20) == 0)
res = snprintf(iperf_result_file, max_fname,
"/%s", entry->d_name);
else if (strncmp(entry->d_name, "sigma_dut-iperf-pid-",
20) == 0)
res = snprintf(iperf_pid_file, max_fname,
"/%s", entry->d_name);
else
continue;
if (res < 0 || res >= max_fname)
return ERROR_SEND_STATUS;
}
closedir(dir);
if (!strlen(iperf_result_file) || !strlen(iperf_pid_file)) {
sigma_dut_print(dut, DUT_MSG_INFO,
"Could not find iperf result or PID file");
return ERROR_SEND_STATUS;
}
}
f = fopen(concat_sigma_tmpdir(dut, iperf_pid_file, iperf,
sizeof(iperf)), "r");
if (!f) {
send_resp(dut, conn, SIGMA_ERROR,
"errorCode,PID file does not exist");
return STATUS_SENT;
}
if (fscanf(f, "%d", &pid) != 1 || pid <= 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "No PID for iperf process");
fclose(f);
unlink(concat_sigma_tmpdir(dut, iperf_pid_file, iperf,
sizeof(iperf)));
return ERROR_SEND_STATUS;
}
fclose(f);
unlink(concat_sigma_tmpdir(dut, iperf_pid_file, iperf,
sizeof(iperf)));
if (kill(pid, SIGINT) < 0 && errno != ESRCH) {
sigma_dut_print(dut, DUT_MSG_DEBUG, "kill failed: %s",
strerror(errno));
}
usleep(250000);
/* parse iperf output which is stored in sigma_dut-iperf-res* */
summary_buf[0] = '\0';
histogram_buf[0] = '\0';
f = fopen(concat_sigma_tmpdir(dut, iperf_result_file, iperf,
sizeof(iperf)), "r");
if (!f) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"No iperf result file found");
send_resp(dut, conn, SIGMA_COMPLETE,
"bandwidth,0,totalbytes,0,latency,0");
return STATUS_SENT;
}
/* find the last line which has the received bytes summary */
while (fgets(buf, sizeof(buf), f)) {
char *pos;
pos = strchr(buf, '\n');
if (pos)
*pos = '\0';
sigma_dut_print(dut, DUT_MSG_DEBUG, "iperf: %s", buf);
pos = strstr(buf, "out-of-order");
if (pos)
continue;
pos = strstr(buf, " sec ");
if (pos)
strlcpy(summary_buf, buf, sizeof(summary_buf));
pos = strstr(buf, "clients should use --trip-times");
if (pos)
latency_expected = true;
if (latency_expected) {
pos = strstr(buf, "%=");
if (pos)
strlcpy(histogram_buf, buf,
sizeof(histogram_buf));
}
}
fclose(f);
unlink(concat_sigma_tmpdir(dut, iperf_result_file, iperf,
sizeof(iperf)));
res = snprintf(buf, sizeof(buf), "bandwidth,0,totalbytes,0%s",
latency_expected ? ",latency,0" : "");
if (res < 0 || res >= sizeof(buf))
return ERROR_SEND_STATUS;
pos = strstr(summary_buf, "Bytes");
if (!pos || pos == summary_buf) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Can not parse iperf results: Bytes");
send_resp(dut, conn, SIGMA_COMPLETE, buf);
return STATUS_SENT;
}
if (pos[-1] == 'G')
factor = 1024 * 1024 * 1024;
else if (pos[-1] == 'M')
factor = 1024 * 1024;
else if (pos[-1] == 'K')
factor = 1024;
else
factor = 1;
if (pos) {
pos -= 2;
while (pos > summary_buf && (pos[-1] != ' '))
pos--;
totalbytes = atof(pos);
} else
totalbytes = 0;
l_totalbytes = totalbytes * factor;
pos = strstr(summary_buf, "bits/sec");
if (!pos || pos == summary_buf) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Can not parse iperf results: bits/sec");
send_resp(dut, conn, SIGMA_COMPLETE, buf);
return STATUS_SENT;
}
if (pos[-1] == 'G')
factor = 1024 * 1024 * 1024 / 8;
else if (pos[-1] == 'M')
factor = 1024 * 1024 / 8;
else if (pos[-1] == 'K')
factor = 1024 / 8;
else
factor = 1 / 8;
if (pos && pos - summary_buf > 2) {
pos -= 2;
while (pos > summary_buf && (pos[-1] != ' '))
pos--;
bandwidth = atof(pos);
} else
bandwidth = 0;
l_bandwidth = bandwidth * factor;
if (latency_expected) {
pos = strstr(histogram_buf, "%=");
if (!pos || pos == histogram_buf) {
/* Not a fatal error. */
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Skip iperf results for latency.");
latency = "NA";
} else {
latency = pos + 2;
pos = strstr(latency, ",");
if (!pos || pos == latency) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Can not parse iperf results: latency");
send_resp(dut, conn, SIGMA_COMPLETE, buf);
return STATUS_SENT_ERROR;
}
pos[0] = '\0';
}
res = snprintf(buf, sizeof(buf),
"bandwidth,%lu,totalbytes,%lu,latency,%s",
l_bandwidth, l_totalbytes, latency);
} else {
res = snprintf(buf, sizeof(buf),
"bandwidth,%lu,totalbytes,%lu",
l_bandwidth, l_totalbytes);
}
if (res < 0 || res >= sizeof(buf))
return ERROR_SEND_STATUS;
send_resp(dut, conn, SIGMA_COMPLETE, buf);
return STATUS_SENT;
}
void traffic_register_cmds(void)
{
sigma_dut_reg_cmd("traffic_send_ping", NULL, cmd_traffic_send_ping);
sigma_dut_reg_cmd("traffic_stop_ping", NULL, cmd_traffic_stop_ping);
sigma_dut_reg_cmd("traffic_start_iperf", NULL, cmd_traffic_start_iperf);
sigma_dut_reg_cmd("traffic_stop_iperf", NULL, cmd_traffic_stop_iperf);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,30 @@
#!/usr/bin/python
#
# Sigma Control API DUT (helpers for calling tshark)
# Copyright (c) 2014, Qualcomm Atheros, Inc.
# All Rights Reserved.
# Licensed under the Clear BSD license. See README for more details.
def tshark_fieldnames():
fields = {}
with open("sniffer-tshark-fields.txt", "r") as f:
for l in f.read().splitlines():
[sigma_name,tshark_name] = l.split('\t')
fields[sigma_name.lower()] = tshark_name
return fields
def tshark_framenames():
frames = {}
with open("sniffer-tshark-frames.txt", "r") as f:
for l in f.read().splitlines():
[sigma_name,tshark_name] = l.split('\t')
frames[sigma_name.lower()] = tshark_name
return frames
def tshark_hasfields():
fields = {}
with open("sniffer-tshark-hasfields.txt", "r") as f:
for l in f.read().splitlines():
[sigma_name,tshark_name] = l.split('\t')
fields[sigma_name.lower()] = tshark_name
return fields

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,166 @@
/*
* wlantest control interface
* Copyright (c) 2010, Jouni Malinen <j@w1.fi>
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#ifndef WLANTEST_CTRL_H
#define WLANTEST_CTRL_H
#define WLANTEST_SOCK_NAME "w1.fi.wlantest"
#define WLANTEST_CTRL_MAX_CMD_LEN 1000
#define WLANTEST_CTRL_MAX_RESP_LEN 1000
enum wlantest_ctrl_cmd {
WLANTEST_CTRL_SUCCESS,
WLANTEST_CTRL_FAILURE,
WLANTEST_CTRL_INVALID_CMD,
WLANTEST_CTRL_UNKNOWN_CMD,
WLANTEST_CTRL_PING,
WLANTEST_CTRL_TERMINATE,
WLANTEST_CTRL_LIST_BSS,
WLANTEST_CTRL_LIST_STA,
WLANTEST_CTRL_FLUSH,
WLANTEST_CTRL_CLEAR_STA_COUNTERS,
WLANTEST_CTRL_CLEAR_BSS_COUNTERS,
WLANTEST_CTRL_GET_STA_COUNTER,
WLANTEST_CTRL_GET_BSS_COUNTER,
WLANTEST_CTRL_INJECT,
WLANTEST_CTRL_VERSION,
WLANTEST_CTRL_ADD_PASSPHRASE,
WLANTEST_CTRL_INFO_STA,
WLANTEST_CTRL_INFO_BSS,
WLANTEST_CTRL_SEND,
WLANTEST_CTRL_CLEAR_TDLS_COUNTERS,
WLANTEST_CTRL_GET_TDLS_COUNTER,
};
enum wlantest_ctrl_attr {
WLANTEST_ATTR_BSSID,
WLANTEST_ATTR_STA_ADDR,
WLANTEST_ATTR_STA_COUNTER,
WLANTEST_ATTR_BSS_COUNTER,
WLANTEST_ATTR_COUNTER,
WLANTEST_ATTR_INJECT_FRAME,
WLANTEST_ATTR_INJECT_SENDER_AP,
WLANTEST_ATTR_INJECT_PROTECTION,
WLANTEST_ATTR_VERSION,
WLANTEST_ATTR_PASSPHRASE,
WLANTEST_ATTR_STA_INFO,
WLANTEST_ATTR_BSS_INFO,
WLANTEST_ATTR_INFO,
WLANTEST_ATTR_FRAME,
WLANTEST_ATTR_TDLS_COUNTER,
WLANTEST_ATTR_STA2_ADDR,
WLANTEST_ATTR_WEPKEY,
};
enum wlantest_bss_counter {
WLANTEST_BSS_COUNTER_VALID_BIP_MMIE,
WLANTEST_BSS_COUNTER_INVALID_BIP_MMIE,
WLANTEST_BSS_COUNTER_MISSING_BIP_MMIE,
WLANTEST_BSS_COUNTER_BIP_DEAUTH,
WLANTEST_BSS_COUNTER_BIP_DISASSOC,
NUM_WLANTEST_BSS_COUNTER
};
enum wlantest_sta_counter {
WLANTEST_STA_COUNTER_AUTH_TX,
WLANTEST_STA_COUNTER_AUTH_RX,
WLANTEST_STA_COUNTER_ASSOCREQ_TX,
WLANTEST_STA_COUNTER_REASSOCREQ_TX,
WLANTEST_STA_COUNTER_PTK_LEARNED,
WLANTEST_STA_COUNTER_VALID_DEAUTH_TX,
WLANTEST_STA_COUNTER_VALID_DEAUTH_RX,
WLANTEST_STA_COUNTER_INVALID_DEAUTH_TX,
WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX,
WLANTEST_STA_COUNTER_VALID_DISASSOC_TX,
WLANTEST_STA_COUNTER_VALID_DISASSOC_RX,
WLANTEST_STA_COUNTER_INVALID_DISASSOC_TX,
WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX,
WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_TX,
WLANTEST_STA_COUNTER_VALID_SAQUERYREQ_RX,
WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_TX,
WLANTEST_STA_COUNTER_INVALID_SAQUERYREQ_RX,
WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_TX,
WLANTEST_STA_COUNTER_VALID_SAQUERYRESP_RX,
WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_TX,
WLANTEST_STA_COUNTER_INVALID_SAQUERYRESP_RX,
WLANTEST_STA_COUNTER_PING_OK,
WLANTEST_STA_COUNTER_ASSOCRESP_COMEBACK,
WLANTEST_STA_COUNTER_REASSOCRESP_COMEBACK,
WLANTEST_STA_COUNTER_PING_OK_FIRST_ASSOC,
WLANTEST_STA_COUNTER_VALID_DEAUTH_RX_ACK,
WLANTEST_STA_COUNTER_VALID_DISASSOC_RX_ACK,
WLANTEST_STA_COUNTER_INVALID_DEAUTH_RX_ACK,
WLANTEST_STA_COUNTER_INVALID_DISASSOC_RX_ACK,
WLANTEST_STA_COUNTER_DEAUTH_RX_ASLEEP,
WLANTEST_STA_COUNTER_DEAUTH_RX_AWAKE,
WLANTEST_STA_COUNTER_DISASSOC_RX_ASLEEP,
WLANTEST_STA_COUNTER_DISASSOC_RX_AWAKE,
WLANTEST_STA_COUNTER_PROT_DATA_TX,
WLANTEST_STA_COUNTER_DEAUTH_RX_RC6,
WLANTEST_STA_COUNTER_DEAUTH_RX_RC7,
WLANTEST_STA_COUNTER_DISASSOC_RX_RC6,
WLANTEST_STA_COUNTER_DISASSOC_RX_RC7,
NUM_WLANTEST_STA_COUNTER
};
enum wlantest_tdls_counter {
WLANTEST_TDLS_COUNTER_VALID_DIRECT_LINK,
WLANTEST_TDLS_COUNTER_INVALID_DIRECT_LINK,
WLANTEST_TDLS_COUNTER_VALID_AP_PATH,
WLANTEST_TDLS_COUNTER_INVALID_AP_PATH,
WLANTEST_TDLS_COUNTER_SETUP_REQ,
WLANTEST_TDLS_COUNTER_SETUP_RESP_OK,
WLANTEST_TDLS_COUNTER_SETUP_RESP_FAIL,
WLANTEST_TDLS_COUNTER_SETUP_CONF_OK,
WLANTEST_TDLS_COUNTER_SETUP_CONF_FAIL,
WLANTEST_TDLS_COUNTER_TEARDOWN,
NUM_WLANTEST_TDLS_COUNTER
};
enum wlantest_inject_frame {
WLANTEST_FRAME_AUTH,
WLANTEST_FRAME_ASSOCREQ,
WLANTEST_FRAME_REASSOCREQ,
WLANTEST_FRAME_DEAUTH,
WLANTEST_FRAME_DISASSOC,
WLANTEST_FRAME_SAQUERYREQ,
};
/**
* enum wlantest_inject_protection - WLANTEST_CTRL_INJECT protection
* @WLANTEST_INJECT_NORMAL: Use normal rules (protect if key is set)
* @WLANTEST_INJECT_PROTECTED: Force protection (fail if not possible)
* @WLANTEST_INJECT_UNPROTECTED: Force unprotected
* @WLANTEST_INJECT_INCORRECT_KEY: Force protection with incorrect key
*/
enum wlantest_inject_protection {
WLANTEST_INJECT_NORMAL,
WLANTEST_INJECT_PROTECTED,
WLANTEST_INJECT_UNPROTECTED,
WLANTEST_INJECT_INCORRECT_KEY,
};
enum wlantest_sta_info {
WLANTEST_STA_INFO_PROTO,
WLANTEST_STA_INFO_PAIRWISE,
WLANTEST_STA_INFO_KEY_MGMT,
WLANTEST_STA_INFO_RSN_CAPAB,
WLANTEST_STA_INFO_STATE,
WLANTEST_STA_INFO_GTK,
};
enum wlantest_bss_info {
WLANTEST_BSS_INFO_PROTO,
WLANTEST_BSS_INFO_PAIRWISE,
WLANTEST_BSS_INFO_GROUP,
WLANTEST_BSS_INFO_GROUP_MGMT,
WLANTEST_BSS_INFO_KEY_MGMT,
WLANTEST_BSS_INFO_RSN_CAPAB,
};
#endif /* WLANTEST_CTRL_H */

View File

@@ -0,0 +1,545 @@
/*
* wpa_supplicant/hostapd control interface library
* Copyright (c) 2004-2007, Jouni Malinen <j@w1.fi>
* Copyright (c) 2018, The Linux Foundation
*
* This software may be distributed under the terms of the BSD license.
* See README for more details.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifdef __QNXNTO__
#include <sys/select.h>
#endif /* __QNXNTO__ */
#include <sys/stat.h>
#define CONFIG_CTRL_IFACE
#define CONFIG_CTRL_IFACE_UNIX
#define os_malloc malloc
#define os_free free
#define os_memset memset
#define os_memcmp memcmp
#define os_snprintf snprintf
#define os_strlen strlen
#define os_strncmp strncmp
#define os_strlcpy strlcpy
#include "sigma_dut.h"
#ifdef CONFIG_CTRL_IFACE
#ifdef CONFIG_CTRL_IFACE_UNIX
#include <sys/un.h>
#endif /* CONFIG_CTRL_IFACE_UNIX */
#ifdef ANDROID
#include <dirent.h>
#include <cutils/sockets.h>
#include <grp.h>
#include <pwd.h>
#endif /* ANDROID */
#include "wpa_ctrl.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;
struct sockaddr_in local;
struct sockaddr_in dest;
char *cookie;
#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)
{
return wpa_ctrl_open2(ctrl_path, NULL);
}
struct wpa_ctrl * wpa_ctrl_open2(const char *ctrl_path,
const char *cli_path)
{
struct wpa_ctrl *ctrl;
static int counter = 0;
int ret;
size_t res;
int tries = 0;
#ifdef ANDROID
struct passwd *pw;
struct group *gr;
#endif /* ANDROID */
if (ctrl_path == NULL)
return NULL;
ctrl = os_malloc(sizeof(*ctrl));
if (ctrl == NULL)
return NULL;
os_memset(ctrl, 0, sizeof(*ctrl));
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:
if (cli_path && cli_path[0] == '/') {
ret = os_snprintf(ctrl->local.sun_path,
sizeof(ctrl->local.sun_path),
"%s/" CONFIG_CTRL_IFACE_CLIENT_PREFIX "%d-%d",
cli_path, (int) getpid(), counter);
} else {
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 (ret < 0 || (size_t) ret >= sizeof(ctrl->local.sun_path)) {
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);
pw = getpwnam("system");
gr = getgrnam("wifi");
if (pw && gr)
chown(ctrl->local.sun_path, pw->pw_uid, gr->gr_gid);
/*
* 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;
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;
}
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);
}
#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;
ctrl = os_malloc(sizeof(*ctrl));
if (ctrl == NULL)
return NULL;
os_memset(ctrl, 0, sizeof(*ctrl));
ctrl->s = socket(PF_INET, SOCK_DGRAM, 0);
if (ctrl->s < 0) {
perror("socket");
os_free(ctrl);
return NULL;
}
ctrl->local.sin_family = AF_INET;
ctrl->local.sin_addr.s_addr = htonl((127 << 24) | 1);
if (bind(ctrl->s, (struct sockaddr *) &ctrl->local,
sizeof(ctrl->local)) < 0) {
close(ctrl->s);
os_free(ctrl);
return NULL;
}
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);
if (connect(ctrl->s, (struct sockaddr *) &ctrl->dest,
sizeof(ctrl->dest)) < 0) {
perror("connect");
close(ctrl->s);
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);
}
return ctrl;
}
void wpa_ctrl_close(struct wpa_ctrl *ctrl)
{
close(ctrl->s);
os_free(ctrl->cookie);
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;
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;
}
if (send(ctrl->s, _cmd, _cmd_len, 0) < 0) {
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 (ret < 0 || ret >= 256) {
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 */

View File

@@ -0,0 +1,291 @@
/*
* 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 TLS certificate chain validation error */
#define WPA_EVENT_EAP_TLS_CERT_ERROR "CTRL-EVENT-EAP-TLS-CERT-ERROR "
/** 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 "
/** New scan results available */
#define WPA_EVENT_SCAN_RESULTS "CTRL-EVENT-SCAN-RESULTS "
/** 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 "
/** 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 "
#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 "
/** 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: <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 INTERWORKING_AP "INTERWORKING-AP "
#define INTERWORKING_NO_MATCH "INTERWORKING-NO-MATCH "
/* 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 "
/* 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_open2 - Open a control interface to wpa_supplicant/hostapd
* @ctrl_path: Path for UNIX domain sockets; ignored if UDP sockets are used.
* @cli_path: Path for client UNIX domain sockets; ignored if UDP socket
* is 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
* when the socket path for client need to be specified explicitly. Default
* ctrl_path is usually /var/run/wpa_supplicant or /var/run/hostapd and client
* socket path is /tmp.
*/
struct wpa_ctrl * wpa_ctrl_open2(const char *ctrl_path, const char *cli_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. This
* function will block if no messages are available. 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 CONFIG_CTRL_IFACE_UDP
#define WPA_CTRL_IFACE_PORT 9877
#define WPA_GLOBAL_CTRL_IFACE_PORT 9878
#endif /* CONFIG_CTRL_IFACE_UDP */
#ifdef __cplusplus
}
#endif
#endif /* WPA_CTRL_H */

View File

@@ -0,0 +1,997 @@
/*
* Sigma Control API DUT (station/AP)
* Copyright (c) 2010-2011, Atheros Communications, Inc.
* Copyright (c) 2011-2014, 2016, Qualcomm Atheros, Inc.
* Copyright (c) 2018-2021, The Linux Foundation
* All Rights Reserved.
* Licensed under the Clear BSD license. See README for more details.
*/
#include "sigma_dut.h"
#include <sys/stat.h>
#include "wpa_ctrl.h"
#include "wpa_helpers.h"
#define DEFAULT_HAPD_CTRL_PATH "/var/run/hostapd/"
extern char *sigma_wpas_ctrl;
extern char *client_socket_path;
extern char *sigma_hapd_ctrl;
const char * get_main_ifname(struct sigma_dut *dut)
{
enum driver_type drv = get_driver_type(dut);
enum openwrt_driver_type openwrt_drv = get_openwrt_driver_type();
if (dut->main_ifname) {
if (dut->use_5g && dut->main_ifname_5g)
return dut->main_ifname_5g;
if (!dut->use_5g && dut->main_ifname_2g)
return dut->main_ifname_2g;
return dut->main_ifname;
}
if (drv == DRIVER_ATHEROS || openwrt_drv == OPENWRT_DRIVER_ATHEROS) {
if (if_nametoindex("ath2") > 0)
return "ath2";
else if (if_nametoindex("ath1") > 0)
return "ath1";
else
return "ath0";
}
if (if_nametoindex("p2p0") > 0)
return "p2p0";
if (if_nametoindex("wlan1") > 0) {
struct stat s;
if (stat("/sys/module/mac80211", &s) == 0 &&
if_nametoindex("wlan0")) {
/*
* Likely a dual-radio AP device; use wlan0 for STA/P2P
* operations.
*/
return "wlan0";
}
return "wlan1";
}
if (if_nametoindex("wlan0") > 0)
return "wlan0";
return "unknown";
}
const char * get_station_ifname(struct sigma_dut *dut)
{
if (dut->station_ifname) {
if (dut->use_5g && dut->station_ifname_5g)
return dut->station_ifname_5g;
if (!dut->use_5g && dut->station_ifname_2g)
return dut->station_ifname_2g;
return dut->station_ifname;
}
/*
* If we have both wlan0 and wlan1, assume the first one is the station
* interface.
*/
if (if_nametoindex("wlan1") > 0 && if_nametoindex("wlan0") > 0)
return "wlan0";
if (if_nametoindex("ath0") > 0)
return "ath0";
/* If nothing else matches, hope for best and guess.. */
return "wlan0";
}
const char * get_p2p_ifname(struct sigma_dut *dut, const char *primary_ifname)
{
if (strcmp(get_station_ifname(dut), primary_ifname) != 0)
return primary_ifname;
if (dut->p2p_ifname)
return dut->p2p_ifname;
return get_station_ifname(dut);
}
void dut_ifc_reset(struct sigma_dut *dut)
{
char buf[256];
const char *ifc = get_station_ifname(dut);
snprintf(buf, sizeof(buf), "ifconfig %s down", ifc);
run_system(dut, buf);
snprintf(buf, sizeof(buf), "ifconfig %s up", ifc);
run_system(dut, buf);
}
int wpa_ctrl_command(const char *path, const char *ifname, const char *cmd)
{
struct wpa_ctrl *ctrl;
char buf[128];
size_t len;
snprintf(buf, sizeof(buf), "%s%s", path, ifname);
ctrl = wpa_ctrl_open2(buf, client_socket_path);
if (ctrl == NULL) {
printf("wpa_command: wpa_ctrl_open2(%s) failed\n", buf);
return -1;
}
len = sizeof(buf);
if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL) < 0) {
printf("wpa_command: wpa_ctrl_request failed\n");
wpa_ctrl_close(ctrl);
return -1;
}
wpa_ctrl_close(ctrl);
buf[len] = '\0';
if (strncmp(buf, "FAIL", 4) == 0) {
printf("wpa_command: Command failed (FAIL received)\n");
return -1;
}
return 0;
}
int wpa_command(const char *ifname, const char *cmd)
{
printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
return wpa_ctrl_command(sigma_wpas_ctrl, ifname, cmd);
}
int hapd_command(const char *ifname, const char *cmd)
{
const char *path = sigma_hapd_ctrl ? sigma_hapd_ctrl :
DEFAULT_HAPD_CTRL_PATH;
printf("hapd_command(ifname='%s', cmd='%s')\n", ifname, cmd);
return wpa_ctrl_command(path, ifname, cmd);
}
int wpa_ctrl_command_resp(const char *path, const char *ifname,
const char *cmd, char *resp, size_t resp_size)
{
struct wpa_ctrl *ctrl;
char buf[128];
size_t len;
snprintf(buf, sizeof(buf), "%s%s", path, ifname);
ctrl = wpa_ctrl_open2(buf, client_socket_path);
if (ctrl == NULL) {
printf("wpa_command: wpa_ctrl_open2(%s) failed\n", buf);
return -1;
}
len = resp_size;
if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), resp, &len, NULL) < 0) {
printf("wpa_command: wpa_ctrl_request failed\n");
wpa_ctrl_close(ctrl);
return -1;
}
wpa_ctrl_close(ctrl);
resp[len] = '\0';
return 0;
}
int wpa_command_resp(const char *ifname, const char *cmd,
char *resp, size_t resp_size)
{
printf("wpa_command(ifname='%s', cmd='%s')\n", ifname, cmd);
return wpa_ctrl_command_resp(sigma_wpas_ctrl, ifname, cmd,
resp, resp_size);
}
int hapd_command_resp(const char *ifname, const char *cmd,
char *resp, size_t resp_size)
{
const char *path = sigma_hapd_ctrl ? sigma_hapd_ctrl :
DEFAULT_HAPD_CTRL_PATH;
printf("hapd_command(ifname='%s', cmd='%s')\n", ifname, cmd);
return wpa_ctrl_command_resp(path, ifname, cmd, resp, resp_size);
}
struct wpa_ctrl * open_wpa_ctrl_mon(const char *ctrl_path, const char *ifname)
{
struct wpa_ctrl *ctrl;
char path[256];
snprintf(path, sizeof(path), "%s%s", ctrl_path, ifname);
ctrl = wpa_ctrl_open2(path, client_socket_path);
if (ctrl == NULL)
return NULL;
if (wpa_ctrl_attach(ctrl) < 0) {
wpa_ctrl_close(ctrl);
return NULL;
}
return ctrl;
}
struct wpa_ctrl * open_wpa_mon(const char *ifname)
{
return open_wpa_ctrl_mon(sigma_wpas_ctrl, ifname);
}
struct wpa_ctrl * open_hapd_mon(const char *ifname)
{
const char *path = sigma_hapd_ctrl ?
sigma_hapd_ctrl : DEFAULT_HAPD_CTRL_PATH;
return open_wpa_ctrl_mon(path, ifname);
}
int get_wpa_cli_events_timeout(struct sigma_dut *dut, struct wpa_ctrl *mon,
const char **events, char *buf, size_t buf_size,
unsigned int timeout)
{
int fd, ret;
fd_set rfd;
char *pos;
struct timeval tv;
time_t start, now;
int i;
for (i = 0; events[i]; i++) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Waiting for wpa_cli event: %s", events[i]);
}
fd = wpa_ctrl_get_fd(mon);
if (fd < 0)
return -1;
if (timeout)
time(&start);
while (1) {
size_t len;
FD_ZERO(&rfd);
FD_SET(fd, &rfd);
if (timeout) {
time(&now);
if ((unsigned int) (now - start) >= timeout)
tv.tv_sec = 1;
else
tv.tv_sec = timeout -
(unsigned int) (now - start) + 1;
tv.tv_usec = 0;
}
ret = select(fd + 1, &rfd, NULL, NULL, timeout ? &tv : NULL);
if (ret == 0) {
sigma_dut_print(dut, DUT_MSG_INFO, "Timeout on "
"waiting for events");
return -1;
}
if (ret < 0) {
sigma_dut_print(dut, DUT_MSG_INFO, "select: %s",
strerror(errno));
return -1;
}
len = buf_size;
if (wpa_ctrl_recv(mon, buf, &len) < 0) {
sigma_dut_print(dut, DUT_MSG_ERROR, "Failure while "
"waiting for events");
return -1;
}
if (len == buf_size)
len--;
buf[len] = '\0';
pos = strchr(buf, '>');
if (pos) {
for (i = 0; events[i]; i++) {
if (strncmp(pos + 1, events[i],
strlen(events[i])) == 0)
return 0; /* Event found */
}
}
if (!timeout)
continue;
time(&now);
if ((unsigned int) (now - start) > timeout) {
sigma_dut_print(dut, DUT_MSG_INFO, "Timeout on "
"waiting for event");
return -1;
}
}
}
int get_wpa_cli_events(struct sigma_dut *dut, struct wpa_ctrl *mon,
const char **events, char *buf, size_t buf_size)
{
return get_wpa_cli_events_timeout(dut, mon, events, buf, buf_size,
dut->default_timeout);
}
int get_wpa_cli_event2(struct sigma_dut *dut, struct wpa_ctrl *mon,
const char *event, const char *event2,
char *buf, size_t buf_size)
{
const char *events[3] = { event, event2, NULL };
return get_wpa_cli_events(dut, mon, events, buf, buf_size);
}
int get_wpa_cli_event(struct sigma_dut *dut, struct wpa_ctrl *mon,
const char *event, char *buf, size_t buf_size)
{
return get_wpa_cli_event2(dut, mon, event, NULL, buf, buf_size);
}
/*
* signal_poll cmd output sample
* RSSI=-51
* LINKSPEED=866
* NOISE=-101
* FREQUENCY=5180
* AVG_RSSI=-50
*/
int get_wpa_signal_poll(struct sigma_dut *dut, const char *ifname,
const char *field, char *obuf, size_t obuf_size)
{
struct wpa_ctrl *ctrl;
char buf[4096];
char *pos, *end;
size_t len, flen;
snprintf(buf, sizeof(buf), "%s%s", sigma_wpas_ctrl, ifname);
ctrl = wpa_ctrl_open2(buf, client_socket_path);
if (!ctrl) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to connect to wpa_supplicant");
return -1;
}
len = sizeof(buf);
if (wpa_ctrl_request(ctrl, "SIGNAL_POLL", 11, buf, &len, NULL) < 0) {
wpa_ctrl_close(ctrl);
sigma_dut_print(dut, DUT_MSG_ERROR, "ctrl request failed");
return -1;
}
buf[len] = '\0';
wpa_ctrl_close(ctrl);
flen = strlen(field);
pos = buf;
while (pos + flen < buf + len) {
if (pos > buf) {
if (*pos != '\n') {
pos++;
continue;
}
pos++;
}
if (strncmp(pos, field, flen) != 0 || pos[flen] != '=') {
pos++;
continue;
}
pos += flen + 1;
end = strchr(pos, '\n');
if (!end) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Could not find signal poll field '%s' - end is NULL",
field);
return -1;
}
*end++ = '\0';
if (end - pos > (int) obuf_size) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"signal poll out buffer is too small");
return -1;
}
memcpy(obuf, pos, end - pos);
return 0;
}
sigma_dut_print(dut, DUT_MSG_ERROR, "signal poll param not found");
return -1;
}
int get_wpa_ssid_bssid(struct sigma_dut *dut, const char *ifname,
char *buf, size_t buf_size)
{
struct wpa_ctrl *ctrl;
char buf_local[4096];
char *network, *ssid, *bssid;
size_t buf_size_local;
unsigned int count = 0;
int len, res;
char *save_ptr_network = NULL;
ctrl = open_wpa_mon(ifname);
if (!ctrl) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to connect to wpa_supplicant");
return -1;
}
wpa_command(ifname, "BSS_FLUSH");
if (wpa_command(ifname, "SCAN TYPE=ONLY")) {
wpa_ctrl_detach(ctrl);
wpa_ctrl_close(ctrl);
sigma_dut_print(dut, DUT_MSG_ERROR, "SCAN command failed");
return -1;
}
res = get_wpa_cli_event(dut, ctrl, "CTRL-EVENT-SCAN-RESULTS",
buf_local, sizeof(buf_local));
wpa_ctrl_detach(ctrl);
buf_size_local = sizeof(buf_local);
if (res < 0 || wpa_ctrl_request(ctrl, "BSS RANGE=ALL MASK=0x1002", 25,
buf_local, &buf_size_local, NULL) < 0) {
wpa_ctrl_close(ctrl);
sigma_dut_print(dut, DUT_MSG_ERROR, "BSS ctrl request failed");
return -1;
}
buf_local[buf_size_local] = '\0';
wpa_ctrl_close(ctrl);
/* Below is BSS RANGE=ALL MASK=0x1002 command sample output which is
* parsed to get the BSSID and SSID parameters.
* Even number of lines, first line BSSID of network 1, second line SSID
* of network 1, ...
*
* bssid=xx:xx:xx:xx:xx:x1
* ssid=SSID1
* bssid=xx:xx:xx:xx:xx:x2
* ssid=SSID2
*/
network = strtok_r(buf_local, "\n", &save_ptr_network);
while (network) {
sigma_dut_print(dut, DUT_MSG_DEBUG, "BSSID: %s", network);
bssid = NULL;
if (!strtok_r(network, "=", &bssid)) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Invalid BSS result: BSSID not found");
return -1;
}
network = strtok_r(NULL, "\n", &save_ptr_network);
if (network) {
sigma_dut_print(dut, DUT_MSG_DEBUG, "SSID: %s",
network);
ssid = NULL;
if (!strtok_r(network, "=", &ssid)) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Invalid BSS result: SSID is null");
return -1;
}
} else {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Invalid BSS result: SSID not found");
return -1;
}
/* Skip comma for first entry */
count++;
len = snprintf(buf, buf_size, "%sSSID%d,%s,BSSID%d,%s",
count > 1 ? "," : "",
count, ssid, count, bssid);
if (len < 0 || (size_t) len >= buf_size) {
buf[0] = '\0';
return 0;
}
buf_size -= len;
buf += len;
network = strtok_r(NULL, "\n", &save_ptr_network);
}
return 0;
}
static int get_wpa_ctrl_mlo_status(const char *path, const char *ifname,
const char *cmd, char *obuf,
size_t obuf_size)
{
struct wpa_ctrl *ctrl;
char buf[4096];
size_t len;
int res;
res = snprintf(buf, sizeof(buf), "%s%s", path, ifname);
if (res < 0 || res >= sizeof(buf))
return -1;
ctrl = wpa_ctrl_open2(buf, client_socket_path);
if (!ctrl)
return -1;
len = sizeof(buf);
if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL) < 0) {
wpa_ctrl_close(ctrl);
return -1;
}
wpa_ctrl_close(ctrl);
buf[len] = '\0';
if (len >= obuf_size)
return -1;
memcpy(obuf, buf, len + 1);
return 0;
}
static int get_wpa_mlo_status(const char *ifname, char *obuf, size_t obuf_size)
{
return get_wpa_ctrl_mlo_status(sigma_wpas_ctrl, ifname, "MLO_STATUS",
obuf, obuf_size);
}
int get_mlo_link_mac_ap_link(struct sigma_dut *dut, const char *ifname,
const char *ap_link_addr,
char *obuf, size_t obuf_size)
{
char buf[4096];
char *param;
size_t flen, flen2;
int ap_link_match = 0;
char *save_ptr = NULL;
if (get_wpa_mlo_status(ifname, buf, sizeof(buf))) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to get MLO status");
return -1;
}
flen = strlen("ap_link_addr");
flen2 = strlen("sta_link_addr");
param = strtok_r(buf, "\n", &save_ptr);
while (param) {
if (strncasecmp(param, "ap_link_addr", flen) == 0 &&
strlen(param) > flen + 1 &&
strncasecmp(&param[flen + 1], ap_link_addr, 18) == 0)
ap_link_match = 1;
if (ap_link_match) {
if (strncasecmp(param, "sta_link_addr", flen2) == 0 &&
strlen(param) > flen2 + 1) {
sigma_dut_print(dut, DUT_MSG_DEBUG,
"STA link addr %s",
&param[flen2 + 1]);
strlcpy(obuf, &param[flen2 + 1], obuf_size);
return 0;
}
}
param = strtok_r(NULL, "\n", &save_ptr);
}
if (!ap_link_match)
sigma_dut_print(dut, DUT_MSG_ERROR,
"AP link address not found");
return -1;
}
int get_mlo_link_id_link_mac(struct sigma_dut *dut, const char *ifname,
const char *link_addr,
char *obuf, size_t obuf_size)
{
char buf[4096];
char *param;
size_t flen, flen2;
char *saveptr = NULL;
if (get_wpa_mlo_status(ifname, buf, sizeof(buf))) {
sigma_dut_print(dut, DUT_MSG_ERROR,
"Failed to get MLO Status");
return -1;
}
flen = strlen("sta_link_addr");
flen2 = strlen("link_id");
param = strtok_r(buf, "\n", &saveptr);
while (param) {
if (strncasecmp(param, "link_id", flen2) == 0)
strlcpy(obuf, &param[flen2 + 1], obuf_size);
if (strncasecmp(param, "sta_link_addr", flen) == 0) {
if (strncasecmp(&param[flen + 1], link_addr, 18) == 0) {
sigma_dut_print(dut, DUT_MSG_INFO,
"MLO link id for STA link MAC is %s",
&param[flen2 + 1]);
return 0;
}
}
param = strtok_r(NULL, "\n", &saveptr);
}
sigma_dut_print(dut, DUT_MSG_ERROR, "link id not found");
return -1;
}
int get_connected_mlo_link_ids(struct sigma_dut *dut, const char *ifname)
{
char buf[4096];
char *param;
size_t flen;
char *saveptr = NULL;
int links_bitmask = 0;
if (get_wpa_status(ifname, "wpa_state", buf, sizeof(buf)) < 0 ||
strncmp(buf, "COMPLETED", 9) != 0) {
sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Not connected",
__func__);
return 0;
}
if (get_wpa_mlo_status(ifname, buf, sizeof(buf))) {
sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: Non-MLO connection",
__func__);
return 0;
}
flen = strlen("link_id");
param = strtok_r(buf, "\n", &saveptr);
while (param) {
if (strncasecmp(param, "link_id", flen) == 0) {
int link_id = atoi(&param[flen + 1]);
sigma_dut_print(dut, DUT_MSG_DEBUG,
"Found connected link ID %d", link_id);
links_bitmask |= BIT(link_id);
}
param = strtok_r(NULL, "\n", &saveptr);
}
return links_bitmask;
}
static int get_wpa_ctrl_status_field(const char *path, const char *ifname,
const char *cmd, const char *field,
char *obuf, size_t obuf_size)
{
struct wpa_ctrl *ctrl;
char buf[4096];
char *pos, *end;
size_t len, flen;
snprintf(buf, sizeof(buf), "%s%s", path, ifname);
ctrl = wpa_ctrl_open2(buf, client_socket_path);
if (ctrl == NULL)
return -1;
len = sizeof(buf);
if (wpa_ctrl_request(ctrl, cmd, strlen(cmd), buf, &len, NULL) < 0) {
wpa_ctrl_close(ctrl);
return -1;
}
wpa_ctrl_close(ctrl);
buf[len] = '\0';
flen = strlen(field);
pos = buf;
while (pos + flen < buf + len) {
if (pos > buf) {
if (*pos != '\n') {
pos++;
continue;
}
pos++;
}
if (strncmp(pos, field, flen) != 0 || pos[flen] != '=') {
pos++;
continue;
}
pos += flen + 1;
end = strchr(pos, '\n');
if (end == NULL)
return -1;
*end++ = '\0';
if (end - pos > (int) obuf_size)
return -1;
memcpy(obuf, pos, end - pos);
return 0;
}
return -1;
}
int get_wpa_status(const char *ifname, const char *field, char *obuf,
size_t obuf_size)
{
return get_wpa_ctrl_status_field(sigma_wpas_ctrl, ifname, "STATUS",
field, obuf, obuf_size);
}
int get_hapd_config(const char *ifname, const char *field, char *obuf,
size_t obuf_size)
{
const char *path = sigma_hapd_ctrl ?
sigma_hapd_ctrl : DEFAULT_HAPD_CTRL_PATH;
return get_wpa_ctrl_status_field(path, ifname, "GET_CONFIG",
field, obuf, obuf_size);
}
int wait_ip_addr(struct sigma_dut *dut, const char *ifname, int timeout)
{
char ip[30];
int count = timeout;
while (count > 0) {
sigma_dut_print(dut, DUT_MSG_DEBUG, "%s: ifname='%s' - %d "
"seconds remaining",
__func__, ifname, count);
count--;
if (get_wpa_status(ifname, "ip_address", ip, sizeof(ip)) == 0
&& strlen(ip) > 0) {
sigma_dut_print(dut, DUT_MSG_INFO, "IP address "
"found: '%s'", ip);
return 0;
}
sleep(1);
}
sigma_dut_print(dut, DUT_MSG_INFO, "%s: Could not get IP address for "
"ifname='%s'", __func__, ifname);
return -1;
}
void remove_wpa_networks(const char *ifname)
{
char buf[4096];
char cmd[256];
char *pos;
if (wpa_command_resp(ifname, "LIST_NETWORKS", buf, sizeof(buf)) < 0)
return;
/* Skip the first line (header) */
pos = strchr(buf, '\n');
if (pos == NULL)
return;
pos++;
while (pos && pos[0]) {
int id = atoi(pos);
snprintf(cmd, sizeof(cmd), "REMOVE_NETWORK %d", id);
wpa_command(ifname, cmd);
pos = strchr(pos, '\n');
if (pos)
pos++;
}
}
int add_network(const char *ifname)
{
char res[30];
if (wpa_command_resp(ifname, "ADD_NETWORK", res, sizeof(res)) < 0)
return -1;
return atoi(res);
}
int set_network(const char *ifname, int id, const char *field,
const char *value)
{
char buf[200];
snprintf(buf, sizeof(buf), "SET_NETWORK %d %s %s", id, field, value);
return wpa_command(ifname, buf);
}
int set_network_quoted(const char *ifname, int id, const char *field,
const char *value)
{
char buf[200];
snprintf(buf, sizeof(buf), "SET_NETWORK %d %s \"%s\"",
id, field, value);
return wpa_command(ifname, buf);
}
int add_cred(const char *ifname)
{
char res[30];
if (wpa_command_resp(ifname, "ADD_CRED", res, sizeof(res)) < 0)
return -1;
return atoi(res);
}
int set_cred(const char *ifname, int id, const char *field, const char *value)
{
char buf[200];
snprintf(buf, sizeof(buf), "SET_CRED %d %s %s", id, field, value);
return wpa_command(ifname, buf);
}
int set_cred_quoted(const char *ifname, int id, const char *field,
const char *value)
{
char buf[200];
snprintf(buf, sizeof(buf), "SET_CRED %d %s \"%s\"",
id, field, value);
return wpa_command(ifname, buf);
}
const char * concat_sigma_tmpdir(struct sigma_dut *dut, const char *src,
char *dst, size_t len)
{
snprintf(dst, len, "%s%s", dut->sigma_tmpdir, src);
return dst;
}
int start_sta_mode(struct sigma_dut *dut)
{
FILE *f;
char buf[256];
char sta_conf_path[100];
const char *ifname;
char *tmp, *pos;
if (dut->mode == SIGMA_MODE_STATION) {
if ((dut->use_5g && dut->sta_2g_started) ||
(!dut->use_5g && dut->sta_5g_started)) {
stop_sta_mode(dut);
sleep(1);
} else {
return 0;
}
}
if (dut->mode == SIGMA_MODE_AP) {
if (system("killall hostapd") == 0) {
int i;
/* Wait some time to allow hostapd to complete cleanup
* before starting a new process */
for (i = 0; i < 10; i++) {
usleep(500000);
if (system("pidof hostapd") != 0)
break;
}
}
}
if (dut->mode == SIGMA_MODE_SNIFFER && dut->sniffer_ifname) {
snprintf(buf, sizeof(buf), "ifconfig %s down",
dut->sniffer_ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_INFO,
"Failed to run '%s'", buf);
}
snprintf(buf, sizeof(buf), "iw dev %s set type station",
dut->sniffer_ifname);
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_INFO,
"Failed to run '%s'", buf);
}
}
dut->mode = SIGMA_MODE_STATION;
ifname = get_main_ifname(dut);
if (wpa_command(ifname, "PING") == 0)
return 0; /* wpa_supplicant is already running */
/* Start wpa_supplicant */
f = fopen(concat_sigma_tmpdir(dut, "/sigma_dut-sta.conf", sta_conf_path,
sizeof(sta_conf_path)), "w");
if (f == NULL)
return -1;
tmp = strdup(sigma_wpas_ctrl);
if (tmp == NULL) {
fclose(f);
return -1;
}
pos = tmp;
while (pos[0] != '\0' && pos[1] != '\0')
pos++;
if (*pos == '/')
*pos = '\0';
fprintf(f, "ctrl_interface=%s\n", tmp);
free(tmp);
fprintf(f, "device_name=Test client\n");
fprintf(f, "device_type=1-0050F204-1\n");
if (is_60g_sigma_dut(dut)) {
fprintf(f, "eapol_version=2\n");
fprintf(f,
"config_methods=display push_button keypad virtual_display physical_display virtual_push_button\n");
}
fclose(f);
#ifdef __QNXNTO__
snprintf(buf, sizeof(buf),
"wpa_supplicant -Dqca -i%s -B %s%s%s -c %s/sigma_dut-sta.conf",
ifname,
dut->wpa_supplicant_debug_log ? "-K -t -ddd " : "",
(dut->wpa_supplicant_debug_log &&
dut->wpa_supplicant_debug_log[0]) ? "-f " : "",
dut->wpa_supplicant_debug_log ?
dut->wpa_supplicant_debug_log : "",
dut->sigma_tmpdir);
#else /*__QNXNTO__*/
snprintf(buf, sizeof(buf),
"%swpa_supplicant -Dnl80211 -i%s -B %s%s%s -c %s/sigma_dut-sta.conf",
file_exists("wpa_supplicant") ? "./" : "",
ifname,
dut->wpa_supplicant_debug_log ? "-K -t -ddd " : "",
(dut->wpa_supplicant_debug_log &&
dut->wpa_supplicant_debug_log[0]) ? "-f " : "",
dut->wpa_supplicant_debug_log ?
dut->wpa_supplicant_debug_log : "",
dut->sigma_tmpdir);
#endif /*__QNXNTO__*/
if (system(buf) != 0) {
sigma_dut_print(dut, DUT_MSG_INFO, "Failed to run '%s'", buf);
return -1;
}
sleep(1);
if (wpa_command(ifname, "PING")) {
sigma_dut_print(dut, DUT_MSG_INFO, "Failed to communicate "
"with wpa_supplicant");
return -1;
}
if (dut->use_5g)
dut->sta_5g_started = 1;
else
dut->sta_2g_started = 1;
return 0;
}
void stop_sta_mode(struct sigma_dut *dut)
{
if (is_60g_sigma_dut(dut)) {
wpa_command(get_main_ifname(dut), "TERMINATE");
return;
}
wpa_command("wlan0", "TERMINATE");
wpa_command("wlan1", "TERMINATE");
wpa_command("ath0", "TERMINATE");
wpa_command("ath1", "TERMINATE");
if (dut->main_ifname_2g)
wpa_command(dut->main_ifname_2g, "TERMINATE");
if (dut->main_ifname_5g)
wpa_command(dut->main_ifname_5g, "TERMINATE");
if (dut->station_ifname_2g)
wpa_command(dut->station_ifname_2g, "TERMINATE");
if (dut->station_ifname_5g)
wpa_command(dut->station_ifname_5g, "TERMINATE");
dut->sta_2g_started = 0;
dut->sta_5g_started = 0;
}

View File

@@ -0,0 +1,70 @@
/*
* Sigma Control API DUT (station/AP)
* Copyright (c) 2010, Atheros Communications, Inc.
* Copyright (c) 2012-2014, 2016, Qualcomm Atheros, Inc.
* Copyright (c) 2018, The Linux Foundation
* All Rights Reserved.
* Licensed under the Clear BSD license. See README for more details.
*/
#ifndef WPA_HELPERS_H
#define WPA_HELPERS_H
const char * get_main_ifname(struct sigma_dut *dut);
const char * get_station_ifname(struct sigma_dut *dut);
const char * get_p2p_ifname(struct sigma_dut *dut, const char *primary_ifname);
void dut_ifc_reset(struct sigma_dut *dut);
int wpa_command(const char *ifname, const char *cmd);
int hapd_command(const char *ifname, const char *cmd);
int wpa_command_resp(const char *ifname, const char *cmd,
char *resp, size_t resp_size);
int hapd_command_resp(const char *ifname, const char *cmd,
char *resp, size_t resp_size);
int get_wpa_status(const char *ifname, const char *field, char *obuf,
size_t obuf_size);
int get_wpa_signal_poll(struct sigma_dut *dut, const char *ifname,
const char *field, char *obuf, size_t obuf_size);
int get_wpa_ssid_bssid(struct sigma_dut *dut, const char *ifname,
char *buf, size_t buf_size);
int get_hapd_config(const char *ifname, const char *field, char *obuf,
size_t obuf_size);
void remove_wpa_networks(const char *ifname);
int get_mlo_link_mac_ap_link(struct sigma_dut *dut, const char *ifname,
const char *ap_link_addr,
char *obuf, size_t obuf_size);
int get_mlo_link_id_link_mac(struct sigma_dut *dut, const char *ifname,
const char *link_addr,
char *obuf, size_t obuf_size);
int get_connected_mlo_link_ids(struct sigma_dut *dut, const char *ifname);
struct wpa_ctrl * open_wpa_mon(const char *ifname);
struct wpa_ctrl * open_hapd_mon(const char *ifname);
int wait_ip_addr(struct sigma_dut *dut, const char *ifname, int timeout);
int get_wpa_cli_event(struct sigma_dut *dut, struct wpa_ctrl *mon,
const char *event, char *buf, size_t buf_size);
int get_wpa_cli_event2(struct sigma_dut *dut, struct wpa_ctrl *mon,
const char *event, const char *event2,
char *buf, size_t buf_size);
int get_wpa_cli_events(struct sigma_dut *dut, struct wpa_ctrl *mon,
const char **events, char *buf, size_t buf_size);
int get_wpa_cli_events_timeout(struct sigma_dut *dut, struct wpa_ctrl *mon,
const char **events, char *buf, size_t buf_size,
unsigned int timeout);
int add_network(const char *ifname);
int set_network(const char *ifname, int id, const char *field,
const char *value);
int set_network_quoted(const char *ifname, int id, const char *field,
const char *value);
int add_cred(const char *ifname);
int set_cred(const char *ifname, int id, const char *field, const char *value);
int set_cred_quoted(const char *ifname, int id, const char *field,
const char *value);
const char * concat_sigma_tmpdir(struct sigma_dut *dut, const char *src,
char *dst, size_t len);
int start_sta_mode(struct sigma_dut *dut);
void stop_sta_mode(struct sigma_dut *dut);
#endif /* WPA_HELPERS_H */