replace common qcom sources with samsung ones
This commit is contained in:
116
qcom/opensource/wlan/utils/sigma-dut/Android.mk
Normal file
116
qcom/opensource/wlan/utils/sigma-dut/Android.mk
Normal 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)
|
108
qcom/opensource/wlan/utils/sigma-dut/CONTRIBUTIONS
Normal file
108
qcom/opensource/wlan/utils/sigma-dut/CONTRIBUTIONS
Normal 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.
|
10
qcom/opensource/wlan/utils/sigma-dut/DPP/README
Normal file
10
qcom/opensource/wlan/utils/sigma-dut/DPP/README
Normal 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
|
111
qcom/opensource/wlan/utils/sigma-dut/DPP/dpp-rest-server.py
Executable file
111
qcom/opensource/wlan/utils/sigma-dut/DPP/dpp-rest-server.py
Executable 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()
|
@@ -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
|
@@ -0,0 +1 @@
|
||||
dpp-rest:00112233445566778899aabbccddeeff
|
103
qcom/opensource/wlan/utils/sigma-dut/Makefile
Normal file
103
qcom/opensource/wlan/utils/sigma-dut/Makefile
Normal 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)
|
@@ -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
|
122
qcom/opensource/wlan/utils/sigma-dut/README
Normal file
122
qcom/opensource/wlan/utils/sigma-dut/README
Normal 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.
|
14590
qcom/opensource/wlan/utils/sigma-dut/ap.c
Normal file
14590
qcom/opensource/wlan/utils/sigma-dut/ap.c
Normal file
File diff suppressed because it is too large
Load Diff
123
qcom/opensource/wlan/utils/sigma-dut/atheros.c
Normal file
123
qcom/opensource/wlan/utils/sigma-dut/atheros.c
Normal 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 */
|
||||
}
|
268
qcom/opensource/wlan/utils/sigma-dut/basic.c
Normal file
268
qcom/opensource/wlan/utils/sigma-dut/basic.c
Normal 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);
|
||||
}
|
37
qcom/opensource/wlan/utils/sigma-dut/cmds_reg.c
Normal file
37
qcom/opensource/wlan/utils/sigma-dut/cmds_reg.c
Normal 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 */
|
||||
}
|
1002
qcom/opensource/wlan/utils/sigma-dut/dev.c
Normal file
1002
qcom/opensource/wlan/utils/sigma-dut/dev.c
Normal file
File diff suppressed because it is too large
Load Diff
270
qcom/opensource/wlan/utils/sigma-dut/dhcp.c
Normal file
270
qcom/opensource/wlan/utils/sigma-dut/dhcp.c
Normal 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");
|
||||
}
|
||||
|
||||
}
|
90
qcom/opensource/wlan/utils/sigma-dut/dnssd.c
Normal file
90
qcom/opensource/wlan/utils/sigma-dut/dnssd.c
Normal 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;
|
||||
}
|
88
qcom/opensource/wlan/utils/sigma-dut/dpp-ca.py
Executable file
88
qcom/opensource/wlan/utils/sigma-dut/dpp-ca.py
Executable 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()
|
4766
qcom/opensource/wlan/utils/sigma-dut/dpp.c
Normal file
4766
qcom/opensource/wlan/utils/sigma-dut/dpp.c
Normal file
File diff suppressed because it is too large
Load Diff
144
qcom/opensource/wlan/utils/sigma-dut/e_loop.c
Normal file
144
qcom/opensource/wlan/utils/sigma-dut/e_loop.c
Normal 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;
|
||||
}
|
1058
qcom/opensource/wlan/utils/sigma-dut/ftm.c
Normal file
1058
qcom/opensource/wlan/utils/sigma-dut/ftm.c
Normal file
File diff suppressed because it is too large
Load Diff
1602
qcom/opensource/wlan/utils/sigma-dut/miracast.c
Normal file
1602
qcom/opensource/wlan/utils/sigma-dut/miracast.c
Normal file
File diff suppressed because it is too large
Load Diff
57
qcom/opensource/wlan/utils/sigma-dut/miracast.h
Normal file
57
qcom/opensource/wlan/utils/sigma-dut/miracast.h
Normal 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 */
|
3803
qcom/opensource/wlan/utils/sigma-dut/nan.c
Normal file
3803
qcom/opensource/wlan/utils/sigma-dut/nan.c
Normal file
File diff suppressed because it is too large
Load Diff
40
qcom/opensource/wlan/utils/sigma-dut/nfc-status
Executable file
40
qcom/opensource/wlan/utils/sigma-dut/nfc-status
Executable 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
|
7726
qcom/opensource/wlan/utils/sigma-dut/nl80211_copy.h
Normal file
7726
qcom/opensource/wlan/utils/sigma-dut/nl80211_copy.h
Normal file
File diff suppressed because it is too large
Load Diff
2997
qcom/opensource/wlan/utils/sigma-dut/p2p.c
Normal file
2997
qcom/opensource/wlan/utils/sigma-dut/p2p.c
Normal file
File diff suppressed because it is too large
Load Diff
52
qcom/opensource/wlan/utils/sigma-dut/powerswitch.c
Normal file
52
qcom/opensource/wlan/utils/sigma-dut/powerswitch.c
Normal 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);
|
||||
}
|
@@ -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
|
||||
|
22
qcom/opensource/wlan/utils/sigma-dut/probe_req_wildcard.txt
Normal file
22
qcom/opensource/wlan/utils/sigma-dut/probe_req_wildcard.txt
Normal 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
|
16582
qcom/opensource/wlan/utils/sigma-dut/qca-vendor_copy.h
Normal file
16582
qcom/opensource/wlan/utils/sigma-dut/qca-vendor_copy.h
Normal file
File diff suppressed because it is too large
Load Diff
228
qcom/opensource/wlan/utils/sigma-dut/scripts/hs20-action.sh
Normal file
228
qcom/opensource/wlan/utils/sigma-dut/scripts/hs20-action.sh
Normal 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
|
1250
qcom/opensource/wlan/utils/sigma-dut/server.c
Normal file
1250
qcom/opensource/wlan/utils/sigma-dut/server.c
Normal file
File diff suppressed because it is too large
Load Diff
1441
qcom/opensource/wlan/utils/sigma-dut/sigma_dut.c
Normal file
1441
qcom/opensource/wlan/utils/sigma-dut/sigma_dut.c
Normal file
File diff suppressed because it is too large
Load Diff
1500
qcom/opensource/wlan/utils/sigma-dut/sigma_dut.h
Normal file
1500
qcom/opensource/wlan/utils/sigma-dut/sigma_dut.h
Normal file
File diff suppressed because it is too large
Load Diff
79
qcom/opensource/wlan/utils/sigma-dut/sniffer-check-p2p-noa-duration.py
Executable file
79
qcom/opensource/wlan/utils/sigma-dut/sniffer-check-p2p-noa-duration.py
Executable 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"
|
69
qcom/opensource/wlan/utils/sigma-dut/sniffer-control-field-check.py
Executable file
69
qcom/opensource/wlan/utils/sigma-dut/sniffer-control-field-check.py
Executable 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"
|
77
qcom/opensource/wlan/utils/sigma-dut/sniffer-control-filter-capture.py
Executable file
77
qcom/opensource/wlan/utils/sigma-dut/sniffer-control-filter-capture.py
Executable 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)
|
40
qcom/opensource/wlan/utils/sigma-dut/sniffer-get-field-value.py
Executable file
40
qcom/opensource/wlan/utils/sigma-dut/sniffer-get-field-value.py
Executable 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)
|
@@ -0,0 +1 @@
|
||||
NoA_Duration wifi_p2p.noa.duration
|
@@ -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
|
@@ -0,0 +1 @@
|
||||
NoA wifi_p2p.type == 12
|
391
qcom/opensource/wlan/utils/sigma-dut/sniffer.c
Normal file
391
qcom/opensource/wlan/utils/sigma-dut/sniffer.c
Normal 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);
|
||||
}
|
18967
qcom/opensource/wlan/utils/sigma-dut/sta.c
Normal file
18967
qcom/opensource/wlan/utils/sigma-dut/sta.c
Normal file
File diff suppressed because it is too large
Load Diff
970
qcom/opensource/wlan/utils/sigma-dut/traffic.c
Normal file
970
qcom/opensource/wlan/utils/sigma-dut/traffic.c
Normal 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);
|
||||
}
|
1800
qcom/opensource/wlan/utils/sigma-dut/traffic_agent.c
Normal file
1800
qcom/opensource/wlan/utils/sigma-dut/traffic_agent.c
Normal file
File diff suppressed because it is too large
Load Diff
30
qcom/opensource/wlan/utils/sigma-dut/tshark.py
Normal file
30
qcom/opensource/wlan/utils/sigma-dut/tshark.py
Normal 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
|
2627
qcom/opensource/wlan/utils/sigma-dut/uapsd_stream.c
Normal file
2627
qcom/opensource/wlan/utils/sigma-dut/uapsd_stream.c
Normal file
File diff suppressed because it is too large
Load Diff
1228
qcom/opensource/wlan/utils/sigma-dut/utils.c
Normal file
1228
qcom/opensource/wlan/utils/sigma-dut/utils.c
Normal file
File diff suppressed because it is too large
Load Diff
1129
qcom/opensource/wlan/utils/sigma-dut/wlantest.c
Normal file
1129
qcom/opensource/wlan/utils/sigma-dut/wlantest.c
Normal file
File diff suppressed because it is too large
Load Diff
166
qcom/opensource/wlan/utils/sigma-dut/wlantest_ctrl.h
Normal file
166
qcom/opensource/wlan/utils/sigma-dut/wlantest_ctrl.h
Normal 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 */
|
545
qcom/opensource/wlan/utils/sigma-dut/wpa_ctrl.c
Normal file
545
qcom/opensource/wlan/utils/sigma-dut/wpa_ctrl.c
Normal 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 */
|
291
qcom/opensource/wlan/utils/sigma-dut/wpa_ctrl.h
Normal file
291
qcom/opensource/wlan/utils/sigma-dut/wpa_ctrl.h
Normal 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 */
|
997
qcom/opensource/wlan/utils/sigma-dut/wpa_helpers.c
Normal file
997
qcom/opensource/wlan/utils/sigma-dut/wpa_helpers.c
Normal 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(¶m[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",
|
||||
¶m[flen2 + 1]);
|
||||
strlcpy(obuf, ¶m[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, ¶m[flen2 + 1], obuf_size);
|
||||
|
||||
if (strncasecmp(param, "sta_link_addr", flen) == 0) {
|
||||
if (strncasecmp(¶m[flen + 1], link_addr, 18) == 0) {
|
||||
sigma_dut_print(dut, DUT_MSG_INFO,
|
||||
"MLO link id for STA link MAC is %s",
|
||||
¶m[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(¶m[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;
|
||||
}
|
70
qcom/opensource/wlan/utils/sigma-dut/wpa_helpers.h
Normal file
70
qcom/opensource/wlan/utils/sigma-dut/wpa_helpers.h
Normal 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 */
|
Reference in New Issue
Block a user