Add initial source code.
This commit is contained in:
Родитель
a3d4006da5
Коммит
dd922ff2a5
|
@ -0,0 +1,96 @@
|
|||
AccessModifierOffset: -4
|
||||
AlignAfterOpenBracket: DontAlign
|
||||
AlignConsecutiveAssignments: false
|
||||
# AlignConsecutiveBitFields: true
|
||||
AlignConsecutiveDeclarations: false
|
||||
# AlignConsecutiveMacros: true
|
||||
AlignEscapedNewlines: Right
|
||||
AlignOperands: false
|
||||
AlignTrailingComments: true
|
||||
# AllowAllArgumentsOnNextLine: true
|
||||
# AllowAllConstructorInitializersOnNextLine: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: true
|
||||
AllowShortBlocksOnASingleLine: true
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
# AllowShortLambdasOnASingleLine: Inline
|
||||
# AllowShortEnumsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: InlineOnly
|
||||
# AllowShortIfStatementsOnASingleLine: Never
|
||||
AllowShortLoopsOnASingleLine: true
|
||||
AlwaysBreakAfterReturnType: All
|
||||
AlwaysBreakBeforeMultilineStrings: false
|
||||
AlwaysBreakTemplateDeclarations: Yes
|
||||
BasedOnStyle: WebKit
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
# AfterCaseLabel: false
|
||||
AfterClass: true
|
||||
AfterControlStatement: false
|
||||
AfterEnum: true
|
||||
AfterFunction: true
|
||||
AfterNamespace: true
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: true
|
||||
AfterUnion: true
|
||||
AfterExternBlock: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
SplitEmptyFunction: false
|
||||
SplitEmptyRecord: false
|
||||
SplitEmptyNamespace: true
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Custom
|
||||
BreakInheritanceList: AfterColon
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializers: AfterColon
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 0
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth : 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: false
|
||||
# DeriveLineEnding: true
|
||||
# DerivePointerAlignment: true
|
||||
FixNamespaceComments: true
|
||||
IncludeBlocks: Preserve
|
||||
# IndentCaseBlocks: false
|
||||
IndentCaseLabels: true
|
||||
# IndentExternBlock: NoIndent
|
||||
# IndentGotoLabels: false
|
||||
IndentPPDirectives: None
|
||||
IndentWidth: 4
|
||||
# InsertTrailingCommas: Wrapped
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
PointerAlignment: Left
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SortUsingDeclarations: true
|
||||
SpaceAfterCStyleCast: false
|
||||
# SpaceAfterLogicalNot: false
|
||||
SpaceAfterTemplateKeyword: true
|
||||
# SpaceAroundPointerQualifiers: After
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeCpp11BracedList: false
|
||||
SpaceBeforeCtorInitializerColon: true
|
||||
SpaceBeforeInheritanceColon: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceBeforeRangeBasedForLoopColon: true
|
||||
# SpaceBeforeSquareBrackets: false
|
||||
# SpaceInEmptyBlock: false
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: false
|
||||
SpacesInCStyleCastParentheses: false
|
||||
# SpacesInConditionalStatement: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
TabWidth: 4
|
||||
Standard: Cpp11
|
||||
# UseCRLF: false
|
||||
UseTab: Never
|
|
@ -1,350 +1,38 @@
|
|||
## Ignore Visual Studio temporary files, build results, and
|
||||
## files generated by popular Visual Studio add-ons.
|
||||
##
|
||||
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
|
||||
# Prerequisites
|
||||
*.d
|
||||
|
||||
# User-specific files
|
||||
*.rsuser
|
||||
*.suo
|
||||
*.user
|
||||
*.userosscache
|
||||
*.sln.docstates
|
||||
|
||||
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||
*.userprefs
|
||||
|
||||
# Mono auto generated files
|
||||
mono_crash.*
|
||||
|
||||
# Build results
|
||||
[Dd]ebug/
|
||||
[Dd]ebugPublic/
|
||||
[Rr]elease/
|
||||
[Rr]eleases/
|
||||
x64/
|
||||
x86/
|
||||
[Aa][Rr][Mm]/
|
||||
[Aa][Rr][Mm]64/
|
||||
bld/
|
||||
[Bb]in/
|
||||
[Oo]bj/
|
||||
[Ll]og/
|
||||
[Ll]ogs/
|
||||
|
||||
# Visual Studio 2015/2017 cache/options directory
|
||||
.vs/
|
||||
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||
#wwwroot/
|
||||
|
||||
# Visual Studio 2017 auto generated files
|
||||
Generated\ Files/
|
||||
|
||||
# MSTest test Results
|
||||
[Tt]est[Rr]esult*/
|
||||
[Bb]uild[Ll]og.*
|
||||
|
||||
# NUnit
|
||||
*.VisualState.xml
|
||||
TestResult.xml
|
||||
nunit-*.xml
|
||||
|
||||
# Build Results of an ATL Project
|
||||
[Dd]ebugPS/
|
||||
[Rr]eleasePS/
|
||||
dlldata.c
|
||||
|
||||
# Benchmark Results
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
||||
# .NET Core
|
||||
project.lock.json
|
||||
project.fragment.lock.json
|
||||
artifacts/
|
||||
|
||||
# StyleCop
|
||||
StyleCopReport.xml
|
||||
|
||||
# Files built by Visual Studio
|
||||
*_i.c
|
||||
*_p.c
|
||||
*_h.h
|
||||
*.ilk
|
||||
*.meta
|
||||
# Compiled Object files
|
||||
*.slo
|
||||
*.lo
|
||||
*.o
|
||||
*.obj
|
||||
*.iobj
|
||||
|
||||
# Precompiled Headers
|
||||
*.gch
|
||||
*.pch
|
||||
*.pdb
|
||||
*.ipdb
|
||||
*.pgc
|
||||
*.pgd
|
||||
*.rsp
|
||||
*.sbr
|
||||
*.tlb
|
||||
*.tli
|
||||
*.tlh
|
||||
*.tmp
|
||||
*.tmp_proj
|
||||
*_wpftmp.csproj
|
||||
*.log
|
||||
*.vspscc
|
||||
*.vssscc
|
||||
.builds
|
||||
*.pidb
|
||||
*.svclog
|
||||
*.scc
|
||||
|
||||
# Chutzpah Test files
|
||||
_Chutzpah*
|
||||
# Compiled Dynamic libraries
|
||||
*.so
|
||||
*.dylib
|
||||
*.dll
|
||||
|
||||
# Visual C++ cache files
|
||||
ipch/
|
||||
*.aps
|
||||
*.ncb
|
||||
*.opendb
|
||||
*.opensdf
|
||||
*.sdf
|
||||
*.cachefile
|
||||
*.VC.db
|
||||
*.VC.VC.opendb
|
||||
# Fortran module files
|
||||
*.mod
|
||||
*.smod
|
||||
|
||||
# Visual Studio profiler
|
||||
*.psess
|
||||
*.vsp
|
||||
*.vspx
|
||||
*.sap
|
||||
# Compiled Static libraries
|
||||
*.lai
|
||||
*.la
|
||||
*.a
|
||||
*.lib
|
||||
|
||||
# Visual Studio Trace Files
|
||||
*.e2e
|
||||
# Executables
|
||||
*.exe
|
||||
*.out
|
||||
*.app
|
||||
|
||||
# TFS 2012 Local Workspace
|
||||
$tf/
|
||||
|
||||
# Guidance Automation Toolkit
|
||||
*.gpState
|
||||
|
||||
# ReSharper is a .NET coding add-in
|
||||
_ReSharper*/
|
||||
*.[Rr]e[Ss]harper
|
||||
*.DotSettings.user
|
||||
|
||||
# TeamCity is a build add-in
|
||||
_TeamCity*
|
||||
|
||||
# DotCover is a Code Coverage Tool
|
||||
*.dotCover
|
||||
|
||||
# AxoCover is a Code Coverage Tool
|
||||
.axoCover/*
|
||||
!.axoCover/settings.json
|
||||
|
||||
# Visual Studio code coverage results
|
||||
*.coverage
|
||||
*.coveragexml
|
||||
|
||||
# NCrunch
|
||||
_NCrunch_*
|
||||
.*crunch*.local.xml
|
||||
nCrunchTemp_*
|
||||
|
||||
# MightyMoose
|
||||
*.mm.*
|
||||
AutoTest.Net/
|
||||
|
||||
# Web workbench (sass)
|
||||
.sass-cache/
|
||||
|
||||
# Installshield output folder
|
||||
[Ee]xpress/
|
||||
|
||||
# DocProject is a documentation generator add-in
|
||||
DocProject/buildhelp/
|
||||
DocProject/Help/*.HxT
|
||||
DocProject/Help/*.HxC
|
||||
DocProject/Help/*.hhc
|
||||
DocProject/Help/*.hhk
|
||||
DocProject/Help/*.hhp
|
||||
DocProject/Help/Html2
|
||||
DocProject/Help/html
|
||||
|
||||
# Click-Once directory
|
||||
publish/
|
||||
|
||||
# Publish Web Output
|
||||
*.[Pp]ublish.xml
|
||||
*.azurePubxml
|
||||
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||
# but database connection strings (with potential passwords) will be unencrypted
|
||||
*.pubxml
|
||||
*.publishproj
|
||||
|
||||
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||
# in these scripts will be unencrypted
|
||||
PublishScripts/
|
||||
|
||||
# NuGet Packages
|
||||
*.nupkg
|
||||
# NuGet Symbol Packages
|
||||
*.snupkg
|
||||
# The packages folder can be ignored because of Package Restore
|
||||
**/[Pp]ackages/*
|
||||
# except build/, which is used as an MSBuild target.
|
||||
!**/[Pp]ackages/build/
|
||||
# Uncomment if necessary however generally it will be regenerated when needed
|
||||
#!**/[Pp]ackages/repositories.config
|
||||
# NuGet v3's project.json files produces more ignorable files
|
||||
*.nuget.props
|
||||
*.nuget.targets
|
||||
|
||||
# Microsoft Azure Build Output
|
||||
csx/
|
||||
*.build.csdef
|
||||
|
||||
# Microsoft Azure Emulator
|
||||
ecf/
|
||||
rcf/
|
||||
|
||||
# Windows Store app package directories and files
|
||||
AppPackages/
|
||||
BundleArtifacts/
|
||||
Package.StoreAssociation.xml
|
||||
_pkginfo.txt
|
||||
*.appx
|
||||
*.appxbundle
|
||||
*.appxupload
|
||||
|
||||
# Visual Studio cache files
|
||||
# files ending in .cache can be ignored
|
||||
*.[Cc]ache
|
||||
# but keep track of directories ending in .cache
|
||||
!?*.[Cc]ache/
|
||||
|
||||
# Others
|
||||
ClientBin/
|
||||
~$*
|
||||
*~
|
||||
*.dbmdl
|
||||
*.dbproj.schemaview
|
||||
*.jfm
|
||||
*.pfx
|
||||
*.publishsettings
|
||||
orleans.codegen.cs
|
||||
|
||||
# Including strong name files can present a security risk
|
||||
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||
#*.snk
|
||||
|
||||
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||
#bower_components/
|
||||
|
||||
# RIA/Silverlight projects
|
||||
Generated_Code/
|
||||
|
||||
# Backup & report files from converting an old project file
|
||||
# to a newer Visual Studio version. Backup files are not needed,
|
||||
# because we have git ;-)
|
||||
_UpgradeReport_Files/
|
||||
Backup*/
|
||||
UpgradeLog*.XML
|
||||
UpgradeLog*.htm
|
||||
ServiceFabricBackup/
|
||||
*.rptproj.bak
|
||||
|
||||
# SQL Server files
|
||||
*.mdf
|
||||
*.ldf
|
||||
*.ndf
|
||||
|
||||
# Business Intelligence projects
|
||||
*.rdl.data
|
||||
*.bim.layout
|
||||
*.bim_*.settings
|
||||
*.rptproj.rsuser
|
||||
*- [Bb]ackup.rdl
|
||||
*- [Bb]ackup ([0-9]).rdl
|
||||
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||
|
||||
# Microsoft Fakes
|
||||
FakesAssemblies/
|
||||
|
||||
# GhostDoc plugin setting file
|
||||
*.GhostDoc.xml
|
||||
|
||||
# Node.js Tools for Visual Studio
|
||||
.ntvs_analysis.dat
|
||||
node_modules/
|
||||
|
||||
# Visual Studio 6 build log
|
||||
*.plg
|
||||
|
||||
# Visual Studio 6 workspace options file
|
||||
*.opt
|
||||
|
||||
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||
*.vbw
|
||||
|
||||
# Visual Studio LightSwitch build output
|
||||
**/*.HTMLClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/GeneratedArtifacts
|
||||
**/*.DesktopClient/ModelManifest.xml
|
||||
**/*.Server/GeneratedArtifacts
|
||||
**/*.Server/ModelManifest.xml
|
||||
_Pvt_Extensions
|
||||
|
||||
# Paket dependency manager
|
||||
.paket/paket.exe
|
||||
paket-files/
|
||||
|
||||
# FAKE - F# Make
|
||||
.fake/
|
||||
|
||||
# CodeRush personal settings
|
||||
.cr/personal
|
||||
|
||||
# Python Tools for Visual Studio (PTVS)
|
||||
__pycache__/
|
||||
*.pyc
|
||||
|
||||
# Cake - Uncomment if you are using it
|
||||
# tools/**
|
||||
# !tools/packages.config
|
||||
|
||||
# Tabs Studio
|
||||
*.tss
|
||||
|
||||
# Telerik's JustMock configuration file
|
||||
*.jmconfig
|
||||
|
||||
# BizTalk build output
|
||||
*.btp.cs
|
||||
*.btm.cs
|
||||
*.odx.cs
|
||||
*.xsd.cs
|
||||
|
||||
# OpenCover UI analysis results
|
||||
OpenCover/
|
||||
|
||||
# Azure Stream Analytics local run output
|
||||
ASALocalRun/
|
||||
|
||||
# MSBuild Binary and Structured Log
|
||||
*.binlog
|
||||
|
||||
# NVidia Nsight GPU debugger configuration file
|
||||
*.nvuser
|
||||
|
||||
# MFractors (Xamarin productivity tool) working folder
|
||||
.mfractor/
|
||||
|
||||
# Local History for Visual Studio
|
||||
.localhistory/
|
||||
|
||||
# BeatPulse healthcheck temp database
|
||||
healthchecksdb
|
||||
|
||||
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||
MigrationBackup/
|
||||
|
||||
# Ionide (cross platform F# VS Code tools) working folder
|
||||
.ionide/
|
||||
# Build directories.
|
||||
build*/
|
||||
debug/
|
||||
release/
|
||||
.vscode
|
|
@ -0,0 +1,86 @@
|
|||
# project options
|
||||
cmake_minimum_required(VERSION 3.14)
|
||||
project(wifi-telemetry CXX)
|
||||
|
||||
# c++ standard options
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_CXX_EXTENSIONS OFF)
|
||||
|
||||
# allow setting target_link_libraries() from any dir
|
||||
cmake_policy(SET CMP0079 NEW)
|
||||
|
||||
# define option for use of Microsoft tracelogging
|
||||
option(
|
||||
ENABLE_MS_LTTNG_EXTENSIONS
|
||||
"Enable use of Microsoft tracelogging extensions for LTTNG"
|
||||
OFF
|
||||
)
|
||||
|
||||
# define option to build hostap dev dependency in-tree
|
||||
option(
|
||||
BUILD_HOSTAP_EXTERNAL
|
||||
"Build wpa_supplicant/hostapd from built-in external source"
|
||||
ON
|
||||
)
|
||||
|
||||
# define option to build sdbus-c++ dev dependency in-tree
|
||||
option(
|
||||
BUILD_SDBUS_CPP_EXTERNAL
|
||||
"Build sdbus-c++ from built-in external source"
|
||||
ON
|
||||
)
|
||||
|
||||
include(ExternalProject)
|
||||
include(GNUInstallDirs)
|
||||
include(CheckPIESupported)
|
||||
include(cmake/find_wpa_client.cmake)
|
||||
include(cmake/find_systemd.cmake)
|
||||
include(cmake/FindLTTngUST.cmake)
|
||||
include(cmake/find_pthreads.cmake)
|
||||
include(cmake/find_sdbus-cpp.cmake)
|
||||
if (ENABLE_MS_LTTNG_EXTENSIONS)
|
||||
include(cmake/find_tracelogging.cmake)
|
||||
endif()
|
||||
|
||||
check_pie_supported()
|
||||
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
|
||||
|
||||
# compilation options
|
||||
add_compile_options(
|
||||
-Wall
|
||||
-Wshadow
|
||||
-Wformat-security
|
||||
-Werror
|
||||
-Wextra
|
||||
-Wpedantic
|
||||
-Wconversion
|
||||
)
|
||||
|
||||
if (CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
add_compile_options(
|
||||
-fstack-protector
|
||||
-fvisibility=hidden
|
||||
)
|
||||
elseif (CMAKE_C_COMPILER_ID STREQUAL "GNU")
|
||||
add_compile_options(
|
||||
-fstack-clash-protection
|
||||
-fstack-protector-all
|
||||
-fvisibility=hidden
|
||||
-Wl,-z,noexecstack
|
||||
-Wl,-z,now
|
||||
-Wl,-z,relro
|
||||
)
|
||||
endif()
|
||||
|
||||
if (CMAKE_BUILD_TYPE MATCHES "(Release|RelWithDebInfo|MinSizeRel)")
|
||||
add_compile_definitions(_FORTIFY_SOURCE=2)
|
||||
endif()
|
||||
|
||||
if (ENABLE_MS_LTTNG_EXTENSIONS)
|
||||
add_compile_definitions(TRACE_USE_TRACELOGGING)
|
||||
endif()
|
||||
|
||||
include_directories(include)
|
||||
|
||||
add_subdirectory(src)
|
88
README.md
88
README.md
|
@ -1,33 +1,55 @@
|
|||
# Project
|
||||
|
||||
> This repo has been populated by an initial template to help get you started. Please
|
||||
> make sure to update the content to build a great experience for community-building.
|
||||
|
||||
As the maintainer of this project, please make a few updates:
|
||||
|
||||
- Improving this README.MD file to provide a great experience
|
||||
- Updating SUPPORT.MD with content about this project's support experience
|
||||
- Understanding the security reporting process in SECURITY.MD
|
||||
- Remove this section from the README
|
||||
|
||||
## Contributing
|
||||
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a
|
||||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
|
||||
the rights to use your contribution. For details, visit https://cla.opensource.microsoft.com.
|
||||
|
||||
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
|
||||
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
|
||||
provided by the bot. You will only need to do this once across all repos using our CLA.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
|
||||
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
||||
## Trademarks
|
||||
|
||||
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
|
||||
trademarks or logos is subject to and must follow
|
||||
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
|
||||
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
|
||||
Any use of third-party trademarks or logos are subject to those third-party's policies.
|
||||
# Wi-Fi Telemetry
|
||||
|
||||
This project provides a Wi-Fi telemetry library and daemon. It enables realtime
|
||||
collection and reporting of Wi-Fi related events. It can be used in conjunction
|
||||
with the the [wifi-ztp](https://github.com/microsoft/wifi-ztp) project to
|
||||
analyze and collect Wi-Fi zero touch provisioning telemetry as well (-s ztp
|
||||
command line option).
|
||||
|
||||
## Building
|
||||
|
||||
### Ubuntu (focal)
|
||||
|
||||
```bash
|
||||
sudo apt install \
|
||||
build-essential \
|
||||
cmake \
|
||||
git \
|
||||
liblttng-ust-dev \
|
||||
libpci-dev \
|
||||
libssl-dev \
|
||||
libsystemd-dev \
|
||||
pkg-config
|
||||
```
|
||||
|
||||
Checkout and build:
|
||||
|
||||
```bash
|
||||
git clone git@github.com:microsoft/wifi-telemetry.git
|
||||
cd wifi-telemetry
|
||||
mkdir build && cd $_
|
||||
cmake ..
|
||||
make -j $(nproc)
|
||||
```
|
||||
|
||||
## Contributing
|
||||
|
||||
This project welcomes contributions and suggestions. Most contributions require you to agree to a
|
||||
Contributor License Agreement (CLA) declaring that you have the right to, and actually do, grant us
|
||||
the rights to use your contribution. For details, visit [https://cla.opensource.microsoft.com](https://cla.opensource.microsoft.com).
|
||||
|
||||
When you submit a pull request, a CLA bot will automatically determine whether you need to provide
|
||||
a CLA and decorate the PR appropriately (e.g., status check, comment). Simply follow the instructions
|
||||
provided by the bot. You will only need to do this once across all repos using our CLA.
|
||||
|
||||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
|
||||
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or
|
||||
contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
|
||||
|
||||
## Trademarks
|
||||
|
||||
This project may contain trademarks or logos for projects, products, or services. Authorized use of Microsoft
|
||||
trademarks or logos is subject to and must follow
|
||||
[Microsoft's Trademark & Brand Guidelines](https://www.microsoft.com/en-us/legal/intellectualproperty/trademarks/usage/general).
|
||||
Use of Microsoft trademarks or logos in modified versions of this project must not cause confusion or imply Microsoft sponsorship.
|
||||
Any use of third-party trademarks or logos are subject to those third-party's policies.
|
||||
|
|
23
SUPPORT.md
23
SUPPORT.md
|
@ -1,25 +1,14 @@
|
|||
# TODO: The maintainer of this repo has not yet edited this file
|
||||
|
||||
**REPO OWNER**: Do you want Customer Service & Support (CSS) support for this product/project?
|
||||
|
||||
- **No CSS support:** Fill out this template with information about how to file issues and get help.
|
||||
- **Yes CSS support:** Fill out an intake form at [aka.ms/spot](https://aka.ms/spot). CSS will work with/help you to determine next steps. More details also available at [aka.ms/onboardsupport](https://aka.ms/onboardsupport).
|
||||
- **Not sure?** Fill out a SPOT intake as though the answer were "Yes". CSS will help you decide.
|
||||
|
||||
*Then remove this first heading from this SUPPORT.MD file before publishing your repo.*
|
||||
|
||||
# Support
|
||||
|
||||
## How to file issues and get help
|
||||
|
||||
This project uses GitHub Issues to track bugs and feature requests. Please search the existing
|
||||
issues before filing new issues to avoid duplicates. For new issues, file your bug or
|
||||
feature request as a new Issue.
|
||||
This project uses GitHub Issues to track bugs and feature requests. Please
|
||||
search the existing issues before filing new issues to avoid duplicates. For
|
||||
new issues, file your bug or feature request as a new Issue.
|
||||
|
||||
For help and questions about using this project, please **REPO MAINTAINER: INSERT INSTRUCTIONS HERE
|
||||
FOR HOW TO ENGAGE REPO OWNERS OR COMMUNITY FOR HELP. COULD BE A STACK OVERFLOW TAG OR OTHER
|
||||
CHANNEL. WHERE WILL YOU HELP PEOPLE?**.
|
||||
For help and questions about using this project, please contact
|
||||
<wifiztpsupport@microsoft.com>.
|
||||
|
||||
## Microsoft Support Policy
|
||||
|
||||
Support for this **PROJECT or PRODUCT** is limited to the resources listed above.
|
||||
Support for this project is limited to the resources listed above.
|
||||
|
|
|
@ -0,0 +1,116 @@
|
|||
#.rst:
|
||||
# FindLTTngUST
|
||||
# ------------
|
||||
#
|
||||
# This module finds the `LTTng-UST <http://lttng.org/>`__ library.
|
||||
#
|
||||
# Imported target
|
||||
# ^^^^^^^^^^^^^^^
|
||||
#
|
||||
# This module defines the following :prop_tgt:`IMPORTED` target:
|
||||
#
|
||||
# ``LTTng::UST``
|
||||
# The LTTng-UST library, if found
|
||||
#
|
||||
# Result variables
|
||||
# ^^^^^^^^^^^^^^^^
|
||||
#
|
||||
# This module sets the following
|
||||
#
|
||||
# ``LTTNGUST_FOUND``
|
||||
# ``TRUE`` if system has LTTng-UST
|
||||
# ``LTTNGUST_INCLUDE_DIRS``
|
||||
# The LTTng-UST include directories
|
||||
# ``LTTNGUST_LIBRARIES``
|
||||
# The libraries needed to use LTTng-UST
|
||||
# ``LTTNGUST_VERSION_STRING``
|
||||
# The LTTng-UST version
|
||||
# ``LTTNGUST_HAS_TRACEF``
|
||||
# ``TRUE`` if the ``tracef()`` API is available in the system's LTTng-UST
|
||||
# ``LTTNGUST_HAS_TRACELOG``
|
||||
# ``TRUE`` if the ``tracelog()`` API is available in the system's LTTng-UST
|
||||
|
||||
#=============================================================================
|
||||
# Copyright 2016 Kitware, Inc.
|
||||
# Copyright 2016 Philippe Proulx <pproulx@efficios.com>
|
||||
#
|
||||
# Distributed under the OSI-approved BSD License (the "License");
|
||||
# see accompanying file Copyright.txt for details.
|
||||
#
|
||||
# This software is distributed WITHOUT ANY WARRANTY; without even the
|
||||
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
# See the License for more information.
|
||||
#=============================================================================
|
||||
# (To distribute this file outside of CMake, substitute the full
|
||||
# License text for the above reference.)
|
||||
|
||||
find_path(LTTNGUST_INCLUDE_DIRS NAMES lttng/tracepoint.h)
|
||||
# Must also check for the path of generated header files since out-of-tree
|
||||
# build is a possibility (Yocto).
|
||||
find_path(LTTNGUST_INCLUDE_DIRS_GENERATED NAMES lttng/ust-config.h)
|
||||
find_library(LTTNGUST_LIBRARIES NAMES lttng-ust)
|
||||
|
||||
if(LTTNGUST_INCLUDE_DIRS AND LTTNGUST_INCLUDE_DIRS_GENERATED AND LTTNGUST_LIBRARIES)
|
||||
# find tracef() and tracelog() support
|
||||
set(LTTNGUST_HAS_TRACEF 0)
|
||||
set(LTTNGUST_HAS_TRACELOG 0)
|
||||
|
||||
if(EXISTS "${LTTNGUST_INCLUDE_DIRS}/lttng/tracef.h")
|
||||
set(LTTNGUST_HAS_TRACEF TRUE)
|
||||
endif()
|
||||
|
||||
if(EXISTS "${LTTNGUST_INCLUDE_DIRS}/lttng/tracelog.h")
|
||||
set(LTTNGUST_HAS_TRACELOG TRUE)
|
||||
endif()
|
||||
|
||||
# get version
|
||||
set(lttngust_version_file "${LTTNGUST_INCLUDE_DIRS_GENERATED}/lttng/ust-version.h")
|
||||
|
||||
if(EXISTS "${lttngust_version_file}")
|
||||
file(STRINGS "${lttngust_version_file}" lttngust_version_major_string
|
||||
REGEX "^[\t ]*#define[\t ]+LTTNG_UST_MAJOR_VERSION[\t ]+[0-9]+[\t ]*$")
|
||||
file(STRINGS "${lttngust_version_file}" lttngust_version_minor_string
|
||||
REGEX "^[\t ]*#define[\t ]+LTTNG_UST_MINOR_VERSION[\t ]+[0-9]+[\t ]*$")
|
||||
file(STRINGS "${lttngust_version_file}" lttngust_version_patch_string
|
||||
REGEX "^[\t ]*#define[\t ]+LTTNG_UST_PATCHLEVEL_VERSION[\t ]+[0-9]+[\t ]*$")
|
||||
string(REGEX REPLACE ".*([0-9]+).*" "\\1"
|
||||
lttngust_v_major "${lttngust_version_major_string}")
|
||||
string(REGEX REPLACE ".*([0-9]+).*" "\\1"
|
||||
lttngust_v_minor "${lttngust_version_minor_string}")
|
||||
string(REGEX REPLACE ".*([0-9]+).*" "\\1"
|
||||
lttngust_v_patch "${lttngust_version_patch_string}")
|
||||
set(LTTNGUST_VERSION_STRING
|
||||
"${lttngust_v_major}.${lttngust_v_minor}.${lttngust_v_patch}")
|
||||
unset(lttngust_version_major_string)
|
||||
unset(lttngust_version_minor_string)
|
||||
unset(lttngust_version_patch_string)
|
||||
unset(lttngust_v_major)
|
||||
unset(lttngust_v_minor)
|
||||
unset(lttngust_v_patch)
|
||||
else()
|
||||
message(FATAL_ERROR "Missing version header")
|
||||
endif()
|
||||
|
||||
unset(lttngust_version_file)
|
||||
|
||||
if(NOT TARGET LTTng::UST)
|
||||
add_library(LTTng::UST UNKNOWN IMPORTED)
|
||||
set_target_properties(LTTng::UST PROPERTIES
|
||||
INTERFACE_INCLUDE_DIRECTORIES "${LTTNGUST_INCLUDE_DIRS};${LTTNGUST_INCLUDE_DIRS_GENERATED}"
|
||||
INTERFACE_LINK_LIBRARIES ${CMAKE_DL_LIBS}
|
||||
IMPORTED_LINK_INTERFACE_LANGUAGES "C"
|
||||
IMPORTED_LOCATION "${LTTNGUST_LIBRARIES}")
|
||||
endif()
|
||||
|
||||
# add libdl to required libraries
|
||||
set(LTTNGUST_LIBRARIES ${LTTNGUST_LIBRARIES} ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
|
||||
# handle the QUIETLY and REQUIRED arguments and set LTTNGUST_FOUND to
|
||||
# TRUE if all listed variables are TRUE
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(LTTngUST FOUND_VAR LTTNGUST_FOUND
|
||||
REQUIRED_VARS LTTNGUST_LIBRARIES
|
||||
LTTNGUST_INCLUDE_DIRS
|
||||
VERSION_VAR LTTNGUST_VERSION_STRING)
|
||||
mark_as_advanced(LTTNGUST_LIBRARIES LTTNGUST_INCLUDE_DIRS)
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
find_package(Threads REQUIRED)
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
if (BUILD_SDBUS_CPP_EXTERNAL)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../external/sdbus-c++)
|
||||
else()
|
||||
find_package(sdbus-c++ REQUIRED)
|
||||
endif()
|
|
@ -0,0 +1,9 @@
|
|||
find_library(LIBSYSTEMD
|
||||
NAMES libsystemd.so
|
||||
REQUIRED)
|
||||
|
||||
if(LIBSYSTEMD)
|
||||
set(LIBSYSTEMD_TARGET ${LIBSYSTEMD})
|
||||
endif()
|
||||
|
||||
MESSAGE(STATUS LIBSYSTEMD=${LIBSYSTEMD})
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
find_package(tracelogging REQUIRED)
|
|
@ -0,0 +1,12 @@
|
|||
if (BUILD_HOSTAP_EXTERNAL)
|
||||
add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/../external/hostap)
|
||||
else()
|
||||
find_library(LIBWPA_CLIENT
|
||||
NAMES libwpa_client.so
|
||||
REQUIRED)
|
||||
endif()
|
||||
|
||||
if(LIBWPA_CLIENT)
|
||||
set(LIBWPA_CLIENT_TARGET ${LIBWPA_CLIENT})
|
||||
MESSAGE(STATUS "Found wpa client: ${LIBWPA_CLIENT}")
|
||||
endif()
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
include(CMakeFindDependencyMacro)
|
||||
|
||||
find_library(LIBSYSTEMD NAMES libsystemd.so)
|
||||
find_library(LIBWPA_CLIENT NAMES libwpa_client.so)
|
||||
find_dependency(LTTngUST)
|
||||
find_dependency(Threads)
|
||||
|
||||
include("${CMAKE_CURRENT_LIST_DIR}/wifi-telemetry-targets.cmake")
|
|
@ -0,0 +1,2 @@
|
|||
CONFIG_CTRL_IFACE=y
|
||||
CONFIG_BUILD_WPA_CLIENT_SO=y
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
find_program(MAKE_EXE
|
||||
NAMES gmake nmake make
|
||||
REQUIRED
|
||||
)
|
||||
|
||||
set(HOSTAP_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/hostap-prefix/src/hostap/wpa_supplicant)
|
||||
|
||||
ExternalProject_Add(hostap
|
||||
GIT_REPOSITORY "http://w1.fi/hostap.git"
|
||||
GIT_TAG "5f082c158c49a23614b69e4465e9a7299f004f5f"
|
||||
CONFIGURE_COMMAND cp -n ${CMAKE_CURRENT_SOURCE_DIR}/.config ${HOSTAP_PREFIX}/.config
|
||||
BINARY_DIR ${HOSTAP_PREFIX}
|
||||
BUILD_COMMAND QUIET=1 $(MAKE) libwpa_client.so
|
||||
INSTALL_DIR ${HOSTAP_PREFIX}
|
||||
INSTALL_COMMAND QUIET=1 $(MAKE) install
|
||||
)
|
||||
|
||||
set(LIBWPA_CLIENT
|
||||
${HOSTAP_PREFIX}/libwpa_client.so
|
||||
CACHE FILEPATH
|
||||
"wpa client shared object"
|
||||
)
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
set(SDBUS_CPP_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/sdbus-cpp-prefix)
|
||||
|
||||
ExternalProject_Add(sdbus-cpp
|
||||
GIT_REPOSITORY "https://github.com/Kistler-Group/sdbus-cpp.git"
|
||||
GIT_TAG "v0.8.3"
|
||||
)
|
||||
|
||||
set(SDBUS_CPP_EXTERNAL_LIBS
|
||||
"${SDBUS_CPP_PREFIX}/src/sdbus-cpp-build"
|
||||
CACHE PATH
|
||||
"Directory of external sdbus-c++ libraries"
|
||||
)
|
||||
set(SDBUS_CPP_EXTERNAL_NAME
|
||||
sdbus-c++
|
||||
CACHE STRING
|
||||
"sdbus-c++ shared object name"
|
||||
)
|
||||
set(SDBUS_CPP_EXTERNAL
|
||||
${SDBUS_CPP_EXTERNAL_LIBS}/lib${SDBUS_CPP_EXTERNAL_NAME}.so
|
||||
CACHE FILEPATH
|
||||
"sdbus-c++ shared object"
|
||||
)
|
|
@ -0,0 +1,230 @@
|
|||
|
||||
#ifndef __WIFI_80211_HPP__
|
||||
#define __WIFI_80211_HPP__
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
|
||||
/**
|
||||
* @brief Unsolicited Management Frame reason code for Disassociation.
|
||||
* @see IEEE Std 802.11-2016, Section 9.4.1.7, Table 9-45.
|
||||
*/
|
||||
enum class WifiDeauthenticationReasonCode : uint16_t
|
||||
{
|
||||
Unspecified = 1,
|
||||
InvalidAuthentication = 2,
|
||||
LeavingNetworkDeauth = 3,
|
||||
Inactivity = 4,
|
||||
NoMoreStas = 5,
|
||||
InvalidClass2Frame = 6,
|
||||
InvalidClass3Frame = 7,
|
||||
LeavingNetworkDisassoc = 8,
|
||||
NotAuthenticated = 9,
|
||||
UnacceptablePowerCapability = 10,
|
||||
UnacceptableSupportedChannels = 11,
|
||||
BssTransitionDeassocac = 12,
|
||||
InvalidElement = 13,
|
||||
MicFailure = 14,
|
||||
FourWayHandshakeTimeout = 15,
|
||||
GroupKeyHandshakeTimeout = 16,
|
||||
HandshakeElementMismatch = 17,
|
||||
InvalidGroupCipher = 18,
|
||||
InvalidPairwiseCipher = 19,
|
||||
InvalidAkmp = 20,
|
||||
UnsupportedRsneVersion = 21,
|
||||
InvalidRsneCapabilities = 22,
|
||||
Ieee80211XAuthFailed = 23,
|
||||
CipherOutOfPolicy = 24,
|
||||
TdlsPeerUnreachable = 25,
|
||||
TdlsUnspecifiedReason = 26,
|
||||
SspRequestedDissassoc = 27,
|
||||
NoSspRoamingAgreement = 28,
|
||||
BadCipherOrAkm = 29,
|
||||
NotAuthorizedThisLocation = 30,
|
||||
ServiceChangePrecludesTs = 31,
|
||||
UnspecifiedQosReason = 32,
|
||||
NotEnoughBandwidth = 33,
|
||||
MissingAcks = 34,
|
||||
ExceededTxop = 35,
|
||||
StaLeaving = 36,
|
||||
EndTsBaDls = 37,
|
||||
UnknownTsBa = 38,
|
||||
Timeout = 39,
|
||||
PeerkeyMismatch = 45,
|
||||
PeerInitiated = 46,
|
||||
ApInitiated = 47,
|
||||
InvalidFtActionFrameCount = 48,
|
||||
InvalidPmkid = 49,
|
||||
InvalidMde = 50,
|
||||
InvalidFte = 51,
|
||||
MeshPeeringCanceled = 52,
|
||||
MeshMaxPeers = 53,
|
||||
MeshConfigurationPolicyViolation = 54,
|
||||
MeshCloseRecvd = 55,
|
||||
MeshMaxRetries = 56,
|
||||
MeshConfirmTimeout = 57,
|
||||
MeshInvalidGtk = 58,
|
||||
MeshInconsistentParameters = 59,
|
||||
MeshInvalidSecurityCapability = 60,
|
||||
MeshPathErrorNoProxyInformation = 61,
|
||||
MeshPathErrorNoForwardingInformation = 62,
|
||||
MeshPathErrorDestinationUnreachable = 63,
|
||||
MaxAddressAlreadyExistsInMbss = 64,
|
||||
MeshChannelSwitchRegulatoryRequirements = 65,
|
||||
MeshChannelSwitchUnspecified = 66,
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Unsolicited Management Frame status code.
|
||||
* @see IEEE Std 802.11-2016, Section 9.4.1.9, Table 9-46.
|
||||
*/
|
||||
enum class WifiStatusCode : uint16_t
|
||||
{
|
||||
Success = 0,
|
||||
Refused = 1,
|
||||
TdlsRejectedAlternativeProvided = 2,
|
||||
TdlsRejected = 3,
|
||||
/* reserved = 4 */
|
||||
SecurityDisabled = 5,
|
||||
UnacceptableLifetime = 6,
|
||||
NotInSameBss = 7,
|
||||
/* reserved = 8-9 */
|
||||
RefusedCapabilitiesMismatch = 10,
|
||||
DeniedNoAssociationExists = 11,
|
||||
DeniedOtherReason = 12,
|
||||
UnsupportedAuthAlgorithm = 13,
|
||||
TransactionSequenceError = 14,
|
||||
ChallengeFailure = 15,
|
||||
RejectedSequenceTimeout = 16,
|
||||
DeniedNoMoreStas = 17,
|
||||
RefusedBasicRatesMismatch = 18,
|
||||
DeniedNoShortPreableSupport = 19,
|
||||
/* reserved = 20-21 */
|
||||
RejectedSpectrumManagementRequired = 22,
|
||||
RejectedBadPowerCapability = 23,
|
||||
RejectedBadSupportedChannels = 24,
|
||||
DeniedNoShortSlotTimeSupport = 25,
|
||||
/* reserved = 26 */
|
||||
DeniedNoHtSupport = 27,
|
||||
R0KHUnreachable = 28,
|
||||
DeniedPcoTimeNotSupported = 29,
|
||||
RefusedTemporarily = 30,
|
||||
RobustManagementPolicyViolation = 31,
|
||||
UnspecifiedQosFailure = 32,
|
||||
DeniedInsufficientBandwidth = 33,
|
||||
DeniedPoorChannelConditions = 34,
|
||||
DeniedQosNotSupported = 35,
|
||||
/* reserved = 36 */
|
||||
RequestDeclined = 37,
|
||||
InvalidParameters = 38,
|
||||
RejectedWithSuggestedChanges = 39,
|
||||
StatusInvalidElement = 40,
|
||||
StatusInvalidGroupCipher = 41,
|
||||
StatusInvalidPairwiseCipher = 42,
|
||||
StatusInvalidAkmp = 43,
|
||||
UnsupportedRsneVersion = 44,
|
||||
InvalidRsneCapabilities = 45,
|
||||
StatusCipherOutOfPolicy = 46,
|
||||
RejectedForDelayPeriod = 47,
|
||||
DlsNotAllowed = 48,
|
||||
NotPresent = 49,
|
||||
NotQosSta = 50,
|
||||
DeniedListenIntervalTooLarge = 51,
|
||||
StatusInvalidFtActionFrameCount = 52,
|
||||
StatusInvalidPmkid = 53,
|
||||
StatusInvalidMde = 54,
|
||||
StatusInvalidFte = 55,
|
||||
RequestTclasNotSupported = 56,
|
||||
InsufficientTclasProcessingResources = 57,
|
||||
TryAnotherBss = 58,
|
||||
GasAdvertisementProtocolNotSupported = 59,
|
||||
NoOutstandingGasRequest = 60,
|
||||
GasResponseNotReceivedFromServer = 61,
|
||||
GasQueryTimeout = 62,
|
||||
GasQueryResponseTooLarge = 63,
|
||||
RejectedHomeWithSuggestedChanges = 64,
|
||||
ServerUnreachable = 65,
|
||||
/* reserved = 66 */
|
||||
RejectedForSspPermissions = 67,
|
||||
RefusedUnauthenticatedAccessNotSupported = 68,
|
||||
/* reserved = 69-71 */
|
||||
InvalidRsne = 72,
|
||||
UApsdCoexistanceNotSupported = 73,
|
||||
UApsdCoexModeNotSupported = 74,
|
||||
BadIntervalWithUApsdCoex = 75,
|
||||
AntiCloggingTokenRequired = 76,
|
||||
UnsupportedFiniteCyclicGroup = 77,
|
||||
CannotFindAlternativeTbtt = 78,
|
||||
TransmissionFailure = 79,
|
||||
RequestTclassNotSupported = 80,
|
||||
TclasResourcesExhausted = 81,
|
||||
RejectedWithSuggestedBssTransition = 82,
|
||||
RejectWithSchedule = 83,
|
||||
RejectNoWakeupSpecified = 84,
|
||||
SuccessPowerSaveMode = 85,
|
||||
PendingAdmittingFstSession = 86,
|
||||
PerformingFstNow = 87,
|
||||
PendingGapInBaWindow = 88,
|
||||
RejectUPidSetting = 89,
|
||||
/* reserved = 90-91 */
|
||||
RefusedExternalReason = 92,
|
||||
RefusedApOutOutMemory = 93,
|
||||
RejectedEmergencyServicesNotSupported = 94,
|
||||
QueryResponseOutstanding = 95,
|
||||
RejectBadDseBand = 96,
|
||||
TclasProcessingTerminated = 97,
|
||||
TsScheduleConflict = 98,
|
||||
DeniedWithSuggestedBandAndChannel = 99,
|
||||
MccaopReservationConflict = 100,
|
||||
MafLimitExceeded = 101,
|
||||
MccaTrackLimitExceeded = 102,
|
||||
DeniedDueToSpectrumManagement = 103,
|
||||
DeniedVhtNotSupported = 104,
|
||||
EnablementDenied = 105,
|
||||
RestrictionFromAuthorixzedGdb = 106,
|
||||
AuthorizationDeenabled = 107,
|
||||
/* reserved = 108-165, 535 */
|
||||
};
|
||||
|
||||
enum class WifiAuthenticationType : uint32_t
|
||||
{
|
||||
Unknown = 0x0000,
|
||||
Open = 0x0001,
|
||||
WpaPsk = 0x0002,
|
||||
Shared = 0x0004,
|
||||
Wpa = 0x0008,
|
||||
Wpa2 = 0x0010,
|
||||
Wpa2Psk = 0x0020,
|
||||
};
|
||||
|
||||
inline const char*
|
||||
WifiAuthenticationTypeToString(const WifiAuthenticationType auth_type)
|
||||
{
|
||||
static const char* strs[] = {
|
||||
"unknown",
|
||||
"open",
|
||||
"wpa-psk",
|
||||
"shared",
|
||||
"wpa",
|
||||
"wpa2",
|
||||
"wpa2-psk"
|
||||
};
|
||||
|
||||
return strs[unsigned(auth_type)];
|
||||
}
|
||||
|
||||
typedef std::array<uint8_t, 6> wifi_80211_mac;
|
||||
|
||||
#define WIFI_80211_MAC_FMT "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx"
|
||||
#define STR_2_WIFI80211_MAC(a) &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]
|
||||
|
||||
static const wifi_80211_mac wifi_80211_any_address{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
static const wifi_80211_mac wifi_80211_broadcast_address{ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
|
||||
static inline bool
|
||||
is_wifi80211_broadcast_address(const wifi_80211_mac& mac)
|
||||
{
|
||||
return mac == wifi_80211_broadcast_address;
|
||||
}
|
||||
|
||||
#endif //__WIFI_80211_HPP__
|
|
@ -0,0 +1,123 @@
|
|||
|
||||
#ifndef __WIFI_FORMAT_80211_MAC_HPP__
|
||||
#define __WIFI_FORMAT_80211_MAC_HPP__
|
||||
|
||||
#include <iomanip>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211.hpp"
|
||||
|
||||
class put_dot11mac
|
||||
{
|
||||
public:
|
||||
put_dot11mac(
|
||||
const wifi_80211_mac& mac,
|
||||
const char separator = ':') :
|
||||
m_mac(mac),
|
||||
m_separator(separator)
|
||||
{}
|
||||
|
||||
std::ostream&
|
||||
operator()(
|
||||
std::ostream& out)
|
||||
{
|
||||
out << std::setbase(16)
|
||||
<< std::setw(2) << std::setfill('0') << short(m_mac[0]) << m_separator
|
||||
<< std::setw(2) << std::setfill('0') << short(m_mac[1]) << m_separator
|
||||
<< std::setw(2) << std::setfill('0') << short(m_mac[2]) << m_separator
|
||||
<< std::setw(2) << std::setfill('0') << short(m_mac[3]) << m_separator
|
||||
<< std::setw(2) << std::setfill('0') << short(m_mac[4]) << m_separator
|
||||
<< std::setw(2) << std::setfill('0') << short(m_mac[5])
|
||||
<< std::setbase(0);
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
private:
|
||||
const wifi_80211_mac& m_mac;
|
||||
const char m_separator;
|
||||
};
|
||||
|
||||
inline std::ostream&
|
||||
operator<<(
|
||||
std::ostream& out,
|
||||
put_dot11mac manipulator)
|
||||
{
|
||||
return manipulator(out);
|
||||
}
|
||||
|
||||
class get_dot11mac
|
||||
{
|
||||
public:
|
||||
get_dot11mac(
|
||||
wifi_80211_mac& mac,
|
||||
const char separator = ':') :
|
||||
m_mac(mac),
|
||||
m_separator(separator)
|
||||
{}
|
||||
|
||||
std::istream&
|
||||
operator()(
|
||||
std::istream& in)
|
||||
{
|
||||
static constexpr std::size_t c_NumOctets = std::tuple_size<std::decay<decltype(m_mac)>::type>::value;
|
||||
static constexpr std::size_t c_NumSeparators = c_NumOctets - 1;
|
||||
|
||||
uint32_t mac[c_NumOctets];
|
||||
char separators[c_NumSeparators];
|
||||
|
||||
in >> std::setbase(16)
|
||||
>> mac[0] >> separators[0]
|
||||
>> mac[1] >> separators[1]
|
||||
>> mac[2] >> separators[2]
|
||||
>> mac[3] >> separators[3]
|
||||
>> mac[4] >> separators[4]
|
||||
>> mac[5]
|
||||
>> std::setbase(0);
|
||||
|
||||
for (std::size_t i = 0; i < c_NumOctets; i++) {
|
||||
if (i < c_NumSeparators && separators[i] != m_separator) {
|
||||
in.setstate(std::ios_base::failbit);
|
||||
break;
|
||||
}
|
||||
|
||||
m_mac[i] = uint8_t(mac[i] & 0x000000FF);
|
||||
}
|
||||
|
||||
return in;
|
||||
}
|
||||
|
||||
private:
|
||||
wifi_80211_mac& m_mac;
|
||||
const char m_separator;
|
||||
};
|
||||
|
||||
inline std::istream&
|
||||
operator>>(
|
||||
std::istream& in,
|
||||
get_dot11mac manipulator)
|
||||
{
|
||||
return manipulator(in);
|
||||
}
|
||||
|
||||
inline std::string
|
||||
wifi_80211_mac_to_string(const wifi_80211_mac& mac, const char separator = ':')
|
||||
{
|
||||
std::ostringstream ss;
|
||||
ss << put_dot11mac(mac, separator);
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
inline wifi_80211_mac
|
||||
wifi_80211_mac_from_string(const std::string& mac_str, const char separator = ':')
|
||||
{
|
||||
std::istringstream ss(mac_str);
|
||||
wifi_80211_mac mac;
|
||||
ss >> get_dot11mac(mac, separator);
|
||||
|
||||
return mac;
|
||||
}
|
||||
|
||||
#endif //__WIFI_FORMAT_80211_MAC_HPP__
|
|
@ -0,0 +1,11 @@
|
|||
|
||||
#ifndef __WIFI_COMMON_HPP__
|
||||
#define __WIFI_COMMON_HPP__
|
||||
|
||||
enum class WifiOperationalMode
|
||||
{
|
||||
Station,
|
||||
AccessPoint,
|
||||
};
|
||||
|
||||
#endif //__WIFI_COMMON_HPP__
|
|
@ -0,0 +1,102 @@
|
|||
|
||||
#ifndef __WIFI_DPP_HPP__
|
||||
#define __WIFI_DPP_HPP__
|
||||
|
||||
enum class WifiDppRole
|
||||
{
|
||||
Initiator,
|
||||
Responder
|
||||
};
|
||||
|
||||
inline const char*
|
||||
WifiDppRoleToString(const WifiDppRole role)
|
||||
{
|
||||
static const char* strs[] = {
|
||||
"initiator",
|
||||
"responder"
|
||||
};
|
||||
|
||||
return strs[unsigned(role)];
|
||||
}
|
||||
|
||||
enum class WifiDppDeviceRole
|
||||
{
|
||||
Enrollee,
|
||||
Configurator
|
||||
};
|
||||
|
||||
inline const char*
|
||||
WifiDppDeviceRoleToString(const WifiDppDeviceRole role)
|
||||
{
|
||||
static const char* strs[] = {
|
||||
"enrollee",
|
||||
"configurator"
|
||||
};
|
||||
|
||||
return strs[unsigned(role)];
|
||||
}
|
||||
|
||||
enum class WifiDppExchangeEnrolleeState
|
||||
{
|
||||
Bootstrapping,
|
||||
Authenticated,
|
||||
Provisioning,
|
||||
Provisioned,
|
||||
Terminated
|
||||
};
|
||||
|
||||
inline const char*
|
||||
WifiDppExchangeEnrolleeStateToString(const WifiDppExchangeEnrolleeState state)
|
||||
{
|
||||
static const char* strs[] = {
|
||||
"bootstrapping",
|
||||
"authenticated",
|
||||
"provisioning",
|
||||
"provisioned",
|
||||
"terminated"
|
||||
};
|
||||
|
||||
return strs[unsigned(state)];
|
||||
}
|
||||
|
||||
enum class WifiDppExchangeConfiguratorState
|
||||
{
|
||||
Bootstrapping,
|
||||
Authenticated,
|
||||
Finished,
|
||||
Terminated
|
||||
};
|
||||
|
||||
inline const char*
|
||||
WifiDppExchangeConfiguratorStateToString(const WifiDppExchangeConfiguratorState state)
|
||||
{
|
||||
static const char* strs[] = {
|
||||
"bootstrapping",
|
||||
"authenticated",
|
||||
"finished",
|
||||
"terminated"
|
||||
};
|
||||
|
||||
return strs[unsigned(state)];
|
||||
}
|
||||
|
||||
enum class WifiDppFailureType
|
||||
{
|
||||
None,
|
||||
Unspecified,
|
||||
AuthenticationTimeout,
|
||||
};
|
||||
|
||||
inline const char*
|
||||
WifiDppFailureTypeToString(const WifiDppFailureType type)
|
||||
{
|
||||
static const char* strs[] = {
|
||||
"none",
|
||||
"unspecified",
|
||||
"authentication-timeout",
|
||||
};
|
||||
|
||||
return strs[unsigned(type)];
|
||||
}
|
||||
|
||||
#endif //__WIFI_DPP_HPP__
|
|
@ -0,0 +1,80 @@
|
|||
|
||||
#ifndef __WIFI_DPP_EXCHANGE_HPP__
|
||||
#define __WIFI_DPP_EXCHANGE_HPP__
|
||||
|
||||
#include <chrono>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211.hpp"
|
||||
#include "wifi-telemetry/wifi/wifi_common.hpp"
|
||||
#include "wifi-telemetry/wifi/wifi_dpp.hpp"
|
||||
|
||||
struct WifiDppExchange
|
||||
{
|
||||
WifiDppExchange(WifiDppDeviceRole device_role_, WifiDppRole role_) :
|
||||
WifiDppExchange(device_role_, role_, std::chrono::system_clock::now())
|
||||
{}
|
||||
|
||||
WifiDppExchange(WifiDppDeviceRole device_role_, WifiDppRole role_, std::chrono::time_point<std::chrono::system_clock> timestamp_start_) :
|
||||
device_role(device_role_),
|
||||
role(role_),
|
||||
timestamp_start(timestamp_start_)
|
||||
{}
|
||||
|
||||
virtual ~WifiDppExchange(void) = default;
|
||||
|
||||
void
|
||||
start(void)
|
||||
{
|
||||
if (!timestamp_start)
|
||||
timestamp_start = std::chrono::system_clock::now();
|
||||
}
|
||||
|
||||
void
|
||||
stop(void)
|
||||
{
|
||||
if (timestamp_start && !timestamp_end) {
|
||||
timestamp_end = std::chrono::system_clock::now();
|
||||
duration = std::chrono::duration_cast<std::chrono::milliseconds>(timestamp_end.value() - timestamp_start.value());
|
||||
}
|
||||
}
|
||||
|
||||
WifiDppDeviceRole device_role;
|
||||
WifiDppRole role;
|
||||
WifiDppFailureType failure_type = WifiDppFailureType::None;
|
||||
std::optional<std::string> failure_details;
|
||||
std::optional<std::chrono::time_point<std::chrono::system_clock>> timestamp_start;
|
||||
std::optional<std::chrono::time_point<std::chrono::system_clock>> timestamp_end;
|
||||
std::optional<std::chrono::milliseconds> duration;
|
||||
};
|
||||
|
||||
struct WifiDppExchangeEnrollee :
|
||||
public WifiDppExchange
|
||||
{
|
||||
WifiDppExchangeEnrollee(WifiDppRole role_) :
|
||||
WifiDppExchange(WifiDppDeviceRole::Enrollee, role_)
|
||||
{}
|
||||
|
||||
WifiDppExchangeEnrolleeState state = WifiDppExchangeEnrolleeState::Bootstrapping;
|
||||
std::unordered_set<uint32_t> chirp_frequencies;
|
||||
};
|
||||
|
||||
struct WifiDppExchangeConfigurator :
|
||||
public WifiDppExchange
|
||||
{
|
||||
WifiDppExchangeConfigurator(int32_t peer_id_, const wifi_80211_mac peer_bssid_, uint32_t frequency_, WifiDppRole role_) :
|
||||
WifiDppExchange(WifiDppDeviceRole::Configurator, role_),
|
||||
peer_id(peer_id_),
|
||||
peer_bssid(peer_bssid_),
|
||||
frequency(frequency_)
|
||||
{}
|
||||
|
||||
WifiDppExchangeConfiguratorState state = WifiDppExchangeConfiguratorState::Bootstrapping;
|
||||
int32_t peer_id;
|
||||
wifi_80211_mac peer_bssid;
|
||||
uint32_t frequency;
|
||||
};
|
||||
|
||||
#endif //__WIFI_DPP_EXCHANGE_HPP__
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#ifndef __WIFI_TELEMETRY_80211_HPP__
|
||||
#define __WIFI_TELEMETRY_80211_HPP__
|
||||
|
||||
enum class WifiConnectionAttemptResult
|
||||
{
|
||||
Succeeded = 0,
|
||||
Unspecified = 1,
|
||||
AuthenticationRejected = 2,
|
||||
AssociationRejected = 3,
|
||||
NetworkNotFound = 4,
|
||||
};
|
||||
|
||||
#endif // __WIFI_TELEMETRY_80211_HPP__
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
#ifndef __WIFI_INTERFACE_CONFIGURATION_HPP__
|
||||
#define __WIFI_INTERFACE_CONFIGURATION_HPP__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_common.hpp"
|
||||
|
||||
struct WifiInterfaceConfiguration
|
||||
{
|
||||
WifiInterfaceConfiguration(const std::string& name_, const WifiOperationalMode operational_mode_) :
|
||||
name(name_),
|
||||
operational_mode(operational_mode_)
|
||||
{}
|
||||
|
||||
WifiInterfaceConfiguration(const std::string& name_) :
|
||||
WifiInterfaceConfiguration(name_, WifiOperationalMode::Station)
|
||||
{}
|
||||
|
||||
std::string name;
|
||||
WifiOperationalMode operational_mode;
|
||||
};
|
||||
|
||||
#endif //__WIFI_INTERFACE_CONFIGURATION_HPP__
|
|
@ -0,0 +1,103 @@
|
|||
|
||||
#ifndef __WIFI_TELEMETRY_MONITOR_HPP__
|
||||
#define __WIFI_TELEMETRY_MONITOR_HPP__
|
||||
|
||||
#include <memory>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
#include "wifi-telemetry/wifi_interface_configuration.hpp"
|
||||
#include "wifi-telemetry/wifi_telemetry_source_instance.hpp"
|
||||
#include "wifi-telemetry/wifi_telemetry_source.hpp"
|
||||
#include "wifi-telemetry/wifi/wifi_common.hpp"
|
||||
|
||||
class __attribute__ ((visibility ("default"))) WifiTelemetryMonitor
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Construct a new Wifi Telemetry Monitor object.
|
||||
*/
|
||||
WifiTelemetryMonitor(void);
|
||||
~WifiTelemetryMonitor(void);
|
||||
|
||||
/**
|
||||
* @brief Adds a new telemetry source.
|
||||
*
|
||||
* @tparam TSource The type of the telemetry source. Must be a type deriving from WifiTelemetrySource.
|
||||
* @tparam TSourceArgs The parameter pack type for T's constructor arguments.
|
||||
* @param interface The interface configuration of the source (if any).
|
||||
* @param activation_args The arguments needed to activate the telemetry source, or nullptr if none.
|
||||
* @param args The arguments to forward to the constructor of type TSource.
|
||||
* @return std::shared_ptr<TSource>
|
||||
*/
|
||||
template <
|
||||
typename TSource,
|
||||
typename ...TSourceArgs,
|
||||
typename std::enable_if<std::is_base_of<WifiTelemetrySource, TSource>::value>* = nullptr
|
||||
>
|
||||
std::shared_ptr<TSource>
|
||||
add_source(const std::optional<WifiInterfaceConfiguration>& interface, const std::shared_ptr<WifiTelemetrySourceActivationArgs> activation_args, TSourceArgs... args)
|
||||
{
|
||||
std::shared_ptr<TSource> source = std::make_shared<TSource>(interface, args...);
|
||||
add_source_impl(source, activation_args);
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a new telemetry source. This version assumes no activation args are required.
|
||||
*
|
||||
* @tparam TSource The type of the telemetry source. Must be a type deriving from WifiTelemetrySource.
|
||||
* @tparam TSourceArgs The parameter pack type for T's constructor arguments.
|
||||
* @param interface The interface configuration of the source (if any).
|
||||
* @param args The arguments to forward to the constructor of type TSource.
|
||||
* @return std::shared_ptr<TSource>
|
||||
*/
|
||||
template <
|
||||
typename TSource,
|
||||
typename ...TSourceArgs,
|
||||
typename std::enable_if<std::is_base_of<WifiTelemetrySource, TSource>::value>* = nullptr
|
||||
>
|
||||
std::shared_ptr<TSource>
|
||||
add_source(const std::optional<WifiInterfaceConfiguration>& interface, TSourceArgs&&... args)
|
||||
{
|
||||
std::shared_ptr<TSource> source = std::make_shared<TSource>(interface, args...);
|
||||
add_source_impl(source);
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes a telemetry source from the monitor.
|
||||
*
|
||||
* @param source A previously added telemetry source.
|
||||
*/
|
||||
void
|
||||
remove_source(const std::shared_ptr<WifiTelemetrySource> source);
|
||||
|
||||
/**
|
||||
* @brief Starts monitoring the configured interface.
|
||||
*/
|
||||
void
|
||||
start(void);
|
||||
|
||||
/**
|
||||
* @brief Stops monitoring the configured interface.
|
||||
*/
|
||||
void
|
||||
stop(void);
|
||||
|
||||
private:
|
||||
void
|
||||
add_source_impl(const std::shared_ptr<WifiTelemetrySource> source, const std::shared_ptr<WifiTelemetrySourceActivationArgs> activation_args = nullptr);
|
||||
|
||||
std::size_t
|
||||
activate_sources(void);
|
||||
|
||||
void
|
||||
deactivate_sources(void);
|
||||
|
||||
protected:
|
||||
bool m_activated = false;
|
||||
std::vector<std::unique_ptr<WifiTelemetrySourceInstance>> m_sources;
|
||||
};
|
||||
|
||||
#endif //__WIFI_TELEMETRY_MONITOR_HPP__
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
#ifndef __WIFI_TELEMETRY_SOURCE_HPP__
|
||||
#define __WIFI_TELEMETRY_SOURCE_HPP__
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_common.hpp"
|
||||
#include "wifi-telemetry/wifi_interface_configuration.hpp"
|
||||
|
||||
struct WifiTelemetrySourceActivationArgs
|
||||
{
|
||||
~WifiTelemetrySourceActivationArgs(void) = default;
|
||||
};
|
||||
|
||||
class WifiTelemetrySource
|
||||
{
|
||||
protected:
|
||||
WifiTelemetrySource(const std::optional<WifiInterfaceConfiguration>& interface);
|
||||
WifiTelemetrySource(const std::optional<WifiInterfaceConfiguration>& interface, const std::string& name);
|
||||
|
||||
public:
|
||||
virtual ~WifiTelemetrySource(void);
|
||||
|
||||
virtual int
|
||||
activate(const std::shared_ptr<WifiTelemetrySourceActivationArgs> args);
|
||||
|
||||
virtual void
|
||||
deactivate(void);
|
||||
|
||||
virtual const std::string_view
|
||||
name() const;
|
||||
|
||||
const std::optional<WifiInterfaceConfiguration>&
|
||||
interface(void) const;
|
||||
|
||||
protected:
|
||||
std::string m_name = "unnamed";
|
||||
const std::optional<WifiInterfaceConfiguration> m_interface;
|
||||
};
|
||||
|
||||
#endif //__WIFI_TELEMETRY_SOURCE_HPP__
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
#ifndef __WIFI_TELEMETRY_SOURCE_INSTANCE_HPP__
|
||||
#define __WIFI_TELEMETRY_SOURCE_INSTANCE_HPP__
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "wifi-telemetry/wifi_telemetry_source.hpp"
|
||||
|
||||
struct WifiTelemetrySourceInstance
|
||||
{
|
||||
public:
|
||||
WifiTelemetrySourceInstance(std::shared_ptr<WifiTelemetrySource> source_, const std::shared_ptr<WifiTelemetrySourceActivationArgs> args_) :
|
||||
source(std::move(source_)),
|
||||
args(args_)
|
||||
{}
|
||||
|
||||
virtual ~WifiTelemetrySourceInstance(void) = default;
|
||||
|
||||
std::shared_ptr<WifiTelemetrySource> source;
|
||||
std::shared_ptr<WifiTelemetrySourceActivationArgs> args;
|
||||
};
|
||||
|
||||
#endif // __WIFI_TELEMETRY_SOURCE_INSTANCE_HPP__
|
|
@ -0,0 +1,110 @@
|
|||
|
||||
#ifndef __WIFI_TELEMETRY_SOURCE_WPA_HPP__
|
||||
#define __WIFI_TELEMETRY_SOURCE_WPA_HPP__
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_common.hpp"
|
||||
#include "wifi-telemetry/wifi/wifi_dpp_exchange.hpp"
|
||||
#include "wifi-telemetry/wifi_telemetry_source.hpp"
|
||||
#include "wifi-telemetry/wpa/wifi_telemetry_input_station_connection_attempt.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_controller.hpp"
|
||||
|
||||
class __attribute__((visibility("default"))) WifiTelemetrySourceWpa :
|
||||
public WifiTelemetrySource,
|
||||
public std::enable_shared_from_this<WifiTelemetrySourceWpa>,
|
||||
public WpaEventHandler
|
||||
{
|
||||
public:
|
||||
WifiTelemetrySourceWpa(const std::optional<WifiInterfaceConfiguration>& interface);
|
||||
~WifiTelemetrySourceWpa(void);
|
||||
|
||||
int
|
||||
activate(const std::shared_ptr<WifiTelemetrySourceActivationArgs> args) override;
|
||||
|
||||
void
|
||||
deactivate(void) override;
|
||||
|
||||
private:
|
||||
bool
|
||||
trace_station(void) const;
|
||||
|
||||
bool
|
||||
trace_ap(void) const;
|
||||
|
||||
bool
|
||||
trace_dpp(void) const;
|
||||
|
||||
bool
|
||||
trace_dpp_enrollee(void) const;
|
||||
|
||||
bool
|
||||
trace_dpp_configurator(void) const;
|
||||
|
||||
// WpaEventHandler
|
||||
void
|
||||
on_connected(const WpaEventArgs<WpaEventConnected>& args) override;
|
||||
|
||||
void
|
||||
on_disconnected(const WpaEventArgs<WpaEventDisconnected>& args) override;
|
||||
|
||||
void
|
||||
on_association_rejected(const WpaEventArgs<WpaEventAssociationRejected>& args) override;
|
||||
|
||||
void
|
||||
on_authentication_rejected(const WpaEventArgs<WpaEventAuthenticationRejected>& args) override;
|
||||
|
||||
void
|
||||
on_network_not_found(const WpaEventArgs<WpaEventNetworkNotFound>& args) override;
|
||||
|
||||
void
|
||||
on_dpp_chirp_received(const WpaEventArgs<WpaEventDppChirpReceived>& args) override;
|
||||
|
||||
void
|
||||
on_dpp_frame_transmit_status(const WpaEventArgs<WpaEventDppFrameTransmitStatus>& args) override;
|
||||
|
||||
void
|
||||
on_dpp_authentication_init_failure(const WpaEventArgs<WpaEventDppAuthenticationInitFailure>& args) override;
|
||||
|
||||
void
|
||||
on_dpp_authentication_succeeded(const WpaEventArgs<WpaEventDppAuthenticationSucceeded>& args) override;
|
||||
|
||||
void
|
||||
on_dpp_configuration_received(const WpaEventArgs<WpaEventDppConfigurationReceived>& args) override;
|
||||
|
||||
void
|
||||
on_dpp_configuration_sent(const WpaEventArgs<WpaEventDppConfigurationSent>& args) override;
|
||||
|
||||
void
|
||||
on_dpp_failure(const WpaEventArgs<WpaEventDppFailure>& args) override;
|
||||
|
||||
private:
|
||||
template<
|
||||
typename T,
|
||||
typename std::enable_if<std::is_base_of<WifiDppExchange, T>::value>* = nullptr>
|
||||
std::shared_ptr<T>
|
||||
resolve_dpp_exchange(void)
|
||||
{
|
||||
return std::dynamic_pointer_cast<T>(m_dpp_exchange);
|
||||
}
|
||||
|
||||
bool
|
||||
is_dpp_exchange_in_progress(void) const;
|
||||
|
||||
void
|
||||
complete_connection_attempt(const WifiTelemetryInputStationConnectionAttempt& input);
|
||||
|
||||
void
|
||||
complete_dpp_exchange_enrollee(std::shared_ptr<WifiDppExchangeEnrollee>& enrollee);
|
||||
|
||||
void
|
||||
complete_dpp_exchange_configurator(std::shared_ptr<WifiDppExchangeConfigurator>& configurator);
|
||||
|
||||
std::shared_ptr<WifiDppExchange> m_dpp_exchange = nullptr;
|
||||
std::shared_ptr<WpaController> m_controller;
|
||||
WpaEventToken m_event_token;
|
||||
};
|
||||
|
||||
#endif //__WIFI_TELEMETRY_SOURCE_WPA_HPP__
|
|
@ -0,0 +1,34 @@
|
|||
|
||||
#ifndef __WIFI_TELEMETRY_SOURCE_ZTPD_HPP__
|
||||
#define __WIFI_TELEMETRY_SOURCE_ZTPD_HPP__
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include <sdbus-c++/sdbus-c++.h>
|
||||
|
||||
#include "wifi-telemetry/wifi_telemetry_source.hpp"
|
||||
|
||||
class __attribute__((visibility("default"))) WifiTelemetrySourceZtpd :
|
||||
public WifiTelemetrySource,
|
||||
public sdbus::ProxyInterfaces<sdbus::Properties_proxy>
|
||||
{
|
||||
public:
|
||||
WifiTelemetrySourceZtpd(const std::optional<WifiInterfaceConfiguration>& interface_config);
|
||||
~WifiTelemetrySourceZtpd(void);
|
||||
|
||||
int
|
||||
activate(const std::shared_ptr<WifiTelemetrySourceActivationArgs> args) override;
|
||||
|
||||
void
|
||||
deactivate(void) override;
|
||||
|
||||
private:
|
||||
// sdbus::Properties_proxy
|
||||
void
|
||||
onPropertiesChanged(const std::string& interfaceName,
|
||||
const std::map<std::string, sdbus::Variant>& changedProperties,
|
||||
const std::vector<std::string>& invalidatedProperties) override;
|
||||
};
|
||||
|
||||
#endif //__WIFI_TELEMETRY_SOURCE_ZTPD_HPP__
|
|
@ -0,0 +1,106 @@
|
|||
|
||||
#ifndef __WIFI_TELEMETRY_INPUT_STATION_CONNECTION_ATTEMPT_HPP__
|
||||
#define __WIFI_TELEMETRY_INPUT_STATION_CONNECTION_ATTEMPT_HPP__
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211.hpp"
|
||||
#include "wifi-telemetry/wifi/wifi_telemetry_80211.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command_signal_poll.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command_status.hpp"
|
||||
|
||||
/**
|
||||
* @brief Helper class that sanitizes the connection_attempt telemetry event
|
||||
* inputs.
|
||||
*
|
||||
* Some of the input data is optional; this class checks such inputs for their
|
||||
* existence/validity, and if missing/invalid, assigns defaults or appropriate
|
||||
* values that the telemetry system understands as being invalid.
|
||||
*/
|
||||
class WifiTelemetryInputStationConnectionAttempt
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* @brief Factory methods for creating instances of the correspoding
|
||||
* result-type.
|
||||
*
|
||||
* These ensure that invalid objects are impossible to create. For example,
|
||||
* if the connection attempt result was 'AssociationRejected' ALL required
|
||||
* parameters must be specified for the instance to be created since no
|
||||
* public constructor exists that allows construction without the required
|
||||
* arguments.
|
||||
*/
|
||||
|
||||
static WifiTelemetryInputStationConnectionAttempt
|
||||
unspecified(void);
|
||||
|
||||
static WifiTelemetryInputStationConnectionAttempt
|
||||
succeeded(const wifi_80211_mac& bssid, const std::shared_ptr<WpaCommandSignalPollResponse> signal_poll, const std::shared_ptr<WpaCommandStatusResponse> status);
|
||||
|
||||
static WifiTelemetryInputStationConnectionAttempt
|
||||
association_rejected(const std::optional<wifi_80211_mac>& bssid, const WifiStatusCode status_code);
|
||||
|
||||
static WifiTelemetryInputStationConnectionAttempt
|
||||
authentication_rejected(const wifi_80211_mac& bssid, const WifiStatusCode status_code, const WifiAuthenticationType authentication_type);
|
||||
|
||||
static WifiTelemetryInputStationConnectionAttempt
|
||||
network_not_found(void);
|
||||
|
||||
uint32_t
|
||||
result(void) const;
|
||||
|
||||
const char*
|
||||
bssid(void) const;
|
||||
|
||||
const char*
|
||||
ssid(void) const;
|
||||
|
||||
int32_t
|
||||
noise(void) const;
|
||||
|
||||
int32_t
|
||||
rssi(void) const;
|
||||
|
||||
int32_t
|
||||
link_speed(void) const;
|
||||
|
||||
uint32_t
|
||||
frequency(void) const;
|
||||
|
||||
uint32_t
|
||||
wifi_generation(void) const;
|
||||
|
||||
const char*
|
||||
key_mgmt(void) const;
|
||||
|
||||
const char*
|
||||
pairwise_cipher(void) const;
|
||||
|
||||
const char*
|
||||
group_cipher(void) const;
|
||||
|
||||
uint16_t
|
||||
status_code(void) const;
|
||||
|
||||
const char*
|
||||
authentication_type(void) const;
|
||||
|
||||
private:
|
||||
WifiTelemetryInputStationConnectionAttempt(
|
||||
const WifiConnectionAttemptResult result,
|
||||
const std::optional<wifi_80211_mac> bssid,
|
||||
const std::shared_ptr<WpaCommandSignalPollResponse> signal_poll,
|
||||
const std::shared_ptr<WpaCommandStatusResponse> status,
|
||||
const WifiStatusCode status_code,
|
||||
const WifiAuthenticationType authentication_type);
|
||||
|
||||
const WifiConnectionAttemptResult m_result;
|
||||
const std::string m_bssid;
|
||||
const std::shared_ptr<WpaCommandSignalPollResponse> m_signal_poll;
|
||||
const std::shared_ptr<WpaCommandStatusResponse> m_status;
|
||||
const WifiStatusCode m_status_code;
|
||||
const std::string m_authentication_type;
|
||||
};
|
||||
|
||||
#endif //__WIFI_TELEMETRY_INPUT_STATION_CONNECTION_ATTEMPT_HPP__
|
|
@ -0,0 +1,26 @@
|
|||
|
||||
#ifndef __WPA_COMMAND_HPP__
|
||||
#define __WPA_COMMAND_HPP__
|
||||
|
||||
#include <cinttypes>
|
||||
#include <memory>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_command_response.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command_response_parser.hpp"
|
||||
|
||||
struct WpaCommand : private WpaCommandResponseParserFactory
|
||||
{
|
||||
WpaCommand(const std::string& name);
|
||||
virtual ~WpaCommand() = default;
|
||||
|
||||
std::shared_ptr<WpaCommandResponse>
|
||||
parse_response(const std::string_view payload) const;
|
||||
|
||||
const std::string name;
|
||||
std::string data;
|
||||
};
|
||||
|
||||
#endif //__WPA_COMMAND_HPP__
|
|
@ -0,0 +1,54 @@
|
|||
|
||||
#ifndef __WPA_COMMAND_BSS_HPP__
|
||||
#define __WPA_COMMAND_BSS_HPP__
|
||||
|
||||
#include <cinttypes>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command_response_parser.hpp"
|
||||
|
||||
struct WpaCommandBssResponseParser : public WpaCommandResponseParser
|
||||
{
|
||||
WpaCommandBssResponseParser(const std::string_view payload);
|
||||
|
||||
std::shared_ptr<WpaCommandResponse>
|
||||
parse_payload(void) const override;
|
||||
};
|
||||
|
||||
struct WpaCommandBssResponse : public WpaCommandResponse
|
||||
{
|
||||
WpaCommandBssResponse();
|
||||
|
||||
wifi_80211_mac bssid;
|
||||
uint32_t id;
|
||||
uint32_t capabilities;
|
||||
uint32_t update_index;
|
||||
uint64_t tsf;
|
||||
int32_t frequency;
|
||||
int32_t beacon_int;
|
||||
int32_t quality;
|
||||
int32_t snr;
|
||||
int32_t estimated_throughput;
|
||||
int32_t age;
|
||||
std::string flags;
|
||||
std::string ssid;
|
||||
std::vector<uint8_t> ie;
|
||||
std::vector<uint8_t> beacon_ie;
|
||||
};
|
||||
|
||||
struct WpaCommandBss : public WpaCommand
|
||||
{
|
||||
WpaCommandBss(std::string bssid_);
|
||||
WpaCommandBss(const wifi_80211_mac& bssid_);
|
||||
|
||||
std::string bssid;
|
||||
|
||||
private:
|
||||
std::unique_ptr<WpaCommandResponseParser>
|
||||
create_response_parser(const std::string_view payload) const override;
|
||||
};
|
||||
|
||||
#endif // __WPA_COMMAND_BSS_HPP__
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
#ifndef __WPA_COMMAND_KEY_VALUE_PAIR_HPP__
|
||||
#define __WPA_COMMAND_KEY_VALUE_PAIR_HPP__
|
||||
|
||||
#include <cstddef>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
|
||||
struct WpaCommandKeyValuePair
|
||||
{
|
||||
WpaCommandKeyValuePair(const char* key_, bool is_required);
|
||||
|
||||
const char*
|
||||
operator()(void) const;
|
||||
|
||||
bool
|
||||
resolve(const std::string_view input);
|
||||
|
||||
const char* key;
|
||||
const std::size_t key_length;
|
||||
std::optional<const char*> value;
|
||||
std::size_t value_pos;
|
||||
bool is_required;
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
WpaValueRequired = true,
|
||||
WpaValueOptional = false
|
||||
};
|
||||
|
||||
#endif //__WPA_COMMAND_KEY_VALUE_PAIR_HPP__
|
|
@ -0,0 +1,24 @@
|
|||
|
||||
#ifndef __WPA_COMMAND_RESPONSE_HPP__
|
||||
#define __WPA_COMMAND_RESPONSE_HPP__
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
struct WpaCommandResponse
|
||||
{
|
||||
virtual ~WpaCommandResponse() = default;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Used to send+receive unstructured commands+responses.
|
||||
*/
|
||||
struct WpaCommandResponseGeneric : public WpaCommandResponse
|
||||
{
|
||||
WpaCommandResponseGeneric(const std::string payload);
|
||||
|
||||
std::string payload;
|
||||
};
|
||||
|
||||
#endif //__WPA_COMMAND_RESPONSE_HPP__
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
#ifndef __WPA_COMMAND_RESPONSE_PARSER_HPP__
|
||||
#define __WPA_COMMAND_RESPONSE_PARSER_HPP__
|
||||
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_command_key_value_pair.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command_response.hpp"
|
||||
|
||||
struct WpaCommandResponseParser
|
||||
{
|
||||
WpaCommandResponseParser(const std::string& command_name, const std::string_view payload, const std::initializer_list<WpaCommandKeyValuePair> properties);
|
||||
virtual ~WpaCommandResponseParser() = default;
|
||||
|
||||
virtual std::shared_ptr<WpaCommandResponse>
|
||||
parse(void);
|
||||
|
||||
const std::string command_name;
|
||||
const std::string_view payload;
|
||||
|
||||
protected:
|
||||
virtual std::shared_ptr<WpaCommandResponse>
|
||||
parse_payload(void) const = 0;
|
||||
|
||||
bool
|
||||
resolve_properties(void);
|
||||
|
||||
protected:
|
||||
std::vector<WpaCommandKeyValuePair> properties;
|
||||
std::optional<bool> properties_resolved_result = std::nullopt;
|
||||
};
|
||||
|
||||
struct WpaCommandResponseParserFactory
|
||||
{
|
||||
virtual std::unique_ptr<WpaCommandResponseParser>
|
||||
create_response_parser(const std::string_view payload) const = 0;
|
||||
};
|
||||
|
||||
#endif //__WPA_COMMAND_RESPONSE_PARSER_HPP__
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
#ifndef __WPA_COMMAND_SIGNAL_POLL_HPP__
|
||||
#define __WPA_COMMAND_SIGNAL_POLL_HPP__
|
||||
|
||||
#include <cinttypes>
|
||||
#include <initializer_list>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_command.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command_response.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command_response_parser.hpp"
|
||||
|
||||
struct WpaCommandSignalPollResponseParser : public WpaCommandResponseParser
|
||||
{
|
||||
WpaCommandSignalPollResponseParser(const std::string_view payload);
|
||||
|
||||
std::shared_ptr<WpaCommandResponse>
|
||||
parse_payload(void) const override;
|
||||
};
|
||||
|
||||
struct WpaCommandSignalPollResponse : public WpaCommandResponse
|
||||
{
|
||||
WpaCommandSignalPollResponse(int32_t noise, int32_t rssi, int32_t link_speed, uint32_t frequency);
|
||||
|
||||
int32_t noise;
|
||||
int32_t rssi;
|
||||
int32_t link_speed;
|
||||
uint32_t frequency;
|
||||
std::optional<std::string> channel_width;
|
||||
std::optional<int32_t> center_frequency_1 = std::nullopt;
|
||||
std::optional<int32_t> center_frequency_2 = std::nullopt;
|
||||
std::optional<int32_t> rssi_average = std::nullopt;
|
||||
std::optional<int32_t> rssi_average_beacon = std::nullopt;
|
||||
};
|
||||
|
||||
struct WpaCommandSignalPoll : public WpaCommand
|
||||
{
|
||||
WpaCommandSignalPoll(void);
|
||||
|
||||
private:
|
||||
std::unique_ptr<WpaCommandResponseParser>
|
||||
create_response_parser(const std::string_view payload) const override;
|
||||
};
|
||||
|
||||
#endif // __WPA_COMMAND_SIGNAL_POLL_HPP__
|
|
@ -0,0 +1,60 @@
|
|||
|
||||
#ifndef __WPA_COMMAND_STATUS_HPP__
|
||||
#define __WPA_COMMAND_STATUS_HPP__
|
||||
|
||||
#include <cinttypes>
|
||||
#include <string>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_state.hpp"
|
||||
|
||||
struct WpaCommandStatusResponseParser : public WpaCommandResponseParser
|
||||
{
|
||||
WpaCommandStatusResponseParser(const std::string_view payload);
|
||||
|
||||
std::shared_ptr<WpaCommandResponse>
|
||||
parse_payload(void) const override;
|
||||
};
|
||||
|
||||
struct WpaCommandStatusResponse : public WpaCommandResponse
|
||||
{
|
||||
WpaCommandStatusResponse(void) = default;
|
||||
WpaCommandStatusResponse(WpaState state_);
|
||||
|
||||
WpaState state = WpaState::Unknown;
|
||||
std::optional<wifi_80211_mac> bssid;
|
||||
std::optional<uint32_t> frequency;
|
||||
std::optional<std::string> ssid;
|
||||
std::optional<std::string> passphrase;
|
||||
std::optional<std::string> id_string;
|
||||
std::optional<std::string> mode;
|
||||
std::optional<uint32_t> wifi_generation;
|
||||
std::optional<int32_t> sae_group;
|
||||
std::optional<std::string> ip_address;
|
||||
std::optional<std::string> p2p_address;
|
||||
std::optional<std::string> address;
|
||||
std::optional<int32_t> hs20;
|
||||
std::optional<std::string> provisioning_sp;
|
||||
std::optional<std::string> home_sp;
|
||||
std::optional<std::string> sp_type;
|
||||
std::optional<std::string> eap_session_id;
|
||||
std::optional<std::string> uuid;
|
||||
std::optional<bool> ieee80211ac;
|
||||
std::optional<std::string> pairwise_cipher;
|
||||
std::optional<std::string> group_cipher;
|
||||
std::optional<std::string> key_mgmt;
|
||||
std::optional<int32_t> pmf;
|
||||
std::optional<std::string> mgmt_group_cipher;
|
||||
};
|
||||
|
||||
struct WpaCommandStatus : public WpaCommand
|
||||
{
|
||||
WpaCommandStatus(void);
|
||||
|
||||
private:
|
||||
std::unique_ptr<WpaCommandResponseParser>
|
||||
create_response_parser(const std::string_view payload) const override;
|
||||
};
|
||||
|
||||
#endif // __WPA_COMMAND_STATUS_HPP__
|
|
@ -0,0 +1,4 @@
|
|||
|
||||
#include "wifi-telemetry/wpa/wpa_command_bss.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command_signal_poll.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command_status.hpp"
|
|
@ -0,0 +1,160 @@
|
|||
|
||||
#ifndef __WPA_CONTROLLER_HPP__
|
||||
#define __WPA_CONTROLLER_HPP__
|
||||
|
||||
#include <chrono>
|
||||
#include <filesystem>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <shared_mutex>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
#include <wpa_ctrl.h>
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_command.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command_response.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event_handler.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_interface_info.hpp"
|
||||
|
||||
typedef uint32_t WpaEventToken;
|
||||
|
||||
class WpaController
|
||||
{
|
||||
public:
|
||||
WpaController(const std::string_view interface, WpaType type);
|
||||
WpaController(const std::string_view interface, WpaType type, const std::string_view control_socket_path);
|
||||
~WpaController(void);
|
||||
|
||||
/**
|
||||
* @brief Registers a handler for wpa events.
|
||||
*
|
||||
* @param handler The handler to invoke in response to events.
|
||||
* @return WpaEventToken A registration token to be used to unregister the handler.
|
||||
*/
|
||||
WpaEventToken
|
||||
register_for_events(std::weak_ptr<WpaEventHandler> handler);
|
||||
|
||||
/**
|
||||
* @brief Unregisters an event handler for wpa events.
|
||||
*
|
||||
* @param token The registration token previously obtains from register_for_events.
|
||||
*/
|
||||
void
|
||||
unregister_for_events(WpaEventToken token);
|
||||
|
||||
/**
|
||||
* @brief
|
||||
*
|
||||
* @param command
|
||||
* @return std::shared_ptr<WpaControllerResponse>
|
||||
*/
|
||||
std::shared_ptr<WpaCommandResponse>
|
||||
send_command(const WpaCommand& command);
|
||||
|
||||
/**
|
||||
* @brief Syntactic sugar for returning a specific derived type for the response.
|
||||
*
|
||||
* @tparam TResponse
|
||||
* @param command
|
||||
* @return std::shared_ptr<TResponse>
|
||||
*/
|
||||
template <
|
||||
typename TResponse,
|
||||
typename std::enable_if<std::is_base_of<WpaCommandResponse, TResponse>::value>* = nullptr>
|
||||
std::shared_ptr<TResponse>
|
||||
send_command(const WpaCommand& command)
|
||||
{
|
||||
return std::dynamic_pointer_cast<TResponse>(send_command(command));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Returns the type of controller
|
||||
*
|
||||
* @return const WpaType The type of controller.
|
||||
*/
|
||||
WpaType
|
||||
type(void) const
|
||||
{
|
||||
return m_type;
|
||||
}
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Retrieves the next available message from the control socket and
|
||||
* processes it.
|
||||
*/
|
||||
void
|
||||
process_wpa_event_next(void);
|
||||
|
||||
/**
|
||||
* @brief Waits for and processes all wpa control events.
|
||||
*/
|
||||
void
|
||||
process_wpa_events(void);
|
||||
|
||||
/**
|
||||
* @brief Get the command control socket object.
|
||||
*
|
||||
* @return struct wpa_ctrl*
|
||||
*/
|
||||
struct wpa_ctrl*
|
||||
get_command_control_socket(void);
|
||||
|
||||
private:
|
||||
const WpaType m_type;
|
||||
std::string m_interface;
|
||||
std::filesystem::path m_ctrl_socket_path;
|
||||
std::thread m_ctrl_event_thread;
|
||||
bool m_terminate_pending = false;
|
||||
int m_ctrl_event_fd_stop = -1;
|
||||
struct wpa_ctrl* m_ctrl_event = nullptr;
|
||||
struct wpa_ctrl* m_ctrl_command = nullptr;
|
||||
std::shared_mutex m_ctrl_command_gate;
|
||||
|
||||
uint32_t m_event_token_next = 0;
|
||||
std::mutex m_event_subscribers_gate;
|
||||
std::unordered_map<WpaEventToken, std::weak_ptr<WpaEventHandler>> m_event_subscribers;
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Maximum wpas message size, in bytes. The wpa_cli tool uses this
|
||||
* as an upper bound so is used similarly here.
|
||||
*/
|
||||
static constexpr std::size_t c_wpa_event_size_max = 4096;
|
||||
|
||||
/**
|
||||
* @brief Default control socket pasth for wpa_supplicant.
|
||||
*/
|
||||
static constexpr std::string_view m_ctrl_socket_path_default_wpas = std::string_view("/var/run/wpa_supplicant");
|
||||
|
||||
/**
|
||||
* @brief Default control socket pasth for hostapd.
|
||||
*/
|
||||
static constexpr std::string_view m_ctrl_socket_path_default_hostapd = std::string_view("/var/run/hostapd");
|
||||
|
||||
/**
|
||||
* @brief Determines default control socket path for each wpa service type.
|
||||
*
|
||||
* @param type The type of wpa service to determine the default control socket for.
|
||||
* @return constexpr std::string_view A string describing the default control sock path.
|
||||
*/
|
||||
static constexpr std::string_view
|
||||
default_control_socket_path(WpaType type)
|
||||
{
|
||||
switch (type) {
|
||||
case WpaType::Hostapd:
|
||||
return m_ctrl_socket_path_default_hostapd;
|
||||
case WpaType::WpaSupplicant:
|
||||
return m_ctrl_socket_path_default_wpas;
|
||||
default:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif //__WPA_CONTROLLER_HPP__
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
#ifndef __WPA_EVENT_HPP__
|
||||
#define __WPA_EVENT_HPP__
|
||||
|
||||
enum WpaEventType
|
||||
{
|
||||
Connected,
|
||||
Disconnected,
|
||||
NetworkNotFound,
|
||||
AssociationRejected,
|
||||
AuthenticationRejected,
|
||||
DppAuthenticationInitFailure,
|
||||
DppAuthenticationSucceeded,
|
||||
DppConfigurationReceived,
|
||||
DppConfigurationSent,
|
||||
DppFailure,
|
||||
DppFrameTransmitStatus,
|
||||
DppChirpReceived
|
||||
};
|
||||
|
||||
struct WpaEvent
|
||||
{
|
||||
WpaEvent(WpaEventType type);
|
||||
|
||||
WpaEventType type;
|
||||
virtual ~WpaEvent() = default;
|
||||
};
|
||||
|
||||
#endif //__WPA_EVENT_HPP__
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
#ifndef __WPA_EVENT_ASSOCIATION_REJECTED_HPP__
|
||||
#define __WPA_EVENT_ASSOCIATION_REJECTED_HPP__
|
||||
|
||||
#include <optional>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
|
||||
struct WpaEventAssociationRejected : public WpaEvent
|
||||
{
|
||||
WpaEventAssociationRejected(WifiStatusCode status_code);
|
||||
WpaEventAssociationRejected(WifiStatusCode status_code, const wifi_80211_mac& bssid);
|
||||
|
||||
const WifiStatusCode status_code;
|
||||
const std::optional<wifi_80211_mac> bssid = std::nullopt;
|
||||
};
|
||||
|
||||
#endif // __WPA_EVENT_ASSOCIATION_REJECTED_HPP__
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
#ifndef __WPA_EVENT_AUTHENTICATION_REJECTED_HPP__
|
||||
#define __WPA_EVENT_AUTHENTICATION_REJECTED_HPP__
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
|
||||
struct WpaEventAuthenticationRejected : public WpaEvent
|
||||
{
|
||||
WpaEventAuthenticationRejected(const wifi_80211_mac& bssid, WifiStatusCode status_code, WifiAuthenticationType authentication_type);
|
||||
|
||||
const wifi_80211_mac bssid;
|
||||
const WifiStatusCode status_code;
|
||||
const WifiAuthenticationType authentication_type;
|
||||
};
|
||||
|
||||
#endif // __WPA_EVENT_AUTHENTICATION_REJECTED_HPP__
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
#ifndef __WPA_EVENT_CONNECTED_HPP__
|
||||
#define __WPA_EVENT_CONNECTED_HPP__
|
||||
|
||||
#include <array>
|
||||
#include <cinttypes>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
|
||||
struct WpaEventConnected : public WpaEvent
|
||||
{
|
||||
WpaEventConnected(const wifi_80211_mac& bssid);
|
||||
const wifi_80211_mac bssid;
|
||||
};
|
||||
|
||||
#endif // __WPA_EVENT_CONNECTED_HPP__
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
#ifndef __WPA_EVENT_DISCONNECTED_HPP__
|
||||
#define __WPA_EVENT_DISCONNECTED_HPP__
|
||||
|
||||
#include <array>
|
||||
#include <cinttypes>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
|
||||
struct WpaEventDisconnected : public WpaEvent
|
||||
{
|
||||
WpaEventDisconnected(const wifi_80211_mac& bssid_, WifiDeauthenticationReasonCode reason_code_, bool locally_generated);
|
||||
|
||||
const wifi_80211_mac bssid;
|
||||
const WifiDeauthenticationReasonCode reason_code;
|
||||
bool locally_generated = false;
|
||||
};
|
||||
|
||||
#endif // __WPA_EVENT_DISCONNECTED_HPP__
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#ifndef __WPA_EVENT_DPP_AUTH_INIT_FAILURE_HPP__
|
||||
#define __WPA_EVENT_DPP_AUTH_INIT_FAILURE_HPP__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_event_dpp_failure.hpp"
|
||||
|
||||
struct WpaEventDppAuthenticationInitFailure : public WpaEventDppFailure
|
||||
{
|
||||
WpaEventDppAuthenticationInitFailure(void);
|
||||
};
|
||||
|
||||
#endif // __WPA_EVENT_DPP_AUTH_INIT_FAILURE_HPP__
|
|
@ -0,0 +1,13 @@
|
|||
|
||||
#ifndef __WPA_EVENT_DPP_AUTH_SUCCESS_HPP__
|
||||
#define __WPA_EVENT_DPP_AUTH_SUCCESS_HPP__
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
|
||||
struct WpaEventDppAuthenticationSucceeded : public WpaEvent
|
||||
{
|
||||
WpaEventDppAuthenticationSucceeded(int initiator);
|
||||
int initiator;
|
||||
};
|
||||
|
||||
#endif // __WPA_EVENT_DPP_AUTH_SUCCESS_HPP__
|
|
@ -0,0 +1,19 @@
|
|||
|
||||
#ifndef __WPA_EVENT_DPP_CHIRP_RECEIVED_HPP__
|
||||
#define __WPA_EVENT_DPP_CHIRP_RECEIVED_HPP__
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
|
||||
struct WpaEventDppChirpReceived : public WpaEvent
|
||||
{
|
||||
WpaEventDppChirpReceived(int32_t id, const wifi_80211_mac& bssid, unsigned int frequency);
|
||||
|
||||
int32_t id;
|
||||
wifi_80211_mac bssid;
|
||||
uint32_t frequency;
|
||||
};
|
||||
|
||||
#endif // __WPA_EVENT_DPP_CHIRP_RECEIVED_HPP__
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
#ifndef __WPA_EVENT_DPP_CONF_RECEIVED_HPP__
|
||||
#define __WPA_EVENT_DPP_CONF_RECEIVED_HPP__
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
|
||||
struct WpaEventDppConfigurationReceived : public WpaEvent
|
||||
{
|
||||
WpaEventDppConfigurationReceived(void);
|
||||
};
|
||||
|
||||
#endif // __WPA_EVENT_DPP_CONF_RECEIVED_HPP__
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
#ifndef __WPA_EVENT_DPP_CONF_SENT_HPP__
|
||||
#define __WPA_EVENT_DPP_CONF_SENT_HPP__
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
|
||||
struct WpaEventDppConfigurationSent : public WpaEvent
|
||||
{
|
||||
WpaEventDppConfigurationSent(void);
|
||||
};
|
||||
|
||||
#endif // __WPA_EVENT_DPP_CONF_SENT_HPP__
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
#ifndef __WPA_EVENT_DPP_FAILURE_HPP__
|
||||
#define __WPA_EVENT_DPP_FAILURE_HPP__
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_dpp.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
|
||||
struct WpaEventDppFailure : public WpaEvent
|
||||
{
|
||||
WpaEventDppFailure(const std::string& failure_details = "");
|
||||
WpaEventDppFailure(WifiDppFailureType failure_type, const std::string& failure_details = "");
|
||||
|
||||
WifiDppFailureType failure_type;
|
||||
const std::string failure_details;
|
||||
|
||||
protected:
|
||||
WpaEventDppFailure(WpaEventType type, WifiDppFailureType failure_type, const std::string& failure_details = "");
|
||||
};
|
||||
|
||||
#endif // __WPA_EVENT_DPP_FAILURE_HPP__
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
#ifndef __WPA_EVENT_DPP_FRAME_TRANSMIT_STATUS_HPP__
|
||||
#define __WPA_EVENT_DPP_FRAME_TRANSMIT_STATUS_HPP__
|
||||
|
||||
#include <cinttypes>
|
||||
#include <string>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
|
||||
struct WpaEventDppFrameTransmitStatus : public WpaEvent
|
||||
{
|
||||
WpaEventDppFrameTransmitStatus(const wifi_80211_mac& destination_bssid, unsigned int frequency, const std::string& status);
|
||||
|
||||
wifi_80211_mac destination_bssid;
|
||||
uint32_t frequency;
|
||||
std::string status;
|
||||
};
|
||||
|
||||
#endif // __WPA_EVENT_DPP_FRAME_TRANSMIT_STATUS_HPP__
|
|
@ -0,0 +1,68 @@
|
|||
|
||||
#ifndef __WPA_EVENT_HANDLER_HPP__
|
||||
#define __WPA_EVENT_HANDLER_HPP__
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_events.hpp"
|
||||
|
||||
template <typename T>
|
||||
struct WpaEventArgs
|
||||
{
|
||||
WpaEventArgs(std::chrono::time_point<std::chrono::system_clock> timestamp_, std::shared_ptr<T> event_) :
|
||||
timestamp(timestamp_),
|
||||
event(event_)
|
||||
{}
|
||||
|
||||
std::chrono::time_point<std::chrono::system_clock> timestamp;
|
||||
std::shared_ptr<T> event;
|
||||
|
||||
const T&
|
||||
data() const
|
||||
{
|
||||
return *event;
|
||||
}
|
||||
};
|
||||
|
||||
class WpaEventHandler
|
||||
{
|
||||
public:
|
||||
virtual void
|
||||
on_connected(const WpaEventArgs<WpaEventConnected>& args);
|
||||
|
||||
virtual void
|
||||
on_disconnected(const WpaEventArgs<WpaEventDisconnected>& args);
|
||||
|
||||
virtual void
|
||||
on_association_rejected(const WpaEventArgs<WpaEventAssociationRejected>& args);
|
||||
|
||||
virtual void
|
||||
on_authentication_rejected(const WpaEventArgs<WpaEventAuthenticationRejected>& args);
|
||||
|
||||
virtual void
|
||||
on_network_not_found(const WpaEventArgs<WpaEventNetworkNotFound>& args);
|
||||
|
||||
virtual void
|
||||
on_dpp_chirp_received(const WpaEventArgs<WpaEventDppChirpReceived>& args);
|
||||
|
||||
virtual void
|
||||
on_dpp_frame_transmit_status(const WpaEventArgs<WpaEventDppFrameTransmitStatus>& args);
|
||||
|
||||
virtual void
|
||||
on_dpp_authentication_init_failure(const WpaEventArgs<WpaEventDppAuthenticationInitFailure>& args);
|
||||
|
||||
virtual void
|
||||
on_dpp_authentication_succeeded(const WpaEventArgs<WpaEventDppAuthenticationSucceeded>& args);
|
||||
|
||||
virtual void
|
||||
on_dpp_configuration_received(const WpaEventArgs<WpaEventDppConfigurationReceived>& args);
|
||||
|
||||
virtual void
|
||||
on_dpp_configuration_sent(const WpaEventArgs<WpaEventDppConfigurationSent>& args);
|
||||
|
||||
virtual void
|
||||
on_dpp_failure(const WpaEventArgs<WpaEventDppFailure>& args);
|
||||
};
|
||||
|
||||
#endif //__WPA_EVENT_HANDLER_HPP__
|
|
@ -0,0 +1,12 @@
|
|||
|
||||
#ifndef __WPA_EVENT_NETWORK_NOT_FOUND_HPP__
|
||||
#define __WPA_EVENT_NETWORK_NOT_FOUND_HPP__
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
|
||||
struct WpaEventNetworkNotFound : public WpaEvent
|
||||
{
|
||||
WpaEventNetworkNotFound(void);
|
||||
};
|
||||
|
||||
#endif // __WPA_EVENT_NETWORK_NOT_FOUND_HPP__
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event_association_rejected.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event_authentication_rejected.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event_connected.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event_disconnected.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event_dpp_auth_init_failure.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event_dpp_auth_success.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event_dpp_chirp_received.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event_dpp_conf_received.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event_dpp_conf_sent.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event_dpp_failure.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event_dpp_frame_transmit_status.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_event_network_not_found.hpp"
|
|
@ -0,0 +1,38 @@
|
|||
|
||||
#ifndef __WPA_INTERFACE_INFO_HPP__
|
||||
#define __WPA_INTERFACE_INFO_HPP__
|
||||
|
||||
#include <stdexcept>
|
||||
#include <string>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_common.hpp"
|
||||
|
||||
enum WpaType
|
||||
{
|
||||
Hostapd,
|
||||
WpaSupplicant
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Interface information common to all interfaces and modes.
|
||||
*/
|
||||
struct WpaInterfaceInfo
|
||||
{
|
||||
std::string name;
|
||||
std::string address;
|
||||
|
||||
static constexpr WpaType
|
||||
TypeFromOperationalMode(WifiOperationalMode mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case WifiOperationalMode::Station:
|
||||
return WpaType::WpaSupplicant;
|
||||
case WifiOperationalMode::AccessPoint:
|
||||
return WpaType::Hostapd;
|
||||
default:
|
||||
throw new std::invalid_argument("no WpaType for operational mode");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#endif // __WPA_INTERFACE_INFO_HPP__
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
#ifndef __WPA_STATE_HPP__
|
||||
#define __WPA_STATE_HPP__
|
||||
|
||||
#include <cinttypes>
|
||||
|
||||
enum class WpaState : uint32_t
|
||||
{
|
||||
Unknown = 0,
|
||||
Disconnected = 1,
|
||||
InterfaceDisabled = 2,
|
||||
Inactive = 3,
|
||||
Scanning = 4,
|
||||
Authenticating = 5,
|
||||
Associating = 6,
|
||||
Associated = 7,
|
||||
FourWayHandshake = 8,
|
||||
GroupHandshake = 9,
|
||||
Completed = 10
|
||||
};
|
||||
|
||||
WpaState
|
||||
wpa_state_from_string(const char* state);
|
||||
|
||||
#endif //__WPA_STATE_HPP__
|
|
@ -0,0 +1,101 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -euf -o pipefail
|
||||
|
||||
TEMPDIR=
|
||||
DEBUG=
|
||||
FEATURE=wifi-telemetry
|
||||
REDIRECT=/dev/null
|
||||
GIT_REPO_DEFAULT="git@github.com:microsoft/wifi-telemetry.git"
|
||||
RELEASE_BRANCH_SOURCE_DEFAULT="main"
|
||||
|
||||
function usage() {
|
||||
echo "$0 -v <version number> [-b <release source branch name>] [-r <git repo url>] [-f] [-d]"
|
||||
echo
|
||||
echo " -v <version number>"
|
||||
echo " The numerical version, in semver format, of the release."
|
||||
echo " Eg. 0.3.5"
|
||||
echo " -b <release source branch name>"
|
||||
echo " The name of the branch from which release source should be obtained."
|
||||
echo " (default=${RELEASE_BRANCH_SOURCE_DEFAULT})"
|
||||
echo " -r <git repo url>"
|
||||
echo " The git repo url to use."
|
||||
echo " (default=${GIT_REPO_DEFAULT}"
|
||||
echo " -f"
|
||||
echo " Determines whether or not release tags should be forcibly pushed."
|
||||
echo " Note that this will overwrite any existing tags; use with caution."
|
||||
echo " (default=disabled)"
|
||||
echo " -d"
|
||||
echo " Enable script debugging. This enables script output (stdout+stderr)."
|
||||
echo
|
||||
}
|
||||
|
||||
function finish() {
|
||||
if [ ! -z ${TEMPDIR+x} ]; then
|
||||
rm -rf ${TEMPDIR} >& ${REDIRECT}
|
||||
fi
|
||||
}
|
||||
|
||||
function main() {
|
||||
local RELEASE_VERSION=
|
||||
local RELEASE_BRANCH_SOURCE=${RELEASE_BRANCH_SOURCE_DEFAULT}
|
||||
local FORCE=
|
||||
local GIT_REPO=${GIT_REPO_DEFAULT}
|
||||
|
||||
while getopts ":v:b:r:fd" opt; do
|
||||
case ${opt} in
|
||||
v)
|
||||
RELEASE_VERSION="${OPTARG}"
|
||||
;;
|
||||
b)
|
||||
RELEASE_BRANCH_SOURCE="${OPTARG}"
|
||||
;;
|
||||
r)
|
||||
GIT_REPO="${OPTARG}"
|
||||
;;
|
||||
f)
|
||||
FORCE=" -f"
|
||||
;;
|
||||
d)
|
||||
DEBUG=1
|
||||
REDIRECT=/dev/tty
|
||||
;;
|
||||
*)
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [ -z ${RELEASE_VERSION+x} ]; then
|
||||
echo "missing release version"
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local RELEASE_VERSION_TAG=v${RELEASE_VERSION}
|
||||
local RELEASE_NAME=${FEATURE}-${RELEASE_VERSION}
|
||||
local RELEASE_DIR_SOURCE=${FEATURE}-release-${RELEASE_VERSION}
|
||||
local RELEASE_DIR=${RELEASE_NAME}
|
||||
local RELEASE_ARCHIVE=${RELEASE_NAME}
|
||||
|
||||
TEMPDIR=$(mktemp -d)
|
||||
pushd ${TEMPDIR} >& ${REDIRECT}
|
||||
echo "checking out branch '${RELEASE_BRANCH_SOURCE}' from ${GIT_REPO}"
|
||||
git clone ${GIT_REPO} --branch ${RELEASE_BRANCH_SOURCE} ${RELEASE_DIR_SOURCE} >& ${REDIRECT}
|
||||
pushd ${RELEASE_DIR_SOURCE} >& ${REDIRECT}
|
||||
echo "tagging as ${RELEASE_VERSION_TAG}"
|
||||
git tag ${RELEASE_VERSION_TAG} ${FORCE} >& ${REDIRECT}
|
||||
git push origin refs/tags/${RELEASE_VERSION_TAG} ${FORCE} >& ${REDIRECT}
|
||||
popd >& ${REDIRECT}
|
||||
|
||||
echo "preparing release archive"
|
||||
git clone --depth 1 --branch ${RELEASE_VERSION_TAG} ${GIT_REPO} ${RELEASE_DIR} >& ${REDIRECT}
|
||||
pushd ${RELEASE_DIR} >& ${REDIRECT}
|
||||
rm -rf .vscode .git .gitignore >& ${REDIRECT}
|
||||
popd >& ${REDIRECT}
|
||||
popd >& ${REDIRECT}
|
||||
tar cJf ${PWD}/${RELEASE_NAME}.tar.xz -C ${TEMPDIR} ${RELEASE_DIR} >& ${REDIRECT}
|
||||
echo "created release archive ${RELEASE_NAME}.tar.xz -> $(sha256sum ${RELEASE_NAME}.tar.xz | awk '{print $1}')"
|
||||
}
|
||||
|
||||
main "$@"
|
||||
finish
|
|
@ -0,0 +1,14 @@
|
|||
|
||||
install(
|
||||
EXPORT wifi-telemetry-targets
|
||||
NAMESPACE wifi-telemetry::
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wifi-telemetry
|
||||
)
|
||||
|
||||
install(
|
||||
FILES "${CMAKE_CURRENT_SOURCE_DIR}/../cmake/wifi-telemetry-config.cmake"
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/wifi-telemetry
|
||||
)
|
||||
|
||||
add_subdirectory(daemon)
|
||||
add_subdirectory(lib)
|
|
@ -0,0 +1,35 @@
|
|||
|
||||
add_executable(wifi-telemetryd
|
||||
""
|
||||
)
|
||||
|
||||
set_property(
|
||||
TARGET wifi-telemetryd
|
||||
PROPERTY POSITION_INDEPENDENT_CODE TRUE
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS wifi-telemetryd
|
||||
DESTINATION ${CMAKE_INSTALL_SBINDIR}
|
||||
)
|
||||
|
||||
target_sources(wifi-telemetryd
|
||||
PRIVATE
|
||||
main.cxx
|
||||
)
|
||||
|
||||
target_include_directories(wifi-telemetryd
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../include
|
||||
)
|
||||
|
||||
target_link_libraries(wifi-telemetryd
|
||||
PRIVATE
|
||||
wifi-telemetry
|
||||
INTERFACE
|
||||
${LIBSYSTEMD_TARGET}
|
||||
${LIBWPA_CLIENT_TARGET}
|
||||
)
|
||||
|
||||
add_subdirectory(systemd)
|
|
@ -0,0 +1,118 @@
|
|||
|
||||
#include <getopt.h>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include <stdexcept>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
|
||||
#include "wifi-telemetry/wifi_telemetry_monitor.hpp"
|
||||
#include "wifi-telemetry/wifi_telemetry_source_wpa.hpp"
|
||||
#include "wifi-telemetry/wifi_telemetry_source_ztpd.hpp"
|
||||
|
||||
static char*
|
||||
triml(char* s)
|
||||
{
|
||||
while (isspace(*s))
|
||||
s++;
|
||||
return s;
|
||||
}
|
||||
|
||||
static WifiOperationalMode
|
||||
parse_wifi_operational_mode(const char* operational_mode)
|
||||
{
|
||||
if (strcmp(operational_mode, "ap") == 0 ||
|
||||
strcmp(operational_mode, "access-point") == 0) {
|
||||
return WifiOperationalMode::AccessPoint;
|
||||
} else if (strcmp(operational_mode, "sta") == 0 ||
|
||||
strcmp(operational_mode, "station") == 0) {
|
||||
return WifiOperationalMode::Station;
|
||||
}
|
||||
|
||||
throw new std::invalid_argument("invalid operational mode string");
|
||||
}
|
||||
|
||||
struct WifiTelemetrySourceArgs
|
||||
{
|
||||
explicit WifiTelemetrySourceArgs(const std::string& name_) :
|
||||
name(name_)
|
||||
{}
|
||||
|
||||
std::string name;
|
||||
std::optional<std::string> interface;
|
||||
std::optional<WifiOperationalMode> operational_mode;
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
WifiTelemetryMonitor monitor{};
|
||||
WifiTelemetrySourceArgs* source_active = nullptr;
|
||||
std::vector<WifiTelemetrySourceArgs> sources{};
|
||||
|
||||
for (;;) {
|
||||
int opt = getopt(argc, argv, "i:o:s:");
|
||||
if (opt < 0)
|
||||
break;
|
||||
|
||||
switch (opt) {
|
||||
case 'i':
|
||||
if (source_active)
|
||||
source_active->interface = triml(optarg);
|
||||
break;
|
||||
case 'o':
|
||||
if (source_active)
|
||||
source_active->operational_mode = parse_wifi_operational_mode(triml(optarg));
|
||||
break;
|
||||
case 's':
|
||||
source_active = &sources.emplace_back(triml(optarg));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (sources.size() == 0) {
|
||||
std::cerr << "no sources added" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (const auto& source : sources) {
|
||||
// prepare interface configuration, if specified
|
||||
std::optional<WifiInterfaceConfiguration> interface;
|
||||
if (source.interface.has_value()) {
|
||||
interface.emplace(source.interface.value());
|
||||
if (source.operational_mode.has_value())
|
||||
interface->operational_mode = source.operational_mode.value();
|
||||
}
|
||||
|
||||
// add the source
|
||||
if (source.name == "wpa")
|
||||
monitor.add_source<WifiTelemetrySourceWpa>(interface);
|
||||
else if (source.name == "ztp")
|
||||
monitor.add_source<WifiTelemetrySourceZtpd>(interface);
|
||||
}
|
||||
|
||||
monitor.start();
|
||||
|
||||
// Mask SIGTERM and SIGINT so they can be explicitly waited on from the main thread.
|
||||
int signal;
|
||||
sigset_t mask;
|
||||
sigemptyset(&mask);
|
||||
sigaddset(&mask, SIGTERM);
|
||||
sigaddset(&mask, SIGINT);
|
||||
|
||||
if (sigprocmask(SIG_BLOCK, &mask, nullptr) < 0) {
|
||||
std::cerr << "failed to block terminate signals" << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Wait for the process to be signaled to exit.
|
||||
while (sigwait(&mask, &signal) != 0)
|
||||
;
|
||||
|
||||
// Received interrupt or terminate signal, so shutdown.
|
||||
monitor.stop();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wifi-telemetryd-ap@.service.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wifi-telemetryd-ap@.service
|
||||
)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wifi-telemetryd-station@.service.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wifi-telemetryd-station@.service
|
||||
)
|
||||
|
||||
configure_file(
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wifi-telemetryd-ztp.service.in
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wifi-telemetryd-ztp.service
|
||||
)
|
||||
|
||||
install(
|
||||
FILES
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wifi-telemetryd-ap@.service
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wifi-telemetryd-station@.service
|
||||
${CMAKE_CURRENT_BINARY_DIR}/wifi-telemetryd-ztp.service
|
||||
DESTINATION ${CMAKE_INSTALL_LIBDIR}/systemd/system
|
||||
)
|
|
@ -0,0 +1,9 @@
|
|||
[Unit]
|
||||
Description=Wi-Fi Telemetry Daemon (WPA Access Point)
|
||||
Requires=sys-subsystem-net-devices-%i.device
|
||||
After=sys-subsystem-net-devices-%i.device
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=on-failure
|
||||
ExecStart=${CMAKE_INSTALL_FULL_SBINDIR}/wifi-telemetryd -s wpa -o ap -i %i
|
|
@ -0,0 +1,9 @@
|
|||
[Unit]
|
||||
Description=Wi-Fi Telemetry Daemon (WPA Station)
|
||||
Requires=sys-subsystem-net-devices-%i.device
|
||||
After=sys-subsystem-net-devices-%i.device
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=on-failure
|
||||
ExecStart=${CMAKE_INSTALL_FULL_SBINDIR}/wifi-telemetryd -s wpa -o station -i %i
|
|
@ -0,0 +1,7 @@
|
|||
[Unit]
|
||||
Description=Wi-Fi Telemetry Daemon (Zero Touch Provisioning)
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
Restart=on-failure
|
||||
ExecStart=${CMAKE_INSTALL_FULL_SBINDIR}/wifi-telemetryd -s ztp
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
add_library(wifi-telemetry
|
||||
SHARED
|
||||
""
|
||||
)
|
||||
|
||||
if (BUILD_HOSTAP_EXTERNAL)
|
||||
add_dependencies(wifi-telemetry hostap)
|
||||
endif()
|
||||
|
||||
target_include_directories(wifi-telemetry
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/../../include
|
||||
)
|
||||
|
||||
target_link_libraries(wifi-telemetry
|
||||
INTERFACE
|
||||
${LIBSYSTEMD_TARGET}
|
||||
${LIBWPA_CLIENT_TARGET}
|
||||
udev
|
||||
pci
|
||||
)
|
||||
|
||||
target_sources(wifi-telemetry
|
||||
PRIVATE
|
||||
wifi_device_info.cxx
|
||||
wifi_telemetry_monitor.cxx
|
||||
wifi_telemetry_source.cxx
|
||||
wifi_telemetry_instance_impl.cxx
|
||||
wifi_telemetry_source_wpa.cxx
|
||||
wifi_telemetry_source_ztpd.cxx
|
||||
../../include/wifi-telemetry/wifi/wifi_80211_format_mac.hpp
|
||||
)
|
||||
|
||||
add_subdirectory(wpa)
|
||||
add_subdirectory(lttng-providers)
|
||||
add_subdirectory(ztpd)
|
||||
|
||||
install(
|
||||
TARGETS wifi-telemetry
|
||||
EXPORT wifi-telemetry-targets
|
||||
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
|
||||
)
|
||||
install(
|
||||
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/../../include/
|
||||
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
|
||||
)
|
|
@ -0,0 +1,28 @@
|
|||
|
||||
target_sources(wifi-telemetry
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wifi_telemetry_lttng_provider_station.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wifi_telemetry_lttng_provider_dpp.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wifi_telemetry_lttng_provider_wifi.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wifi_telemetry_trace_dpp.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wifi_telemetry_trace_station.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wifi_telemetry_trace_wifi.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wifi_telemetry_trace.cxx
|
||||
)
|
||||
|
||||
target_include_directories(wifi-telemetry
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(wifi-telemetry
|
||||
INTERFACE
|
||||
LTTng::UST
|
||||
)
|
||||
|
||||
if (ENABLE_MS_LTTNG_EXTENSIONS)
|
||||
target_link_libraries(wifi-telemetry
|
||||
PRIVATE
|
||||
tracelogging::tracelogging
|
||||
)
|
||||
endif()
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
#define TRACEPOINT_DEFINE
|
||||
#define TRACEPOINT_CREATE_PROBES
|
||||
|
||||
#include "wifi_telemetry_lttng_provider_dpp.hpp"
|
|
@ -0,0 +1,326 @@
|
|||
|
||||
#undef TRACEPOINT_PROVIDER
|
||||
#define TRACEPOINT_PROVIDER wifi_dpp
|
||||
|
||||
#undef TRACEPOINT_INCLUDE
|
||||
#define TRACEPOINT_INCLUDE "./wifi_telemetry_lttng_provider_dpp.hpp"
|
||||
|
||||
#if !defined(__WIFI_TELEMETRY_LTTNG_PROVIDER_DPP_HPP__) || defined(TRACEPOINT_HEADER_MULTI_READ)
|
||||
#define _TRACEPOINT_LTTNG_UST_TRACEF_PROVIDER_H
|
||||
|
||||
#define __WIFI_TELEMETRY_LTTNG_PROVIDER_DPP_HPP__
|
||||
|
||||
#include <lttng/tracepoint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* @brief Event for a completed Device Provisioning Protocol (DPP) enrollee
|
||||
* exchange.
|
||||
*
|
||||
* This event fires each time a DPP exchange completes with the host device
|
||||
* acting as the enrollee device role. The event has a state which describes
|
||||
* the furthest state of the exchange reached, which is a relative indication
|
||||
* of success or failure.
|
||||
*
|
||||
* See the telemetry field descriptions below to determine which fields are
|
||||
* valid for specific state values.
|
||||
*/
|
||||
TRACEPOINT_EVENT(
|
||||
wifi_dpp,
|
||||
dpp_exchange_enrollee,
|
||||
TP_ARGS(
|
||||
const char *, interface,
|
||||
const char *, state,
|
||||
const char *, role,
|
||||
uint64_t, duration_milliseconds,
|
||||
size_t, chirp_frequencies_count,
|
||||
const uint32_t *, chirp_frequencies,
|
||||
const char *, failure_type,
|
||||
const char *, failure_details
|
||||
),
|
||||
TP_FIELDS(
|
||||
/**
|
||||
* @brief Interface name [required].
|
||||
*
|
||||
* This fields describes the name of the wireless interface. It is
|
||||
* always included in the telemetry event. The interface may be virtual
|
||||
* or physical; no indication is provided in the event.
|
||||
*
|
||||
* The data is formatted as a free-form string, consisting of
|
||||
* printable ASCII characters.
|
||||
*
|
||||
* @example wlan0
|
||||
* @example wlp4s0
|
||||
*/
|
||||
ctf_string(interface, interface)
|
||||
|
||||
/**
|
||||
* @brief The last/furthest state of the dpp exchange reached [required].
|
||||
*
|
||||
* This field describes the furthest state of the dpp exchange reached.
|
||||
* The exchange was successful if the terminal state was entered,
|
||||
* indicated by the value "provisioned". The following are the possible
|
||||
* values:
|
||||
*
|
||||
* - bootstrapping
|
||||
* This is the initial state.
|
||||
* - authenticated
|
||||
* This state is entered once bootstrapping has completed.
|
||||
* - provisioning
|
||||
* This state is entered once the dpp peer has been successfully
|
||||
* authenticated.
|
||||
* - provisioned
|
||||
* This state is entered once the enrollee has received a network
|
||||
* configuration object.
|
||||
* - terminated
|
||||
* This state is erntered if an error occurs during the exchange. In
|
||||
* this case, the 'failure_type' and 'failure_details' fields provide
|
||||
* more information about the cause of the failure.
|
||||
*/
|
||||
ctf_string(state, state)
|
||||
|
||||
/**
|
||||
* @brief DPP exchange role [required].
|
||||
*
|
||||
* This field indicates the DPP role of the host, either initiator or
|
||||
* responder.
|
||||
*
|
||||
* The following strings are the possible values of this field:
|
||||
*
|
||||
* - initiator
|
||||
* - responder
|
||||
*/
|
||||
ctf_string(role, role)
|
||||
|
||||
/**
|
||||
* @brief Exchange duration (milliseconds) [required].
|
||||
*
|
||||
* This fields describes the duration of the DPP exchange, in
|
||||
* milliseconds.
|
||||
*
|
||||
* The exchange is started when the first presence announcement (chirp)
|
||||
* is transmitted and completes when either a timeout occurs, an error
|
||||
* is encountered, or the enrollee is successfully provisioned.
|
||||
*
|
||||
* @example 2100
|
||||
*/
|
||||
ctf_integer(uint64_t, duration_milliseconds, duration_milliseconds)
|
||||
|
||||
/**
|
||||
* @brief Exchange presence announcement (chirp) frequencies [required].
|
||||
*
|
||||
* This field describes all the frequencies where presence announcement
|
||||
* frames were sent. This is an additive, unique list that includes
|
||||
* every such frequency chirped, even if the last iteration of chirping
|
||||
* did not include a particular frequency.
|
||||
*
|
||||
* The chirp frequencies are encoded as an array of 32-bit unsigned
|
||||
* integers.
|
||||
*/
|
||||
ctf_sequence(uint32_t, chirp_frequencies, chirp_frequencies, size_t, chirp_frequencies_count)
|
||||
|
||||
/**
|
||||
* @brief The DPP failure type [conditional].
|
||||
*
|
||||
* This field describes the category of failure that occurred if the
|
||||
* exchange failed. This field is only valid when the state field has
|
||||
* the value "terminated".
|
||||
*
|
||||
* The following strings are the possible values of this field:
|
||||
*
|
||||
* - none
|
||||
* This occurs when there was no error.
|
||||
* - unspecified
|
||||
* This occurs when the error is not known.
|
||||
* - authentication-timeout
|
||||
* This occurs when the DPP peer took too long to respond to the
|
||||
* authentication request frame.
|
||||
*/
|
||||
ctf_string(failure_type, failure_type)
|
||||
|
||||
/**
|
||||
* @brief DPP failure details [conditional].
|
||||
*
|
||||
* This field describes additional details regarding the cause of the
|
||||
* failure. This field is only valid when the state field has the value
|
||||
* "terminated". It is a free-form string.
|
||||
*/
|
||||
ctf_string(failure_details, failure_details)))
|
||||
|
||||
/**
|
||||
* @brief Event for a complete dpp configurator exchange.
|
||||
*/
|
||||
TRACEPOINT_EVENT(
|
||||
wifi_dpp,
|
||||
dpp_exchange_configurator,
|
||||
TP_ARGS(
|
||||
const char *, interface,
|
||||
const char *, state,
|
||||
const char *, role,
|
||||
uint64_t, duration_milliseconds,
|
||||
const char *, bssid,
|
||||
uint32_t, frequency,
|
||||
const char *, failure_type,
|
||||
const char *, failure_details
|
||||
),
|
||||
TP_FIELDS(
|
||||
/**
|
||||
* @brief Interface name [required].
|
||||
*
|
||||
* This fields describes the name of the wireless interface. It is
|
||||
* always included in the telemetry event. The interface may be virtual
|
||||
* or physical; no indication is provided in the event.
|
||||
*
|
||||
* The data is formatted as a free-form string, consisting of
|
||||
* printable ASCII characters.
|
||||
*
|
||||
* @example wlan0
|
||||
* @example wlp4s0
|
||||
*/
|
||||
ctf_string(interface, interface)
|
||||
|
||||
/**
|
||||
* @brief The last/furthest state of the dpp exchange reached [required].
|
||||
*
|
||||
* This field describes the furthest state of the dpp exchange reached.
|
||||
* The exchange was successful if the terminal state was entered,
|
||||
* indicated by the value "finished". The following are the possible
|
||||
* values:
|
||||
*
|
||||
* - bootstrapping
|
||||
* This is the initial state.
|
||||
* - authenticated
|
||||
* This state is entered once bootstrapping has completed.
|
||||
* - finished
|
||||
* This state is entered once the configurator has sent a network
|
||||
* configuration object to the enrollee.
|
||||
* - terminated
|
||||
* This state is erntered if an error occurs during the exchange. In
|
||||
* this case, the 'failure_type' and 'failure_details' fields provide
|
||||
* more information about the cause of the failure.
|
||||
*/
|
||||
ctf_string(state, state)
|
||||
|
||||
/**
|
||||
* @brief DPP exchange role [required].
|
||||
*
|
||||
* This field indicates the DPP role of the host, either initiator or
|
||||
* responder.
|
||||
*
|
||||
* The following strings are the possible values of this field:
|
||||
*
|
||||
* - initiator
|
||||
* - responder
|
||||
*/
|
||||
ctf_string(role, role)
|
||||
|
||||
/**
|
||||
* @brief Exchange duration (milliseconds) [required].
|
||||
*
|
||||
* This fields describes the duration of the DPP exchange, in
|
||||
* milliseconds.
|
||||
*
|
||||
* The exchange is started when the first presence announcement (chirp)
|
||||
* is received and completes when either a timeout occurs, an error
|
||||
* is encountered, or a network configuration object is sent to the
|
||||
* enrollee.
|
||||
*
|
||||
* @example 2100
|
||||
*/
|
||||
ctf_integer(uint64_t, duration_milliseconds, duration_milliseconds)
|
||||
|
||||
/**
|
||||
* @brief The Basic Service Set Identifier (BSSID) of the enrollee
|
||||
* [required].
|
||||
*
|
||||
* This field describes the BSSID of the enrollee involved in the
|
||||
* exchange.
|
||||
*
|
||||
* The data is formatted as a 48-bit sequence of hexadecimal pairs,
|
||||
* separated by a colon (:).
|
||||
*
|
||||
* @example 70:66:55:09:b6:6f
|
||||
* @example 72:66:55:27:2c:1b
|
||||
*/
|
||||
ctf_string(bssid, bssid)
|
||||
|
||||
/**
|
||||
* @brief The radio frequency used for the exchange (MHz) [optional].
|
||||
*
|
||||
* This field describes the radio frequency used for the exchange. This
|
||||
* field is always valid for all state field values except
|
||||
* 'bootstrapping', for which it is optionally valid. A value of zero
|
||||
* (0) indicates the field is invalid and should be ignored.
|
||||
*
|
||||
* @example 2412
|
||||
* @example 5180
|
||||
*/
|
||||
ctf_integer(uint32_t, frequency, frequency)
|
||||
|
||||
/**
|
||||
* @brief The DPP failure type [conditional].
|
||||
*
|
||||
* This field describes the category of failure that occurred if the
|
||||
* exchange failed. This field is only valid when the state field has
|
||||
* the value "terminated".
|
||||
*
|
||||
* The following strings are the possible values of this field:
|
||||
*
|
||||
* - none
|
||||
* This occurs when there was no error.
|
||||
* - unspecified
|
||||
* This occurs when the error is not known.
|
||||
* - authentication-timeout
|
||||
* This occurs when the DPP peer took too long to respond to the
|
||||
* authentication request frame.
|
||||
*/
|
||||
ctf_string(failure_type, failure_type)
|
||||
|
||||
/**
|
||||
* @brief DPP failure details [conditional].
|
||||
*
|
||||
* This field describes additional details regarding the cause of the
|
||||
* failure. This field is only valid when the state field has the value
|
||||
* "terminated". It is a free-form string.
|
||||
*/
|
||||
ctf_string(failure_details, failure_details)))
|
||||
|
||||
/**
|
||||
* @brief Event for Device Provisioning Protocol device role change.
|
||||
*
|
||||
* This event fires any time the active DPP device roles change on the host.
|
||||
* The event reports the currently active device roles (not the device role
|
||||
* that changed disposition).
|
||||
*/
|
||||
TRACEPOINT_EVENT(
|
||||
wifi_dpp,
|
||||
dpp_device_roles_changed,
|
||||
TP_ARGS(
|
||||
const char*, device_roles),
|
||||
TP_FIELDS(
|
||||
/**
|
||||
* @brief Active Device Provisioning Protocol (DPP) device roles
|
||||
* [required].
|
||||
*
|
||||
* This field describes the currently active DPP device roles. There
|
||||
* are two possible values:
|
||||
*
|
||||
* - enrollee
|
||||
* - configurator
|
||||
*
|
||||
* This field is encoded as a single string using the comma (,) as a
|
||||
* delimeter for each active device role, with no additional spaces
|
||||
* separating the delimeter and subsequent role(s). The string may be
|
||||
* empty or contain any combination of the above values in any order.
|
||||
*
|
||||
* @example enrollee,configurator
|
||||
* @example enrollee
|
||||
* @example configurator
|
||||
* @example configurator,enrollee
|
||||
*/
|
||||
ctf_string(device_roles, device_roles)))
|
||||
|
||||
#endif // !defined(__WIFI_TELEMETRY_LTTNG_PROVIDER_DPP_HPP__) || defined(TRACEPOINT_HEADER_MULTI_READ)
|
||||
|
||||
#include <lttng/tracepoint-event.h>
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
#define TRACEPOINT_DEFINE
|
||||
#define TRACEPOINT_CREATE_PROBES
|
||||
|
||||
#include "wifi_telemetry_lttng_provider_station.hpp"
|
|
@ -0,0 +1,387 @@
|
|||
|
||||
#undef TRACEPOINT_PROVIDER
|
||||
#define TRACEPOINT_PROVIDER wifi_station
|
||||
|
||||
#undef TRACEPOINT_INCLUDE
|
||||
#define TRACEPOINT_INCLUDE "./wifi_telemetry_lttng_provider_station.hpp"
|
||||
|
||||
#if !defined(__WIFI_TELEMETRY_LTTNG_PROVIDER_STATION_HPP__) || defined(TRACEPOINT_HEADER_MULTI_READ)
|
||||
#define _TRACEPOINT_LTTNG_UST_TRACEF_PROVIDER_H
|
||||
|
||||
#define __WIFI_TELEMETRY_LTTNG_PROVIDER_STATION_HPP__
|
||||
|
||||
#include <lttng/tracepoint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "wifi-telemetry/wpa/wifi_telemetry_input_station_connection_attempt.hpp"
|
||||
|
||||
/**
|
||||
* @brief Event for a connection attempt from a wifi station (client) to an
|
||||
* access point or other peer.
|
||||
*
|
||||
* This event fires upon completion of all connection attempts. The attempt has
|
||||
* a result which describes whether it was successful, and result-specific
|
||||
* fields that further describe details of the result; connection state
|
||||
* information when succesful, and failure details otherwise.
|
||||
*
|
||||
* See the telemetry field descriptions below to determine which fields are
|
||||
* valid for specific result values.
|
||||
*/
|
||||
TRACEPOINT_EVENT(
|
||||
wifi_station,
|
||||
connection_attempt,
|
||||
TP_ARGS(
|
||||
const char*, interface,
|
||||
const WifiTelemetryInputStationConnectionAttempt*, data),
|
||||
TP_FIELDS(
|
||||
/**
|
||||
* @brief Interface name [required].
|
||||
*
|
||||
* This fields describes the name of the wireless interface. It is
|
||||
* always included in the telemetry event. The interface may be virtual
|
||||
* or physical; no indication is provided in the event.
|
||||
*
|
||||
* The data is formatted as a free-form string, consisting of
|
||||
* printable ASCII characters.
|
||||
*
|
||||
* @example wlan0
|
||||
* @example wlp4s0
|
||||
*/
|
||||
ctf_string(interface, interface)
|
||||
|
||||
/**
|
||||
* @brief The result of the connection attempt [required].
|
||||
*
|
||||
* This field describes the coarse result of the connection attempt.
|
||||
*
|
||||
* The data is formatted as an unsigned, 32-bit integer. @see
|
||||
* WifiConnectionAttemptResult for a complete list of all possible
|
||||
* values this field can take.
|
||||
*
|
||||
* result values and sub-fields:
|
||||
*
|
||||
* - WifiConnectionAttemptResult::Succeeded (value=0)
|
||||
* This result occurs when the connection attempt was successful and a
|
||||
* valid connection was made. In this case, the following telemetry
|
||||
* fields will further describe the state of the connection:
|
||||
*
|
||||
* - bssid
|
||||
* - ssid
|
||||
* - rssi
|
||||
* - noise
|
||||
* - link_speed
|
||||
* - frequency
|
||||
* - wifi_generation
|
||||
* - key_mgmt
|
||||
* - group_cipher
|
||||
*
|
||||
* - WifiConnectionAttemptResult::Unspecified (value=1)
|
||||
* This result occurs when the connection attempt failed and no
|
||||
* specific reason for the failure could be determined. No additional
|
||||
* fields are valid for this result value.
|
||||
*
|
||||
* - WifiConnectionAttemptResult::AuthenticationRejected (value=2)
|
||||
* This result occurs when the connection attempt failed due to
|
||||
* authentication being rejected by the peer. In this case, the
|
||||
* following telemetry fields in this event will further describe the
|
||||
* reason for failure:
|
||||
*
|
||||
* - bssid
|
||||
* - status_code
|
||||
* - authentication_type
|
||||
*
|
||||
* The status code field describes the specific reason for failure.
|
||||
* See the comments in status code for more details. The
|
||||
* autnentication type field describes the type of authentication
|
||||
* attempted.
|
||||
*
|
||||
* - WifiConnectionAttemptResult::AssociationRejected (value=3)
|
||||
* This result occurs when the connection attempt failed due to
|
||||
* association being rejected. In this case, the following telemetry
|
||||
* fields in this event will further describe the reason for failure:
|
||||
*
|
||||
* - bssid
|
||||
* - status_code
|
||||
*
|
||||
* The status code field describes the specific reason for failure. See
|
||||
* the comments in status code for more details.
|
||||
*
|
||||
* - WifiConnectionAttemptResult::NetworkNotFound:
|
||||
* This result occurs whenm the connection attempt failed due to the
|
||||
* selected network not being found. This can occur when either the
|
||||
* target network is not in radio range, or when the target network was
|
||||
* found but does not match the characteristics of its profile. For
|
||||
* example, this can occur when the network profile specifies the
|
||||
* target network uses one type of authentication, but the actual
|
||||
* network uses a different type. In this case, no additional telemetry
|
||||
* fields are valid.
|
||||
*/
|
||||
ctf_integer(uint32_t, result, data->result())
|
||||
|
||||
/**
|
||||
* @brief The Basic Service Set Identifier (BSSID) of the connection
|
||||
* attempt peer [conditional].
|
||||
*
|
||||
* This field describes the BSSID of the wireless device peer involved
|
||||
* in the connection attempt.
|
||||
*
|
||||
* The data is formatted as a 48-bit sequence of hexadecimal pairs,
|
||||
* separated by a colon (:).
|
||||
*
|
||||
* @example 70:66:55:09:b6:6f
|
||||
* @example 72:66:55:27:2c:1b
|
||||
*/
|
||||
ctf_string(bssid, data->bssid())
|
||||
|
||||
/**
|
||||
* @brief The Service Set Identifier (SSID) of the peer [conditional].
|
||||
*
|
||||
* This field describes the SSID of the wireless device peer involved
|
||||
* in the connection attempt.
|
||||
*
|
||||
* @example My Home Network
|
||||
* @example Microsoft-Guest
|
||||
*/
|
||||
ctf_string(ssid, data->ssid())
|
||||
|
||||
/**
|
||||
* @brief Connection Received Signal Strength Indicator (RSSI) [conditional].
|
||||
*
|
||||
* This field describes the RSSI of the connection at the time
|
||||
* the connection was established. This is technically a unit-less
|
||||
* value, however, is typically reported in dBm. RSSI units and values
|
||||
* are vendor specific and so should not be compared across vendors and
|
||||
* in some cases, even different devices.
|
||||
*
|
||||
* This field is only valid when result == 0 (Succeeded) and is
|
||||
* otherwise undefined and must be discarded.
|
||||
*
|
||||
* @example -70
|
||||
* @example 10
|
||||
*/
|
||||
ctf_integer(int32_t, rssi, data->rssi())
|
||||
|
||||
/**
|
||||
* @brief Connection noise level (dB) [conditional].
|
||||
*
|
||||
* This fields describes the noise level of the connection at the time
|
||||
* the connection was established. The unit is decibels (dB).
|
||||
*
|
||||
* This field is only valid when result == 0 (Succeeded) and is
|
||||
* otherwise undefined and must be discarded.
|
||||
*/
|
||||
ctf_integer(int32_t, noise, data->noise())
|
||||
|
||||
/**
|
||||
* @brief Connection link speed (Mbps) [conditional].
|
||||
*
|
||||
* This fields describes the link speed of the connection at the time
|
||||
* the connection was established. The unit is Mbps.
|
||||
*
|
||||
* This field is only valid when result == 0 (Succeeded) and is
|
||||
* otherwise undefined and must be discarded.
|
||||
*/
|
||||
ctf_integer(int32_t, link_speed, data->link_speed())
|
||||
|
||||
/**
|
||||
* @brief Connection frequency (MHz) [conditional].
|
||||
*
|
||||
* This field describes the frequency of the connection at the time the
|
||||
* connection was established. The unit is MHz.
|
||||
*
|
||||
* This field is only valid when result == 0 (Succeeded) and is
|
||||
* otherwise undefined and must be discarded.
|
||||
*/
|
||||
ctf_integer(uint32_t, frequency, data->frequency())
|
||||
|
||||
/**
|
||||
* @brief Connection Wi-Fi generation [conditional].
|
||||
*
|
||||
* This field describes the numerical Wi-Fi generation of the
|
||||
* connection. This corresponds to specific IEEE Wi-Fi standards,
|
||||
* starting with 802.11n (4), 802.11ac (5), 802.11ax (6).
|
||||
*
|
||||
* This field is only valid when result == 0 (Succeeded) and is
|
||||
* otherwise undefined and must be discarded.
|
||||
*/
|
||||
ctf_integer(uint32_t, wifi_generation, data->wifi_generation())
|
||||
|
||||
/**
|
||||
* @brief Connection key management [conditional].
|
||||
*
|
||||
* This field describes the key management method used by the
|
||||
* connection. The following strings are some of the possible values:
|
||||
*
|
||||
* - NONE
|
||||
* - WPA-NONE
|
||||
* - IEEE 802.1X (no WPA)
|
||||
* - FT-EAP
|
||||
* - FT-EAP-SHA384
|
||||
* - FT-PSK
|
||||
* - WPA2-EAP-SHA256
|
||||
* - WPA2-PSK-SHA256
|
||||
* - WPS
|
||||
* - SAE
|
||||
* - FT-SAE
|
||||
* - OSEN
|
||||
* - WPA2-EAP-SUITE-B
|
||||
* - WPA2-EAP-SUITE-B-192
|
||||
* - FILS-SHA256
|
||||
* - FILS-SHA384
|
||||
* - FT-FILS-SHA256
|
||||
* - FT-FILS-SHA384
|
||||
* - OWE
|
||||
* - DPP
|
||||
* - UNKNOWN
|
||||
*
|
||||
* This field is only valid when result == 0 (Succeeded) and is
|
||||
* otherwise undefined and must be discarded.
|
||||
*/
|
||||
ctf_string(key_mgmt, data->key_mgmt())
|
||||
|
||||
/**
|
||||
* @brief Connection pairwise cipher [conditional].
|
||||
*
|
||||
* This fields describes the connection pairwise cipher. The pairwise
|
||||
* cipher is used for unicast (point-to-point) traffic.
|
||||
*
|
||||
* The following strings are some of the possible values:
|
||||
* - NONE
|
||||
* - WEP-40
|
||||
* - WEP-104
|
||||
* - TKIP
|
||||
* - CCMP
|
||||
* - CCMP+TKIP
|
||||
* - GCMP
|
||||
* - GCMP-256
|
||||
* - CCMP-256
|
||||
* - BIP
|
||||
* - BIP-GMAC-128
|
||||
* - BIP-GMAC-256
|
||||
* - BIP-CMAC-256
|
||||
* - GTK_NOT_USED
|
||||
* - UNKNOWN
|
||||
*
|
||||
* This field is only valid when result == 0 (Succeeded) and is
|
||||
* otherwise undefined and must be discarded.
|
||||
*/
|
||||
ctf_string(pairwise_cipher, data->pairwise_cipher())
|
||||
|
||||
/**
|
||||
* @brief Connection group cipher [conditional].
|
||||
*
|
||||
* This fields describes the connection group cipher. The group cipher
|
||||
* is used for multicast traffic.
|
||||
*
|
||||
* The possible values are the same as pairwise_cipher.
|
||||
*
|
||||
* This field is only valid when result == 0 (Succeeded) and is
|
||||
* otherwise undefined and must be discarded.
|
||||
*/
|
||||
ctf_string(group_cipher, data->group_cipher())
|
||||
|
||||
/**
|
||||
* @brief The Wi-Fi status code of the connection attempt [conditional].
|
||||
*
|
||||
* This fields describes the Wi-Status code of the connection attempt.
|
||||
* The values are defined in IEEE Std 802.11-2016, Section 9.4.1.9,
|
||||
* Table 9-46. @see WifiStatusCode for a more detailed description.
|
||||
*
|
||||
* This field is only valid when:
|
||||
* result == 2 (AuthenticationRejected) OR
|
||||
* result == 3 (AssociationRejected)
|
||||
* and is otherwise undefined and must be discarded
|
||||
*/
|
||||
ctf_integer(uint16_t, status_code, data->status_code())
|
||||
|
||||
/**
|
||||
* @brief The connection authentication type [conditional].
|
||||
*
|
||||
* This field describes the general authentication type of the
|
||||
* connnection attempt.
|
||||
*
|
||||
* The following strings are some of the possible values:
|
||||
*
|
||||
* - unknown
|
||||
* - open
|
||||
* - wpa-psk
|
||||
* - shared
|
||||
* - wpa
|
||||
* - wpa2
|
||||
* - wpa2-psk
|
||||
*
|
||||
* This field is only valid when result == 2
|
||||
* (AuthenticationRejected) and is otherwise undefined and must be
|
||||
* discarded.
|
||||
*/
|
||||
ctf_string(authentication_type, data->authentication_type())))
|
||||
|
||||
/**
|
||||
* @brief Event for a connection drop from an access point or other wireless peer.
|
||||
*
|
||||
* This event fires any time an established wireless connection is severred or
|
||||
* dropped, regardless of whether it was a healthy/expected disconnection or an
|
||||
* unhealthy/unexpected one.
|
||||
*/
|
||||
TRACEPOINT_EVENT(
|
||||
wifi_station,
|
||||
connection_drop,
|
||||
TP_ARGS(
|
||||
const char*, interface,
|
||||
const char*, bssid,
|
||||
uint16_t, reason_code,
|
||||
int, locally_generated),
|
||||
TP_FIELDS(
|
||||
/**
|
||||
* @brief Interface name [required].
|
||||
*
|
||||
* This fields describes the name of the wireless interface. It is
|
||||
* always included in the telemetry event. The interface may be virtual
|
||||
* or physical; no indication is provided in the event.
|
||||
*
|
||||
* The data is formatted as a free-form string, consisting of
|
||||
* printable ASCII characters.
|
||||
*
|
||||
* @example wlan0
|
||||
* @example wlp4s0
|
||||
*/
|
||||
ctf_string(interface, interface)
|
||||
|
||||
/**
|
||||
* @brief The Basic Service Set Identifier (BSSID) of the connection
|
||||
* attempt peer [required].
|
||||
*
|
||||
* This field describes the BSSID of the wireless device peer that was
|
||||
* disconnected.
|
||||
*
|
||||
* The data is formatted as a 48-bit sequence of hexadecimal pairs,
|
||||
* separated by a colon (:).
|
||||
*
|
||||
* @example 70:66:55:09:b6:6f
|
||||
* @example 72:66:55:27:2c:1b
|
||||
*/
|
||||
ctf_string(bssid, bssid)
|
||||
|
||||
/**
|
||||
* @brief The reason code for disassociation [required].
|
||||
*
|
||||
* This field describes the reason for disassociation (connection
|
||||
* drop). The values are defined in IEEE Std 802.11-2016, Section
|
||||
* 9.4.1.4, Table 9-45. @see WifiDeauthenticationReasonCode for a more
|
||||
* detailed description.
|
||||
*/
|
||||
ctf_integer(uint16_t, reason_code, reason_code)
|
||||
|
||||
/**
|
||||
* @brief Local generation/request indicator [required].
|
||||
*
|
||||
* This field describes whether the connection drop originated from the
|
||||
* client (locally_generated != 0) or originated from the peer
|
||||
* (locally_generated == 0).
|
||||
*/
|
||||
ctf_integer(int, locally_generated, locally_generated)))
|
||||
|
||||
#endif // !defined(__WIFI_TELEMETRY_LTTNG_PROVIDER_STATION_HPP__) || defined(TRACEPOINT_HEADER_MULTI_READ
|
||||
|
||||
#include <lttng/tracepoint-event.h>
|
|
@ -0,0 +1,5 @@
|
|||
|
||||
#define TRACEPOINT_DEFINE
|
||||
#define TRACEPOINT_CREATE_PROBES
|
||||
|
||||
#include "wifi_telemetry_lttng_provider_wifi.hpp"
|
|
@ -0,0 +1,164 @@
|
|||
|
||||
#undef TRACEPOINT_PROVIDER
|
||||
#define TRACEPOINT_PROVIDER wifi
|
||||
|
||||
#undef TRACEPOINT_INCLUDE
|
||||
#define TRACEPOINT_INCLUDE "./wifi_telemetry_lttng_provider_wifi.hpp"
|
||||
|
||||
#if !defined(__WIFI_TELEMETRY_LTTNG_PROVIDER_WIFI_HPP__) || defined(TRACEPOINT_HEADER_MULTI_READ)
|
||||
#define _TRACEPOINT_LTTNG_UST_TRACEF_PROVIDER_H
|
||||
|
||||
#define __WIFI_TELEMETRY_LTTNG_PROVIDER_WIFI_HPP__
|
||||
|
||||
#include <lttng/tracepoint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include "wifi_device_info.hpp"
|
||||
|
||||
/**
|
||||
* @brief Event for wifi device/chipset information.
|
||||
*
|
||||
* This event fires periodically to report information about the wifi chipset
|
||||
* and driver being used for a particular interface. The event will fire each
|
||||
* start() is called on a WifiTelemetryMonitor instance. All telemetry events
|
||||
* generated from the monitor can then be associated with the device
|
||||
* information reported at the beginning of the session.
|
||||
*/
|
||||
TRACEPOINT_EVENT(
|
||||
wifi,
|
||||
device_info,
|
||||
TP_ARGS(
|
||||
const struct WifiDeviceInfo*, device),
|
||||
TP_FIELDS(
|
||||
/**
|
||||
* @brief Interface name [required].
|
||||
*
|
||||
* This fields describes the name of the wireless interface. It is
|
||||
* always included in the telemetry event. The interface may be virtual
|
||||
* or physical; no indication is provided in the event.
|
||||
*
|
||||
* The data is formatted as a free-form string, consisting of
|
||||
* printable ASCII characters.
|
||||
*
|
||||
* @example wlan0
|
||||
* @example wlp4s0
|
||||
*/
|
||||
ctf_string(interface, device->interface.c_str())
|
||||
|
||||
/**
|
||||
* @brief Wi-Fi Basic Service Set Identifier (BSSID) [required].
|
||||
*
|
||||
* This field describes the BSSID of the wireless device, which
|
||||
* uniquely identifies an 802.11-based wireless device.
|
||||
*
|
||||
* The data is formatted as a 48-bit sequence of hexadecimal pairs,
|
||||
* separated by a colon (:).
|
||||
*
|
||||
* @example 70:66:55:09:b6:6f
|
||||
* @example 72:66:55:27:2c:1b
|
||||
*/
|
||||
ctf_string(bssid, device->bssid.c_str())
|
||||
|
||||
/**
|
||||
* @brief Device subsystem [required].
|
||||
*
|
||||
* This fields describes the kernel subsystem that is used to host the
|
||||
* device. This typically describes the device's bus.
|
||||
*
|
||||
* The data is formatted as a free-form string, consisting of printable
|
||||
* ASCII characters.
|
||||
*
|
||||
* @example pci
|
||||
* @example usb
|
||||
*/
|
||||
ctf_string(subsystem, device->subsystem.c_str())
|
||||
|
||||
/**
|
||||
* @brief Kernel driver (module) name [required].
|
||||
*
|
||||
* This field describes the name of the kernel driver (module) used to
|
||||
* control the device.
|
||||
*
|
||||
* The data is formatted as a free-form string, consisting of printable
|
||||
* ASCII characters.
|
||||
*
|
||||
* @example ath10k
|
||||
* @example rtl88x2ce
|
||||
*/
|
||||
ctf_string(kernel_driver, device->kernel_driver.c_str())
|
||||
|
||||
/**
|
||||
* @brief Kernel driver (module) version [required].
|
||||
*
|
||||
* This fields describes the version string of the kernel driver
|
||||
* (module). Each module may define this string arbitrarily; it may
|
||||
* contain numerical version information.
|
||||
*
|
||||
* The data is formatted as a free-form string, consisting of printable
|
||||
* ASCII characters.
|
||||
*
|
||||
* @example v5.9.0.3_36433.20200310_COEX20200103-1717
|
||||
*/
|
||||
ctf_string(kernel_driver_version, device->kernel_driver_version.c_str())
|
||||
|
||||
/**
|
||||
* @brief Device vendor name [optional].
|
||||
*
|
||||
* This fields describes the vendor of the device.
|
||||
*
|
||||
* The data is formatted as a free-form string, consisting of printable
|
||||
* ASCII characters.
|
||||
*
|
||||
* @example Intel Corporation
|
||||
* @example Realtek Semiconductor Co., Ltd.
|
||||
*/
|
||||
ctf_string(vendor, device->vendor.value_or("").c_str())
|
||||
|
||||
/**
|
||||
* @brief Device model name [optional].
|
||||
*
|
||||
* This fields describes the device name or model of the device,
|
||||
* differentiating it from other devices manufactured by the vendor.
|
||||
*
|
||||
* The data is formatted as a free-form string, consisting of printable
|
||||
* ASCII characters.
|
||||
*
|
||||
* @example Device c822
|
||||
*/
|
||||
ctf_string(device, device->device.value_or("").c_str())
|
||||
|
||||
/**
|
||||
* @brief Device subsystem vendor [optional].
|
||||
*
|
||||
* This field describes the name of the subsystem-specific vendor of
|
||||
* the device. This can be different from the device vendor field when
|
||||
* the bus portion of the device is implemented using different IHV
|
||||
* hardware components.
|
||||
*
|
||||
* The data is formatted as a free-form string, consisting of printable
|
||||
* ASCII characters.
|
||||
*
|
||||
* @example AzureWave
|
||||
*/
|
||||
ctf_string(subsystem_vendor, device->subsystem_vendor.value_or("").c_str())
|
||||
|
||||
/**
|
||||
* @brief Device subsystem model name [optional].
|
||||
*
|
||||
* This field describes the name of the subsystem-specific vendor of
|
||||
* the device, differentiating it from other devices manufactured by
|
||||
* the subsystem vendor. This can be different from the device model
|
||||
* field when the bus potion of the device is implemented using
|
||||
* different IHV hardware components.
|
||||
*
|
||||
* The data is formatted as a free-form string, consisting of printable
|
||||
* ASCII characters.
|
||||
|
||||
* @example Device 3750
|
||||
*/
|
||||
ctf_string(subsystem_device, device->subsystem_device.value_or("").c_str())))
|
||||
|
||||
#endif // !defined(__WIFI_TELEMETRY_LTTNG_PROVIDER_WIFI_HPP__) || defined(TRACEPOINT_HEADER_MULTI_READ)
|
||||
|
||||
#include <lttng/tracepoint-event.h>
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
#include "wifi_telemetry_trace.hpp"
|
||||
#include "wifi_telemetry_trace_dpp.hpp"
|
||||
#include "wifi_telemetry_trace_station.hpp"
|
||||
#include "wifi_telemetry_trace_wifi.hpp"
|
||||
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
#include "wifi_telemetry_tracelogging.hpp"
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
|
||||
void
|
||||
WifiTelemetryTraceProvider::RegisterAll(void)
|
||||
{
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
TraceLoggingRegister(g_TraceloggingProviderWifi);
|
||||
TraceLoggingRegister(g_TraceloggingProviderWifiDpp);
|
||||
TraceLoggingRegister(g_TraceloggingProviderWifiStation);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetryTraceProvider::UnregisterAll(void)
|
||||
{
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
TraceLoggingUnregister(g_TraceloggingProviderWifi);
|
||||
TraceLoggingUnregister(g_TraceloggingProviderWifiDpp);
|
||||
TraceLoggingUnregister(g_TraceloggingProviderWifiStation);
|
||||
#endif
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
#ifndef __WIFI_TELEMETRY_TRACE_HPP__
|
||||
#define __WIFI_TELEMETRY_TRACE_HPP__
|
||||
|
||||
struct WifiTelemetryTraceProvider
|
||||
{
|
||||
/**
|
||||
* @brief Registers all Tracelogging-based providers with LLTNG. This must
|
||||
* be called prior to generating any tracelogging-based telemetry events.
|
||||
*/
|
||||
static void
|
||||
RegisterAll(void);
|
||||
|
||||
/**
|
||||
* @brief Unregisters all Tracelogging-based providers from LTTNG.
|
||||
*/
|
||||
static void
|
||||
UnregisterAll(void);
|
||||
};
|
||||
|
||||
#endif //__WIFI_TELEMETRY_TRACEPROVIDERS_HPP__
|
|
@ -0,0 +1,91 @@
|
|||
|
||||
#include "wifi_telemetry_trace_dpp.hpp"
|
||||
#include "wifi_telemetry_lttng_provider_dpp.hpp"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wc99-extensions"
|
||||
#pragma clang diagnostic ignored "-Wgnu-statement-expression"
|
||||
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||
#endif //__clang__
|
||||
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
// Provider UUID: 91adedb1-4f70-405f-9771-00415a5e375e
|
||||
TRACELOGGING_DEFINE_PROVIDER(
|
||||
g_TraceloggingProviderWifiDpp,
|
||||
"Microsoft.Azure.Device.Wifi.Dpp",
|
||||
(0x91adedb1, 0x4f70, 0x405f, 0x97, 0x71, 0x00, 0x41, 0x5a, 0x5e, 0x37, 0x5e));
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
|
||||
void
|
||||
trace_dpp_exchange_enrollee(const char* interface, const char* state, const char* role, uint64_t duration_milliseconds, size_t chirp_frequencies_count, const uint32_t* chirp_frequencies, const char* failure_type, const char* failure_details)
|
||||
{
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
TraceLoggingWrite(g_TraceloggingProviderWifiDpp,
|
||||
"DppExchangeEnrollee",
|
||||
TraceLoggingString(interface, "interface"),
|
||||
TraceLoggingString(state, "exchangeState"),
|
||||
TraceLoggingString(role, "dppDeviceRole"),
|
||||
TraceLoggingUInt64(duration_milliseconds, "durationMilliseconds"),
|
||||
TraceLoggingUInt32Array(chirp_frequencies, static_cast<uint16_t>(chirp_frequencies_count), "chirpFrequenciesMhz"),
|
||||
TraceLoggingString(failure_type, "failureType"),
|
||||
TraceLoggingString(failure_details, "failureDetails"));
|
||||
#else // TRACE_USE_TRACELOGGING
|
||||
tracepoint(wifi_dpp,
|
||||
dpp_exchange_enrollee,
|
||||
interface,
|
||||
role,
|
||||
state,
|
||||
duration_milliseconds,
|
||||
chirp_frequencies_count,
|
||||
chirp_frequencies,
|
||||
failure_type,
|
||||
failure_details);
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
}
|
||||
|
||||
void
|
||||
trace_dpp_exchange_configurator(const char* interface, const char* state, const char* role, uint64_t duration_milliseconds, const char* bssid, uint32_t frequency, const char* failure_type, const char* failure_details)
|
||||
{
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
TraceLoggingWrite(g_TraceloggingProviderWifiDpp,
|
||||
"DppExchangeConfigurator",
|
||||
TraceLoggingString(interface, "interface"),
|
||||
TraceLoggingString(state, "exchangeState"),
|
||||
TraceLoggingString(role, "dppDeviceRole"),
|
||||
TraceLoggingUInt64(duration_milliseconds, "durationMilliseconds"),
|
||||
TraceLoggingString(bssid, "bssid"),
|
||||
TraceLoggingUInt32(frequency, "frequencyMHz"),
|
||||
TraceLoggingString(failure_type, "failureType"),
|
||||
TraceLoggingString(failure_details, "failureDetails"));
|
||||
#else // TRACE_USE_TRACELOGGING
|
||||
tracepoint(wifi_dpp,
|
||||
dpp_exchange_configurator,
|
||||
interface,
|
||||
role,
|
||||
state,
|
||||
duration_milliseconds,
|
||||
bssid,
|
||||
frequency,
|
||||
failure_type,
|
||||
failure_details);
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
}
|
||||
|
||||
void
|
||||
trace_dpp_device_roles_changed(const char* device_roles)
|
||||
{
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
TraceLoggingWrite(g_TraceloggingProviderWifiDpp,
|
||||
"DppDeviceRolesChanged",
|
||||
TraceLoggingString(device_roles, "dppDeviceRolesActive"));
|
||||
#else // TRACE_USE_TRACELOGGING
|
||||
tracepoint(wifi_dpp,
|
||||
dpp_device_roles_changed,
|
||||
device_roles);
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif //__clang__
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
#ifndef __WIFI_TELEMETRY_TRACE_DPP_HPP__
|
||||
#define __WIFI_TELEMETRY_TRACE_DPP_HPP__
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
#include "wifi_telemetry_tracelogging.hpp"
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
TRACELOGGING_DECLARE_PROVIDER(g_TraceloggingProviderWifiDpp);
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
|
||||
void
|
||||
trace_dpp_exchange_enrollee(const char* interface, const char* state, const char* role, uint64_t duration_milliseconds, size_t chirp_frequencies_count, const uint32_t* chirp_frequencies, const char* failure_type, const char* failure_details);
|
||||
|
||||
void
|
||||
trace_dpp_exchange_configurator(const char* interface, const char* state, const char* role, uint64_t duration_milliseconds, const char* bssid, uint32_t frequency, const char* failure_type, const char* failure_details);
|
||||
|
||||
void
|
||||
trace_dpp_device_roles_changed(const char* device_roles);
|
||||
|
||||
#endif //__WIFI_TELEMETRY_TRACE_DPP_HPP__
|
|
@ -0,0 +1,70 @@
|
|||
|
||||
#include "wifi_telemetry_trace_station.hpp"
|
||||
#include "wifi_telemetry_lttng_provider_station.hpp"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wc99-extensions"
|
||||
#pragma clang diagnostic ignored "-Wgnu-statement-expression"
|
||||
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||
#endif //__clang__
|
||||
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
// Provider UUID: 00bb2910-064f-41b3-8ead-ad6d608a10d0
|
||||
TRACELOGGING_DEFINE_PROVIDER(
|
||||
g_TraceloggingProviderWifiStation,
|
||||
"Microsoft.Azure.Device.Wifi.Station",
|
||||
(0x00bb2910, 0x064f, 0x41b3, 0x8e, 0xad, 0xad, 0x6d, 0x60, 0x8a, 0x10, 0xd0));
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
|
||||
void
|
||||
trace_station_connection_attempt(const char* interface, const WifiTelemetryInputStationConnectionAttempt* data)
|
||||
{
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
TraceLoggingWrite(g_TraceloggingProviderWifiStation,
|
||||
"ConnectionAttempt",
|
||||
TraceLoggingString(interface, "interface"),
|
||||
TraceLoggingUInt32(data->result(), "result"),
|
||||
TraceLoggingString(data->bssid(), "bssid"),
|
||||
TraceLoggingString(data->ssid(), "ssid"),
|
||||
TraceLoggingInt32(data->rssi(), "rssi"),
|
||||
TraceLoggingInt32(data->noise(), "noiseDb"),
|
||||
TraceLoggingInt32(data->link_speed(), "linkSpeedMbps"),
|
||||
TraceLoggingUInt32(data->frequency(), "frequencyMHz"),
|
||||
TraceLoggingUInt32(data->wifi_generation(), "wifiGeneration"),
|
||||
TraceLoggingString(data->key_mgmt(), "keyManagement"),
|
||||
TraceLoggingString(data->pairwise_cipher(), "pairwiseCipher"),
|
||||
TraceLoggingString(data->group_cipher(), "groupCipher"),
|
||||
TraceLoggingUInt16(data->status_code(), "statusCode"),
|
||||
TraceLoggingString(data->authentication_type(), "authenticationType"));
|
||||
#else // TRACE_USE_TRACELOGGING
|
||||
tracepoint(wifi_station,
|
||||
connection_attempt,
|
||||
interface,
|
||||
data);
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
}
|
||||
|
||||
void
|
||||
trace_station_connection_drop(const char* interface, const char* bssid, uint16_t reason_code, int locally_generated)
|
||||
{
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
TraceLoggingWrite(g_TraceloggingProviderWifiStation,
|
||||
"ConnectionDrop",
|
||||
TraceLoggingString(interface, "interface"),
|
||||
TraceLoggingString(bssid, "bssid"),
|
||||
TraceLoggingUInt16(reason_code, "reasonCode"),
|
||||
TraceLoggingBoolean(!!locally_generated, "locallyGenerated"));
|
||||
#else // TRACE_USE_TRACELOGGING
|
||||
tracepoint(wifi_station,
|
||||
connection_drop,
|
||||
interface,
|
||||
bssid,
|
||||
reason_code,
|
||||
locally_generated);
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif //__clang__
|
|
@ -0,0 +1,20 @@
|
|||
|
||||
#ifndef __WIFI_TELEMETRY_TRACE_STATION_HPP__
|
||||
#define __WIFI_TELEMETRY_TRACE_STATION_HPP__
|
||||
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
#include "wifi_telemetry_tracelogging.hpp"
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
#include "wifi-telemetry/wpa/wifi_telemetry_input_station_connection_attempt.hpp"
|
||||
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
TRACELOGGING_DECLARE_PROVIDER(g_TraceloggingProviderWifiStation);
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
|
||||
void
|
||||
trace_station_connection_attempt(const char *interface, const WifiTelemetryInputStationConnectionAttempt *data);
|
||||
|
||||
void
|
||||
trace_station_connection_drop(const char *interface, const char *bssid, uint16_t reason_code, int locally_generated);
|
||||
|
||||
#endif //__WIFI_TELEMETRY_TRACE_STATION_HPP__
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
#include "wifi_telemetry_trace_wifi.hpp"
|
||||
#include "wifi_telemetry_lttng_provider_wifi.hpp"
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wc99-extensions"
|
||||
#pragma clang diagnostic ignored "-Wgnu-statement-expression"
|
||||
#pragma clang diagnostic ignored "-Wgnu-zero-variadic-macro-arguments"
|
||||
#endif //__clang__
|
||||
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
// Provider UUID: d4238472-0bb9-4b64-af1e-14f3f7a5411b
|
||||
TRACELOGGING_DEFINE_PROVIDER(
|
||||
g_TraceloggingProviderWifi,
|
||||
"Microsoft.Azure.Device.Wifi",
|
||||
(0xd4238472, 0x0bb9, 0x4b64, 0xaf, 0x1e, 0x14, 0xf3, 0xf7, 0xa5, 0x41, 0x1b));
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
|
||||
void
|
||||
trace_wifi_device_info(const struct WifiDeviceInfo* device)
|
||||
{
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
TraceLoggingWrite(g_TraceloggingProviderWifi,
|
||||
"DeviceInfo",
|
||||
TraceLoggingString(device->interface.c_str(), "interface"),
|
||||
TraceLoggingString(device->bssid.c_str(), "bssid"),
|
||||
TraceLoggingString(device->subsystem.c_str(), "subsystem"),
|
||||
TraceLoggingString(device->kernel_driver.c_str(), "kernelDriver"),
|
||||
TraceLoggingString(device->kernel_driver_version.c_str(), "kernelDriverVersion"),
|
||||
TraceLoggingString(device->vendor.value_or("").c_str(), "vendor"),
|
||||
TraceLoggingString(device->device.value_or("").c_str(), "model"),
|
||||
TraceLoggingString(device->subsystem_vendor.value_or("").c_str(), "subsystemVendor"),
|
||||
TraceLoggingString(device->subsystem_device.value_or("").c_str(), "subsystemModel"));
|
||||
#else // TRACE_USE_TRACELOGGING
|
||||
tracepoint(wifi,
|
||||
device_info,
|
||||
device);
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
#pragma clang diagnostic pop
|
||||
#endif //__clang__
|
|
@ -0,0 +1,17 @@
|
|||
|
||||
#ifndef __WIFI_TELEMETRY_TRACEPROVIDER_WIFI_HPP__
|
||||
#define __WIFI_TELEMETRY_TRACEPROVIDER_WIFI_HPP__
|
||||
|
||||
#include "wifi_device_info.hpp"
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
#include "wifi_telemetry_tracelogging.hpp"
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
|
||||
#ifdef TRACE_USE_TRACELOGGING
|
||||
TRACELOGGING_DECLARE_PROVIDER(g_TraceloggingProviderWifi);
|
||||
#endif // !TRACE_USE_TRACELOGGING
|
||||
|
||||
void
|
||||
trace_wifi_device_info(const struct WifiDeviceInfo* info);
|
||||
|
||||
#endif //__WIFI_TELEMETRY_TRACEPROVIDER_WIFI_HPP__
|
|
@ -0,0 +1,22 @@
|
|||
/**
|
||||
* This file should be used in place of #include'ing TraceLoggingProvider.h
|
||||
* directly because it re-defines as macros what LTTNG has defined as an enum
|
||||
* :-(
|
||||
*/
|
||||
#include <tracelogging/TraceLoggingProvider.h>
|
||||
|
||||
#undef TRACE_EMERG
|
||||
#undef TRACE_ALERT
|
||||
#undef TRACE_CRIT
|
||||
#undef TRACE_ERR
|
||||
#undef TRACE_WARNING
|
||||
#undef TRACE_NOTICE
|
||||
#undef TRACE_INFO
|
||||
#undef TRACE_DEBUG_SYSTEM
|
||||
#undef TRACE_DEBUG_PROGRAM
|
||||
#undef TRACE_DEBUG_PROCESS
|
||||
#undef TRACE_DEBUG_MODULE
|
||||
#undef TRACE_DEBUG_UNIT
|
||||
#undef TRACE_DEBUG_FUNCTION
|
||||
#undef TRACE_DEBUG_LINE
|
||||
#undef TRACE_DEBUG
|
|
@ -0,0 +1,131 @@
|
|||
|
||||
#include <cstdlib>
|
||||
#include <filesystem>
|
||||
#include <libudev.h>
|
||||
#include <stdexcept>
|
||||
#include <string.h>
|
||||
|
||||
extern "C" {
|
||||
#include <pci/pci.h>
|
||||
}
|
||||
|
||||
#include "wifi_device_info.hpp"
|
||||
|
||||
WifiDeviceInfo::WifiDeviceInfo(
|
||||
const std::string& interface_,
|
||||
const std::string& bssid_,
|
||||
const std::string& subsystem_,
|
||||
const std::string& kernel_driver_,
|
||||
const std::string& kernel_driver_version_) :
|
||||
interface(interface_),
|
||||
bssid(bssid_),
|
||||
subsystem(subsystem_),
|
||||
kernel_driver(kernel_driver_),
|
||||
kernel_driver_version(kernel_driver_version_)
|
||||
{}
|
||||
|
||||
static uint16_t
|
||||
hexstr_to_uint16(const char *str)
|
||||
{
|
||||
if (!str)
|
||||
return 0;
|
||||
|
||||
unsigned long value = strtoul(str, nullptr, 16);
|
||||
if (value > UINT16_MAX)
|
||||
value = 0;
|
||||
|
||||
return static_cast<uint16_t>(value);
|
||||
}
|
||||
|
||||
static void
|
||||
fill_ids_pci(WifiDeviceInfo& device_info, struct udev_device *parent)
|
||||
{
|
||||
const char *vendor_str = udev_device_get_sysattr_value(parent, "vendor");
|
||||
const char *device_str = udev_device_get_sysattr_value(parent, "device");
|
||||
const char *subsystem_device_str = udev_device_get_sysattr_value(parent, "subsystem_device");
|
||||
const char *subsystem_vendor_str = udev_device_get_sysattr_value(parent, "subsystem_vendor");
|
||||
|
||||
uint16_t vendor = hexstr_to_uint16(vendor_str);
|
||||
uint16_t device = hexstr_to_uint16(device_str);
|
||||
uint16_t svendor = hexstr_to_uint16(subsystem_vendor_str);
|
||||
uint16_t sdevice = hexstr_to_uint16(subsystem_device_str);
|
||||
|
||||
struct pci_access *pacc = pci_alloc();
|
||||
char pci_vendor[128];
|
||||
char pci_device[128];
|
||||
char pci_svendor[128];
|
||||
char pci_sdevice[128];
|
||||
|
||||
pci_init(pacc);
|
||||
|
||||
device_info.vendor = pci_lookup_name(pacc, pci_vendor, sizeof pci_vendor, PCI_LOOKUP_VENDOR, vendor, device);
|
||||
device_info.device = pci_lookup_name(pacc, pci_device, sizeof pci_device, PCI_LOOKUP_DEVICE, vendor, device);
|
||||
device_info.subsystem_vendor = pci_lookup_name(pacc, pci_svendor, sizeof pci_svendor, PCI_LOOKUP_VENDOR | PCI_LOOKUP_SUBSYSTEM, svendor);
|
||||
device_info.subsystem_device = pci_lookup_name(pacc, pci_sdevice, sizeof pci_sdevice, PCI_LOOKUP_DEVICE | PCI_LOOKUP_SUBSYSTEM, vendor, device, svendor, sdevice);
|
||||
|
||||
pci_cleanup(pacc);
|
||||
}
|
||||
|
||||
static void
|
||||
fill_ids_generic(WifiDeviceInfo& device_info, struct udev_device *parent)
|
||||
{
|
||||
const char *vendor = udev_device_get_property_value(parent, "ID_VENDOR_FROM_DATABASE");
|
||||
const char *model = udev_device_get_property_value(parent, "ID_MODEL_FROM_DATABASE");
|
||||
|
||||
if (!vendor)
|
||||
vendor = udev_device_get_property_value(parent, "ID_VENDOR");
|
||||
if (!model)
|
||||
model = udev_device_get_property_value(parent, "ID_MODEL");
|
||||
|
||||
if (vendor)
|
||||
device_info.vendor = vendor;
|
||||
if (model)
|
||||
device_info.device = model;
|
||||
}
|
||||
|
||||
static void
|
||||
fill_ids(WifiDeviceInfo& device_info, struct udev_device *parent)
|
||||
{
|
||||
if (device_info.subsystem == "pci")
|
||||
fill_ids_pci(device_info, parent);
|
||||
else
|
||||
fill_ids_generic(device_info, parent);
|
||||
}
|
||||
|
||||
WifiDeviceInfo
|
||||
WifiDeviceInfo::from_interface(const std::string& interface)
|
||||
{
|
||||
const std::filesystem::path sysfs_path = std::filesystem::path("/sys/class/net") / interface;
|
||||
struct udev *udev = udev_new();
|
||||
struct udev_device *device = udev_device_new_from_syspath(udev, sysfs_path.c_str());
|
||||
if (!device)
|
||||
throw new std::invalid_argument(std::string("invalid sysfs path ") + sysfs_path.c_str());
|
||||
|
||||
// Ensure this is a wireless device.
|
||||
const char *devtype = udev_device_get_devtype(device);
|
||||
if (!devtype || strcmp(devtype, "wlan") != 0)
|
||||
throw new std::invalid_argument(interface + " is not a wireless device");
|
||||
|
||||
struct udev_device *device_parent = udev_device_get_parent(device);
|
||||
const char *kernel_driver_syspath = udev_device_get_syspath(device_parent);
|
||||
const std::filesystem::path sysfs_path_kmodule = std::filesystem::path(kernel_driver_syspath) / "driver/module";
|
||||
struct udev_device *device_module = udev_device_new_from_syspath(udev, sysfs_path_kmodule.c_str());
|
||||
if (!device_module)
|
||||
throw new std::invalid_argument("unable to obtain device kernel module");
|
||||
|
||||
const char *address = udev_device_get_sysattr_value(device, "address");
|
||||
const char *subsystem = udev_device_get_subsystem(device_parent);
|
||||
const char *kernel_driver = udev_device_get_driver(device_parent);
|
||||
const char *kernel_driver_version = udev_device_get_sysattr_value(device_module, "version");
|
||||
|
||||
WifiDeviceInfo device_info { interface, address, subsystem, kernel_driver, kernel_driver_version };
|
||||
|
||||
fill_ids(device_info, device_parent);
|
||||
|
||||
udev_device_unref(device_module);
|
||||
udev_device_unref(device_parent);
|
||||
udev_device_unref(device);
|
||||
udev_unref(udev);
|
||||
|
||||
return device_info;
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
|
||||
#ifndef __WIFI_DEVICE_INFO_HPP__
|
||||
#define __WIFI_DEVICE_INFO_HPP__
|
||||
|
||||
#include <optional>
|
||||
#include <string>
|
||||
|
||||
struct WifiDeviceInfo
|
||||
{
|
||||
WifiDeviceInfo(
|
||||
const std::string& interface,
|
||||
const std::string& bssid,
|
||||
const std::string& subsystem,
|
||||
const std::string& kernel_driver,
|
||||
const std::string& kernel_driver_version);
|
||||
|
||||
const std::string interface;
|
||||
const std::string bssid;
|
||||
const std::string subsystem;
|
||||
const std::string kernel_driver;
|
||||
const std::string kernel_driver_version;
|
||||
|
||||
std::optional<std::string> vendor;
|
||||
std::optional<std::string> device;
|
||||
std::optional<std::string> subsystem_vendor;
|
||||
std::optional<std::string> subsystem_device;
|
||||
|
||||
static WifiDeviceInfo
|
||||
from_interface(const std::string& interface);
|
||||
};
|
||||
|
||||
#endif // __WIFI_DEVICE_INFO_HPP__
|
|
@ -0,0 +1,29 @@
|
|||
|
||||
#include "wifi_telemetry_instance_impl.hpp"
|
||||
|
||||
WifiTelemetrySourceInstanceImpl::WifiTelemetrySourceInstanceImpl(std::shared_ptr<WifiTelemetrySource> source_, const std::shared_ptr<WifiTelemetrySourceActivationArgs> args_) :
|
||||
WifiTelemetrySourceInstance(source_, args_)
|
||||
{}
|
||||
|
||||
int
|
||||
WifiTelemetrySourceInstanceImpl::activate(void)
|
||||
{
|
||||
if (m_activated)
|
||||
return 0;
|
||||
|
||||
int ret = source->activate(args);
|
||||
if (ret == 0)
|
||||
m_activated = true;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceInstanceImpl::deactivate(void)
|
||||
{
|
||||
if (!m_activated)
|
||||
return;
|
||||
|
||||
source->deactivate();
|
||||
m_activated = false;
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
|
||||
#ifndef __WIFI_TELEMETRY_SOURCE_INSTANCE_IMPL_HPP__
|
||||
#define __WIFI_TELEMETRY_SOURCE_INSTANCE_IMPL_HPP__
|
||||
|
||||
#include "wifi-telemetry/wifi_telemetry_source_instance.hpp"
|
||||
|
||||
struct WifiTelemetrySourceInstanceImpl :
|
||||
public WifiTelemetrySourceInstance
|
||||
{
|
||||
WifiTelemetrySourceInstanceImpl(std::shared_ptr<WifiTelemetrySource> source, const std::shared_ptr<WifiTelemetrySourceActivationArgs> args);
|
||||
|
||||
int
|
||||
activate(void);
|
||||
|
||||
void
|
||||
deactivate(void);
|
||||
|
||||
private:
|
||||
bool m_activated = false;
|
||||
};
|
||||
|
||||
#endif // __WIFI_TELEMETRY_SOURCE_INSTANCE_IMPL_HPP__
|
|
@ -0,0 +1,110 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <iostream>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "wifi-telemetry/wifi_telemetry_monitor.hpp"
|
||||
#include "wifi_device_info.hpp"
|
||||
#include "wifi_telemetry_instance_impl.hpp"
|
||||
#include "wifi_telemetry_trace.hpp"
|
||||
#include "wifi_telemetry_trace_wifi.hpp"
|
||||
|
||||
WifiTelemetryMonitor::WifiTelemetryMonitor(void)
|
||||
{
|
||||
WifiTelemetryTraceProvider::RegisterAll();
|
||||
}
|
||||
|
||||
WifiTelemetryMonitor::~WifiTelemetryMonitor(void)
|
||||
{
|
||||
WifiTelemetryTraceProvider::UnregisterAll();
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetryMonitor::add_source_impl(const std::shared_ptr<WifiTelemetrySource> source, const std::shared_ptr<WifiTelemetrySourceActivationArgs> activation_args)
|
||||
{
|
||||
auto instance = std::make_unique<WifiTelemetrySourceInstanceImpl>(source, activation_args);
|
||||
if (m_activated)
|
||||
instance->activate();
|
||||
|
||||
m_sources.push_back(std::move(instance));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Removes a telemetry source from the monitor.
|
||||
*
|
||||
* @param registration_token The registration token obtained from add_source().
|
||||
*/
|
||||
void
|
||||
WifiTelemetryMonitor::remove_source(const std::shared_ptr<WifiTelemetrySource> source)
|
||||
{
|
||||
const auto& result = std::find_if(std::begin(m_sources), std::end(m_sources), [&](const auto& instance) {
|
||||
return (instance->source == source);
|
||||
});
|
||||
|
||||
if (result == std::end(m_sources))
|
||||
return;
|
||||
|
||||
WifiTelemetrySourceInstanceImpl& instance = dynamic_cast<WifiTelemetrySourceInstanceImpl&>(**result);
|
||||
|
||||
instance.deactivate();
|
||||
m_sources.erase(result);
|
||||
}
|
||||
|
||||
std::size_t
|
||||
WifiTelemetryMonitor::activate_sources(void)
|
||||
{
|
||||
std::size_t num_activated = 0;
|
||||
std::unordered_set<std::string> interfaces;
|
||||
|
||||
for (auto& instance : m_sources) {
|
||||
int ret = dynamic_cast<WifiTelemetrySourceInstanceImpl&>(*instance).activate();
|
||||
if (ret < 0) {
|
||||
std::cerr << "failed to activate telemetry source '" << instance->source->name() << "' (" << ret << ")" << std::endl;
|
||||
continue;
|
||||
}
|
||||
|
||||
// Generate a telemetry event for each unique interface being monitored.
|
||||
if (instance->source->interface()) {
|
||||
const auto& [interface, inserted] = interfaces.insert(instance->source->interface()->name);
|
||||
if (inserted) {
|
||||
try {
|
||||
WifiDeviceInfo device_info = WifiDeviceInfo::from_interface(*interface);
|
||||
trace_wifi_device_info(&device_info);
|
||||
} catch (...) {
|
||||
std::cout << "warning: failed to generate wifi device info telemetry event for " << *interface << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
num_activated++;
|
||||
std::cout << "activated telemetry source '" << instance->source->name() << "'" << std::endl;
|
||||
}
|
||||
|
||||
return num_activated;
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetryMonitor::deactivate_sources(void)
|
||||
{
|
||||
for (auto& instance : m_sources) {
|
||||
dynamic_cast<WifiTelemetrySourceInstanceImpl&>(*instance).deactivate();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetryMonitor::start(void)
|
||||
{
|
||||
std::size_t num_activated_desired = m_sources.size();
|
||||
std::size_t num_activated_actual = activate_sources();
|
||||
std::cout << "telemetry monitor started with " << num_activated_actual << " of " << num_activated_desired
|
||||
<< " telemetry sources" << std::endl;
|
||||
m_activated = true;
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetryMonitor::stop(void)
|
||||
{
|
||||
deactivate_sources();
|
||||
m_activated = false;
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
#include "wifi-telemetry/wifi_telemetry_source.hpp"
|
||||
|
||||
WifiTelemetrySource::WifiTelemetrySource(const std::optional<WifiInterfaceConfiguration>& interface) :
|
||||
m_interface(interface)
|
||||
{}
|
||||
|
||||
WifiTelemetrySource::WifiTelemetrySource(const std::optional<WifiInterfaceConfiguration>& interface, const std::string& name) :
|
||||
m_name(name),
|
||||
m_interface(interface)
|
||||
{}
|
||||
|
||||
WifiTelemetrySource::~WifiTelemetrySource(void)
|
||||
{}
|
||||
|
||||
int
|
||||
WifiTelemetrySource::activate(const std::shared_ptr<WifiTelemetrySourceActivationArgs> /* args */)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySource::deactivate(void)
|
||||
{}
|
||||
|
||||
const std::string_view
|
||||
WifiTelemetrySource::name(void) const
|
||||
{
|
||||
return m_name;
|
||||
}
|
||||
|
||||
const std::optional<WifiInterfaceConfiguration>&
|
||||
WifiTelemetrySource::interface(void) const
|
||||
{
|
||||
return m_interface;
|
||||
}
|
|
@ -0,0 +1,358 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211_format_mac.hpp"
|
||||
#include "wifi-telemetry/wifi_telemetry_source_wpa.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_commands.hpp"
|
||||
#include "wifi_telemetry_trace_dpp.hpp"
|
||||
#include "wifi_telemetry_trace_station.hpp"
|
||||
|
||||
WifiTelemetrySourceWpa::WifiTelemetrySourceWpa(const std::optional<WifiInterfaceConfiguration>& interface) :
|
||||
WifiTelemetrySource(interface, "wpa")
|
||||
{
|
||||
if (!interface.has_value())
|
||||
throw new std::invalid_argument("WifiTelemetrySourceWpa requires interface configuration, but none was supplied");
|
||||
}
|
||||
|
||||
WifiTelemetrySourceWpa::~WifiTelemetrySourceWpa(void)
|
||||
{
|
||||
if (m_controller) {
|
||||
m_controller->unregister_for_events(m_event_token);
|
||||
m_controller = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
WifiTelemetrySourceWpa::activate(const std::shared_ptr<WifiTelemetrySourceActivationArgs> /* args */)
|
||||
{
|
||||
WpaType type = WpaInterfaceInfo::TypeFromOperationalMode(m_interface->operational_mode);
|
||||
|
||||
m_controller = std::make_unique<WpaController>(m_interface->name, type);
|
||||
m_event_token = m_controller->register_for_events(weak_from_this());
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::deactivate(void)
|
||||
{
|
||||
m_controller = nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
WifiTelemetrySourceWpa::trace_station(void) const
|
||||
{
|
||||
return (m_interface->operational_mode == WifiOperationalMode::Station);
|
||||
}
|
||||
|
||||
bool
|
||||
WifiTelemetrySourceWpa::trace_ap(void) const
|
||||
{
|
||||
return (m_interface->operational_mode == WifiOperationalMode::AccessPoint);
|
||||
}
|
||||
|
||||
bool
|
||||
WifiTelemetrySourceWpa::trace_dpp_enrollee(void) const
|
||||
{
|
||||
// right now, assume all enrollees are wifi stations.
|
||||
return trace_station();
|
||||
}
|
||||
|
||||
bool
|
||||
WifiTelemetrySourceWpa::trace_dpp_configurator(void) const
|
||||
{
|
||||
// right now, assume all configurators are wifi access points.
|
||||
return trace_ap();
|
||||
}
|
||||
|
||||
bool
|
||||
WifiTelemetrySourceWpa::trace_dpp(void) const
|
||||
{
|
||||
return trace_dpp_enrollee() || trace_dpp_configurator();
|
||||
}
|
||||
|
||||
bool
|
||||
WifiTelemetrySourceWpa::is_dpp_exchange_in_progress(void) const
|
||||
{
|
||||
return (m_dpp_exchange != nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::on_disconnected(const WpaEventArgs<WpaEventDisconnected>& args)
|
||||
{
|
||||
if (!trace_station())
|
||||
return;
|
||||
|
||||
const auto& event = args.data();
|
||||
std::string bssid = wifi_80211_mac_to_string(event.bssid);
|
||||
|
||||
trace_station_connection_drop(
|
||||
m_interface->name.c_str(),
|
||||
bssid.c_str(),
|
||||
uint16_t(event.reason_code),
|
||||
event.locally_generated);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::complete_connection_attempt(const WifiTelemetryInputStationConnectionAttempt& input)
|
||||
{
|
||||
trace_station_connection_attempt(m_interface->name.c_str(), &input);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::on_connected(const WpaEventArgs<WpaEventConnected>& args)
|
||||
{
|
||||
if (!trace_station())
|
||||
return;
|
||||
|
||||
const auto& event = args.data();
|
||||
|
||||
struct WpaCommandSignalPoll signal_poll{};
|
||||
auto response_signal_poll = m_controller->send_command<WpaCommandSignalPollResponse>(signal_poll);
|
||||
if (!response_signal_poll) {
|
||||
std::cerr << "unable to obtain signal poll data" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
struct WpaCommandStatus command_status{};
|
||||
auto response_status = m_controller->send_command<WpaCommandStatusResponse>(command_status);
|
||||
if (!response_status) {
|
||||
std::cerr << "unable to obtain interface status data" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
auto connection_attempt_data = WifiTelemetryInputStationConnectionAttempt::succeeded(
|
||||
event.bssid,
|
||||
response_signal_poll,
|
||||
response_status);
|
||||
|
||||
complete_connection_attempt(connection_attempt_data);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::on_association_rejected(const WpaEventArgs<WpaEventAssociationRejected>& args)
|
||||
{
|
||||
if (!trace_station())
|
||||
return;
|
||||
|
||||
const auto& event = args.data();
|
||||
auto connection_attempt_data = WifiTelemetryInputStationConnectionAttempt::association_rejected(
|
||||
event.bssid,
|
||||
event.status_code);
|
||||
|
||||
complete_connection_attempt(connection_attempt_data);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::on_authentication_rejected(const WpaEventArgs<WpaEventAuthenticationRejected>& args)
|
||||
{
|
||||
if (!trace_station())
|
||||
return;
|
||||
|
||||
const auto& event = args.data();
|
||||
auto connection_attempt_data = WifiTelemetryInputStationConnectionAttempt::authentication_rejected(
|
||||
event.bssid,
|
||||
event.status_code,
|
||||
event.authentication_type);
|
||||
|
||||
complete_connection_attempt(connection_attempt_data);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::on_network_not_found(const WpaEventArgs<WpaEventNetworkNotFound>& /* args */)
|
||||
{
|
||||
if (!trace_station())
|
||||
return;
|
||||
|
||||
auto connection_attempt_data = WifiTelemetryInputStationConnectionAttempt::network_not_found();
|
||||
complete_connection_attempt(connection_attempt_data);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::complete_dpp_exchange_enrollee(std::shared_ptr<WifiDppExchangeEnrollee>& enrollee)
|
||||
{
|
||||
enrollee->stop();
|
||||
|
||||
std::vector<uint32_t> chirp_frequencies(enrollee->chirp_frequencies.begin(), enrollee->chirp_frequencies.end());
|
||||
uint64_t duration_milliseconds = enrollee->duration.has_value()
|
||||
? static_cast<uint64_t>(enrollee->duration->count())
|
||||
: 0;
|
||||
|
||||
trace_dpp_exchange_enrollee(
|
||||
m_interface->name.c_str(),
|
||||
WifiDppRoleToString(enrollee->role),
|
||||
WifiDppExchangeEnrolleeStateToString(enrollee->state),
|
||||
duration_milliseconds,
|
||||
chirp_frequencies.size(),
|
||||
chirp_frequencies.data(),
|
||||
WifiDppFailureTypeToString(enrollee->failure_type),
|
||||
enrollee->failure_details.value_or("").c_str());
|
||||
|
||||
m_dpp_exchange.reset();
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::complete_dpp_exchange_configurator(std::shared_ptr<WifiDppExchangeConfigurator>& configurator)
|
||||
{
|
||||
configurator->stop();
|
||||
|
||||
std::string bssid = wifi_80211_mac_to_string(configurator->peer_bssid);
|
||||
uint64_t duration_milliseconds = configurator->duration.has_value()
|
||||
? static_cast<uint64_t>(configurator->duration->count())
|
||||
: 0;
|
||||
|
||||
trace_dpp_exchange_configurator(
|
||||
m_interface->name.c_str(),
|
||||
WifiDppRoleToString(configurator->role),
|
||||
WifiDppExchangeConfiguratorStateToString(configurator->state),
|
||||
duration_milliseconds,
|
||||
bssid.c_str(),
|
||||
configurator->frequency,
|
||||
WifiDppFailureTypeToString(configurator->failure_type),
|
||||
configurator->failure_details.value_or("").c_str());
|
||||
|
||||
m_dpp_exchange.reset();
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::on_dpp_chirp_received(const WpaEventArgs<WpaEventDppChirpReceived>& args)
|
||||
{
|
||||
if (!trace_dpp_configurator())
|
||||
return;
|
||||
|
||||
const auto& event = args.data();
|
||||
|
||||
// configurator doesn't know about this device yet (id == -1), or another exchange in progress.
|
||||
if (event.id == -1 || is_dpp_exchange_in_progress())
|
||||
return;
|
||||
|
||||
m_dpp_exchange = std::make_shared<WifiDppExchangeConfigurator>(event.id, event.bssid, event.frequency, WifiDppRole::Initiator);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::on_dpp_authentication_init_failure(const WpaEventArgs<WpaEventDppAuthenticationInitFailure>& args)
|
||||
{
|
||||
if (!trace_dpp() || !is_dpp_exchange_in_progress())
|
||||
return;
|
||||
|
||||
const auto& event = args.data();
|
||||
m_dpp_exchange->failure_type = event.failure_type;
|
||||
m_dpp_exchange->failure_details = event.failure_details;
|
||||
|
||||
switch (m_dpp_exchange->device_role) {
|
||||
case WifiDppDeviceRole::Enrollee: {
|
||||
auto enrollee = resolve_dpp_exchange<WifiDppExchangeEnrollee>();
|
||||
enrollee->state = WifiDppExchangeEnrolleeState::Terminated;
|
||||
complete_dpp_exchange_enrollee(enrollee);
|
||||
break;
|
||||
}
|
||||
case WifiDppDeviceRole::Configurator: {
|
||||
auto configurator = resolve_dpp_exchange<WifiDppExchangeConfigurator>();
|
||||
configurator->state = WifiDppExchangeConfiguratorState::Terminated;
|
||||
complete_dpp_exchange_configurator(configurator);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::on_dpp_authentication_succeeded(const WpaEventArgs<WpaEventDppAuthenticationSucceeded>& /* args */)
|
||||
{
|
||||
if (!trace_dpp() || !is_dpp_exchange_in_progress())
|
||||
return;
|
||||
|
||||
switch (m_dpp_exchange->device_role) {
|
||||
case WifiDppDeviceRole::Enrollee: {
|
||||
auto enrollee = resolve_dpp_exchange<WifiDppExchangeEnrollee>();
|
||||
enrollee->state = WifiDppExchangeEnrolleeState::Authenticated;
|
||||
break;
|
||||
}
|
||||
case WifiDppDeviceRole::Configurator: {
|
||||
auto configurator = resolve_dpp_exchange<WifiDppExchangeConfigurator>();
|
||||
configurator->state = WifiDppExchangeConfiguratorState::Authenticated;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::on_dpp_configuration_received(const WpaEventArgs<WpaEventDppConfigurationReceived>& /* args */)
|
||||
{
|
||||
if (!trace_dpp_enrollee() || !is_dpp_exchange_in_progress())
|
||||
return;
|
||||
|
||||
if (m_dpp_exchange->device_role != WifiDppDeviceRole::Enrollee)
|
||||
return;
|
||||
|
||||
auto enrollee = resolve_dpp_exchange<WifiDppExchangeEnrollee>();
|
||||
enrollee->state = WifiDppExchangeEnrolleeState::Provisioned;
|
||||
complete_dpp_exchange_enrollee(enrollee);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::on_dpp_configuration_sent(const WpaEventArgs<WpaEventDppConfigurationSent>& /* args */)
|
||||
{
|
||||
if (!trace_dpp_configurator() || !is_dpp_exchange_in_progress())
|
||||
return;
|
||||
|
||||
if (m_dpp_exchange->device_role != WifiDppDeviceRole::Configurator)
|
||||
return;
|
||||
|
||||
auto configurator = resolve_dpp_exchange<WifiDppExchangeConfigurator>();
|
||||
configurator->state = WifiDppExchangeConfiguratorState::Finished;
|
||||
complete_dpp_exchange_configurator(configurator);
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::on_dpp_failure(const WpaEventArgs<WpaEventDppFailure>& args)
|
||||
{
|
||||
if (!trace_dpp() || !is_dpp_exchange_in_progress())
|
||||
return;
|
||||
|
||||
const auto& event = args.data();
|
||||
m_dpp_exchange->failure_type = event.failure_type;
|
||||
m_dpp_exchange->failure_details = event.failure_details;
|
||||
|
||||
switch (m_dpp_exchange->device_role) {
|
||||
case WifiDppDeviceRole::Enrollee: {
|
||||
auto enrollee = resolve_dpp_exchange<WifiDppExchangeEnrollee>();
|
||||
enrollee->state = WifiDppExchangeEnrolleeState::Terminated;
|
||||
complete_dpp_exchange_enrollee(enrollee);
|
||||
break;
|
||||
}
|
||||
case WifiDppDeviceRole::Configurator: {
|
||||
auto configurator = resolve_dpp_exchange<WifiDppExchangeConfigurator>();
|
||||
configurator->state = WifiDppExchangeConfiguratorState::Terminated;
|
||||
complete_dpp_exchange_configurator(configurator);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceWpa::on_dpp_frame_transmit_status(const WpaEventArgs<WpaEventDppFrameTransmitStatus>& args)
|
||||
{
|
||||
if (!trace_dpp_enrollee())
|
||||
return;
|
||||
|
||||
const auto& event = args.data();
|
||||
bool is_success = (event.status == "SUCCESS");
|
||||
bool is_broadcast = is_wifi80211_broadcast_address(event.destination_bssid);
|
||||
|
||||
if (is_broadcast) { // this indicates a chirp
|
||||
if (!is_dpp_exchange_in_progress())
|
||||
m_dpp_exchange = std::make_shared<WifiDppExchangeEnrollee>(WifiDppRole::Responder);
|
||||
|
||||
auto enrollee = resolve_dpp_exchange<WifiDppExchangeEnrollee>();
|
||||
if (is_success)
|
||||
enrollee->chirp_frequencies.insert(event.frequency);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
#include <numeric>
|
||||
|
||||
#include "wifi-telemetry/wifi_telemetry_source_ztpd.hpp"
|
||||
#include "wifi_telemetry_trace_dpp.hpp"
|
||||
|
||||
#define ZTP_DBUS_INTERFACE "com.microsoft.ztp1"
|
||||
#define ZTP_DBUS_PATH "/com/microsoft/ztp1"
|
||||
|
||||
WifiTelemetrySourceZtpd::WifiTelemetrySourceZtpd(const std::optional<WifiInterfaceConfiguration>& interface) :
|
||||
WifiTelemetrySource(interface, "ztpd"),
|
||||
ProxyInterfaces(ZTP_DBUS_INTERFACE, ZTP_DBUS_PATH)
|
||||
{}
|
||||
|
||||
WifiTelemetrySourceZtpd::~WifiTelemetrySourceZtpd(void)
|
||||
{}
|
||||
|
||||
int
|
||||
WifiTelemetrySourceZtpd::activate(const std::shared_ptr<WifiTelemetrySourceActivationArgs> /* args */)
|
||||
{
|
||||
registerProxy();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceZtpd::deactivate(void)
|
||||
{
|
||||
unregisterProxy();
|
||||
}
|
||||
|
||||
void
|
||||
WifiTelemetrySourceZtpd::onPropertiesChanged(const std::string& interfaceName, const std::map<std::string, sdbus::Variant>& changedProperties, const std::vector<std::string>& /* invalidatedProperties */)
|
||||
{
|
||||
if (interfaceName != ZTP_DBUS_INTERFACE)
|
||||
return;
|
||||
|
||||
const auto roles_it = changedProperties.find("Roles");
|
||||
if (roles_it == changedProperties.end())
|
||||
return;
|
||||
|
||||
std::string roles{};
|
||||
const auto roles_changed = roles_it->second.get<std::vector<std::string>>();
|
||||
|
||||
if (!roles_changed.empty()) {
|
||||
roles = std::accumulate(
|
||||
/* start */ std::next(std::begin(roles_changed)),
|
||||
/* end */ std::end(roles_changed),
|
||||
/* init */ roles_changed.front(),
|
||||
/* op */ [](std::string current, const std::string& next)
|
||||
{
|
||||
return std::move(current) + ',' + next;
|
||||
});
|
||||
}
|
||||
|
||||
trace_dpp_device_roles_changed(roles.c_str());
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
|
||||
target_sources(wifi-telemetry
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wifi_telemetry_input_station_connection_attempt.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_command.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_command_bss.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_command_key_value_pair.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_command_response.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_command_response_parser.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_command_signal_poll.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_command_status.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_controller.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_association_rejected.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_authentication_rejected.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_connected.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_disconnected.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_dpp_auth_init_failure.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_dpp_auth_success.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_dpp_chirp_received.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_dpp_conf_received.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_dpp_conf_sent.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_dpp_failure.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_dpp_frame_transmit_status.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_handler.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_network_not_found.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_event_parser.cxx
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/wpa_state.cxx
|
||||
)
|
||||
|
||||
target_include_directories(wifi-telemetry
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
)
|
||||
|
||||
target_link_libraries(wifi-telemetry
|
||||
PRIVATE
|
||||
Threads::Threads
|
||||
)
|
|
@ -0,0 +1,187 @@
|
|||
|
||||
#include <limits>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211_format_mac.hpp"
|
||||
#include "wifi-telemetry/wpa/wifi_telemetry_input_station_connection_attempt.hpp"
|
||||
|
||||
WifiTelemetryInputStationConnectionAttempt::WifiTelemetryInputStationConnectionAttempt(
|
||||
const WifiConnectionAttemptResult result,
|
||||
const std::optional<wifi_80211_mac> bssid,
|
||||
const std::shared_ptr<WpaCommandSignalPollResponse> signal_poll,
|
||||
const std::shared_ptr<WpaCommandStatusResponse> status,
|
||||
const WifiStatusCode status_code,
|
||||
const WifiAuthenticationType authentication_type) :
|
||||
m_result(result),
|
||||
m_bssid(wifi_80211_mac_to_string(bssid.value_or(wifi_80211_any_address))),
|
||||
m_signal_poll(signal_poll ? signal_poll : std::make_shared<WpaCommandSignalPollResponse>(0, 0, 0, 0)),
|
||||
m_status(status ? status : std::make_shared<WpaCommandStatusResponse>()),
|
||||
m_status_code(status_code),
|
||||
m_authentication_type(WifiAuthenticationTypeToString(authentication_type))
|
||||
{
|
||||
// sanitize all fields used for telemetry event(s) to defaults
|
||||
|
||||
if (!m_status->wifi_generation)
|
||||
m_status->wifi_generation = 0;
|
||||
|
||||
if (!m_status->key_mgmt)
|
||||
m_status->key_mgmt = "";
|
||||
|
||||
if (!m_status->pairwise_cipher)
|
||||
m_status->pairwise_cipher = "";
|
||||
|
||||
if (!m_status->group_cipher)
|
||||
m_status->group_cipher = "";
|
||||
|
||||
if (!m_status->ssid)
|
||||
m_status->ssid = "";
|
||||
}
|
||||
|
||||
WifiTelemetryInputStationConnectionAttempt
|
||||
WifiTelemetryInputStationConnectionAttempt::unspecified(void)
|
||||
{
|
||||
return {
|
||||
WifiConnectionAttemptResult::Unspecified,
|
||||
std::nullopt,
|
||||
nullptr,
|
||||
nullptr,
|
||||
WifiStatusCode::Success,
|
||||
WifiAuthenticationType::Unknown
|
||||
};
|
||||
}
|
||||
|
||||
WifiTelemetryInputStationConnectionAttempt
|
||||
WifiTelemetryInputStationConnectionAttempt::succeeded(const wifi_80211_mac& bssid, const std::shared_ptr<WpaCommandSignalPollResponse> signal_poll, const std::shared_ptr<WpaCommandStatusResponse> status)
|
||||
{
|
||||
return {
|
||||
WifiConnectionAttemptResult::Succeeded,
|
||||
bssid,
|
||||
signal_poll,
|
||||
status,
|
||||
WifiStatusCode::Success,
|
||||
WifiAuthenticationType::Unknown
|
||||
};
|
||||
}
|
||||
|
||||
WifiTelemetryInputStationConnectionAttempt
|
||||
WifiTelemetryInputStationConnectionAttempt::association_rejected(const std::optional<wifi_80211_mac>& bssid, const WifiStatusCode status_code)
|
||||
{
|
||||
return {
|
||||
WifiConnectionAttemptResult::AssociationRejected,
|
||||
bssid,
|
||||
nullptr,
|
||||
nullptr,
|
||||
status_code,
|
||||
WifiAuthenticationType::Unknown
|
||||
};
|
||||
}
|
||||
|
||||
WifiTelemetryInputStationConnectionAttempt
|
||||
WifiTelemetryInputStationConnectionAttempt::authentication_rejected(const wifi_80211_mac& /* bssid */, const WifiStatusCode status_code, const WifiAuthenticationType authentication_type)
|
||||
{
|
||||
return {
|
||||
WifiConnectionAttemptResult::AuthenticationRejected,
|
||||
std::nullopt,
|
||||
nullptr,
|
||||
nullptr,
|
||||
status_code,
|
||||
authentication_type
|
||||
};
|
||||
}
|
||||
|
||||
WifiTelemetryInputStationConnectionAttempt
|
||||
WifiTelemetryInputStationConnectionAttempt::network_not_found(void)
|
||||
{
|
||||
return {
|
||||
WifiConnectionAttemptResult::NetworkNotFound,
|
||||
std::nullopt,
|
||||
nullptr,
|
||||
nullptr,
|
||||
WifiStatusCode::Success,
|
||||
WifiAuthenticationType::Unknown
|
||||
};
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WifiTelemetryInputStationConnectionAttempt::result(void) const
|
||||
{
|
||||
return uint32_t(m_result);
|
||||
}
|
||||
|
||||
const char*
|
||||
WifiTelemetryInputStationConnectionAttempt::bssid(void) const
|
||||
{
|
||||
return m_bssid.c_str();
|
||||
}
|
||||
|
||||
const char*
|
||||
WifiTelemetryInputStationConnectionAttempt::ssid(void) const
|
||||
{
|
||||
return m_status->ssid.value().c_str();
|
||||
}
|
||||
|
||||
int32_t
|
||||
WifiTelemetryInputStationConnectionAttempt::noise(void) const
|
||||
{
|
||||
return m_signal_poll->noise;
|
||||
}
|
||||
|
||||
int32_t
|
||||
WifiTelemetryInputStationConnectionAttempt::rssi(void) const
|
||||
{
|
||||
return m_signal_poll->rssi;
|
||||
}
|
||||
|
||||
int32_t
|
||||
WifiTelemetryInputStationConnectionAttempt::link_speed(void) const
|
||||
{
|
||||
return m_signal_poll->link_speed;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WifiTelemetryInputStationConnectionAttempt::frequency(void) const
|
||||
{
|
||||
return m_signal_poll->frequency;
|
||||
}
|
||||
|
||||
uint32_t
|
||||
WifiTelemetryInputStationConnectionAttempt::wifi_generation(void) const
|
||||
{
|
||||
return m_status->wifi_generation.value();
|
||||
}
|
||||
|
||||
const char*
|
||||
WifiTelemetryInputStationConnectionAttempt::key_mgmt(void) const
|
||||
{
|
||||
return m_status->key_mgmt.value().c_str();
|
||||
}
|
||||
|
||||
const char*
|
||||
WifiTelemetryInputStationConnectionAttempt::pairwise_cipher(void) const
|
||||
{
|
||||
return m_status->pairwise_cipher.value().c_str();
|
||||
}
|
||||
|
||||
const char*
|
||||
WifiTelemetryInputStationConnectionAttempt::group_cipher(void) const
|
||||
{
|
||||
return m_status->group_cipher.value().c_str();
|
||||
}
|
||||
|
||||
uint16_t
|
||||
WifiTelemetryInputStationConnectionAttempt::status_code(void) const
|
||||
{
|
||||
switch (m_result) {
|
||||
case WifiConnectionAttemptResult::Succeeded:
|
||||
case WifiConnectionAttemptResult::AssociationRejected:
|
||||
case WifiConnectionAttemptResult::AuthenticationRejected:
|
||||
return uint16_t(m_status_code);
|
||||
default:
|
||||
return std::numeric_limits<uint16_t>::max();
|
||||
}
|
||||
}
|
||||
|
||||
const char*
|
||||
WifiTelemetryInputStationConnectionAttempt::authentication_type(void) const
|
||||
{
|
||||
return m_authentication_type.c_str();
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_command.hpp"
|
||||
|
||||
WpaCommand::WpaCommand(const std::string& name_) :
|
||||
name(name_)
|
||||
{}
|
||||
|
||||
std::shared_ptr<WpaCommandResponse>
|
||||
WpaCommand::parse_response(const std::string_view payload) const
|
||||
{
|
||||
std::unique_ptr<WpaCommandResponseParser> parser = create_response_parser(payload);
|
||||
return parser->parse();
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
|
||||
#include <sstream>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211_format_mac.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command_bss.hpp"
|
||||
|
||||
static constexpr char this_command_name[] = "BSS";
|
||||
|
||||
WpaCommandBss::WpaCommandBss(std::string bssid_) :
|
||||
WpaCommand(this_command_name),
|
||||
bssid(bssid_)
|
||||
{
|
||||
std::stringstream ss(name);
|
||||
ss << " " << bssid;
|
||||
data = ss.str();
|
||||
}
|
||||
|
||||
std::unique_ptr<WpaCommandResponseParser>
|
||||
WpaCommandBss::create_response_parser(const std::string_view payload) const
|
||||
{
|
||||
return std::make_unique<WpaCommandBssResponseParser>(payload);
|
||||
}
|
||||
|
||||
WpaCommandBssResponseParser::WpaCommandBssResponseParser(const std::string_view payload_) :
|
||||
WpaCommandResponseParser(this_command_name, payload_, {
|
||||
{ "id=", WpaValueRequired },
|
||||
{ "bssid=", WpaValueRequired },
|
||||
{ "freq=", WpaValueRequired },
|
||||
{ "beacon_int=", WpaValueRequired },
|
||||
{ "capabilities=", WpaValueRequired },
|
||||
{ "qual=", WpaValueRequired },
|
||||
{ "noise=", WpaValueRequired },
|
||||
{ "level=", WpaValueRequired },
|
||||
{ "tsf=", WpaValueRequired },
|
||||
{ "age=", WpaValueRequired },
|
||||
{ "ie=", WpaValueRequired },
|
||||
{ "flags=", WpaValueRequired },
|
||||
{ "ssid=", WpaValueRequired },
|
||||
{ "snr=", WpaValueRequired },
|
||||
{ "est_throughput=", WpaValueRequired },
|
||||
{ "update_idx=", WpaValueRequired },
|
||||
{ "beacon_ie=", WpaValueRequired },
|
||||
})
|
||||
{}
|
||||
|
||||
std::shared_ptr<WpaCommandResponse>
|
||||
WpaCommandBssResponseParser::parse_payload(void) const
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
WpaCommandBss::WpaCommandBss(const wifi_80211_mac& bssid_) :
|
||||
WpaCommandBss(wifi_80211_mac_to_string(bssid_))
|
||||
{}
|
||||
|
||||
WpaCommandBssResponse::WpaCommandBssResponse()
|
||||
{}
|
|
@ -0,0 +1,31 @@
|
|||
|
||||
#include <string.h>
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_command_key_value_pair.hpp"
|
||||
|
||||
WpaCommandKeyValuePair::WpaCommandKeyValuePair(const char* key_, bool is_required_ = WpaValueOptional) :
|
||||
key(key_),
|
||||
key_length(strlen(key)),
|
||||
value(std::nullopt),
|
||||
is_required(is_required_)
|
||||
{}
|
||||
|
||||
const char*
|
||||
WpaCommandKeyValuePair::operator()(void) const
|
||||
{
|
||||
return value.value();
|
||||
}
|
||||
|
||||
bool
|
||||
WpaCommandKeyValuePair::resolve(const std::string_view input)
|
||||
{
|
||||
value_pos = input.find(key);
|
||||
|
||||
if (value_pos != input.npos) {
|
||||
value_pos += key_length;
|
||||
value = input.data() + value_pos;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
|
||||
#include "wifi-telemetry/wpa/wpa_command_response.hpp"
|
||||
|
||||
WpaCommandResponseGeneric::WpaCommandResponseGeneric(const std::string payload_) :
|
||||
payload(payload_)
|
||||
{}
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
#include <iostream>
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_command_response_parser.hpp"
|
||||
|
||||
WpaCommandResponseParser::WpaCommandResponseParser(const std::string& command_name_, const std::string_view payload_, const std::initializer_list<WpaCommandKeyValuePair> properties_) :
|
||||
command_name(command_name_),
|
||||
payload(payload_),
|
||||
properties(properties_)
|
||||
{}
|
||||
|
||||
std::shared_ptr<WpaCommandResponse>
|
||||
WpaCommandResponseParser::parse(void)
|
||||
{
|
||||
return resolve_properties()
|
||||
? parse_payload()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
bool
|
||||
WpaCommandResponseParser::resolve_properties(void)
|
||||
{
|
||||
if (properties_resolved_result.has_value())
|
||||
return properties_resolved_result.value();
|
||||
|
||||
for (auto& property : properties) {
|
||||
if (!property.resolve(payload) && property.is_required) {
|
||||
std::cerr << "invalid " << command_name << " response (" << property.key << " not found)" << std::endl;
|
||||
properties_resolved_result = false;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
properties_resolved_result = true;
|
||||
return true;
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_command_signal_poll.hpp"
|
||||
|
||||
static constexpr char this_command_name[] = "SIGNAL_POLL";
|
||||
|
||||
WpaCommandSignalPoll::WpaCommandSignalPoll(void) :
|
||||
WpaCommand(this_command_name)
|
||||
{
|
||||
data = name;
|
||||
}
|
||||
|
||||
std::unique_ptr<WpaCommandResponseParser>
|
||||
WpaCommandSignalPoll::create_response_parser(const std::string_view payload) const
|
||||
{
|
||||
return std::make_unique<WpaCommandSignalPollResponseParser>(payload);
|
||||
}
|
||||
|
||||
WpaCommandSignalPollResponseParser::WpaCommandSignalPollResponseParser(const std::string_view payload_) :
|
||||
WpaCommandResponseParser(this_command_name, payload_, {
|
||||
{ "RSSI=", WpaValueRequired },
|
||||
{ "NOISE=", WpaValueRequired },
|
||||
{ "LINKSPEED=", WpaValueRequired },
|
||||
{ "FREQUENCY=", WpaValueRequired },
|
||||
{ "CENTER_FRQ1=", WpaValueOptional },
|
||||
{ "CENTER_FRQ2=", WpaValueOptional },
|
||||
{ "WIDTH=", WpaValueOptional },
|
||||
{ "AVG_RSSI=", WpaValueOptional },
|
||||
{ "AVG_BEACON_RSSI=", WpaValueOptional },
|
||||
})
|
||||
{}
|
||||
|
||||
std::shared_ptr<WpaCommandResponse>
|
||||
WpaCommandSignalPollResponseParser::parse_payload() const
|
||||
{
|
||||
int32_t rssi = static_cast<int32_t>(strtol(properties[0](), nullptr, 10));
|
||||
int32_t noise = static_cast<int32_t>(strtol(properties[1](), nullptr, 10));
|
||||
int32_t link_speed = static_cast<int32_t>(strtol(properties[2](), nullptr, 10));
|
||||
uint32_t frequency = static_cast<uint32_t>(strtoul(properties[3](), nullptr, 10));
|
||||
|
||||
std::shared_ptr<WpaCommandSignalPollResponse> response = std::make_shared<WpaCommandSignalPollResponse>(noise, rssi, link_speed, frequency);
|
||||
|
||||
if (properties[4].value)
|
||||
response->center_frequency_1 = static_cast<int32_t>(strtol(properties[4](), nullptr, 10));
|
||||
if (properties[5].value)
|
||||
response->center_frequency_2 = static_cast<int32_t>(strtol(properties[5](), nullptr, 10));
|
||||
if (properties[6].value) {
|
||||
std::size_t value_pos = properties[6].value_pos;
|
||||
std::size_t value_pos_end = payload.find_first_of('\n', value_pos);
|
||||
if (value_pos_end != payload.npos)
|
||||
response->channel_width = payload.substr(value_pos, value_pos_end - value_pos);
|
||||
}
|
||||
if (properties[7].value)
|
||||
response->rssi_average = static_cast<int32_t>(strtol(properties[7](), nullptr, 10));
|
||||
if (properties[8].value)
|
||||
response->rssi_average_beacon = static_cast<int32_t>(strtol(properties[8](), nullptr, 10));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
WpaCommandSignalPollResponse::WpaCommandSignalPollResponse(int32_t noise_, int32_t rssi_, int32_t link_speed_, uint32_t frequency_) :
|
||||
noise(noise_),
|
||||
rssi(rssi_),
|
||||
link_speed(link_speed_),
|
||||
frequency(frequency_)
|
||||
{}
|
|
@ -0,0 +1,83 @@
|
|||
|
||||
#include <algorithm>
|
||||
|
||||
#include "wifi-telemetry/wifi/wifi_80211_format_mac.hpp"
|
||||
#include "wifi-telemetry/wpa/wpa_command_status.hpp"
|
||||
|
||||
static constexpr char this_command_name[] = "STATUS";
|
||||
|
||||
WpaCommandStatus::WpaCommandStatus(void) :
|
||||
WpaCommand(this_command_name)
|
||||
{
|
||||
data = name;
|
||||
}
|
||||
|
||||
std::unique_ptr<WpaCommandResponseParser>
|
||||
WpaCommandStatus::create_response_parser(const std::string_view payload) const
|
||||
{
|
||||
return std::make_unique<WpaCommandStatusResponseParser>(payload);
|
||||
}
|
||||
|
||||
WpaCommandStatusResponseParser::WpaCommandStatusResponseParser(const std::string_view payload_) :
|
||||
WpaCommandResponseParser(this_command_name, payload_, {
|
||||
{ "wpa_state=", WpaValueRequired },
|
||||
{ "ssid=", WpaValueOptional },
|
||||
{ "bssid=", WpaValueOptional },
|
||||
{ "pairwise_cipher=", WpaValueOptional },
|
||||
{ "group_cipher=", WpaValueOptional },
|
||||
{ "key_mgmt=", WpaValueOptional },
|
||||
{ "wifi_generation=", WpaValueOptional },
|
||||
{ "freq=", WpaValueOptional },
|
||||
})
|
||||
{}
|
||||
|
||||
std::shared_ptr<WpaCommandResponse>
|
||||
WpaCommandStatusResponseParser::parse_payload(void) const
|
||||
{
|
||||
std::string state = properties[0]();
|
||||
state.erase(state.find_first_of('\n'));
|
||||
|
||||
auto response = std::make_shared<WpaCommandStatusResponse>(wpa_state_from_string(state.c_str()));
|
||||
|
||||
if (properties[1].value) {
|
||||
std::string ssid = properties[1]();
|
||||
ssid.erase(ssid.find_first_of('\n'));
|
||||
response->ssid = std::move(ssid);
|
||||
}
|
||||
|
||||
if (properties[2].value) {
|
||||
std::string bssid = properties[2]();
|
||||
bssid.erase(bssid.find_first_of('\n'));
|
||||
response->bssid = wifi_80211_mac_from_string(bssid);
|
||||
}
|
||||
|
||||
if (properties[3].value) {
|
||||
std::string pairwise_cipher = properties[3]();
|
||||
pairwise_cipher.erase(pairwise_cipher.find_first_of('\n'));
|
||||
response->pairwise_cipher = std::move(pairwise_cipher);
|
||||
}
|
||||
|
||||
if (properties[4].value) {
|
||||
std::string group_cipher = properties[4]();
|
||||
group_cipher.erase(group_cipher.find_first_of('\n'));
|
||||
response->group_cipher = std::move(group_cipher);
|
||||
}
|
||||
|
||||
if (properties[5].value) {
|
||||
std::string key_mgmt = properties[5]();
|
||||
key_mgmt.erase(key_mgmt.find_first_of('\n'));
|
||||
response->key_mgmt = std::move(key_mgmt);
|
||||
}
|
||||
|
||||
if (properties[6].value)
|
||||
response->wifi_generation = static_cast<uint32_t>(strtoul(properties[6](), nullptr, 10));
|
||||
|
||||
if (properties[7].value)
|
||||
response->frequency = static_cast<uint32_t>(strtoul(properties[7](), nullptr, 10));
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
WpaCommandStatusResponse::WpaCommandStatusResponse(WpaState state_) :
|
||||
state(state_)
|
||||
{}
|
|
@ -0,0 +1,312 @@
|
|||
|
||||
#include <array>
|
||||
#include <cerrno>
|
||||
#include <filesystem>
|
||||
#include <iostream>
|
||||
#include <sys/epoll.h>
|
||||
#include <sys/eventfd.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_controller.hpp"
|
||||
#include "wpa_event_parser.hpp"
|
||||
|
||||
WpaController::WpaController(const std::string_view interface, WpaType type) :
|
||||
WpaController(interface, type, WpaController::default_control_socket_path(type))
|
||||
{
|
||||
}
|
||||
|
||||
WpaController::WpaController(const std::string_view interface, WpaType type, const std::string_view control_socket_path) :
|
||||
m_type(type),
|
||||
m_interface(interface),
|
||||
m_ctrl_socket_path(control_socket_path)
|
||||
{
|
||||
m_ctrl_event_thread = std::thread([this](void)
|
||||
{
|
||||
process_wpa_events();
|
||||
});
|
||||
}
|
||||
|
||||
WpaController::~WpaController(void)
|
||||
{
|
||||
m_terminate_pending = true;
|
||||
|
||||
if (m_ctrl_event_fd_stop != -1) {
|
||||
uint64_t value = 1;
|
||||
ssize_t num_written = write(m_ctrl_event_fd_stop, &value, sizeof value);
|
||||
if (num_written != sizeof value) {
|
||||
int ret = (num_written < 0) ? errno : -ERANGE;
|
||||
std::cerr << "failed to write exit signal descriptor value (" << ret << ")" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
auto lock_exclusive = std::scoped_lock(m_ctrl_command_gate);
|
||||
if (m_ctrl_command) {
|
||||
wpa_ctrl_close(m_ctrl_command);
|
||||
m_ctrl_command = nullptr;
|
||||
}
|
||||
|
||||
m_ctrl_event_thread.join();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Process a pending wpa event.
|
||||
*/
|
||||
void
|
||||
WpaController::process_wpa_event_next(void)
|
||||
{
|
||||
auto timestamp = std::chrono::system_clock::now();
|
||||
char buffer[WpaController::c_wpa_event_size_max];
|
||||
size_t buffer_length = sizeof buffer - 1;
|
||||
|
||||
int ret = wpa_ctrl_recv(m_ctrl_event, buffer, &buffer_length);
|
||||
if (ret < 0) {
|
||||
std::cerr << "failed to receive message from wpa control socket" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
buffer[buffer_length] = '\0';
|
||||
|
||||
std::shared_ptr<WpaEvent> event = WpaEventParser::parse(buffer);
|
||||
if (!event)
|
||||
return;
|
||||
|
||||
// Make a copy of the event subscribers to minimize the time holding the
|
||||
// lock. This is safe since the validity of each subscriber will later be
|
||||
// attempted to be promoted to a full shared_ptr prior to using it.
|
||||
decltype(m_event_subscribers) event_subscribers;
|
||||
{
|
||||
auto lock = std::scoped_lock(m_event_subscribers_gate);
|
||||
event_subscribers = m_event_subscribers;
|
||||
}
|
||||
|
||||
for (const auto& [token, handler_weak] : event_subscribers) {
|
||||
std::shared_ptr<WpaEventHandler> handler = handler_weak.lock();
|
||||
if (!handler)
|
||||
continue;
|
||||
|
||||
switch (event->type) {
|
||||
case WpaEventType::Connected:
|
||||
handler->on_connected({ timestamp, std::dynamic_pointer_cast<WpaEventConnected>(event) });
|
||||
break;
|
||||
case WpaEventType::Disconnected:
|
||||
handler->on_disconnected({ timestamp, std::dynamic_pointer_cast<WpaEventDisconnected>(event) });
|
||||
break;
|
||||
case WpaEventType::AssociationRejected:
|
||||
handler->on_association_rejected({ timestamp, std::dynamic_pointer_cast<WpaEventAssociationRejected>(event) });
|
||||
break;
|
||||
case WpaEventType::AuthenticationRejected:
|
||||
handler->on_authentication_rejected({ timestamp, std::dynamic_pointer_cast<WpaEventAuthenticationRejected>(event) });
|
||||
break;
|
||||
case WpaEventType::NetworkNotFound:
|
||||
handler->on_network_not_found({ timestamp, std::dynamic_pointer_cast<WpaEventNetworkNotFound>(event) });
|
||||
break;
|
||||
case WpaEventType::DppAuthenticationInitFailure:
|
||||
handler->on_dpp_authentication_init_failure({ timestamp, std::dynamic_pointer_cast<WpaEventDppAuthenticationInitFailure>(event) });
|
||||
break;
|
||||
case WpaEventType::DppAuthenticationSucceeded:
|
||||
handler->on_dpp_authentication_succeeded({ timestamp, std::dynamic_pointer_cast<WpaEventDppAuthenticationSucceeded>(event) });
|
||||
break;
|
||||
case WpaEventType::DppConfigurationReceived:
|
||||
handler->on_dpp_configuration_received({ timestamp, std::dynamic_pointer_cast<WpaEventDppConfigurationReceived>(event) });
|
||||
break;
|
||||
case WpaEventType::DppConfigurationSent:
|
||||
handler->on_dpp_configuration_sent({ timestamp, std::dynamic_pointer_cast<WpaEventDppConfigurationSent>(event) });
|
||||
break;
|
||||
case WpaEventType::DppFailure:
|
||||
handler->on_dpp_failure({ timestamp, std::dynamic_pointer_cast<WpaEventDppFailure>(event) });
|
||||
break;
|
||||
case WpaEventType::DppChirpReceived:
|
||||
handler->on_dpp_chirp_received({ timestamp, std::dynamic_pointer_cast<WpaEventDppChirpReceived>(event) });
|
||||
break;
|
||||
case WpaEventType::DppFrameTransmitStatus:
|
||||
handler->on_dpp_frame_transmit_status({ timestamp, std::dynamic_pointer_cast<WpaEventDppFrameTransmitStatus>(event) });
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
WpaController::process_wpa_events(void)
|
||||
{
|
||||
static constexpr int epoll_events_max = 2;
|
||||
|
||||
int ret;
|
||||
int fd_efd = -1;
|
||||
int fd_wpa = -1;
|
||||
bool terminate = false;
|
||||
struct wpa_ctrl* ctrl = nullptr;
|
||||
struct epoll_event events[epoll_events_max] = {};
|
||||
struct epoll_event* event_efd = &events[0];
|
||||
struct epoll_event* event_wpa = &events[1];
|
||||
const std::filesystem::path path = m_ctrl_socket_path / m_interface;
|
||||
|
||||
int fd_epoll = epoll_create1(0);
|
||||
if (fd_epoll < 0) {
|
||||
ret = errno;
|
||||
std::cerr << "failed to create epoll instance for wpa event listener (" << ret << ")" << std::endl;
|
||||
return;
|
||||
}
|
||||
|
||||
// configure eventfd descriptor for thread stop signaling.
|
||||
fd_efd = eventfd(0, 0);
|
||||
if (fd_efd == -1) {
|
||||
ret = errno;
|
||||
std::cerr << "failed to create stop event fd (" << ret << ")" << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
event_efd->events = EPOLLIN;
|
||||
event_efd->data.fd = fd_efd;
|
||||
|
||||
ret = epoll_ctl(fd_epoll, EPOLL_CTL_ADD, fd_efd, event_efd);
|
||||
if (ret < 0) {
|
||||
ret = errno;
|
||||
std::cerr << "failed to register epoll handler for event stop signaling (" << ret << ")" << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// configure control socket descriptor for wpa event signaling.
|
||||
ctrl = wpa_ctrl_open(path.c_str());
|
||||
if (!ctrl) {
|
||||
std::cerr << "failed to open wpa control socket " << path << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
fd_wpa = wpa_ctrl_get_fd(ctrl);
|
||||
event_wpa->events = EPOLLIN;
|
||||
event_wpa->data.fd = fd_wpa;
|
||||
|
||||
ret = epoll_ctl(fd_epoll, EPOLL_CTL_ADD, fd_wpa, event_wpa);
|
||||
if (ret < 0) {
|
||||
ret = errno;
|
||||
std::cerr << "failed to register epoll handler for wpa event listener (" << ret << ")" << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// attach to wpa event stream
|
||||
ret = wpa_ctrl_attach(ctrl);
|
||||
if (ret < 0) {
|
||||
std::cerr << "failed to register event monitor on wpa control socket (" << ret << ")" << std::endl;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
m_ctrl_event = ctrl;
|
||||
m_ctrl_event_fd_stop = fd_efd;
|
||||
|
||||
while (!m_terminate_pending && !terminate) {
|
||||
// wait for at least one event fd to be signaled
|
||||
int num_events = epoll_wait(fd_epoll, events, epoll_events_max, -1);
|
||||
if (num_events < 0) {
|
||||
ret = errno;
|
||||
std::cerr << "failed to wait on epoll event (" << ret << ")" << std::endl;
|
||||
continue;
|
||||
} else if (num_events == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// determine which fd(s) were signaled and handle them.
|
||||
for (int i = 0; i < epoll_events_max; i++) {
|
||||
if (events[i].data.fd == fd_efd) {
|
||||
uint64_t value;
|
||||
ssize_t num_read = read(fd_efd, &value, sizeof value);
|
||||
if (num_read != sizeof value) {
|
||||
ret = errno;
|
||||
std::cerr << "failed to read exit signal descriptor (" << ret << ")" << std::endl;
|
||||
continue;
|
||||
} else if (value > 0) {
|
||||
terminate = true;
|
||||
}
|
||||
} else if (events[i].data.fd == fd_wpa) {
|
||||
while (wpa_ctrl_pending(ctrl) > 0)
|
||||
process_wpa_event_next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cleanup:
|
||||
if (ctrl) {
|
||||
wpa_ctrl_detach(ctrl);
|
||||
wpa_ctrl_close(ctrl);
|
||||
}
|
||||
|
||||
if (fd_efd != -1)
|
||||
close(fd_efd);
|
||||
|
||||
close(fd_epoll);
|
||||
|
||||
m_ctrl_event_fd_stop = -1;
|
||||
m_ctrl_event = nullptr;
|
||||
}
|
||||
|
||||
WpaEventToken
|
||||
WpaController::register_for_events(std::weak_ptr<WpaEventHandler> handler)
|
||||
{
|
||||
auto lock = std::scoped_lock(m_event_subscribers_gate);
|
||||
WpaEventToken token = m_event_token_next++;
|
||||
m_event_subscribers[token] = handler;
|
||||
|
||||
return token;
|
||||
}
|
||||
|
||||
void
|
||||
WpaController::unregister_for_events(WpaEventToken token)
|
||||
{
|
||||
auto lock = std::scoped_lock(m_event_subscribers_gate);
|
||||
m_event_subscribers.erase(token);
|
||||
}
|
||||
|
||||
struct wpa_ctrl*
|
||||
WpaController::get_command_control_socket(void)
|
||||
{
|
||||
const std::filesystem::path path = m_ctrl_socket_path / m_interface;
|
||||
|
||||
// Check if the socket is already available.
|
||||
{
|
||||
auto lock_shared = std::shared_lock(m_ctrl_command_gate);
|
||||
if (m_ctrl_command)
|
||||
return m_ctrl_command;
|
||||
}
|
||||
|
||||
// Check if socket was updated between releasing shared lock and acquiring exclusive lock.
|
||||
auto lock_exclusive = std::scoped_lock(m_ctrl_command_gate);
|
||||
if (m_ctrl_command)
|
||||
return m_ctrl_command;
|
||||
|
||||
struct wpa_ctrl* ctrl = wpa_ctrl_open(path.c_str());
|
||||
if (!ctrl) {
|
||||
std::cerr << "failed to open wpa control socket " << path << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
m_ctrl_command = ctrl;
|
||||
return m_ctrl_command;
|
||||
}
|
||||
|
||||
std::shared_ptr<WpaCommandResponse>
|
||||
WpaController::send_command(const WpaCommand& command)
|
||||
{
|
||||
struct wpa_ctrl* ctrl = get_command_control_socket();
|
||||
if (!ctrl) {
|
||||
std::cerr << "failed to obtain wpa command control socket" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
std::array<char, c_wpa_event_size_max> reply;
|
||||
std::size_t reply_length = reply.size();
|
||||
|
||||
int ret = wpa_ctrl_request(ctrl, command.data.c_str(), command.data.length(), reply.data(), &reply_length, nullptr);
|
||||
switch (ret) {
|
||||
case 0:
|
||||
return command.parse_response(std::string_view(reply.data(), reply_length));
|
||||
case -2:
|
||||
std::cerr << "failed to send/receive wpa command " << command.name << "(timeout)" << std::endl;
|
||||
return nullptr;
|
||||
case -1:
|
||||
std::cerr << "failed to send/receive wpa command " << command.name << std::endl;
|
||||
return nullptr;
|
||||
default:
|
||||
std::cerr << "failed to send/receive wpa command " << command.name << "(unspecified error " << ret << ")" << std::endl;
|
||||
return nullptr;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
#include <chrono>
|
||||
#include <iostream>
|
||||
|
||||
#include "wifi-telemetry/wpa/wpa_event.hpp"
|
||||
|
||||
WpaEvent::WpaEvent(WpaEventType type_) :
|
||||
type(type_)
|
||||
{}
|
|
@ -0,0 +1,15 @@
|
|||
|
||||
#include "wifi-telemetry/wpa/wpa_event_association_rejected.hpp"
|
||||
|
||||
WpaEventAssociationRejected::WpaEventAssociationRejected(WifiStatusCode status_code_) :
|
||||
WpaEvent(WpaEventType::AssociationRejected),
|
||||
status_code(status_code_)
|
||||
{
|
||||
}
|
||||
|
||||
WpaEventAssociationRejected::WpaEventAssociationRejected(WifiStatusCode status_code_, const wifi_80211_mac& bssid_) :
|
||||
WpaEvent(WpaEventType::AssociationRejected),
|
||||
status_code(status_code_),
|
||||
bssid(bssid_)
|
||||
{
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
|
||||
#include "wifi-telemetry/wpa/wpa_event_authentication_rejected.hpp"
|
||||
|
||||
WpaEventAuthenticationRejected::WpaEventAuthenticationRejected(const wifi_80211_mac& bssid_, WifiStatusCode status_code_, WifiAuthenticationType authentication_type_) :
|
||||
WpaEvent(WpaEventType::AuthenticationRejected),
|
||||
bssid(bssid_),
|
||||
status_code(status_code_),
|
||||
authentication_type(authentication_type_)
|
||||
{
|
||||
}
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче