WiFi Channel Settings.
This commit is contained in:
-547
@@ -1,547 +0,0 @@
|
||||
# This is the CMakeCache file.
|
||||
# For build in directory: /home/patch/src/piddle
|
||||
# It was generated by CMake: /usr/local/bin/cmake
|
||||
# You can edit this file to change values found and used by cmake.
|
||||
# If you do not want to change any of the values, simply exit the editor.
|
||||
# If you do want to change a value, simply edit, save, and exit the editor.
|
||||
# The syntax for the file is as follows:
|
||||
# KEY:TYPE=VALUE
|
||||
# KEY is the name of a variable in the cache.
|
||||
# TYPE is a hint to GUIs for the type of VALUE, DO NOT EDIT TYPE!.
|
||||
# VALUE is the current value for the KEY.
|
||||
|
||||
########################
|
||||
# EXTERNAL cache entries
|
||||
########################
|
||||
|
||||
//Build the testing tree.
|
||||
BUILD_TESTING:BOOL=ON
|
||||
|
||||
//Path to a program.
|
||||
BZRCOMMAND:FILEPATH=BZRCOMMAND-NOTFOUND
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_ADDR2LINE:FILEPATH=/usr/bin/addr2line
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_AR:FILEPATH=/usr/bin/ar
|
||||
|
||||
//Choose the type of build, options are: None Debug Release RelWithDebInfo
|
||||
// MinSizeRel ...
|
||||
CMAKE_BUILD_TYPE:STRING=
|
||||
|
||||
//Enable/Disable color output during build.
|
||||
CMAKE_COLOR_MAKEFILE:BOOL=ON
|
||||
|
||||
//CXX compiler
|
||||
CMAKE_CXX_COMPILER:FILEPATH=/usr/bin/c++
|
||||
|
||||
//A wrapper around 'ar' adding the appropriate '--plugin' option
|
||||
// for the GCC compiler
|
||||
CMAKE_CXX_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-8
|
||||
|
||||
//A wrapper around 'ranlib' adding the appropriate '--plugin' option
|
||||
// for the GCC compiler
|
||||
CMAKE_CXX_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-8
|
||||
|
||||
//Flags used by the CXX compiler during all build types.
|
||||
CMAKE_CXX_FLAGS:STRING=
|
||||
|
||||
//Flags used by the CXX compiler during DEBUG builds.
|
||||
CMAKE_CXX_FLAGS_DEBUG:STRING=-g
|
||||
|
||||
//Flags used by the CXX compiler during MINSIZEREL builds.
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
|
||||
|
||||
//Flags used by the CXX compiler during RELEASE builds.
|
||||
CMAKE_CXX_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
|
||||
|
||||
//Flags used by the CXX compiler during RELWITHDEBINFO builds.
|
||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
|
||||
|
||||
//C compiler
|
||||
CMAKE_C_COMPILER:FILEPATH=/usr/bin/cc
|
||||
|
||||
//A wrapper around 'ar' adding the appropriate '--plugin' option
|
||||
// for the GCC compiler
|
||||
CMAKE_C_COMPILER_AR:FILEPATH=/usr/bin/gcc-ar-8
|
||||
|
||||
//A wrapper around 'ranlib' adding the appropriate '--plugin' option
|
||||
// for the GCC compiler
|
||||
CMAKE_C_COMPILER_RANLIB:FILEPATH=/usr/bin/gcc-ranlib-8
|
||||
|
||||
//Flags used by the C compiler during all build types.
|
||||
CMAKE_C_FLAGS:STRING=
|
||||
|
||||
//Flags used by the C compiler during DEBUG builds.
|
||||
CMAKE_C_FLAGS_DEBUG:STRING=-g
|
||||
|
||||
//Flags used by the C compiler during MINSIZEREL builds.
|
||||
CMAKE_C_FLAGS_MINSIZEREL:STRING=-Os -DNDEBUG
|
||||
|
||||
//Flags used by the C compiler during RELEASE builds.
|
||||
CMAKE_C_FLAGS_RELEASE:STRING=-O3 -DNDEBUG
|
||||
|
||||
//Flags used by the C compiler during RELWITHDEBINFO builds.
|
||||
CMAKE_C_FLAGS_RELWITHDEBINFO:STRING=-O2 -g -DNDEBUG
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_DLLTOOL:FILEPATH=CMAKE_DLLTOOL-NOTFOUND
|
||||
|
||||
//Flags used by the linker during all build types.
|
||||
CMAKE_EXE_LINKER_FLAGS:STRING=
|
||||
|
||||
//Flags used by the linker during DEBUG builds.
|
||||
CMAKE_EXE_LINKER_FLAGS_DEBUG:STRING=
|
||||
|
||||
//Flags used by the linker during MINSIZEREL builds.
|
||||
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL:STRING=
|
||||
|
||||
//Flags used by the linker during RELEASE builds.
|
||||
CMAKE_EXE_LINKER_FLAGS_RELEASE:STRING=
|
||||
|
||||
//Flags used by the linker during RELWITHDEBINFO builds.
|
||||
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
||||
|
||||
//Enable/Disable output of compile commands during generation.
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS:BOOL=
|
||||
|
||||
//Install path prefix, prepended onto install directories.
|
||||
CMAKE_INSTALL_PREFIX:PATH=/usr/local
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_LINKER:FILEPATH=/usr/bin/ld
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_MAKE_PROGRAM:FILEPATH=/usr/bin/make
|
||||
|
||||
//Flags used by the linker during the creation of modules during
|
||||
// all build types.
|
||||
CMAKE_MODULE_LINKER_FLAGS:STRING=
|
||||
|
||||
//Flags used by the linker during the creation of modules during
|
||||
// DEBUG builds.
|
||||
CMAKE_MODULE_LINKER_FLAGS_DEBUG:STRING=
|
||||
|
||||
//Flags used by the linker during the creation of modules during
|
||||
// MINSIZEREL builds.
|
||||
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL:STRING=
|
||||
|
||||
//Flags used by the linker during the creation of modules during
|
||||
// RELEASE builds.
|
||||
CMAKE_MODULE_LINKER_FLAGS_RELEASE:STRING=
|
||||
|
||||
//Flags used by the linker during the creation of modules during
|
||||
// RELWITHDEBINFO builds.
|
||||
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_NM:FILEPATH=/usr/bin/nm
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_OBJCOPY:FILEPATH=/usr/bin/objcopy
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_OBJDUMP:FILEPATH=/usr/bin/objdump
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_DESCRIPTION:STATIC=
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_HOMEPAGE_URL:STATIC=
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_NAME:STATIC=PiddleTest
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_VERSION:STATIC=0.1.0
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_VERSION_MAJOR:STATIC=0
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_VERSION_MINOR:STATIC=1
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_VERSION_PATCH:STATIC=0
|
||||
|
||||
//Value Computed by CMake
|
||||
CMAKE_PROJECT_VERSION_TWEAK:STATIC=
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_RANLIB:FILEPATH=/usr/bin/ranlib
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_READELF:FILEPATH=/usr/bin/readelf
|
||||
|
||||
//Flags used by the linker during the creation of shared libraries
|
||||
// during all build types.
|
||||
CMAKE_SHARED_LINKER_FLAGS:STRING=
|
||||
|
||||
//Flags used by the linker during the creation of shared libraries
|
||||
// during DEBUG builds.
|
||||
CMAKE_SHARED_LINKER_FLAGS_DEBUG:STRING=
|
||||
|
||||
//Flags used by the linker during the creation of shared libraries
|
||||
// during MINSIZEREL builds.
|
||||
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL:STRING=
|
||||
|
||||
//Flags used by the linker during the creation of shared libraries
|
||||
// during RELEASE builds.
|
||||
CMAKE_SHARED_LINKER_FLAGS_RELEASE:STRING=
|
||||
|
||||
//Flags used by the linker during the creation of shared libraries
|
||||
// during RELWITHDEBINFO builds.
|
||||
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
||||
|
||||
//If set, runtime paths are not added when installing shared libraries,
|
||||
// but are added when building.
|
||||
CMAKE_SKIP_INSTALL_RPATH:BOOL=NO
|
||||
|
||||
//If set, runtime paths are not added when using shared libraries.
|
||||
CMAKE_SKIP_RPATH:BOOL=NO
|
||||
|
||||
//Flags used by the linker during the creation of static libraries
|
||||
// during all build types.
|
||||
CMAKE_STATIC_LINKER_FLAGS:STRING=
|
||||
|
||||
//Flags used by the linker during the creation of static libraries
|
||||
// during DEBUG builds.
|
||||
CMAKE_STATIC_LINKER_FLAGS_DEBUG:STRING=
|
||||
|
||||
//Flags used by the linker during the creation of static libraries
|
||||
// during MINSIZEREL builds.
|
||||
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL:STRING=
|
||||
|
||||
//Flags used by the linker during the creation of static libraries
|
||||
// during RELEASE builds.
|
||||
CMAKE_STATIC_LINKER_FLAGS_RELEASE:STRING=
|
||||
|
||||
//Flags used by the linker during the creation of static libraries
|
||||
// during RELWITHDEBINFO builds.
|
||||
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO:STRING=
|
||||
|
||||
//Path to a program.
|
||||
CMAKE_STRIP:FILEPATH=/usr/bin/strip
|
||||
|
||||
//If this value is on, makefiles will be generated without the
|
||||
// .SILENT directive, and all commands will be echoed to the console
|
||||
// during the make. This is useful for debugging only. With Visual
|
||||
// Studio IDE projects all commands are done without /nologo.
|
||||
CMAKE_VERBOSE_MAKEFILE:BOOL=FALSE
|
||||
|
||||
//Path to the coverage program that CTest uses for performing coverage
|
||||
// inspection
|
||||
COVERAGE_COMMAND:FILEPATH=/usr/bin/gcov
|
||||
|
||||
//Extra command line flags to pass to the coverage tool
|
||||
COVERAGE_EXTRA_FLAGS:STRING=-l
|
||||
|
||||
//How many times to retry timed-out CTest submissions.
|
||||
CTEST_SUBMIT_RETRY_COUNT:STRING=3
|
||||
|
||||
//How long to wait between timed-out CTest submissions.
|
||||
CTEST_SUBMIT_RETRY_DELAY:STRING=5
|
||||
|
||||
//Path to a program.
|
||||
CVSCOMMAND:FILEPATH=/usr/bin/cvs
|
||||
|
||||
//Options passed to the cvs update command.
|
||||
CVS_UPDATE_OPTIONS:STRING=-d -A -P
|
||||
|
||||
//Maximum time allowed before CTest will kill the test.
|
||||
DART_TESTING_TIMEOUT:STRING=1500
|
||||
|
||||
//Path to a program.
|
||||
GITCOMMAND:FILEPATH=/usr/bin/git
|
||||
|
||||
//Path to a program.
|
||||
HGCOMMAND:FILEPATH=/usr/bin/hg
|
||||
|
||||
//Command to build the project
|
||||
MAKECOMMAND:STRING=/usr/local/bin/cmake --build . --config "${CTEST_CONFIGURATION_TYPE}"
|
||||
|
||||
//Path to the memory checking command, used for memory error detection.
|
||||
MEMORYCHECK_COMMAND:FILEPATH=MEMORYCHECK_COMMAND-NOTFOUND
|
||||
|
||||
//File that contains suppressions for the memory checker
|
||||
MEMORYCHECK_SUPPRESSIONS_FILE:FILEPATH=
|
||||
|
||||
//Path to a program.
|
||||
P4COMMAND:FILEPATH=P4COMMAND-NOTFOUND
|
||||
|
||||
//pkg-config executable
|
||||
PKG_CONFIG_EXECUTABLE:FILEPATH=/usr/bin/pkg-config
|
||||
|
||||
//Value Computed by CMake
|
||||
PiddleTest_BINARY_DIR:STATIC=/home/patch/src/piddle
|
||||
|
||||
//Value Computed by CMake
|
||||
PiddleTest_SOURCE_DIR:STATIC=/home/patch/src/piddle/test
|
||||
|
||||
//Name of the computer/site where compile is being run
|
||||
SITE:STRING=patchbox
|
||||
|
||||
//Path to the SLURM sbatch executable
|
||||
SLURM_SBATCH_COMMAND:FILEPATH=SLURM_SBATCH_COMMAND-NOTFOUND
|
||||
|
||||
//Path to the SLURM srun executable
|
||||
SLURM_SRUN_COMMAND:FILEPATH=SLURM_SRUN_COMMAND-NOTFOUND
|
||||
|
||||
//Path to a program.
|
||||
SVNCOMMAND:FILEPATH=/usr/bin/svn
|
||||
|
||||
//Path to a library.
|
||||
pkgcfg_lib_LILV_0_dl:FILEPATH=/usr/lib/arm-linux-gnueabihf/libdl.so
|
||||
|
||||
//Path to a library.
|
||||
pkgcfg_lib_LILV_0_lilv-0:FILEPATH=/usr/lib/arm-linux-gnueabihf/liblilv-0.so
|
||||
|
||||
//Path to a library.
|
||||
pkgcfg_lib_LILV_0_serd-0:FILEPATH=/usr/lib/arm-linux-gnueabihf/libserd-0.so
|
||||
|
||||
//Path to a library.
|
||||
pkgcfg_lib_LILV_0_sord-0:FILEPATH=/usr/lib/arm-linux-gnueabihf/libsord-0.so
|
||||
|
||||
//Path to a library.
|
||||
pkgcfg_lib_LILV_0_sratom-0:FILEPATH=/usr/lib/arm-linux-gnueabihf/libsratom-0.so
|
||||
|
||||
|
||||
########################
|
||||
# INTERNAL cache entries
|
||||
########################
|
||||
|
||||
//ADVANCED property for variable: BZRCOMMAND
|
||||
BZRCOMMAND-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_ADDR2LINE
|
||||
CMAKE_ADDR2LINE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_AR
|
||||
CMAKE_AR-ADVANCED:INTERNAL=1
|
||||
//This is the directory where this CMakeCache.txt was created
|
||||
CMAKE_CACHEFILE_DIR:INTERNAL=/home/patch/src/piddle
|
||||
//Major version of cmake used to create the current loaded cache
|
||||
CMAKE_CACHE_MAJOR_VERSION:INTERNAL=3
|
||||
//Minor version of cmake used to create the current loaded cache
|
||||
CMAKE_CACHE_MINOR_VERSION:INTERNAL=19
|
||||
//Patch version of cmake used to create the current loaded cache
|
||||
CMAKE_CACHE_PATCH_VERSION:INTERNAL=4268486
|
||||
//ADVANCED property for variable: CMAKE_COLOR_MAKEFILE
|
||||
CMAKE_COLOR_MAKEFILE-ADVANCED:INTERNAL=1
|
||||
//Path to CMake executable.
|
||||
CMAKE_COMMAND:INTERNAL=/usr/local/bin/cmake
|
||||
//Path to cpack program executable.
|
||||
CMAKE_CPACK_COMMAND:INTERNAL=/usr/local/bin/cpack
|
||||
//ADVANCED property for variable: CMAKE_CTEST_COMMAND
|
||||
CMAKE_CTEST_COMMAND-ADVANCED:INTERNAL=1
|
||||
//Path to ctest program executable.
|
||||
CMAKE_CTEST_COMMAND:INTERNAL=/usr/local/bin/ctest
|
||||
//ADVANCED property for variable: CMAKE_CXX_COMPILER
|
||||
CMAKE_CXX_COMPILER-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_CXX_COMPILER_AR
|
||||
CMAKE_CXX_COMPILER_AR-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_CXX_COMPILER_RANLIB
|
||||
CMAKE_CXX_COMPILER_RANLIB-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS
|
||||
CMAKE_CXX_FLAGS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_DEBUG
|
||||
CMAKE_CXX_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_MINSIZEREL
|
||||
CMAKE_CXX_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELEASE
|
||||
CMAKE_CXX_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_CXX_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_CXX_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_COMPILER
|
||||
CMAKE_C_COMPILER-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_COMPILER_AR
|
||||
CMAKE_C_COMPILER_AR-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_COMPILER_RANLIB
|
||||
CMAKE_C_COMPILER_RANLIB-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_FLAGS
|
||||
CMAKE_C_FLAGS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_FLAGS_DEBUG
|
||||
CMAKE_C_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_FLAGS_MINSIZEREL
|
||||
CMAKE_C_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_FLAGS_RELEASE
|
||||
CMAKE_C_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_C_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_C_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_DLLTOOL
|
||||
CMAKE_DLLTOOL-ADVANCED:INTERNAL=1
|
||||
//Executable file format
|
||||
CMAKE_EXECUTABLE_FORMAT:INTERNAL=ELF
|
||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS
|
||||
CMAKE_EXE_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_DEBUG
|
||||
CMAKE_EXE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_MINSIZEREL
|
||||
CMAKE_EXE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELEASE
|
||||
CMAKE_EXE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_EXPORT_COMPILE_COMMANDS
|
||||
CMAKE_EXPORT_COMPILE_COMMANDS-ADVANCED:INTERNAL=1
|
||||
//Name of external makefile project generator.
|
||||
CMAKE_EXTRA_GENERATOR:INTERNAL=
|
||||
//Name of generator.
|
||||
CMAKE_GENERATOR:INTERNAL=Unix Makefiles
|
||||
//Generator instance identifier.
|
||||
CMAKE_GENERATOR_INSTANCE:INTERNAL=
|
||||
//Name of generator platform.
|
||||
CMAKE_GENERATOR_PLATFORM:INTERNAL=
|
||||
//Name of generator toolset.
|
||||
CMAKE_GENERATOR_TOOLSET:INTERNAL=
|
||||
//Source directory with the top level CMakeLists.txt file for this
|
||||
// project
|
||||
CMAKE_HOME_DIRECTORY:INTERNAL=/home/patch/src/piddle/test
|
||||
//Install .so files without execute permission.
|
||||
CMAKE_INSTALL_SO_NO_EXE:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_LINKER
|
||||
CMAKE_LINKER-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_MAKE_PROGRAM
|
||||
CMAKE_MAKE_PROGRAM-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS
|
||||
CMAKE_MODULE_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_DEBUG
|
||||
CMAKE_MODULE_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL
|
||||
CMAKE_MODULE_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELEASE
|
||||
CMAKE_MODULE_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_MODULE_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_NM
|
||||
CMAKE_NM-ADVANCED:INTERNAL=1
|
||||
//number of local generators
|
||||
CMAKE_NUMBER_OF_MAKEFILES:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_OBJCOPY
|
||||
CMAKE_OBJCOPY-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_OBJDUMP
|
||||
CMAKE_OBJDUMP-ADVANCED:INTERNAL=1
|
||||
//Platform information initialized
|
||||
CMAKE_PLATFORM_INFO_INITIALIZED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_RANLIB
|
||||
CMAKE_RANLIB-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_READELF
|
||||
CMAKE_READELF-ADVANCED:INTERNAL=1
|
||||
//Path to CMake installation.
|
||||
CMAKE_ROOT:INTERNAL=/usr/local/share/cmake-3.19
|
||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS
|
||||
CMAKE_SHARED_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_DEBUG
|
||||
CMAKE_SHARED_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL
|
||||
CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELEASE
|
||||
CMAKE_SHARED_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_SKIP_INSTALL_RPATH
|
||||
CMAKE_SKIP_INSTALL_RPATH-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_SKIP_RPATH
|
||||
CMAKE_SKIP_RPATH-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS
|
||||
CMAKE_STATIC_LINKER_FLAGS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_DEBUG
|
||||
CMAKE_STATIC_LINKER_FLAGS_DEBUG-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL
|
||||
CMAKE_STATIC_LINKER_FLAGS_MINSIZEREL-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELEASE
|
||||
CMAKE_STATIC_LINKER_FLAGS_RELEASE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO
|
||||
CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CMAKE_STRIP
|
||||
CMAKE_STRIP-ADVANCED:INTERNAL=1
|
||||
//uname command
|
||||
CMAKE_UNAME:INTERNAL=/usr/bin/uname
|
||||
//ADVANCED property for variable: CMAKE_VERBOSE_MAKEFILE
|
||||
CMAKE_VERBOSE_MAKEFILE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: COVERAGE_COMMAND
|
||||
COVERAGE_COMMAND-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: COVERAGE_EXTRA_FLAGS
|
||||
COVERAGE_EXTRA_FLAGS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CTEST_SUBMIT_RETRY_COUNT
|
||||
CTEST_SUBMIT_RETRY_COUNT-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CTEST_SUBMIT_RETRY_DELAY
|
||||
CTEST_SUBMIT_RETRY_DELAY-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CVSCOMMAND
|
||||
CVSCOMMAND-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: CVS_UPDATE_OPTIONS
|
||||
CVS_UPDATE_OPTIONS-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: DART_TESTING_TIMEOUT
|
||||
DART_TESTING_TIMEOUT-ADVANCED:INTERNAL=1
|
||||
//Details about finding PkgConfig
|
||||
FIND_PACKAGE_MESSAGE_DETAILS_PkgConfig:INTERNAL=[/usr/bin/pkg-config][v0.29()]
|
||||
//ADVANCED property for variable: GITCOMMAND
|
||||
GITCOMMAND-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: HGCOMMAND
|
||||
HGCOMMAND-ADVANCED:INTERNAL=1
|
||||
LILV_0_CFLAGS:INTERNAL=-I/usr/local/include;-I/usr/include/lilv-0;-I/usr/include/sratom-0;-I/usr/include/sord-0;-I/usr/include/serd-0
|
||||
LILV_0_CFLAGS_I:INTERNAL=
|
||||
LILV_0_CFLAGS_OTHER:INTERNAL=
|
||||
LILV_0_FOUND:INTERNAL=1
|
||||
LILV_0_INCLUDEDIR:INTERNAL=/usr/include
|
||||
LILV_0_INCLUDE_DIRS:INTERNAL=/usr/local/include;/usr/include/lilv-0;/usr/include/sratom-0;/usr/include/sord-0;/usr/include/serd-0
|
||||
LILV_0_LDFLAGS:INTERNAL=-llilv-0;-ldl;-lsratom-0;-lsord-0;-lserd-0
|
||||
LILV_0_LDFLAGS_OTHER:INTERNAL=
|
||||
LILV_0_LIBDIR:INTERNAL=/usr/lib/arm-linux-gnueabihf
|
||||
LILV_0_LIBRARIES:INTERNAL=lilv-0;dl;sratom-0;sord-0;serd-0
|
||||
LILV_0_LIBRARY_DIRS:INTERNAL=
|
||||
LILV_0_LIBS:INTERNAL=
|
||||
LILV_0_LIBS_L:INTERNAL=
|
||||
LILV_0_LIBS_OTHER:INTERNAL=
|
||||
LILV_0_LIBS_PATHS:INTERNAL=
|
||||
LILV_0_MODULE_NAME:INTERNAL=lilv-0
|
||||
LILV_0_PREFIX:INTERNAL=/usr
|
||||
LILV_0_STATIC_CFLAGS:INTERNAL=-I/usr/local/include;-I/usr/include/lilv-0;-I/usr/include/sratom-0;-I/usr/include/sord-0;-I/usr/include/serd-0
|
||||
LILV_0_STATIC_CFLAGS_I:INTERNAL=
|
||||
LILV_0_STATIC_CFLAGS_OTHER:INTERNAL=
|
||||
LILV_0_STATIC_INCLUDE_DIRS:INTERNAL=/usr/local/include;/usr/include/lilv-0;/usr/include/sratom-0;/usr/include/sord-0;/usr/include/serd-0
|
||||
LILV_0_STATIC_LDFLAGS:INTERNAL=-llilv-0;-ldl;-lsratom-0;-lsord-0;-lserd-0;-lm
|
||||
LILV_0_STATIC_LDFLAGS_OTHER:INTERNAL=
|
||||
LILV_0_STATIC_LIBDIR:INTERNAL=
|
||||
LILV_0_STATIC_LIBRARIES:INTERNAL=lilv-0;dl;sratom-0;sord-0;serd-0;m
|
||||
LILV_0_STATIC_LIBRARY_DIRS:INTERNAL=
|
||||
LILV_0_STATIC_LIBS:INTERNAL=
|
||||
LILV_0_STATIC_LIBS_L:INTERNAL=
|
||||
LILV_0_STATIC_LIBS_OTHER:INTERNAL=
|
||||
LILV_0_STATIC_LIBS_PATHS:INTERNAL=
|
||||
LILV_0_VERSION:INTERNAL=0.24.2
|
||||
LILV_0_lilv-0_INCLUDEDIR:INTERNAL=
|
||||
LILV_0_lilv-0_LIBDIR:INTERNAL=
|
||||
LILV_0_lilv-0_PREFIX:INTERNAL=
|
||||
LILV_0_lilv-0_VERSION:INTERNAL=
|
||||
//ADVANCED property for variable: MAKECOMMAND
|
||||
MAKECOMMAND-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: MEMORYCHECK_COMMAND
|
||||
MEMORYCHECK_COMMAND-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: MEMORYCHECK_SUPPRESSIONS_FILE
|
||||
MEMORYCHECK_SUPPRESSIONS_FILE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: P4COMMAND
|
||||
P4COMMAND-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: PKG_CONFIG_EXECUTABLE
|
||||
PKG_CONFIG_EXECUTABLE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: SITE
|
||||
SITE-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: SLURM_SBATCH_COMMAND
|
||||
SLURM_SBATCH_COMMAND-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: SLURM_SRUN_COMMAND
|
||||
SLURM_SRUN_COMMAND-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: SVNCOMMAND
|
||||
SVNCOMMAND-ADVANCED:INTERNAL=1
|
||||
__pkg_config_arguments_LILV_0:INTERNAL=lilv-0
|
||||
__pkg_config_checked_LILV_0:INTERNAL=1
|
||||
//ADVANCED property for variable: pkgcfg_lib_LILV_0_dl
|
||||
pkgcfg_lib_LILV_0_dl-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: pkgcfg_lib_LILV_0_lilv-0
|
||||
pkgcfg_lib_LILV_0_lilv-0-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: pkgcfg_lib_LILV_0_serd-0
|
||||
pkgcfg_lib_LILV_0_serd-0-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: pkgcfg_lib_LILV_0_sord-0
|
||||
pkgcfg_lib_LILV_0_sord-0-ADVANCED:INTERNAL=1
|
||||
//ADVANCED property for variable: pkgcfg_lib_LILV_0_sratom-0
|
||||
pkgcfg_lib_LILV_0_sratom-0-ADVANCED:INTERNAL=1
|
||||
prefix_result:INTERNAL=/usr/lib/arm-linux-gnueabihf
|
||||
|
||||
+10
-2
@@ -5,20 +5,22 @@ find_program(NPM_COMMAND npm)
|
||||
|
||||
if (CMAKE_BUILD_TYPE MATCHES Debug)
|
||||
set(BUILD_REACT "echo")
|
||||
set(BUILD_REACT_ARGS Skipping react debug build)
|
||||
else()
|
||||
set(BUILD_REACT ${NPM_COMMAND})
|
||||
set(BUILD_REACT_ARGS run build)
|
||||
endif()
|
||||
|
||||
set (BUILD_DIRECTORY ${PROJECT_SOURCE_DIR}/build/react/build)
|
||||
message(STATUS "React Build...")
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${BUILD_DIRECTORY}/index.html
|
||||
COMMAND ${BUILD_REACT}
|
||||
ARGS run build
|
||||
ARGS ${BUILD_REACT_ARGS}
|
||||
WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}/react
|
||||
|
||||
DEPENDS
|
||||
src/WifiChannel.tsx
|
||||
src/JackServerSettingsDialog.tsx
|
||||
src/JackServerSettings.tsx
|
||||
|
||||
@@ -74,7 +76,13 @@ add_custom_command(
|
||||
src/Utility.tsx
|
||||
src/VuMeter.tsx
|
||||
src/PluginPreset.tsx
|
||||
src/XxxSnippet.tsx
|
||||
src/WifiConfigSettings.tsx
|
||||
src/WifiConfigDialog.tsx
|
||||
src/NoChangePassword.tsx
|
||||
src/XxxSnippet.tsx
|
||||
|
||||
public/iso_codes.json
|
||||
public/logo512.png
|
||||
public/index.html
|
||||
public/manifest.json
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"start": "react-scripts start",
|
||||
"build": "BUILD_PATH='../../build/react/src/build' react-scripts build",
|
||||
"build": "BUILD_PATH='../build/react/build' react-scripts build",
|
||||
"test": "react-scripts test",
|
||||
"eject": "react-scripts eject"
|
||||
},
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
{
|
||||
"AF": "Afghanistan",
|
||||
"AX": "Aland Islands",
|
||||
"AL": "Albania",
|
||||
"DZ": "Algeria",
|
||||
"AS": "American Samoa",
|
||||
"AD": "Andorra",
|
||||
"AO": "Angola",
|
||||
"AI": "Anguilla",
|
||||
"AQ": "Antarctica",
|
||||
"AG": "Antigua And Barbuda",
|
||||
"AR": "Argentina",
|
||||
"AM": "Armenia",
|
||||
"AW": "Aruba",
|
||||
"AU": "Australia",
|
||||
"AT": "Austria",
|
||||
"AZ": "Azerbaijan",
|
||||
"BS": "Bahamas",
|
||||
"BH": "Bahrain",
|
||||
"BD": "Bangladesh",
|
||||
"BB": "Barbados",
|
||||
"BY": "Belarus",
|
||||
"BE": "Belgium",
|
||||
"BZ": "Belize",
|
||||
"BJ": "Benin",
|
||||
"BM": "Bermuda",
|
||||
"BT": "Bhutan",
|
||||
"BO": "Bolivia",
|
||||
"BA": "Bosnia And Herzegovina",
|
||||
"BW": "Botswana",
|
||||
"BV": "Bouvet Island",
|
||||
"BR": "Brazil",
|
||||
"IO": "British Indian Ocean Territory",
|
||||
"BN": "Brunei Darussalam",
|
||||
"BG": "Bulgaria",
|
||||
"BF": "Burkina Faso",
|
||||
"BI": "Burundi",
|
||||
"KH": "Cambodia",
|
||||
"CM": "Cameroon",
|
||||
"CA": "Canada",
|
||||
"CV": "Cape Verde",
|
||||
"KY": "Cayman Islands",
|
||||
"CF": "Central African Republic",
|
||||
"TD": "Chad",
|
||||
"CL": "Chile",
|
||||
"CN": "China",
|
||||
"CX": "Christmas Island",
|
||||
"CC": "Cocos (Keeling) Islands",
|
||||
"CO": "Colombia",
|
||||
"KM": "Comoros",
|
||||
"CG": "Congo",
|
||||
"CD": "Congo, Democratic Republic",
|
||||
"CK": "Cook Islands",
|
||||
"CR": "Costa Rica",
|
||||
"CI": "Cote D\"Ivoire",
|
||||
"HR": "Croatia",
|
||||
"CU": "Cuba",
|
||||
"CY": "Cyprus",
|
||||
"CZ": "Czech Republic",
|
||||
"DK": "Denmark",
|
||||
"DJ": "Djibouti",
|
||||
"DM": "Dominica",
|
||||
"DO": "Dominican Republic",
|
||||
"EC": "Ecuador",
|
||||
"EG": "Egypt",
|
||||
"SV": "El Salvador",
|
||||
"GQ": "Equatorial Guinea",
|
||||
"ER": "Eritrea",
|
||||
"EE": "Estonia",
|
||||
"ET": "Ethiopia",
|
||||
"FK": "Falkland Islands (Malvinas)",
|
||||
"FO": "Faroe Islands",
|
||||
"FJ": "Fiji",
|
||||
"FI": "Finland",
|
||||
"FR": "France",
|
||||
"GF": "French Guiana",
|
||||
"PF": "French Polynesia",
|
||||
"TF": "French Southern Territories",
|
||||
"GA": "Gabon",
|
||||
"GM": "Gambia",
|
||||
"GE": "Georgia",
|
||||
"DE": "Germany",
|
||||
"GH": "Ghana",
|
||||
"GI": "Gibraltar",
|
||||
"GR": "Greece",
|
||||
"GL": "Greenland",
|
||||
"GD": "Grenada",
|
||||
"GP": "Guadeloupe",
|
||||
"GU": "Guam",
|
||||
"GT": "Guatemala",
|
||||
"GG": "Guernsey",
|
||||
"GN": "Guinea",
|
||||
"GW": "Guinea-Bissau",
|
||||
"GY": "Guyana",
|
||||
"HT": "Haiti",
|
||||
"HM": "Heard Island & Mcdonald Islands",
|
||||
"VA": "Holy See (Vatican City State)",
|
||||
"HN": "Honduras",
|
||||
"HK": "Hong Kong",
|
||||
"HU": "Hungary",
|
||||
"IS": "Iceland",
|
||||
"IN": "India",
|
||||
"ID": "Indonesia",
|
||||
"IR": "Iran, Islamic Republic Of",
|
||||
"IQ": "Iraq",
|
||||
"IE": "Ireland",
|
||||
"IM": "Isle Of Man",
|
||||
"IL": "Israel",
|
||||
"IT": "Italy",
|
||||
"JM": "Jamaica",
|
||||
"JP": "Japan",
|
||||
"JE": "Jersey",
|
||||
"JO": "Jordan",
|
||||
"KZ": "Kazakhstan",
|
||||
"KE": "Kenya",
|
||||
"KI": "Kiribati",
|
||||
"KR": "Korea",
|
||||
"KP": "North Korea",
|
||||
"KW": "Kuwait",
|
||||
"KG": "Kyrgyzstan",
|
||||
"LA": "Lao People\"s Democratic Republic",
|
||||
"LV": "Latvia",
|
||||
"LB": "Lebanon",
|
||||
"LS": "Lesotho",
|
||||
"LR": "Liberia",
|
||||
"LY": "Libyan Arab Jamahiriya",
|
||||
"LI": "Liechtenstein",
|
||||
"LT": "Lithuania",
|
||||
"LU": "Luxembourg",
|
||||
"MO": "Macao",
|
||||
"MK": "Macedonia",
|
||||
"MG": "Madagascar",
|
||||
"MW": "Malawi",
|
||||
"MY": "Malaysia",
|
||||
"MV": "Maldives",
|
||||
"ML": "Mali",
|
||||
"MT": "Malta",
|
||||
"MH": "Marshall Islands",
|
||||
"MQ": "Martinique",
|
||||
"MR": "Mauritania",
|
||||
"MU": "Mauritius",
|
||||
"YT": "Mayotte",
|
||||
"MX": "Mexico",
|
||||
"FM": "Micronesia, Federated States Of",
|
||||
"MD": "Moldova",
|
||||
"MC": "Monaco",
|
||||
"MN": "Mongolia",
|
||||
"ME": "Montenegro",
|
||||
"MS": "Montserrat",
|
||||
"MA": "Morocco",
|
||||
"MZ": "Mozambique",
|
||||
"MM": "Myanmar",
|
||||
"NA": "Namibia",
|
||||
"NR": "Nauru",
|
||||
"NP": "Nepal",
|
||||
"NL": "Netherlands",
|
||||
"AN": "Netherlands Antilles",
|
||||
"NC": "New Caledonia",
|
||||
"NZ": "New Zealand",
|
||||
"NI": "Nicaragua",
|
||||
"NE": "Niger",
|
||||
"NG": "Nigeria",
|
||||
"NU": "Niue",
|
||||
"NF": "Norfolk Island",
|
||||
"MP": "Northern Mariana Islands",
|
||||
"NO": "Norway",
|
||||
"OM": "Oman",
|
||||
"PK": "Pakistan",
|
||||
"PW": "Palau",
|
||||
"PS": "Palestinian Territory, Occupied",
|
||||
"PA": "Panama",
|
||||
"PG": "Papua New Guinea",
|
||||
"PY": "Paraguay",
|
||||
"PE": "Peru",
|
||||
"PH": "Philippines",
|
||||
"PN": "Pitcairn",
|
||||
"PL": "Poland",
|
||||
"PT": "Portugal",
|
||||
"PR": "Puerto Rico",
|
||||
"QA": "Qatar",
|
||||
"RE": "Reunion",
|
||||
"RO": "Romania",
|
||||
"RU": "Russian Federation",
|
||||
"RW": "Rwanda",
|
||||
"BL": "Saint Barthelemy",
|
||||
"SH": "Saint Helena",
|
||||
"KN": "Saint Kitts And Nevis",
|
||||
"LC": "Saint Lucia",
|
||||
"MF": "Saint Martin",
|
||||
"PM": "Saint Pierre And Miquelon",
|
||||
"VC": "Saint Vincent And Grenadines",
|
||||
"WS": "Samoa",
|
||||
"SM": "San Marino",
|
||||
"ST": "Sao Tome And Principe",
|
||||
"SA": "Saudi Arabia",
|
||||
"SN": "Senegal",
|
||||
"RS": "Serbia",
|
||||
"SC": "Seychelles",
|
||||
"SL": "Sierra Leone",
|
||||
"SG": "Singapore",
|
||||
"SK": "Slovakia",
|
||||
"SI": "Slovenia",
|
||||
"SB": "Solomon Islands",
|
||||
"SO": "Somalia",
|
||||
"ZA": "South Africa",
|
||||
"GS": "South Georgia And Sandwich Isl.",
|
||||
"ES": "Spain",
|
||||
"LK": "Sri Lanka",
|
||||
"SD": "Sudan",
|
||||
"SR": "Suriname",
|
||||
"SJ": "Svalbard And Jan Mayen",
|
||||
"SZ": "Swaziland",
|
||||
"SE": "Sweden",
|
||||
"CH": "Switzerland",
|
||||
"SY": "Syrian Arab Republic",
|
||||
"TW": "Taiwan",
|
||||
"TJ": "Tajikistan",
|
||||
"TZ": "Tanzania",
|
||||
"TH": "Thailand",
|
||||
"TL": "Timor-Leste",
|
||||
"TG": "Togo",
|
||||
"TK": "Tokelau",
|
||||
"TO": "Tonga",
|
||||
"TT": "Trinidad And Tobago",
|
||||
"TN": "Tunisia",
|
||||
"TR": "Turkey",
|
||||
"TM": "Turkmenistan",
|
||||
"TC": "Turks And Caicos Islands",
|
||||
"TV": "Tuvalu",
|
||||
"UG": "Uganda",
|
||||
"UA": "Ukraine",
|
||||
"AE": "United Arab Emirates",
|
||||
"GB": "United Kingdom",
|
||||
"US": "United States",
|
||||
"UM": "United States Outlying Islands",
|
||||
"UY": "Uruguay",
|
||||
"UZ": "Uzbekistan",
|
||||
"VU": "Vanuatu",
|
||||
"VE": "Venezuela",
|
||||
"VN": "Vietnam",
|
||||
"VG": "Virgin Islands, British",
|
||||
"VI": "Virgin Islands, U.S.",
|
||||
"WF": "Wallis And Futuna",
|
||||
"EH": "Western Sahara",
|
||||
"YE": "Yemen",
|
||||
"ZM": "Zambia",
|
||||
"ZW": "Zimbabwe"
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"socket_server_port": 80,
|
||||
"socket_server_port": 8080,
|
||||
"socket_server_address": "*",
|
||||
|
||||
"max_upload_size": 1048576,
|
||||
|
||||
+1
-1
@@ -646,7 +646,7 @@ const App = withStyles(appStyles)(class extends ResizeResponsiveComponent<AppPro
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<TemporaryDrawer position='left' title="piddle"
|
||||
<TemporaryDrawer position='left' title="PiPedal"
|
||||
is_open={this.state.isDrawerOpen} onClose={() => { this.hideDrawer(); }} >
|
||||
<List subheader={
|
||||
<ListSubheader component="div" id="nested-list-subheader">Banks</ListSubheader>
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
import React from 'react';
|
||||
|
||||
import Dialog, {DialogProps} from '@material-ui/core/Dialog';
|
||||
|
||||
|
||||
interface DialogExProps extends DialogProps {
|
||||
tag: string;
|
||||
}
|
||||
|
||||
interface DialogExState {
|
||||
|
||||
}
|
||||
|
||||
class DialogEx extends React.Component<DialogExProps,DialogExState> {
|
||||
constructor(props: DialogExProps)
|
||||
{
|
||||
super(props);
|
||||
this.state = {
|
||||
|
||||
};
|
||||
this.handlePopState = this.handlePopState.bind(this);
|
||||
|
||||
}
|
||||
|
||||
mounted: boolean = false;
|
||||
|
||||
hasHooks: boolean = false;
|
||||
|
||||
stateWasPopped: boolean = false;
|
||||
handlePopState(e: any): any {
|
||||
this.stateWasPopped = true;
|
||||
let shouldClose = (!e.state || !e.state[this.props.tag]);
|
||||
if (shouldClose)
|
||||
{
|
||||
if (this.props.onClose)
|
||||
{
|
||||
this.props.onClose(e,"backdropClick");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
updateHooks() : void {
|
||||
let wantHooks = this.mounted && this.props.open;
|
||||
if (wantHooks !== this.hasHooks)
|
||||
{
|
||||
this.hasHooks = wantHooks;
|
||||
|
||||
if (this.hasHooks)
|
||||
{
|
||||
this.stateWasPopped = false;
|
||||
window.addEventListener("popstate",this.handlePopState);
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
let state = history.state;
|
||||
if (!state)
|
||||
{
|
||||
state = {};
|
||||
}
|
||||
state[this.props.tag] = true;
|
||||
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
history.pushState(
|
||||
state,
|
||||
"",
|
||||
"#" + this.props.tag
|
||||
);
|
||||
} else {
|
||||
window.removeEventListener("popstate",this.handlePopState);
|
||||
if (!this.stateWasPopped)
|
||||
{
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
history.back();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
onWindowSizeChanged(width: number, height: number): void
|
||||
{
|
||||
this.setState({fullScreen: height < 200})
|
||||
}
|
||||
|
||||
|
||||
componentDidMount()
|
||||
{
|
||||
if (super.componentDidMount)
|
||||
{
|
||||
super.componentDidMount();
|
||||
}
|
||||
this.mounted = true;
|
||||
this.updateHooks();
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
if (super.componentWillUnmount)
|
||||
{
|
||||
super.componentWillUnmount();
|
||||
}
|
||||
this.mounted = false;
|
||||
this.updateHooks();
|
||||
}
|
||||
|
||||
componentDidUpdate()
|
||||
{
|
||||
this.updateHooks();
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
let { tag, ...extra} = this.props;
|
||||
return (
|
||||
<Dialog {...extra}>
|
||||
{this.props.children}
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
export default DialogEx;
|
||||
@@ -187,7 +187,7 @@ export const MidiBindingDialog =
|
||||
this.updateHooks();
|
||||
}
|
||||
componentWillUnmount() {
|
||||
super.componentDidMount();
|
||||
super.componentWillUnmount();
|
||||
|
||||
this.mounted = false;
|
||||
this.updateHooks();
|
||||
|
||||
@@ -0,0 +1,118 @@
|
||||
import React from 'react';
|
||||
import InputAdornment from '@material-ui/core/InputAdornment';
|
||||
import IconButton from '@material-ui/core/IconButton';
|
||||
import FormControl from '@material-ui/core/FormControl';
|
||||
import FormHelperText from '@material-ui/core/FormHelperText';
|
||||
import InputLabel from '@material-ui/core/InputLabel';
|
||||
import Input from '@material-ui/core/Input';
|
||||
|
||||
import Visibility from '@material-ui/icons/Visibility';
|
||||
import VisibilityOff from '@material-ui/icons/VisibilityOff';
|
||||
|
||||
|
||||
|
||||
interface NoChangePasswordProps {
|
||||
hasPassword: boolean;
|
||||
label: string;
|
||||
defaultValue: string;
|
||||
onPasswordChange: (text: string) => void;
|
||||
disabled?: boolean;
|
||||
helperText?: string;
|
||||
error?: boolean;
|
||||
};
|
||||
|
||||
interface NoChangePasswordState {
|
||||
focused: boolean;
|
||||
passwordText: string;
|
||||
showPassword: boolean;
|
||||
};
|
||||
|
||||
class NoChangePassword extends React.Component<NoChangePasswordProps, NoChangePasswordState> {
|
||||
refText: React.Ref<HTMLInputElement | HTMLTextAreaElement>;
|
||||
|
||||
constructor(props: NoChangePasswordProps) {
|
||||
super(props);
|
||||
this.refText = React.createRef();
|
||||
this.state = {
|
||||
focused: false,
|
||||
showPassword: false,
|
||||
passwordText: this.props.defaultValue as string
|
||||
};
|
||||
}
|
||||
|
||||
handleShowPassword() {
|
||||
this.setState({
|
||||
showPassword: !this.state.showPassword
|
||||
});
|
||||
}
|
||||
handleChange(e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) {
|
||||
this.textChanged = true;
|
||||
this.props.onPasswordChange(e.target.value);
|
||||
}
|
||||
|
||||
textChanged: boolean = false;
|
||||
handleFocus(e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) {
|
||||
console.log("onFocus");
|
||||
if (!this.state.focused) {
|
||||
this.textChanged = false;
|
||||
e.target.value = this.state.passwordText;
|
||||
}
|
||||
e.currentTarget.removeAttribute("readonly");
|
||||
this.setState({ focused: true });
|
||||
}
|
||||
handleBlur(e: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) {
|
||||
console.log("onBlur");
|
||||
let text = e.target.value as string;
|
||||
this.setState({ focused: false, passwordText: text });
|
||||
this.props.onPasswordChange(e.target.value);
|
||||
this.textChanged = false;
|
||||
if (text.length === 0 && this.props.hasPassword)
|
||||
{
|
||||
e.target.value = "(Unchanged)";
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
console.log("Render focus: " + this.state.focused)
|
||||
let showUnchanged = (this.state.passwordText.length === 0) && this.props.hasPassword && (!this.state.focused);
|
||||
let thisDefaultValue = showUnchanged ? "(Unchanged)" : this.props.defaultValue;
|
||||
|
||||
let isText = showUnchanged || this.state.showPassword;
|
||||
|
||||
|
||||
return (
|
||||
<FormControl disabled={this.props.disabled} fullWidth error={this.props.error} >
|
||||
<InputLabel htmlFor="standard-adornment-password">{this.props.label}</InputLabel>
|
||||
<Input
|
||||
fullWidth
|
||||
color="primary"
|
||||
spellCheck="false"
|
||||
autoComplete="off"
|
||||
readOnly
|
||||
id="standard-adornment-password"
|
||||
onChange={(e) => this.handleChange(e)}
|
||||
value={thisDefaultValue}
|
||||
onFocus={(e) => this.handleFocus(e)}
|
||||
onBlur={(e) => this.handleBlur(e)}
|
||||
type={isText ? 'text' : 'password'}
|
||||
style={ { color: showUnchanged? '#888': '#000'} }
|
||||
|
||||
endAdornment={
|
||||
<InputAdornment position="end">
|
||||
<IconButton
|
||||
aria-label="toggle password visibility"
|
||||
onClick={(e) => this.handleShowPassword()}
|
||||
onMouseDown={(e) => e.preventDefault()}
|
||||
>
|
||||
{this.state.showPassword ? <Visibility /> : <VisibilityOff />}
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
}
|
||||
/>
|
||||
<FormHelperText >{ this.props.helperText}</FormHelperText>
|
||||
</FormControl>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default NoChangePassword;
|
||||
@@ -117,7 +117,7 @@ const pedalBoardStyles = (theme: Theme) => createStyles({
|
||||
marginBottom: (CELL_HEIGHT - FRAME_SIZE) / 2,
|
||||
width: FRAME_SIZE,
|
||||
height: FRAME_SIZE,
|
||||
border: "1pt black solid",
|
||||
border: "1pt #666 solid",
|
||||
borderRadius: 6
|
||||
},
|
||||
pedalIcon: {
|
||||
|
||||
+108
-6
@@ -13,6 +13,8 @@ import JackHostStatus from './JackHostStatus';
|
||||
import JackServerSettings from './JackServerSettings';
|
||||
import MidiBinding from './MidiBinding';
|
||||
import PluginPreset from './PluginPreset';
|
||||
import WifiConfigSettings from './WifiConfigSettings';
|
||||
import WifiChannel from './WifiChannel';
|
||||
|
||||
|
||||
export enum State {
|
||||
@@ -235,6 +237,7 @@ interface ControlChangedBody {
|
||||
|
||||
export interface PiPedalModel {
|
||||
clientId: number;
|
||||
countryCodes: Object;
|
||||
serverVersion?: PiPedalVersion;
|
||||
errorMessage: ObservableProperty<string>;
|
||||
alertMessage: ObservableProperty<string>;
|
||||
@@ -245,6 +248,7 @@ export interface PiPedalModel {
|
||||
jackSettings: ObservableProperty<JackChannelSelection>;
|
||||
banks: ObservableProperty<BankIndex>;
|
||||
jackServerSettings: ObservableProperty<JackServerSettings>;
|
||||
wifiConfigSettings: ObservableProperty<WifiConfigSettings>;
|
||||
|
||||
presets: ObservableProperty<PresetIndex>;
|
||||
|
||||
@@ -320,13 +324,17 @@ export interface PiPedalModel {
|
||||
|
||||
uploadPreset(file: File, uploadAfter: number): Promise<number>;
|
||||
|
||||
setWifiConfigSettings(wifiConfigSettings: WifiConfigSettings): Promise<void>;
|
||||
|
||||
getWifiChannels(countryIso3661: string): Promise<WifiChannel[]>;
|
||||
|
||||
};
|
||||
|
||||
class PiPedalModelImpl implements PiPedalModel {
|
||||
clientId: number = -1;
|
||||
|
||||
serverVersion?: PiPedalVersion;
|
||||
|
||||
countryCodes: Object = {};
|
||||
socketServerUrl: string = "";
|
||||
varServerUrl: string = "";
|
||||
lv2Path: string = "";
|
||||
@@ -346,6 +354,8 @@ class PiPedalModelImpl implements PiPedalModel {
|
||||
jackServerSettings: ObservableProperty<JackServerSettings>
|
||||
= new ObservableProperty<JackServerSettings>(new JackServerSettings());
|
||||
|
||||
wifiConfigSettings: ObservableProperty<WifiConfigSettings> = new ObservableProperty<WifiConfigSettings>(new WifiConfigSettings());
|
||||
|
||||
|
||||
presets: ObservableProperty<PresetIndex> = new ObservableProperty<PresetIndex>
|
||||
(
|
||||
@@ -459,6 +469,9 @@ class PiPedalModelImpl implements PiPedalModel {
|
||||
} else if (message === "onJackServerSettingsChanged") {
|
||||
let jackServerSettings = new JackServerSettings().deserialize(body);
|
||||
this.jackServerSettings.set(jackServerSettings);
|
||||
} else if (message === "onWifiConfigSettingsChanged") {
|
||||
let wifiConfigSettings = new WifiConfigSettings().deserialize(body);
|
||||
this.wifiConfigSettings.set(wifiConfigSettings);
|
||||
} else if (message === "onBanksChanged") {
|
||||
let banks = new BankIndex().deserialize(body);
|
||||
this.banks.set(banks);
|
||||
@@ -537,6 +550,11 @@ class PiPedalModelImpl implements PiPedalModel {
|
||||
.then(data => {
|
||||
this.pedalBoard.set(new PedalBoard().deserialize(data));
|
||||
|
||||
return this.getWebSocket().request<any>("getWifiConfigSettings");
|
||||
})
|
||||
.then(data => {
|
||||
this.wifiConfigSettings.set(new WifiConfigSettings().deserialize(data));
|
||||
|
||||
return this.getWebSocket().request<any>("getJackServerSettings");
|
||||
})
|
||||
.then(data => {
|
||||
@@ -573,7 +591,7 @@ class PiPedalModelImpl implements PiPedalModel {
|
||||
})
|
||||
}
|
||||
makeSocketServerUrl(hostName: string, port: number): string {
|
||||
return "ws://" + hostName + ":" + port + "/piddle";
|
||||
return "ws://" + hostName + ":" + port + "/pipedal";
|
||||
|
||||
}
|
||||
makeVarServerUrl(protocol: string, hostName: string, port: number): string {
|
||||
@@ -587,11 +605,12 @@ class PiPedalModelImpl implements PiPedalModel {
|
||||
const myRequest = new Request(this.varRequest('config.json'));
|
||||
return fetch(myRequest)
|
||||
.then(
|
||||
response => response.json()
|
||||
|
||||
(response) =>
|
||||
{
|
||||
return response.json();
|
||||
}
|
||||
)
|
||||
.then(data => {
|
||||
console.log("Got config");
|
||||
if (data.max_upload_size)
|
||||
{
|
||||
this.maxUploadSize = data.max_upload_size;
|
||||
@@ -617,6 +636,15 @@ class PiPedalModelImpl implements PiPedalModel {
|
||||
return this.webSocket.connect();
|
||||
})
|
||||
.then(() => {
|
||||
const isoRequest = new Request('iso_codes.json');
|
||||
return fetch(isoRequest);
|
||||
})
|
||||
.then((response) => {
|
||||
return response.json();
|
||||
})
|
||||
.then((countryCodes) => {
|
||||
this.countryCodes = countryCodes as Object;
|
||||
|
||||
return this.getWebSocket().request<number>("hello");
|
||||
})
|
||||
.then((clientId) => {
|
||||
@@ -652,7 +680,12 @@ class PiPedalModelImpl implements PiPedalModel {
|
||||
})
|
||||
.then((data) => {
|
||||
this.presets.set(new PresetIndex().deserialize(data));
|
||||
|
||||
return this.getWebSocket().request<any>("getWifiConfigSettings");
|
||||
})
|
||||
.then(data => {
|
||||
this.wifiConfigSettings.set(new WifiConfigSettings().deserialize(data));
|
||||
|
||||
|
||||
return this.getWebSocket().request<any>("getJackServerSettings");
|
||||
})
|
||||
.then(data => {
|
||||
@@ -1427,6 +1460,75 @@ class PiPedalModelImpl implements PiPedalModel {
|
||||
});
|
||||
return result;
|
||||
}
|
||||
setWifiConfigSettings(wifiConfigSettings: WifiConfigSettings): Promise<void>
|
||||
{
|
||||
let result = new Promise<void>((resolve,reject) =>{
|
||||
let oldSettings = this.wifiConfigSettings.get();
|
||||
wifiConfigSettings = wifiConfigSettings.clone();
|
||||
|
||||
if ((!oldSettings.enable) && (!wifiConfigSettings.enable))
|
||||
{
|
||||
// no effective change.
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
let countryCodeChanged = wifiConfigSettings.countryCode !== oldSettings.countryCode;
|
||||
if (!wifiConfigSettings.enable)
|
||||
{
|
||||
wifiConfigSettings.hasPassword = false;
|
||||
wifiConfigSettings.hotspotName = oldSettings.hotspotName;
|
||||
} else {
|
||||
if (!wifiConfigSettings.hasPassword) {
|
||||
if (wifiConfigSettings.hotspotName === oldSettings.hotspotName && !countryCodeChanged) {
|
||||
// no effective change.
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
// save a version for the server (potentially carrying a password)
|
||||
let serverConfigSettings = wifiConfigSettings.clone();
|
||||
|
||||
|
||||
|
||||
// notify the server.
|
||||
let ws = this.webSocket;
|
||||
if (!ws)
|
||||
{
|
||||
reject("Not connected.");
|
||||
return;
|
||||
}
|
||||
ws.request<void>(
|
||||
"setWifiConfigSettings",
|
||||
serverConfigSettings
|
||||
)
|
||||
.then(()=> {
|
||||
resolve();
|
||||
})
|
||||
.catch((err) =>{
|
||||
reject(err);
|
||||
});
|
||||
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
getWifiChannels(countryIso3661: string): Promise<WifiChannel[]>
|
||||
{
|
||||
let result = new Promise<WifiChannel[]>((resolve,reject) => {
|
||||
if (!this.webSocket) {
|
||||
reject("Connection closed.");
|
||||
return;
|
||||
}
|
||||
this.webSocket.request<WifiChannel[]>("getWifiChannels",countryIso3661)
|
||||
.then((data) => {
|
||||
resolve(WifiChannel.deserialize_array(data));
|
||||
})
|
||||
.catch((err)=> reject(err));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -100,12 +100,12 @@ const styles = (theme: Theme) => createStyles({
|
||||
marginRight: 8,
|
||||
marginBottom: 12,
|
||||
position: "relative",
|
||||
paddingLeft: 0,
|
||||
paddingLeft: 3,
|
||||
paddingRight: 0,
|
||||
paddingTop: 0,
|
||||
paddingBottom: 0,
|
||||
border: "2pt #AAA solid",
|
||||
borderRadius: 10,
|
||||
borderRadius: 4,
|
||||
elevation: 12,
|
||||
display: "flex",
|
||||
flexDirection: "row", flexWrap: "wrap",
|
||||
|
||||
@@ -95,7 +95,7 @@ export default class RenameDialog extends ResizeResponsiveComponent<RenameDialog
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
super.componentDidMount();
|
||||
super.componentWillUnmount();
|
||||
this.mounted = false;
|
||||
this.updateHooks();
|
||||
}
|
||||
|
||||
@@ -5,7 +5,6 @@ import { PiPedalModel, PiPedalModelFactory } from './PiPedalModel';
|
||||
import ButtonBase from "@material-ui/core/ButtonBase";
|
||||
import { TransitionProps } from '@material-ui/core/transitions/transition';
|
||||
import Slide from '@material-ui/core/Slide';
|
||||
import Dialog from '@material-ui/core/Dialog';
|
||||
import AppBar from '@material-ui/core/AppBar';
|
||||
import Toolbar from '@material-ui/core/Toolbar';
|
||||
import { Theme, withStyles, WithStyles, createStyles } from '@material-ui/core/styles';
|
||||
@@ -18,6 +17,9 @@ import SelectHoverBackground from './SelectHoverBackground';
|
||||
import JackServerSettings from './JackServerSettings';
|
||||
import JackServerSettingsDialog from './JackServerSettingsDialog';
|
||||
import JackHostStatus from './JackHostStatus';
|
||||
import WifiConfigSettings from './WifiConfigSettings';
|
||||
import WifiConfigDialog from './WifiConfigDialog';
|
||||
import DialogEx from './DialogEx'
|
||||
|
||||
|
||||
|
||||
@@ -34,6 +36,9 @@ interface SettingsDialogState {
|
||||
jackServerSettings: JackServerSettings;
|
||||
jackStatus?: JackHostStatus;
|
||||
|
||||
wifiConfigSettings: WifiConfigSettings;
|
||||
|
||||
showWifiConfigDialog: boolean;
|
||||
showInputSelectDialog: boolean;
|
||||
showOutputSelectDialog: boolean;
|
||||
showMidiSelectDialog: boolean;
|
||||
@@ -120,6 +125,8 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
||||
jackConfiguration: this.model.jackConfiguration.get(),
|
||||
jackStatus: undefined,
|
||||
jackSettings: this.model.jackSettings.get(),
|
||||
wifiConfigSettings: this.model.wifiConfigSettings.get(),
|
||||
showWifiConfigDialog: false,
|
||||
showInputSelectDialog: false,
|
||||
showOutputSelectDialog: false,
|
||||
showMidiSelectDialog: false,
|
||||
@@ -132,10 +139,28 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
||||
this.handleJackConfigurationChanged = this.handleJackConfigurationChanged.bind(this);
|
||||
this.handleJackSettingsChanged = this.handleJackSettingsChanged.bind(this);
|
||||
this.handleJackServerSettingsChanged = this.handleJackServerSettingsChanged.bind(this);
|
||||
this.handleWifiConfigSettingsChanged = this.handleWifiConfigSettingsChanged.bind(this);
|
||||
|
||||
}
|
||||
|
||||
handleApplyWifiConfig(wifiConfigSettings: WifiConfigSettings): void {
|
||||
this.setState({showWifiConfigDialog: false});
|
||||
this.model.setWifiConfigSettings(wifiConfigSettings)
|
||||
.then(() => {
|
||||
|
||||
})
|
||||
.catch((err) => {
|
||||
this.model.showAlert(err);
|
||||
});
|
||||
}
|
||||
|
||||
handleWifiConfigSettingsChanged(): void {
|
||||
this.setState(
|
||||
{
|
||||
wifiConfigSettings: this.model.wifiConfigSettings.get()
|
||||
}
|
||||
)
|
||||
}
|
||||
handleJackSettingsChanged(): void {
|
||||
this.setState({
|
||||
jackSettings: this.model.jackSettings.get()
|
||||
@@ -177,6 +202,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
||||
this.model.jackSettings.addOnChangedHandler(this.handleJackSettingsChanged);
|
||||
this.model.jackConfiguration.addOnChangedHandler(this.handleJackConfigurationChanged);
|
||||
this.model.jackServerSettings.addOnChangedHandler(this.handleJackServerSettingsChanged);
|
||||
this.model.wifiConfigSettings.addOnChangedHandler(this.handleWifiConfigSettingsChanged);
|
||||
this.model.getJackStatus()
|
||||
.then((jackStatus) =>
|
||||
this.setState(
|
||||
@@ -193,7 +219,8 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
||||
this.handleJackConfigurationChanged();
|
||||
this.handleJackSettingsChanged();
|
||||
this.handleJackServerSettingsChanged();
|
||||
this.timerHandle = setInterval(() => this.tick(), 1000);
|
||||
this.handleWifiConfigSettingsChanged();
|
||||
// xxx UNCOMMENT ME! this.timerHandle = setInterval(() => this.tick(), 1000);
|
||||
} else {
|
||||
if (this.timerHandle) {
|
||||
clearInterval(this.timerHandle);
|
||||
@@ -201,6 +228,8 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
||||
this.model.jackConfiguration.removeOnChangedHandler(this.handleJackConfigurationChanged);
|
||||
this.model.jackSettings.removeOnChangedHandler(this.handleJackSettingsChanged);
|
||||
this.model.jackServerSettings.removeOnChangedHandler(this.handleJackServerSettingsChanged);
|
||||
this.model.wifiConfigSettings.removeOnChangedHandler(this.handleWifiConfigSettingsChanged);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,25 +321,33 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
||||
if (ports.length === 1) return ports[0];
|
||||
return ports.length + " channels";
|
||||
}
|
||||
|
||||
handleShowWifiConfigDialog() {
|
||||
this.setState({
|
||||
showWifiConfigDialog: true
|
||||
});
|
||||
}
|
||||
handleRestart() {
|
||||
this.setState({ restarting: true });
|
||||
this.model.restart()
|
||||
.then(() => {
|
||||
this.setState({ restarting: true });
|
||||
// this.setState({ restarting: true });
|
||||
})
|
||||
.catch((error) => {
|
||||
this.model.showAlert(error);
|
||||
this.setState({ restarting: false });
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
handleShutdown() {
|
||||
this.setState({ shuttingDown: true });
|
||||
this.model.shutdown()
|
||||
.then(() => {
|
||||
this.setState({ shuttingDown: true });
|
||||
})
|
||||
.catch((error) => {
|
||||
this.model.showAlert(error);
|
||||
this.setState({ shuttingDown: false });
|
||||
});
|
||||
|
||||
}
|
||||
@@ -322,7 +359,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
||||
let disableShutdown = this.state.shuttingDown || this.state.restarting;
|
||||
|
||||
return (
|
||||
<Dialog fullScreen open={this.props.open}
|
||||
<DialogEx tag="SettingsDialog" fullScreen open={this.props.open}
|
||||
onClose={() => { this.props.onClose() }} TransitionComponent={Transition}>
|
||||
|
||||
<div style={{ display: "flex", flexDirection: "column", flexWrap: "nowrap", width: "100%", height: "100%", overflow: "hidden" }}>
|
||||
@@ -428,6 +465,18 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
||||
<Divider />
|
||||
<div >
|
||||
<Typography className={classes.sectionHead} display="block" variant="caption" color="secondary">SYSTEM</Typography>
|
||||
<ButtonBase className={classes.setting} disabled={!this.state.wifiConfigSettings.valid}
|
||||
onClick={() => this.handleShowWifiConfigDialog()} >
|
||||
<SelectHoverBackground selected={false} showHover={true} />
|
||||
<div style={{ width: "100%" }}>
|
||||
<Typography className={classes.primaryItem} display="block" variant="body2" color="textPrimary" noWrap>
|
||||
Configure Wi-fi Hotspot</Typography>
|
||||
<Typography display="block" variant="caption" noWrap color="textSecondary">
|
||||
{this.state.wifiConfigSettings.getSummaryText()}
|
||||
</Typography>
|
||||
|
||||
</div>
|
||||
</ButtonBase>
|
||||
<ButtonBase className={classes.setting} disabled={!isConfigValid || disableShutdown}
|
||||
onClick={() => this.handleRestart()} >
|
||||
<SelectHoverBackground selected={false} showHover={true} />
|
||||
@@ -452,7 +501,7 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
||||
) : (
|
||||
<Typography className={classes.primaryItem} display="block" variant="body2" noWrap>Shut down</Typography>
|
||||
)
|
||||
}
|
||||
}
|
||||
</div >
|
||||
</ButtonBase>
|
||||
</div>
|
||||
@@ -483,8 +532,12 @@ const SettingsDialog = withStyles(styles, { withTheme: true })(
|
||||
|
||||
)
|
||||
}
|
||||
<WifiConfigDialog wifiConfigSettings={this.state.wifiConfigSettings} open={this.state.showWifiConfigDialog}
|
||||
onClose={()=> this.setState({showWifiConfigDialog: false})}
|
||||
onOk={(wifiConfigSettings) => this.handleApplyWifiConfig(wifiConfigSettings)}
|
||||
/>
|
||||
|
||||
</Dialog >
|
||||
</DialogEx >
|
||||
|
||||
);
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ export default class UploadDialog extends ResizeResponsiveComponent<UploadDialog
|
||||
this.updateHooks();
|
||||
}
|
||||
componentWillUnmount() {
|
||||
super.componentDidMount();
|
||||
super.componentWillUnmount();
|
||||
this.mounted = false;
|
||||
this.updateHooks();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
export default class WifiChannel {
|
||||
deserialize(input: any): WifiChannel {
|
||||
this.channelId = input.channelId;
|
||||
this.channelName = input.channelName;
|
||||
return this;
|
||||
}
|
||||
static deserialize_array(input: any): WifiChannel[]
|
||||
{
|
||||
let result: WifiChannel[] = [];
|
||||
for (let i = 0; i < input.length; ++i)
|
||||
{
|
||||
result.push(new WifiChannel().deserialize(input[i]));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
channelId: string = "";
|
||||
channelName: string = "";
|
||||
};
|
||||
@@ -0,0 +1,374 @@
|
||||
import React from 'react';
|
||||
import Button from '@material-ui/core/Button';
|
||||
import TextField from '@material-ui/core/TextField';
|
||||
import Dialog from '@material-ui/core/Dialog';
|
||||
import DialogActions from '@material-ui/core/DialogActions';
|
||||
import DialogContent from '@material-ui/core/DialogContent';
|
||||
import DialogTitle from '@material-ui/core/DialogTitle';
|
||||
import Switch from '@material-ui/core/Switch';
|
||||
import FormControlLabel from '@material-ui/core/FormControlLabel';
|
||||
import ResizeResponsiveComponent from './ResizeResponsiveComponent';
|
||||
import WifiConfigSettings from './WifiConfigSettings';
|
||||
import NoChangePassword from './NoChangePassword';
|
||||
import DialogEx from './DialogEx'
|
||||
import Typography from '@material-ui/core/Typography';
|
||||
import { Theme, withStyles, WithStyles,createStyles } from '@material-ui/core/styles';
|
||||
import Select from '@material-ui/core/Select';
|
||||
import FormControl from '@material-ui/core/FormControl';
|
||||
import InputLabel from '@material-ui/core/InputLabel';
|
||||
import MenuItem from '@material-ui/core/MenuItem';
|
||||
import WifiChannel from './WifiChannel';
|
||||
import {PiPedalModel, PiPedalModelFactory} from './PiPedalModel';
|
||||
|
||||
const styles = (theme: Theme) => createStyles({
|
||||
pgraph: {
|
||||
paddingBottom: 16
|
||||
}
|
||||
});
|
||||
|
||||
const NBSP = "\u00A0";
|
||||
|
||||
export interface WifiConfigProps extends WithStyles<typeof styles> {
|
||||
open: boolean,
|
||||
wifiConfigSettings: WifiConfigSettings,
|
||||
onOk: (wifiConfigSettings: WifiConfigSettings) => void,
|
||||
onClose: () => void
|
||||
};
|
||||
|
||||
export interface WifiConfigState {
|
||||
fullScreen: boolean;
|
||||
showWifiWarningDialog: boolean;
|
||||
wifiWarningGiven: boolean;
|
||||
enabled: boolean;
|
||||
name: string;
|
||||
newPassword: string;
|
||||
nameError: boolean;
|
||||
nameErrorMessage: string;
|
||||
passwordError: boolean;
|
||||
passwordErrorMessage: string;
|
||||
countryCode: string;
|
||||
channel: string;
|
||||
wifiChannels: WifiChannel[];
|
||||
};
|
||||
|
||||
|
||||
let validNameRegex = /^[a-zA-Z][a-zA-Z0-9_-]*$/
|
||||
function isValidName(text: string)
|
||||
{
|
||||
return validNameRegex.test(text);
|
||||
}
|
||||
|
||||
const WifiConfigDialog = withStyles(styles, { withTheme: true })(
|
||||
class extends ResizeResponsiveComponent<WifiConfigProps, WifiConfigState> {
|
||||
|
||||
refName: React.RefObject<HTMLInputElement>;
|
||||
refPassword: React.RefObject<HTMLInputElement>;
|
||||
model: PiPedalModel;
|
||||
|
||||
constructor(props: WifiConfigProps) {
|
||||
super(props);
|
||||
this.model = PiPedalModelFactory.getInstance();
|
||||
this.state = {
|
||||
fullScreen: false,
|
||||
enabled: this.props.wifiConfigSettings.enable,
|
||||
name: this.props.wifiConfigSettings.hotspotName,
|
||||
newPassword: "",
|
||||
nameError: false,
|
||||
nameErrorMessage: NBSP,
|
||||
passwordError: false,
|
||||
showWifiWarningDialog: false,
|
||||
wifiWarningGiven: this.props.wifiConfigSettings.wifiWarningGiven,
|
||||
passwordErrorMessage: NBSP,
|
||||
countryCode: this.props.wifiConfigSettings.countryCode,
|
||||
channel: this.props.wifiConfigSettings.channel,
|
||||
wifiChannels: []
|
||||
};
|
||||
this.model.getWifiChannels(this.props.wifiConfigSettings.countryCode)
|
||||
.then((wifiChannels_) => {
|
||||
this.setState({wifiChannels: wifiChannels_});
|
||||
}).catch((err)=> {});
|
||||
|
||||
this.refName = React.createRef<HTMLInputElement>();
|
||||
this.refPassword = React.createRef<HTMLInputElement>();
|
||||
this.handlePopState = this.handlePopState.bind(this);
|
||||
}
|
||||
mounted: boolean = false;
|
||||
|
||||
hasHooks: boolean = false;
|
||||
|
||||
stateWasPopped: boolean = false;
|
||||
|
||||
handleEnableChanged(e: any) {
|
||||
this.setState({ enabled: e.target.checked });
|
||||
}
|
||||
handlePopState(e: any): any {
|
||||
this.stateWasPopped = true;
|
||||
let shouldClose = (!e.state || !e.state.WifiConfig);
|
||||
if (shouldClose) {
|
||||
this.props.onClose();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
updateHooks(): void {
|
||||
let wantHooks = this.mounted && this.props.open;
|
||||
if (wantHooks !== this.hasHooks) {
|
||||
this.hasHooks = wantHooks;
|
||||
|
||||
if (this.hasHooks) {
|
||||
this.stateWasPopped = false;
|
||||
window.addEventListener("popstate", this.handlePopState);
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
let state = history.state;
|
||||
if (!state) {
|
||||
state = {};
|
||||
}
|
||||
state.WifiConfig = true;
|
||||
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
history.pushState(
|
||||
state,
|
||||
"Wi-Fi Configuration",
|
||||
"#WifiConfig"
|
||||
);
|
||||
} else {
|
||||
window.removeEventListener("popstate", this.handlePopState);
|
||||
if (!this.stateWasPopped) {
|
||||
// eslint-disable-next-line no-restricted-globals
|
||||
history.back();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
onWindowSizeChanged(width: number, height: number): void {
|
||||
this.setState({ fullScreen: height < 200 })
|
||||
}
|
||||
|
||||
|
||||
componentDidMount() {
|
||||
super.componentDidMount();
|
||||
this.mounted = true;
|
||||
this.updateHooks();
|
||||
}
|
||||
componentWillUnmount() {
|
||||
super.componentWillUnmount();
|
||||
this.mounted = false;
|
||||
this.updateHooks();
|
||||
}
|
||||
|
||||
componentDidUpdate(prevProps: WifiConfigProps) {
|
||||
this.updateHooks();
|
||||
|
||||
if (this.props.open && !prevProps.open)
|
||||
{
|
||||
this.setState({
|
||||
enabled: this.props.wifiConfigSettings.enable,
|
||||
name: this.props.wifiConfigSettings.hotspotName,
|
||||
newPassword: "",
|
||||
wifiWarningGiven: this.props.wifiConfigSettings.wifiWarningGiven,
|
||||
countryCode: this.props.wifiConfigSettings.countryCode,
|
||||
channel: this.props.wifiConfigSettings.channel
|
||||
});
|
||||
|
||||
if (this.props.wifiConfigSettings.countryCode !== this.state.countryCode)
|
||||
{
|
||||
this.model.getWifiChannels(this.props.wifiConfigSettings.countryCode)
|
||||
.then((wifiChannels) => {
|
||||
this.setState({wifiChannels: wifiChannels});
|
||||
})
|
||||
.catch((error) => {});
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
handleOk(wifiWarningGiven: boolean) {
|
||||
let hasError = false;
|
||||
if (this.state.enabled)
|
||||
{
|
||||
let name = this.state.name;
|
||||
if (name.length === 0) {
|
||||
this.setState({nameError: true, nameErrorMessage: "* Required"});
|
||||
hasError = true;
|
||||
} else {
|
||||
if (!isValidName(name))
|
||||
{
|
||||
this.setState({nameError: true, nameErrorMessage: "Invalid name"});
|
||||
hasError = true;
|
||||
} else if (name.length > 15)
|
||||
{
|
||||
this.setState({nameError: true, nameErrorMessage: "> 15 characters"});
|
||||
hasError = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (this.state.enabled && (!this.props.wifiConfigSettings.hasPassword) && this.state.newPassword.length === 0)
|
||||
{
|
||||
this.setState({passwordError: true, passwordErrorMessage: "* Required"});
|
||||
hasError = true;
|
||||
}
|
||||
if (!hasError)
|
||||
{
|
||||
let wifiConfigSettings = new WifiConfigSettings();
|
||||
wifiConfigSettings.valid = true;
|
||||
|
||||
wifiConfigSettings.enable = this.state.enabled;
|
||||
wifiConfigSettings.hotspotName = this.state.name;
|
||||
if (this.state.newPassword.length === 0 || !this.state.enabled)
|
||||
{
|
||||
wifiConfigSettings.hasPassword = false;
|
||||
} else {
|
||||
wifiConfigSettings.hasPassword = true;
|
||||
wifiConfigSettings.password = this.state.newPassword;
|
||||
}
|
||||
|
||||
if (!this.props.wifiConfigSettings.wifiWarningGiven && !wifiWarningGiven) {
|
||||
this.setState({showWifiWarningDialog: true});
|
||||
} else {
|
||||
wifiConfigSettings.wifiWarningGiven = true;
|
||||
this.props.onOk(wifiConfigSettings);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
handleChannelChange(e: any)
|
||||
{
|
||||
let value = e.target.value as string;
|
||||
this.setState({channel: value });
|
||||
}
|
||||
handleCountryChanged(e: any)
|
||||
{
|
||||
let value = e.target.value as string;
|
||||
|
||||
this.setState({countryCode: value});
|
||||
this.model.getWifiChannels(value)
|
||||
.then(wifiChannels => {
|
||||
this.setState({wifiChannels: wifiChannels});
|
||||
})
|
||||
.catch((error)=> { });
|
||||
}
|
||||
|
||||
render() {
|
||||
let props = this.props;
|
||||
let classes = this.props.classes;
|
||||
let { open, onClose} = props;
|
||||
|
||||
const handleClose = () => {
|
||||
onClose();
|
||||
};
|
||||
|
||||
return (
|
||||
<Dialog open={open} fullWidth onClose={handleClose} style={{}}
|
||||
fullScreen={this.state.fullScreen}
|
||||
>
|
||||
{ this.state.fullScreen && (
|
||||
<DialogTitle>Wi-fi Hotspot</DialogTitle>
|
||||
)}
|
||||
<DialogContent>
|
||||
|
||||
<FormControlLabel
|
||||
control={(
|
||||
<Switch
|
||||
checked={this.state.enabled}
|
||||
onChange={(e: any) => this.handleEnableChanged(e)}
|
||||
color="secondary"
|
||||
/>
|
||||
)}
|
||||
label="Enable"
|
||||
/>
|
||||
<TextField style={{ marginBottom: 16, marginTop: 16 }}
|
||||
|
||||
autoComplete="off"
|
||||
id="name"
|
||||
spellCheck="false"
|
||||
label="SSID"
|
||||
type="text"
|
||||
fullWidth
|
||||
error={this.state.nameError}
|
||||
helperText={this.state.nameErrorMessage}
|
||||
value={this.state.name}
|
||||
onChange={(e) => this.setState({name: e.target.value, nameError: false, nameErrorMessage: NBSP})}
|
||||
inputRef={this.refName}
|
||||
disabled={!this.state.enabled}
|
||||
/>
|
||||
<div style={{ marginBottom: 16 }}>
|
||||
<NoChangePassword
|
||||
onPasswordChange={(text): void => { this.setState({ newPassword: text, passwordError: false, passwordErrorMessage: NBSP }); }}
|
||||
hasPassword={this.props.wifiConfigSettings.hasPassword}
|
||||
label="WEP Passphrase"
|
||||
error={this.state.passwordError}
|
||||
helperText={this.state.passwordErrorMessage}
|
||||
defaultValue={this.state.newPassword}
|
||||
disabled={!this.state.enabled}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ marginBottom: 16}}>
|
||||
<FormControl>
|
||||
<InputLabel htmlFor="countryCodeSelect">Country</InputLabel>
|
||||
<Select id="countryCodeSelect" value={this.state.countryCode} style={{width: 220}}
|
||||
onChange={(event)=>this.handleCountryChanged(event)} >
|
||||
{Object.entries(this.model.countryCodes).map(([key,value])=> {
|
||||
return (
|
||||
<MenuItem value={key}>{value}</MenuItem>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
</div>
|
||||
<div style={{ marginBottom: 24}}>
|
||||
<FormControl>
|
||||
<InputLabel htmlFor="channelSelect">Channel</InputLabel>
|
||||
<Select id="channelSelect" value={this.state.channel} style={{width: 220}} onChange={(e)=>{
|
||||
this.handleChannelChange(e);
|
||||
}}>
|
||||
{this.state.wifiChannels.map((channel)=> {
|
||||
return (
|
||||
<MenuItem value={channel.channelId}>{channel.channelName}</MenuItem>
|
||||
)
|
||||
})}
|
||||
</Select>
|
||||
</FormControl>
|
||||
|
||||
</div>
|
||||
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={handleClose} color="primary" style={{ width: 120 }}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={()=> this.handleOk(false)} color="secondary" style={{ width: 120 }} >
|
||||
OK
|
||||
</Button>
|
||||
</DialogActions>
|
||||
<DialogEx open={this.state.showWifiWarningDialog} tag="wifiConfirm" >
|
||||
<DialogContent>
|
||||
<Typography className={classes.pgraph} variant="body2" color="textPrimary">
|
||||
Enabling the Wi-Fi hotspot will disable regular Wi-Fi network access on the PiPedal device. Once
|
||||
enabled, connect to the hotspot and launch http://172.24.1.1 or http://{this.state.name}.local to access the PiPedal web app again.
|
||||
</Typography>
|
||||
<Typography className={classes.pgraph} variant="body2" color="textPrimary" gutterBottom>
|
||||
Are you sure you want to proceed?
|
||||
</Typography>
|
||||
</DialogContent>
|
||||
<DialogActions>
|
||||
<Button onClick={()=> this.setState({showWifiWarningDialog: false})} color="primary" style={{ width: 120 }}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={()=> {
|
||||
this.setState({showWifiWarningDialog: false});
|
||||
this.handleOk(true);
|
||||
}} color="secondary" style={{ width: 120 }} >
|
||||
PROCEED
|
||||
</Button>
|
||||
</DialogActions>
|
||||
</DialogEx>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
export default WifiConfigDialog;
|
||||
@@ -0,0 +1,45 @@
|
||||
|
||||
|
||||
export default class WifiConfigSettings {
|
||||
deserialize(input: any) : WifiConfigSettings{
|
||||
this.valid = input.valid;
|
||||
this.wifiWarningGiven = input.wifiWarningGiven;
|
||||
this.rebootRequired = input.rebootRequired;
|
||||
this.enable = input.enable;
|
||||
this.hotspotName = input.hotspotName;
|
||||
this.hasPassword = input.hasPassword;
|
||||
this.password = input.password;
|
||||
this.countryCode = input.countryCode;
|
||||
this.channel = input.channel;
|
||||
return this;
|
||||
}
|
||||
clone() : WifiConfigSettings {
|
||||
return this.deserialize(this);
|
||||
}
|
||||
valid: boolean = true;
|
||||
wifiWarningGiven: boolean = false;
|
||||
enable: boolean = true;
|
||||
hasPassword: boolean = false;
|
||||
rebootRequired = false;
|
||||
hotspotName: string = "pipedal";
|
||||
password: string = "";
|
||||
countryCode: string = "US";
|
||||
channel: string = "g6";
|
||||
|
||||
getSummaryText() {
|
||||
let result: string;
|
||||
if (!this.valid) {
|
||||
result = "Not available.";
|
||||
} else if (!this.enable) {
|
||||
result = "Disabled.";
|
||||
} else {
|
||||
result = this.hotspotName;
|
||||
}
|
||||
if (this.rebootRequired)
|
||||
{
|
||||
result += " (Restart required)";
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import React from 'react';
|
||||
import { Theme, withStyles, WithStyles,createStyles } from '@material-ui/core/styles';
|
||||
|
||||
|
||||
const styles = (theme: Theme) => createStyles({
|
||||
});
|
||||
|
||||
|
||||
interface XxxProps extends WithStyles<typeof styles> {
|
||||
theme: Theme,
|
||||
};
|
||||
|
||||
interface XxxState {
|
||||
|
||||
};
|
||||
|
||||
const Xxx = withStyles(styles, { withTheme: true })(
|
||||
|
||||
class extends React.Component<XxxProps, XxxState> {
|
||||
constructor(props: XxxProps)
|
||||
{
|
||||
super(props);
|
||||
this.state = {
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div/>
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export default Xxx;
|
||||
@@ -458,6 +458,9 @@ public:
|
||||
{
|
||||
this->ws_.close(websocket::close_reason());
|
||||
}
|
||||
virtual std::string getFromAddress() const {
|
||||
return this->fromAddress;
|
||||
}
|
||||
virtual void writeCallback(const std::string &text)
|
||||
{
|
||||
{
|
||||
|
||||
@@ -28,6 +28,7 @@ public:
|
||||
virtual void close() = 0;
|
||||
|
||||
virtual void writeCallback(const std::string& text) = 0;
|
||||
virtual std::string getFromAddress() const = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
@@ -43,6 +44,7 @@ private:
|
||||
protected:
|
||||
virtual void onReceive(const std::string_view&text) = 0;
|
||||
public:
|
||||
std::string getFromAddress() const { return writeCallback_->getFromAddress(); }
|
||||
void receive(const std::string_view&text) {
|
||||
onReceive(text);
|
||||
}
|
||||
|
||||
+54
-9
@@ -4,13 +4,27 @@ cmake_minimum_required(VERSION 3.19.0)
|
||||
|
||||
include(FindPkgConfig)
|
||||
|
||||
# Can't get the pkg_check to work.
|
||||
# pkg_check_modules(LIBNL3 "nl-genl-3")
|
||||
# if(!LIBNL3_FOUND)
|
||||
# message(ERROR "libnl-genl-3-dev package not installed.")
|
||||
# else()
|
||||
# message(STATUS "LIBNL3 libraries: ${LIBNL3_LIBRARIES}")
|
||||
# message(STATUS "LBNL3 includes: ${LIBNL3_INCLUDE_DIRS}")
|
||||
# endif()
|
||||
|
||||
# nlgenl-3 library.
|
||||
execute_process(COMMAND ls /usr/include/libnl3/netlink/netlink.h RESULT_VARIABLE LNL3_MISSING OUTPUT_QUIET ERROR_QUIET)
|
||||
if(LNL3_MISSING)
|
||||
message(ERROR " Need to: sudo apt get libnl-3-dev libnl-genl-3-dev ")
|
||||
endif()
|
||||
set(LIBNL3_INCLUDE_DIRS /usr/include/libnl3)
|
||||
set(LIBNL3_LIBRARIES nl-3 nl-genl-3)
|
||||
|
||||
|
||||
pkg_check_modules(SYSTEMD "systemd")
|
||||
if(!SYSTEMD_FOUND)
|
||||
message(ERROR "libsystemd-dev package not installed.")
|
||||
else()
|
||||
message(STATUS "SYSTEMD_LIBRARIES: ${SYSTEMD_LIBRARIES}")
|
||||
message(STATUS "SYSTEMD_INCLUDE_DIRS: ${SYSTEMD_INCLUDE_DIRS}")
|
||||
endif()
|
||||
|
||||
|
||||
@@ -55,8 +69,10 @@ message (STATUS "Cxx flags: ${CMAKE_CXX_FLAGS}" )
|
||||
|
||||
add_definitions(-DBOOST_ERROR_CODE_HEADER_ONLY)
|
||||
|
||||
add_executable(pipedald BeastServer.cpp BeastServer.hpp HtmlHelper.cpp HtmlHelper.hpp pch.h Uri.cpp Uri.hpp
|
||||
RequestHandler.hpp main.cpp json.cpp json.hpp Scratch.cpp Lv2Host.hpp Lv2Host.cpp
|
||||
set (PIPEDAL_SOURCES
|
||||
BeastServer.cpp BeastServer.hpp HtmlHelper.cpp HtmlHelper.hpp pch.h Uri.cpp Uri.hpp
|
||||
WifiConfigSettings.hpp WifiConfigSettings.cpp
|
||||
RequestHandler.hpp json.cpp json.hpp Scratch.cpp Lv2Host.hpp Lv2Host.cpp
|
||||
PluginType.hpp PluginType.cpp
|
||||
Lv2Log.hpp Lv2Log.cpp
|
||||
PiPedalSocket.hpp PiPedalSocket.cpp
|
||||
@@ -93,22 +109,51 @@ add_executable(pipedald BeastServer.cpp BeastServer.hpp HtmlHelper.cpp HtmlHelpe
|
||||
Locale.hpp Locale.cpp
|
||||
Lv2EventBufferWriter.hpp Lv2EventBufferWriter.cpp
|
||||
IpSubnet.hpp
|
||||
)
|
||||
WifiChannels.hpp
|
||||
WifiChannels.cpp
|
||||
RegDb.cpp RegDb.hpp
|
||||
)
|
||||
|
||||
configure_file(config.hpp.in config.hpp)
|
||||
|
||||
#################################
|
||||
add_executable(pipedald ${PIPEDAL_SOURCES} main.cpp
|
||||
)
|
||||
|
||||
include_directories( ${PiPedal_SOURCE_DIR}/. ../build/src)
|
||||
|
||||
target_precompile_headers(pipedald PRIVATE pch.h)
|
||||
|
||||
|
||||
target_include_directories(pipedald PRIVATE
|
||||
${JACK_INCLUDE_DIRS} ${LILV_0_INCLUDE_DIRS} ${SYSTEMD_INCLUDE_DIRS}
|
||||
${JACK_INCLUDE_DIRS} ${LILV_0_INCLUDE_DIRS} ${LIBNL3_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(pipedald PRIVATE pthread atomic stdc++fs
|
||||
${LILV_0_LIBRARIES} ${JACK_LIBRARIES} ${SYSTEMD_LIBRARIES} systemd
|
||||
${LILV_0_LIBRARIES} ${JACK_LIBRARIES} ${LIBNL3_LIBRARIES} systemd
|
||||
)
|
||||
#target_link_libraries(pipedald boost_system)
|
||||
|
||||
#################################
|
||||
add_executable(pipedaltest ${PIPEDAL_SOURCES} testMain.cpp
|
||||
jsonTest.cpp
|
||||
WifiChannelsTest.cpp
|
||||
)
|
||||
|
||||
configure_file(config.hpp.in config.hpp)
|
||||
include_directories( ${PiPedal_SOURCE_DIR}/. ../build/src)
|
||||
|
||||
target_precompile_headers(pipedaltest PRIVATE pch.h)
|
||||
|
||||
|
||||
target_include_directories(pipedaltest PRIVATE
|
||||
${JACK_INCLUDE_DIRS} ${LILV_0_INCLUDE_DIRS} ${LIBNL3_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
target_link_libraries(pipedaltest PRIVATE pthread atomic stdc++fs
|
||||
${LILV_0_LIBRARIES} ${JACK_LIBRARIES} ${LIBNL3_LIBRARIES} systemd
|
||||
)
|
||||
|
||||
#################################
|
||||
|
||||
|
||||
add_executable(pipedalconfig json.cpp json.hpp
|
||||
|
||||
+31
-9
@@ -95,7 +95,6 @@ void PiPedalModel::Load(const PiPedalConfiguration &configuration)
|
||||
|
||||
this->jackHost->SetNotificationCallbacks(this);
|
||||
|
||||
|
||||
if (configuration.GetMLock())
|
||||
{
|
||||
#ifndef NO_MLOCK
|
||||
@@ -126,10 +125,8 @@ void PiPedalModel::Load(const PiPedalConfiguration &configuration)
|
||||
catch (PiPedalException &e)
|
||||
{
|
||||
Lv2Log::error("Failed to load initial plugin. (%s)", e.what());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
IPiPedalModelSubscriber *PiPedalModel::GetNotificationSubscriber(int64_t clientId)
|
||||
@@ -278,7 +275,6 @@ void PiPedalModel::setPedalBoard(int64_t clientId, PedalBoard &pedalBoard)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PiPedalModel::setPedalBoardItemEnable(int64_t clientId, int64_t pedalItemId, bool enabled)
|
||||
{
|
||||
std::lock_guard(this->mutex);
|
||||
@@ -318,7 +314,6 @@ PedalBoard PiPedalModel::getPreset(int64_t instanceId)
|
||||
return this->storage.GetPreset(instanceId);
|
||||
}
|
||||
|
||||
|
||||
void PiPedalModel::setPresetChanged(int64_t clientId, bool value)
|
||||
{
|
||||
if (value != this->hasPresetChanged)
|
||||
@@ -369,14 +364,13 @@ int64_t PiPedalModel::saveCurrentPresetAs(int64_t clientId, const std::string &n
|
||||
return result;
|
||||
}
|
||||
|
||||
int64_t PiPedalModel::uploadPreset(const BankFile&bankFile,int64_t uploadAfter)
|
||||
int64_t PiPedalModel::uploadPreset(const BankFile &bankFile, int64_t uploadAfter)
|
||||
{
|
||||
std::lock_guard(this->mutex);
|
||||
|
||||
int64_t newPreset = this->storage.UploadPreset(bankFile,uploadAfter);
|
||||
int64_t newPreset = this->storage.UploadPreset(bankFile, uploadAfter);
|
||||
firePresetsChanged(-1);
|
||||
return newPreset;
|
||||
|
||||
}
|
||||
|
||||
void PiPedalModel::loadPreset(int64_t clientId, int64_t instanceId)
|
||||
@@ -462,6 +456,35 @@ bool PiPedalModel::renamePreset(int64_t clientId, int64_t instanceId, const std:
|
||||
}
|
||||
}
|
||||
|
||||
void PiPedalModel::setWifiConfigSettings(const WifiConfigSettings &wifiConfigSettings)
|
||||
{
|
||||
std::lock_guard lock(this->mutex);
|
||||
// xxx Commit to local!
|
||||
this->storage.SetWifiConfigSettings(wifiConfigSettings);
|
||||
|
||||
{
|
||||
IPiPedalModelSubscriber **t = new IPiPedalModelSubscriber *[this->subscribers.size()];
|
||||
for (size_t i = 0; i < subscribers.size(); ++i)
|
||||
{
|
||||
t[i] = this->subscribers[i];
|
||||
}
|
||||
size_t n = this->subscribers.size();
|
||||
|
||||
WifiConfigSettings tWifiConfigSettings = storage.GetWifiConfigSettings(); // (the passwordless version)
|
||||
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
t[i]->OnWifiConfigSettingsChanged(tWifiConfigSettings);
|
||||
}
|
||||
delete[] t;
|
||||
}
|
||||
}
|
||||
WifiConfigSettings PiPedalModel::getWifiConfigSettings()
|
||||
{
|
||||
std::lock_guard lock(this->mutex);
|
||||
return this->storage.GetWifiConfigSettings();
|
||||
}
|
||||
|
||||
JackConfiguration PiPedalModel::getJackConfiguration()
|
||||
{
|
||||
std::lock_guard lock(this->mutex); // copy atomically.
|
||||
@@ -983,4 +1006,3 @@ void PiPedalModel::cancelListenForMidiEvent(int64_t clientId, int64_t clientHand
|
||||
jackHost->SetListenForMidiEvent(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
#include "Banks.hpp"
|
||||
#include "PiPedalConfiguration.hpp"
|
||||
#include "JackServerSettings.hpp"
|
||||
#include "WifiConfigSettings.hpp"
|
||||
|
||||
|
||||
namespace pipedal {
|
||||
@@ -34,6 +35,7 @@ public:
|
||||
virtual void OnLoadPluginPreset(int64_t instanceId,const std::vector<ControlValue>&controlValues) = 0;
|
||||
virtual void OnMidiValueChanged(int64_t instanceId, const std::string&symbol, float value) = 0;
|
||||
virtual void OnNotifyMidiListener(int64_t clientHandle, bool isNote, uint8_t noteOrControl) = 0;
|
||||
virtual void OnWifiConfigSettingsChanged(const WifiConfigSettings&wifiConfigSettings) = 0;
|
||||
virtual void Close() = 0;
|
||||
};
|
||||
|
||||
@@ -145,6 +147,10 @@ public:
|
||||
void setJackChannelSelection(int64_t clientId,const JackChannelSelection &channelSelection);
|
||||
JackChannelSelection getJackChannelSelection();
|
||||
|
||||
void setWifiConfigSettings(const WifiConfigSettings&wifiConfigSettings);
|
||||
WifiConfigSettings getWifiConfigSettings();
|
||||
|
||||
|
||||
|
||||
int64_t addVuSubscription(int64_t instanceId);
|
||||
void removeVuSubscription(int64_t subscriptionHandle);
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
#include <atomic>
|
||||
|
||||
#include "ShutdownClient.hpp"
|
||||
#include "WifiConfigSettings.hpp"
|
||||
#include "WifiChannels.hpp"
|
||||
|
||||
using namespace std;
|
||||
using namespace pipedal;
|
||||
@@ -667,6 +669,12 @@ public:
|
||||
{
|
||||
JackHostStatus status = model.getJackStatus();
|
||||
this->Reply(replyTo,"getJackStatus",status);
|
||||
} else if (message == "getWifiChannels")
|
||||
{
|
||||
std::string country;
|
||||
pReader->read(&country);
|
||||
std::vector<WifiChannel> channels = pipedal::getWifiChannels(country.c_str());
|
||||
this->Reply(replyTo,"getWifiChannels",channels);
|
||||
}
|
||||
else if (message == "getPluginPresets")
|
||||
{
|
||||
@@ -688,6 +696,28 @@ public:
|
||||
this->Reply(replyTo,"setJackserverSettings");
|
||||
|
||||
}
|
||||
else if (message == "setWifiConfigSettings") {
|
||||
WifiConfigSettings wifiConfigSettings;
|
||||
pReader->read(&wifiConfigSettings);
|
||||
if (!ShutdownClient::CanUseShutdownClient())
|
||||
{
|
||||
throw PiPedalException("Can't change server settings when running interactively.");
|
||||
}
|
||||
std::string fromAddress = this->getFromAddress();
|
||||
if (!ShutdownClient::IsOnLocalSubnet(fromAddress))
|
||||
{
|
||||
throw PiPedalException("Permission denied. Not on local subnet.");
|
||||
}
|
||||
|
||||
|
||||
this->model.setWifiConfigSettings(wifiConfigSettings);
|
||||
this->Reply(replyTo,"setWifiConfigSettings");
|
||||
}
|
||||
else if (message == "getWifiConfigSettings") {
|
||||
this->Reply(replyTo, "getWifiConfigSettings", model.getWifiConfigSettings());
|
||||
|
||||
}
|
||||
|
||||
else if (message == "getJackServerSettings") {
|
||||
this->Reply(replyTo, "getJackServerSettings", model.GetJackServerSettings());
|
||||
|
||||
@@ -1220,6 +1250,10 @@ public:
|
||||
Send("onJackServerSettingsChanged",jackServerSettings);
|
||||
}
|
||||
|
||||
virtual void OnWifiConfigSettingsChanged(const WifiConfigSettings&wifiConfigSettings) {
|
||||
Send("onWifiConfigSettingsChanged",wifiConfigSettings);
|
||||
}
|
||||
|
||||
virtual void OnPedalBoardChanged(int64_t clientId, const PedalBoard &pedalBoard)
|
||||
{
|
||||
SetCurrentPedalBoardBody body;
|
||||
|
||||
+228
@@ -0,0 +1,228 @@
|
||||
#include "pch.h"
|
||||
#include "RegDb.hpp"
|
||||
#include <fstream>
|
||||
#include <filesystem>
|
||||
#include <unordered_set>
|
||||
|
||||
#include "PiPedalException.hpp"
|
||||
|
||||
#define REGDB_MAGIC 0x52474442
|
||||
#define REGDB_VERSION 19
|
||||
|
||||
|
||||
using namespace pipedal;
|
||||
using namespace std;
|
||||
|
||||
struct RegDbFileHeader {
|
||||
uint32_t magic;
|
||||
uint32_t version;
|
||||
uint32_t countryOffset;
|
||||
uint32_t countryCount;
|
||||
uint32_t signatureLength;
|
||||
|
||||
void toNs() {
|
||||
this->magic = htonl(this->magic);
|
||||
this->version = htonl(this->version);
|
||||
this->countryOffset = htonl(this->countryOffset);
|
||||
this->countryCount = htonl(this->countryCount);
|
||||
this->signatureLength = htonl(this->signatureLength);
|
||||
}
|
||||
};
|
||||
|
||||
struct CountryHeader {
|
||||
char alpha2[2];
|
||||
uint8_t pad;
|
||||
uint8_t dfsRegion; // first 2 bits only.
|
||||
uint32_t rulesOffset;
|
||||
|
||||
void toNs() {
|
||||
this->rulesOffset = htonl(rulesOffset);
|
||||
}
|
||||
|
||||
};
|
||||
struct RulesCollection {
|
||||
uint32_t ruleCount;
|
||||
uint32_t ruleOffsets[1];
|
||||
|
||||
void toNs() {
|
||||
this->ruleCount = htonl(this->ruleCount);
|
||||
uint32_t *p = ruleOffsets;
|
||||
for (uint32_t i = 0; i < this->ruleCount; ++i)
|
||||
{
|
||||
*p = htonl(*p);
|
||||
++p;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Rule {
|
||||
uint32_t frequencyRangeOffset;
|
||||
uint32_t powerRuleOffset;
|
||||
uint32_t flags;
|
||||
|
||||
void toNs() {
|
||||
frequencyRangeOffset = htonl(frequencyRangeOffset);
|
||||
powerRuleOffset = htonl(powerRuleOffset);
|
||||
flags = htonl(flags);
|
||||
}
|
||||
};
|
||||
|
||||
struct FrequencyRange {
|
||||
uint32_t startFrequency; // in khz.
|
||||
uint32_t endFrequency; // in khz.
|
||||
uint32_t maxBandwidth; // in khz.
|
||||
void toNs() {
|
||||
startFrequency = htonl(startFrequency);
|
||||
endFrequency = htonl(endFrequency);
|
||||
maxBandwidth = htonl(maxBandwidth);
|
||||
}
|
||||
};
|
||||
struct PowerRule {
|
||||
uint32_t maximumAntennaGain;
|
||||
uint32_t maximumEirp;
|
||||
void toNs() {
|
||||
maximumAntennaGain = htonl(maximumAntennaGain);
|
||||
maximumEirp = htonl(maximumEirp);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
const char*filePaths[] =
|
||||
{
|
||||
"/usr/lib/crda/regulatory.bin"
|
||||
};
|
||||
|
||||
static std::filesystem::path getFilePath()
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(filePaths)/sizeof(filePaths[0]); ++i)
|
||||
{
|
||||
std::filesystem::path path(filePaths[i]);
|
||||
if (std::filesystem::exists(path)) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
throw PiPedalException("Could not find 'regulatory.bin' file.");
|
||||
}
|
||||
|
||||
RegDb::~RegDb()
|
||||
{
|
||||
delete[] pData;
|
||||
}
|
||||
|
||||
RegDb::RegDb()
|
||||
:pData(nullptr)
|
||||
{
|
||||
RegDbFileHeader header;
|
||||
std::filesystem::path path = getFilePath();
|
||||
ifstream f(path);
|
||||
if (!f.is_open()) {
|
||||
stringstream s;
|
||||
s << "Can't read " << path;
|
||||
throw PiPedalException(s.str());
|
||||
}
|
||||
size_t fileSize = std::filesystem::file_size(path);
|
||||
this->pData = new uint8_t[fileSize];
|
||||
f.read((char*)this->pData,fileSize);
|
||||
|
||||
// convert from big-endian to local byte order;
|
||||
RegDbFileHeader *fileHeader = (RegDbFileHeader*)pData;
|
||||
fileHeader->toNs();
|
||||
if (fileHeader->magic != REGDB_MAGIC)
|
||||
{
|
||||
throw PiPedalException("Invalid file format.");
|
||||
}
|
||||
std::unordered_set<uint32_t> visited;
|
||||
|
||||
CountryHeader*countryHeader = (CountryHeader*)(pData + fileHeader->countryOffset);
|
||||
for (uint32_t i = 0; i < fileHeader->countryCount; ++i)
|
||||
{
|
||||
countryHeader->toNs();
|
||||
if (visited.count(countryHeader->rulesOffset) == 0)
|
||||
{
|
||||
visited.insert(countryHeader->rulesOffset);
|
||||
RulesCollection*pRules = (RulesCollection*)(pData + countryHeader->rulesOffset);
|
||||
pRules->toNs();
|
||||
for (uint32_t nRule = 0; nRule < pRules->ruleCount; ++nRule)
|
||||
{
|
||||
uint32_t ruleOffset = pRules->ruleOffsets[nRule];
|
||||
if (visited.count(ruleOffset) == 0)
|
||||
{
|
||||
visited.insert(ruleOffset);
|
||||
Rule *pRule = (Rule*)(pData + ruleOffset);
|
||||
pRule->toNs();
|
||||
|
||||
if (visited.count(pRule->frequencyRangeOffset) == 0)
|
||||
{
|
||||
visited.insert(pRule->frequencyRangeOffset);
|
||||
|
||||
FrequencyRange*pf = (FrequencyRange*)(pData + pRule->frequencyRangeOffset);
|
||||
pf->toNs();
|
||||
}
|
||||
if (visited.count(pRule->powerRuleOffset) == 0)
|
||||
{
|
||||
visited.insert(pRule->powerRuleOffset);
|
||||
|
||||
PowerRule *pr = (PowerRule*)(pData + pRule->powerRuleOffset);
|
||||
pr->toNs();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
++countryHeader;
|
||||
}
|
||||
|
||||
}
|
||||
bool CrdbRules::GetFrequencyRule(uint32_t frequencyRuleMHz, FrequencyRule*pResult)
|
||||
{
|
||||
memset(pResult,0,sizeof(FrequencyRule));
|
||||
RulesCollection*pRules = (RulesCollection*)(regDb->pData + countryOffset);
|
||||
uint32_t frequencyRuleKHz = frequencyRuleMHz*1000;
|
||||
for (uint32_t i = 0; i < pRules->ruleCount; ++i)
|
||||
{
|
||||
Rule *pRule = (Rule*)(regDb->pData + pRules->ruleOffsets[i]);
|
||||
FrequencyRange*pf = (FrequencyRange*)(regDb->pData + pRule->frequencyRangeOffset);
|
||||
if (frequencyRuleKHz >= pf->startFrequency && frequencyRuleKHz < pf->endFrequency)
|
||||
{
|
||||
PowerRule *pr = (PowerRule*)(regDb->pData + pRule->powerRuleOffset);
|
||||
pResult->flags = (RegRuleFlags)(pRule->flags);
|
||||
pResult->maximumAntennaGain = pr->maximumAntennaGain;
|
||||
pResult->maximumEirp = pr->maximumEirp;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
CrdbRules*RegDb::GetCrdbRules(const char*countryCodeIso633)
|
||||
{
|
||||
const char c0 = countryCodeIso633[0];
|
||||
if (c0 == '\0') return nullptr;
|
||||
const char c1 = countryCodeIso633[1];
|
||||
|
||||
RegDbFileHeader *fileHeader = (RegDbFileHeader*)pData;
|
||||
CountryHeader*countryHeader = (CountryHeader*)(pData + fileHeader->countryOffset);
|
||||
for (uint32_t i = 0; i < fileHeader->countryCount; ++i)
|
||||
{
|
||||
if (countryHeader->alpha2[0] == c0 && countryHeader->alpha2[1] == c1) {
|
||||
return new CrdbRules(
|
||||
this,
|
||||
countryHeader->rulesOffset,
|
||||
(DfsRegion)(countryHeader->dfsRegion & 0x03)
|
||||
);
|
||||
}
|
||||
++countryHeader;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CrdbRules::CrdbRules(RegDb *regDb,uint32_t countryOffset, DfsRegion dfsRegion )
|
||||
: regDb(regDb),
|
||||
countryOffset(countryOffset),
|
||||
dfsRegion(dfsRegion)
|
||||
{
|
||||
}
|
||||
|
||||
DfsRegion CrdbRules::GetDfsRegion() const {
|
||||
return this->dfsRegion;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
namespace pipedal {
|
||||
|
||||
// sync with <linux/nl80211.h
|
||||
enum class RegRuleFlags {
|
||||
NO_OFDM = 1<<0,
|
||||
NO_CCK = 1<<1,
|
||||
NO_INDOOR = 1<<2,
|
||||
NO_OUTDOOR = 1<<3,
|
||||
DFS = 1<<4,
|
||||
PTP_ONLY = 1<<5,
|
||||
PTMP_ONLY = 1<<6,
|
||||
NO_IR = 1<<7,
|
||||
__NO_IBSS = 1<<8,
|
||||
AUTO_BW = 1<<11,
|
||||
IR_CONCURRENT = 1<<12,
|
||||
NO_HT40MINUS = 1<<13,
|
||||
NO_HT40PLUS = 1<<14,
|
||||
NO_80MHZ = 1<<15,
|
||||
NO_160MHZ = 1<<16,
|
||||
NO_HE = 1<<17,
|
||||
};
|
||||
|
||||
enum class DfsRegion {
|
||||
Unset = 0,
|
||||
Fcc = 1,
|
||||
Etsi = 2,
|
||||
Japan = 3
|
||||
};
|
||||
|
||||
struct FrequencyRule {
|
||||
uint32_t maximumAntennaGain; // in mBiu (100*dBi)
|
||||
uint32_t maximumEirp; // in mBm (100*dBm)
|
||||
RegRuleFlags flags;
|
||||
|
||||
bool hasFlag(RegRuleFlags flag) const { return (((int)flag) & (int)this->flags) != 0; }
|
||||
};
|
||||
|
||||
class RegDb;
|
||||
|
||||
class CrdbRules {
|
||||
friend class RegDb;
|
||||
RegDb *regDb = nullptr;
|
||||
uint32_t countryOffset;
|
||||
DfsRegion dfsRegion;
|
||||
CrdbRules(RegDb *regDb,uint32_t countryOffset, DfsRegion dfsRegion );
|
||||
public:
|
||||
virtual DfsRegion GetDfsRegion() const;
|
||||
virtual bool GetFrequencyRule(uint32_t frequencyMHz,FrequencyRule*pResult);
|
||||
};
|
||||
|
||||
class RegDb {
|
||||
private:
|
||||
friend class CrdbRules;
|
||||
uint8_t*pData;
|
||||
|
||||
public:
|
||||
RegDb();
|
||||
~RegDb();
|
||||
CrdbRules *GetCrdbRules(const char*countryCodeIso6333);
|
||||
bool isValid() const { return pData != nullptr; }
|
||||
};
|
||||
|
||||
}
|
||||
@@ -6,6 +6,9 @@
|
||||
#include <arpa/inet.h>
|
||||
#include "Lv2Log.hpp"
|
||||
#include <sstream>
|
||||
#include <sys/types.h>
|
||||
#include <ifaddrs.h>
|
||||
|
||||
|
||||
using namespace pipedal;
|
||||
|
||||
@@ -138,3 +141,52 @@ bool ShutdownClient::SetJackServerConfiguration(const JackServerSettings & jackS
|
||||
|
||||
return WriteMessage(s.str().c_str());
|
||||
}
|
||||
|
||||
bool ShutdownClient::IsOnLocalSubnet(const std::string&fromAddress)
|
||||
{
|
||||
std::string address = fromAddress;
|
||||
if (address.size() == 0) return false;
|
||||
char lastChar = address[address.size()-1];
|
||||
if (address[0] != '[' || lastChar != ']') // i.e. not an ipv6 address;
|
||||
{
|
||||
size_t pos = address.find_last_of(':');
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
address = address.substr(0,pos);
|
||||
}
|
||||
}
|
||||
if (address[0] == '[') return false;
|
||||
|
||||
char buf[512];
|
||||
|
||||
struct in_addr inetAddr;
|
||||
|
||||
memset(&inetAddr,0,sizeof(inetAddr));
|
||||
|
||||
if (inet_pton(AF_INET,address.c_str(),&inetAddr) == 0) {
|
||||
return false;
|
||||
}
|
||||
uint32_t remoteAddress = htonl(inetAddr.s_addr);
|
||||
|
||||
struct ifaddrs *ifap = nullptr;
|
||||
if (getifaddrs(&ifap) != 0) return false;
|
||||
|
||||
bool result = false;
|
||||
for (ifaddrs*p = ifap; p != nullptr; p = p->ifa_next) {
|
||||
if (p->ifa_addr->sa_family == AF_INET && p->ifa_addr != nullptr && p->ifa_netmask != nullptr) { // TODO: Add support for AF_INET6
|
||||
uint32_t netmask = htonl(((sockaddr_in*)(p->ifa_netmask))->sin_addr.s_addr);
|
||||
uint32_t ifAddr = htonl(((sockaddr_in*)(p->ifa_addr))->sin_addr.s_addr);
|
||||
|
||||
if ((netmask & ifAddr) == (netmask & remoteAddress))
|
||||
{
|
||||
result = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
freeifaddrs(ifap);
|
||||
return result;
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ public:
|
||||
static bool CanUseShutdownClient();
|
||||
static bool RequestShutdown(bool restart);
|
||||
static bool SetJackServerConfiguration(const JackServerSettings & jackServerSettings);
|
||||
static bool IsOnLocalSubnet(const std::string&fromAddress);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
@@ -11,6 +11,8 @@ using namespace pipedal;
|
||||
const char *BANK_EXTENSION = ".bank";
|
||||
const char *BANKS_FILENAME = "index.banks";
|
||||
|
||||
#define WIFI_CONFIG_SETTINGS_FILENAME "wifiConfigSettings.json";
|
||||
|
||||
Storage::Storage()
|
||||
{
|
||||
SetDataRoot("~/var/PiPedal");
|
||||
@@ -157,6 +159,7 @@ void Storage::Initialize()
|
||||
catch (const std::exception &)
|
||||
{
|
||||
}
|
||||
LoadWifiConfigSettings();
|
||||
}
|
||||
|
||||
void Storage::LoadBank(int64_t instanceId)
|
||||
@@ -683,3 +686,72 @@ int64_t Storage::UploadPreset(const BankFile&bankFile,int64_t uploadAfter)
|
||||
this->SaveCurrentBank();
|
||||
return lastPreset;
|
||||
}
|
||||
|
||||
void Storage::SetWifiConfigSettings(const WifiConfigSettings & wifiConfigSettings)
|
||||
{
|
||||
WifiConfigSettings copyToSave = wifiConfigSettings;
|
||||
copyToSave.rebootRequired_ = false;
|
||||
if (!copyToSave.enable_)
|
||||
{
|
||||
copyToSave.hasPassword_ = false;
|
||||
}
|
||||
copyToSave.password_ = "";
|
||||
|
||||
std::filesystem::path path = this->dataRoot / WIFI_CONFIG_SETTINGS_FILENAME;
|
||||
{
|
||||
std::ofstream f(path);
|
||||
if (!f.is_open())
|
||||
{
|
||||
throw PiPedalException("Unable to write to " + ((std::string)path));
|
||||
}
|
||||
json_writer writer(f);
|
||||
writer.write(©ToSave);
|
||||
}
|
||||
|
||||
WifiConfigSettings copyToStore = wifiConfigSettings;
|
||||
if (copyToStore.enable_)
|
||||
{
|
||||
copyToStore.hasPassword_ = copyToStore.password_.length() != 0 || this->wifiConfigSettings.hasPassword_;
|
||||
} else {
|
||||
copyToStore.hasPassword_ = false;
|
||||
}
|
||||
copyToStore.password_ = "";
|
||||
copyToStore.rebootRequired_ = true;
|
||||
if (copyToStore.enable_ && !copyToStore.hasPassword_)
|
||||
{
|
||||
copyToStore.hasPassword_ = this->wifiConfigSettings.hasPassword_;
|
||||
}
|
||||
this->wifiConfigSettings = copyToStore;
|
||||
}
|
||||
|
||||
void Storage::LoadWifiConfigSettings()
|
||||
{
|
||||
std::filesystem::path path = this->dataRoot / WIFI_CONFIG_SETTINGS_FILENAME;
|
||||
|
||||
try {
|
||||
if (std::filesystem::is_regular_file(path))
|
||||
{
|
||||
std::ifstream f(path);
|
||||
if (!f.is_open())
|
||||
{
|
||||
throw PiPedalException("Unable to write to " + ((std::string)path));
|
||||
}
|
||||
json_reader reader(f);
|
||||
WifiConfigSettings wifiConfigSettings;
|
||||
reader.read(&wifiConfigSettings);
|
||||
this->wifiConfigSettings = wifiConfigSettings;
|
||||
}
|
||||
} catch (const std::exception&)
|
||||
{
|
||||
|
||||
}
|
||||
this->wifiConfigSettings.valid_ = true;
|
||||
}
|
||||
|
||||
|
||||
WifiConfigSettings Storage::GetWifiConfigSettings()
|
||||
{
|
||||
return this->wifiConfigSettings;
|
||||
}
|
||||
|
||||
|
||||
|
||||
+7
-1
@@ -5,6 +5,7 @@
|
||||
#include "Presets.hpp"
|
||||
#include "Banks.hpp"
|
||||
#include "JackConfiguration.hpp"
|
||||
#include "WifiConfigSettings.hpp"
|
||||
|
||||
|
||||
namespace pipedal {
|
||||
@@ -17,7 +18,7 @@ private:
|
||||
std::filesystem::path dataRoot;
|
||||
BankIndex bankIndex;
|
||||
BankFile currentBank;
|
||||
|
||||
|
||||
private:
|
||||
static std::string SafeEncodeName(const std::string& name);
|
||||
static std::string SafeDecodeName(const std::string& name);
|
||||
@@ -39,6 +40,7 @@ private:
|
||||
std::string GetPresetCopyName(const std::string &name);
|
||||
bool isJackChannelSelectionValid = false;
|
||||
JackChannelSelection jackChannelSelection;
|
||||
WifiConfigSettings wifiConfigSettings;
|
||||
public:
|
||||
Storage();
|
||||
void Initialize();
|
||||
@@ -51,6 +53,7 @@ public:
|
||||
const BankIndex & GetBanks() const { return bankIndex; }
|
||||
|
||||
|
||||
void LoadWifiConfigSettings();
|
||||
void LoadBank(int64_t instanceId);
|
||||
const PedalBoard& GetCurrentPreset();
|
||||
void saveCurrentPreset(const PedalBoard&pedalBoard);
|
||||
@@ -77,6 +80,9 @@ public:
|
||||
void SetJackChannelSelection(const JackChannelSelection&channelSelection);
|
||||
const JackChannelSelection&GetJackChannelSelection(const JackConfiguration &jackConfiguration);
|
||||
|
||||
void SetWifiConfigSettings(const WifiConfigSettings & wifiConfigSettings);
|
||||
WifiConfigSettings GetWifiConfigSettings();
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,615 @@
|
||||
|
||||
#include "pch.h"
|
||||
#include <string>
|
||||
#include <net/if.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/genl/genl.h>
|
||||
#include <netlink/genl/family.h>
|
||||
#include <netlink/genl/ctrl.h>
|
||||
#include <netlink/msg.h>
|
||||
#include <netlink/attr.h>
|
||||
#include <linux/nl80211.h>
|
||||
|
||||
#include <linux/nl80211.h>
|
||||
#include "PiPedalException.hpp"
|
||||
#include "WifiChannels.hpp"
|
||||
#include "Lv2Log.hpp"
|
||||
|
||||
#include "RegDb.hpp"
|
||||
/*
|
||||
Heavily based on code from iw (1) command.
|
||||
https://kernel.googlesource.com/pub/scm/linux/kernel/git/jberg/iw/+/v0.9/COPYING
|
||||
|
||||
Copyright (c) 2007, 2008 Johannes Berg
|
||||
Copyright (c) 2007 Andy Lutomirski
|
||||
Copyright (c) 2007 Mike Kershaw
|
||||
Copyright (c) 2008 Luis R. Rodriguez
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
using namespace pipedal;
|
||||
|
||||
struct MHzToChannel {
|
||||
char band;
|
||||
int channel;
|
||||
int mhz;
|
||||
};
|
||||
|
||||
MHzToChannel mhzToChannels[] = {
|
||||
{'g', 1, 2412},
|
||||
{'g',2, 2417},
|
||||
{'g',3, 2422},
|
||||
{'g',4, 2427},
|
||||
{'g',5, 2432},
|
||||
{'g',6, 2437},
|
||||
{'g',7, 2442},
|
||||
{'g',8, 2447},
|
||||
{'g',9, 2452},
|
||||
{'g',10, 2457},
|
||||
{'g',11, 2462},
|
||||
{'g',12, 2467},
|
||||
{'g',13, 2472},
|
||||
{'g',14, 2484},
|
||||
{'a',7, 5035},
|
||||
{'a',8, 5040},
|
||||
{'a',9, 5045},
|
||||
{'a',11, 5055},
|
||||
{'a',12, 5060},
|
||||
{'a',16, 5080},
|
||||
{'a',32, 5160},
|
||||
{'a',34, 5170},
|
||||
{'a',36, 5180},
|
||||
{'a',38, 5190},
|
||||
{'a',40, 5200},
|
||||
{'a',42, 5210},
|
||||
{'a',44, 5220},
|
||||
{'a',46, 5230},
|
||||
{'a',48, 5240},
|
||||
{'a',50, 5250},
|
||||
{'a',52, 5260},
|
||||
{'a',54, 5270},
|
||||
{'a',56, 5280},
|
||||
{'a',58, 5290},
|
||||
{'a',60, 5300},
|
||||
{'a',62, 5310},
|
||||
{'a',64, 5320},
|
||||
{'a',68, 5340},
|
||||
{'a',96, 5480},
|
||||
{'a',100, 5500},
|
||||
{'a',102, 5510},
|
||||
{'a',104, 5520},
|
||||
{'a',106, 5530},
|
||||
{'a',108, 5540},
|
||||
{'a',110, 5550},
|
||||
{'a',112, 5560},
|
||||
{'a',114, 5570},
|
||||
{'a',116, 5580},
|
||||
{'a',118, 5590},
|
||||
{'a',120, 5600},
|
||||
{'a',122, 5610},
|
||||
{'a',124, 5620},
|
||||
{'a',126, 5630},
|
||||
{'a',128, 5640},
|
||||
{'a',132, 5660},
|
||||
{'a',134, 5670},
|
||||
{'a',136, 5680},
|
||||
{'a',138, 5690},
|
||||
{'a',140, 5700},
|
||||
{'a',142, 5710},
|
||||
{'a',144, 5720},
|
||||
{'a',149, 5745},
|
||||
{'a',151, 5755},
|
||||
{'a',153, 5765},
|
||||
{'a',155, 5775},
|
||||
{'a',157, 5785},
|
||||
{'a',159, 5795},
|
||||
{'a',161, 5805},
|
||||
{'a',163, 5815},
|
||||
{'a',165, 5825},
|
||||
{'a',167, 5835},
|
||||
{'a',169, 5845},
|
||||
{'a',171, 5855},
|
||||
{'a',173, 5865},
|
||||
{'a',175, 5875},
|
||||
{'a',177, 5885},
|
||||
{'a',180, 5900},
|
||||
{'a',182, 5910},
|
||||
{'a',18, 5915},
|
||||
{'a',184, 5920},
|
||||
{'a',187, 5935},
|
||||
{'a',188, 5940},
|
||||
{'a',189, 5945},
|
||||
{'a',192, 5960},
|
||||
{'a',196, 5980},
|
||||
};
|
||||
|
||||
|
||||
bool MHzToChannelNumber(int mhz, char*pBand, int*pChannel)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(mhzToChannels)/sizeof(mhzToChannels[0]); ++i)
|
||||
{
|
||||
if (std::abs(mhz-mhzToChannels[i].mhz) <= 1) {
|
||||
*pBand = mhzToChannels[i].band;
|
||||
*pChannel = mhzToChannels[i].channel;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static nla_policy *makeFreqPolicy()
|
||||
{
|
||||
nla_policy* result = new nla_policy[NL80211_FREQUENCY_ATTR_MAX + 1];
|
||||
memset(result,0,sizeof(nla_policy[NL80211_FREQUENCY_ATTR_MAX + 1]));
|
||||
|
||||
result[NL80211_FREQUENCY_ATTR_FREQ] = {NLA_U32,0,0};
|
||||
result[NL80211_FREQUENCY_ATTR_DISABLED] = {NLA_FLAG,0,0};
|
||||
result[NL80211_FREQUENCY_ATTR_PASSIVE_SCAN] = {NLA_FLAG,0,0};
|
||||
result[NL80211_FREQUENCY_ATTR_NO_IR] = {NLA_FLAG,0,0};
|
||||
result[NL80211_FREQUENCY_ATTR_RADAR] = {NLA_FLAG,0,0};
|
||||
result[NL80211_FREQUENCY_ATTR_INDOOR_ONLY] = {NLA_FLAG,0,0};
|
||||
result[NL80211_FREQUENCY_ATTR_INDOOR_ONLY] = {NLA_FLAG,0,0};
|
||||
result[NL80211_FREQUENCY_ATTR_NO_20MHZ] = {NLA_FLAG,0,0};
|
||||
result[NL80211_FREQUENCY_ATTR_NO_20MHZ] = {NLA_FLAG,0,0};
|
||||
result[NL80211_FREQUENCY_ATTR_NO_HT40_MINUS] = {NLA_FLAG,0,0};
|
||||
result[NL80211_FREQUENCY_ATTR_NO_HT40_PLUS] = {NLA_FLAG,0,0};
|
||||
result[NL80211_FREQUENCY_ATTR_NO_80MHZ] = {NLA_FLAG,0,0};
|
||||
result[NL80211_FREQUENCY_ATTR_NO_160MHZ] = {NLA_FLAG,0,0};
|
||||
return result;
|
||||
}
|
||||
|
||||
static struct nla_policy* freq_policy = makeFreqPolicy();
|
||||
|
||||
|
||||
static nla_policy *makeRatePolicy() {
|
||||
nla_policy* result = new nla_policy[NL80211_BITRATE_ATTR_MAX + 1];
|
||||
memset(result,0,sizeof(nla_policy[NL80211_BITRATE_ATTR_MAX + 1]));
|
||||
result[NL80211_BITRATE_ATTR_RATE] = {.type = NLA_U32};
|
||||
result[NL80211_BITRATE_ATTR_2GHZ_SHORTPREAMBLE] = {.type = NLA_FLAG};
|
||||
return result;
|
||||
};
|
||||
|
||||
static struct nla_policy* rate_policy = makeRatePolicy();
|
||||
|
||||
struct IfType {
|
||||
enum nl80211_iftype iftype;
|
||||
const char*name;
|
||||
};
|
||||
static struct IfType ifTypes[] = {
|
||||
{NL80211_IFTYPE_UNSPECIFIED,"Unspecified"},
|
||||
{NL80211_IFTYPE_ADHOC,"Adhoc"},
|
||||
{NL80211_IFTYPE_STATION,"Station"},
|
||||
{NL80211_IFTYPE_AP,"AP"},
|
||||
{NL80211_IFTYPE_AP_VLAN,"VLAN"},
|
||||
{NL80211_IFTYPE_WDS,"WDS"},
|
||||
{NL80211_IFTYPE_MONITOR,"Monitor"},
|
||||
{NL80211_IFTYPE_MESH_POINT,"Mesh point"},
|
||||
{NL80211_IFTYPE_P2P_CLIENT,"Client"},
|
||||
{NL80211_IFTYPE_P2P_GO,"P2P Go"},
|
||||
{NL80211_IFTYPE_P2P_DEVICE,"P2P"},
|
||||
{NL80211_IFTYPE_OCB,"OCB"},
|
||||
{NL80211_IFTYPE_NAN,"NAN"},
|
||||
|
||||
};
|
||||
const char *iftype_name(enum nl80211_iftype iftype)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(ifTypes)/sizeof(ifTypes[0]); ++i)
|
||||
{
|
||||
if (ifTypes[i].iftype == iftype)
|
||||
{
|
||||
return ifTypes[i].name;
|
||||
}
|
||||
}
|
||||
return "Unknown";
|
||||
}
|
||||
static int phy_lookup(const char *name)
|
||||
{
|
||||
char buf[200];
|
||||
int fd, pos;
|
||||
snprintf(buf, sizeof(buf), "/sys/class/ieee80211/%s/index", name);
|
||||
fd = open(buf, O_RDONLY);
|
||||
pos = read(fd, buf, sizeof(buf) - 1);
|
||||
if (pos < 0)
|
||||
return -1;
|
||||
buf[pos] = '\0';
|
||||
return atoi(buf);
|
||||
}
|
||||
|
||||
static int getWifiName_callback(struct nl_msg *msg, void *arg);
|
||||
static int getWifiInfo_callback(struct nl_msg *msg, void *arg);
|
||||
|
||||
struct WifiChannelInfo
|
||||
{
|
||||
int channelNumber = -1;
|
||||
char band = 'g'; // 'g' or 'a'
|
||||
int mhz = 0;
|
||||
bool disabled = false;
|
||||
bool ir = true;
|
||||
bool radarDetection = false;
|
||||
std::vector<float> bitrates;
|
||||
bool indoorOnly = false;
|
||||
bool noHt40Minus = false;
|
||||
bool noHt40Plus = false;
|
||||
bool no10MHz = false;
|
||||
bool no20MHz = false;
|
||||
bool no80MHz = false;
|
||||
bool no160MHz = false;
|
||||
};
|
||||
|
||||
struct WifiBand
|
||||
{
|
||||
int index;
|
||||
std::vector<WifiChannelInfo> channels;
|
||||
};
|
||||
|
||||
struct WifiInfo
|
||||
{
|
||||
std::string name;
|
||||
std::vector<WifiBand> bands;
|
||||
std::vector<std::string> supportedIfTypes;
|
||||
};
|
||||
class NetLink
|
||||
{
|
||||
private:
|
||||
|
||||
std::vector<WifiBand> result;
|
||||
nl_sock*socket = nullptr;
|
||||
nl_cache*cache = nullptr;
|
||||
genl_family*nl80211 = nullptr;
|
||||
|
||||
int errorCode = -1;
|
||||
|
||||
static int finish_handler(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
NetLink*this_ = (NetLink*)arg;
|
||||
this_->errorCode = 0;
|
||||
return NL_SKIP;
|
||||
}
|
||||
static int ack_handler(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
NetLink*this_ = (NetLink*)arg;
|
||||
this_->errorCode = 0;
|
||||
return NL_STOP;
|
||||
}
|
||||
|
||||
static int error_handler(struct sockaddr_nl *nla, struct nlmsgerr *err,
|
||||
void *arg)
|
||||
{
|
||||
NetLink*this_ = (NetLink*)arg;
|
||||
this_->errorCode = err->error;
|
||||
return NL_STOP;
|
||||
}
|
||||
|
||||
|
||||
static int info_phy_handler(struct nl_msg *msg, void *arg)
|
||||
{
|
||||
return ((NetLink *)arg)->InfoPhyHandler(msg, (WifiInfo *)arg);
|
||||
}
|
||||
int InfoPhyHandler(struct nl_msg *msg, WifiInfo *result)
|
||||
{
|
||||
struct nlattr *tb_msg[NL80211_ATTR_MAX + 1];
|
||||
struct genlmsghdr *gnlh = (genlmsghdr *)nlmsg_data(nlmsg_hdr(msg));
|
||||
struct nlattr *tb_band[NL80211_BAND_ATTR_MAX + 1];
|
||||
struct nlattr *tb_freq[NL80211_FREQUENCY_ATTR_MAX + 1];
|
||||
struct nlattr *tb_rate[NL80211_BITRATE_ATTR_MAX + 1];
|
||||
struct nlattr *nl_band;
|
||||
struct nlattr *nl_freq;
|
||||
struct nlattr *nl_rate;
|
||||
struct nlattr *nl_mode;
|
||||
int bandidx = 1;
|
||||
int rem_band, rem_freq, rem_rate, rem_mode;
|
||||
int open;
|
||||
nla_parse(tb_msg, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
|
||||
genlmsg_attrlen(gnlh, 0), NULL);
|
||||
if (!tb_msg[NL80211_ATTR_WIPHY_BANDS])
|
||||
return NL_SKIP;
|
||||
if (tb_msg[NL80211_ATTR_WIPHY_NAME])
|
||||
result->name = nla_get_string(tb_msg[NL80211_ATTR_WIPHY_NAME]);
|
||||
|
||||
nla_for_each_nested(nl_band, tb_msg[NL80211_ATTR_WIPHY_BANDS], rem_band)
|
||||
{
|
||||
WifiBand band;
|
||||
band.index = bandidx;
|
||||
|
||||
bandidx++;
|
||||
nla_parse(tb_band, NL80211_BAND_ATTR_MAX, (nlattr *)nla_data(nl_band),
|
||||
nla_len(nl_band), NULL);
|
||||
|
||||
nla_for_each_nested(nl_freq, tb_band[NL80211_BAND_ATTR_FREQS], rem_freq)
|
||||
{
|
||||
nla_parse(tb_freq, NL80211_FREQUENCY_ATTR_MAX, (nlattr *)nla_data(nl_freq),
|
||||
nla_len(nl_freq), freq_policy);
|
||||
if (!tb_freq[NL80211_FREQUENCY_ATTR_FREQ])
|
||||
continue;
|
||||
|
||||
WifiChannelInfo channel;
|
||||
|
||||
channel.mhz = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
|
||||
open = 0;
|
||||
if (tb_freq[NL80211_FREQUENCY_ATTR_DISABLED])
|
||||
channel.disabled = true;
|
||||
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_IR])
|
||||
channel.ir = false;
|
||||
if (tb_freq[NL80211_FREQUENCY_ATTR_RADAR])
|
||||
channel.radarDetection = true;
|
||||
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_10MHZ])
|
||||
channel.no10MHz = true;
|
||||
if (tb_freq[NL80211_FREQUENCY_ATTR_INDOOR_ONLY])
|
||||
channel.indoorOnly = true;
|
||||
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_20MHZ])
|
||||
channel.no20MHz = true;
|
||||
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_MINUS])
|
||||
channel.noHt40Minus = true;
|
||||
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_HT40_PLUS])
|
||||
channel.noHt40Plus = true;
|
||||
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_80MHZ])
|
||||
channel.no80MHz = true;
|
||||
if (tb_freq[NL80211_FREQUENCY_ATTR_NO_160MHZ])
|
||||
channel.no160MHz = true;
|
||||
|
||||
if (MHzToChannelNumber(channel.mhz,&channel.band, &channel.channelNumber))
|
||||
{
|
||||
band.channels.push_back(std::move(channel));
|
||||
} else {
|
||||
// throw PiPedalException("Frequency not recognized.");
|
||||
}
|
||||
}
|
||||
nla_for_each_nested(nl_rate, tb_band[NL80211_BAND_ATTR_RATES], rem_rate)
|
||||
{
|
||||
nla_parse(tb_rate, NL80211_BITRATE_ATTR_MAX, (nlattr *)nla_data(nl_rate),
|
||||
nla_len(nl_rate), rate_policy);
|
||||
if (!tb_rate[NL80211_BITRATE_ATTR_RATE])
|
||||
continue;
|
||||
//channel.bitRates.push_back(0.1f * nla_get_u32(tb_rate[NL80211_BITRATE_ATTR_RATE]);
|
||||
}
|
||||
result->bands.push_back(std::move(band));
|
||||
}
|
||||
if (!tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES])
|
||||
return NL_SKIP;
|
||||
|
||||
nla_for_each_nested(nl_mode, tb_msg[NL80211_ATTR_SUPPORTED_IFTYPES], rem_mode)
|
||||
result->supportedIfTypes.push_back(iftype_name((nl80211_iftype)(nl_mode->nla_type)));
|
||||
return NL_SKIP;
|
||||
}
|
||||
|
||||
public:
|
||||
~NetLink()
|
||||
{
|
||||
if (this->cache)
|
||||
{
|
||||
nl_cache_free(cache);
|
||||
cache = nullptr;
|
||||
}
|
||||
if (nl80211 != nullptr)
|
||||
{
|
||||
genl_family_put(nl80211); // (release reference)
|
||||
nl80211 = nullptr;
|
||||
}
|
||||
if (socket)
|
||||
{
|
||||
nl_close(socket);
|
||||
nl_socket_free(socket);
|
||||
socket = nullptr;
|
||||
}
|
||||
}
|
||||
NetLink()
|
||||
{
|
||||
socket = nl_socket_alloc();
|
||||
if (!socket)
|
||||
{
|
||||
throw PiPedalException("Can't allocate netlink socket.");
|
||||
}
|
||||
nl_socket_set_buffer_size(socket, 8192, 8192);
|
||||
|
||||
if (genl_connect(socket))
|
||||
{
|
||||
throw PiPedalException("Failed to connect to netlink socket.");
|
||||
}
|
||||
if (genl_ctrl_alloc_cache(this->socket,&this->cache) != 0) {
|
||||
throw PiPedalException("Failed to allocate generic netlink cache.");
|
||||
}
|
||||
this->nl80211 = genl_ctrl_search_by_name(this->cache, "nl80211");
|
||||
if (!this->nl80211) {
|
||||
throw PiPedalException("nl80211 family not found.");
|
||||
}
|
||||
}
|
||||
void GetAvailableChannels(const char *phyName, WifiInfo *result)
|
||||
{
|
||||
|
||||
struct nl_msg *msg = nullptr;
|
||||
struct nl_cb*cb = nullptr;
|
||||
int devidx = 0;
|
||||
int err;
|
||||
|
||||
devidx = phy_lookup(phyName);
|
||||
try {
|
||||
|
||||
|
||||
msg = nlmsg_alloc();
|
||||
if (!msg)
|
||||
{
|
||||
throw PiPedalException("failed to allocate netlink message");
|
||||
}
|
||||
cb = nl_cb_alloc(NL_CB_DEFAULT);
|
||||
if (!cb)
|
||||
{
|
||||
throw PiPedalException("failed to allocate netlink callbacks");
|
||||
}
|
||||
genlmsg_put(msg, 0, 0, genl_family_get_id(this->nl80211), 0,
|
||||
0, NL80211_CMD_GET_WIPHY, 0);
|
||||
NLA_PUT_U32(msg, NL80211_ATTR_WIPHY, devidx);
|
||||
|
||||
this->errorCode = 0;
|
||||
nl_cb_set(cb, NL_CB_VALID, NL_CB_CUSTOM, info_phy_handler, result);
|
||||
|
||||
nl_cb_err(cb, NL_CB_CUSTOM, error_handler, this);
|
||||
nl_cb_set(cb, NL_CB_FINISH, NL_CB_CUSTOM, finish_handler, this);
|
||||
nl_cb_set(cb, NL_CB_ACK, NL_CB_CUSTOM, ack_handler, this);
|
||||
|
||||
err = nl_send_auto_complete(this->socket, msg);
|
||||
|
||||
if (err < 0)
|
||||
throw PiPedalException("Command failed.");
|
||||
nl_recvmsgs(this->socket, cb);
|
||||
nlmsg_free(msg);
|
||||
if (this->errorCode != 0)
|
||||
{
|
||||
throw PiPedalException("Command failed.");
|
||||
}
|
||||
nl_cb_put(cb);
|
||||
return;
|
||||
nla_put_failure:
|
||||
throw PiPedalException("NLA Put failure.");
|
||||
} catch (const std::exception&e)
|
||||
{
|
||||
if (cb != nullptr)
|
||||
{
|
||||
nl_cb_put(cb);
|
||||
cb = nullptr;
|
||||
}
|
||||
if (msg != nullptr)
|
||||
{
|
||||
nlmsg_free(msg);
|
||||
msg = nullptr;
|
||||
}
|
||||
throw;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
WifiInfo getWifiInfo(const char *phyName)
|
||||
{
|
||||
int index = phy_lookup(phyName);
|
||||
if (index == -1)
|
||||
{
|
||||
throw PiPedalArgumentException("No such device.");
|
||||
}
|
||||
|
||||
NetLink netLink;
|
||||
WifiInfo result;
|
||||
netLink.GetAvailableChannels(phyName,&result);
|
||||
return result;
|
||||
}
|
||||
|
||||
const char*allowOutdoorsLocales[] = {
|
||||
"US","TW","SG",
|
||||
|
||||
};
|
||||
|
||||
static bool allowOutdoors(const char*countryCode)
|
||||
{
|
||||
for (size_t i = 0; i < sizeof(allowOutdoorsLocales)/sizeof(allowOutdoorsLocales[0]); ++i)
|
||||
{
|
||||
if (strcmp(allowOutdoorsLocales[i],countryCode) == 0) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool firstTime = true;
|
||||
static std::unique_ptr<RegDb> g_regDb;
|
||||
std::vector<WifiChannel> pipedal::getWifiChannels(const char*countryIso3661)
|
||||
{
|
||||
// Use the wifi physical device to get a list of channels
|
||||
// that the hardware supports.
|
||||
// The override the hardware's regulation flags using regulation.bin
|
||||
// database info for the selected country code.
|
||||
// If the regulation.bin database doesn't have a matching record,
|
||||
// just pass the data that the wifi reported.
|
||||
|
||||
if (firstTime) {
|
||||
firstTime = false;
|
||||
try {
|
||||
g_regDb = std::make_unique<RegDb>();
|
||||
} catch (const std::exception& e)
|
||||
{
|
||||
std::stringstream s;
|
||||
s << "Failed to open the Wi-Fi regulations.bin database. " << e.what();
|
||||
Lv2Log::error(s.str());
|
||||
}
|
||||
}
|
||||
std::vector<WifiChannel> result;
|
||||
|
||||
WifiInfo wifiInfo = getWifiInfo("phy0");
|
||||
std::unique_ptr<CrdbRules> crdbRules = nullptr;
|
||||
if (g_regDb) {
|
||||
crdbRules = std::unique_ptr<CrdbRules>(g_regDb->GetCrdbRules(countryIso3661));
|
||||
if (!crdbRules) {
|
||||
crdbRules = std::unique_ptr<CrdbRules>(g_regDb->GetCrdbRules("00")); // unset default.
|
||||
}
|
||||
}
|
||||
for (auto &band : wifiInfo.bands)
|
||||
{
|
||||
for (auto &channel: band.channels) {
|
||||
if (crdbRules)
|
||||
{
|
||||
FrequencyRule crdbRule;
|
||||
if (crdbRules->GetFrequencyRule(channel.mhz,&crdbRule))
|
||||
{
|
||||
channel.disabled = false;
|
||||
channel.radarDetection = crdbRule.hasFlag(RegRuleFlags::DFS);
|
||||
channel.ir = !crdbRule.hasFlag(RegRuleFlags::NO_IR);
|
||||
channel.indoorOnly = crdbRule.hasFlag(RegRuleFlags::NO_OUTDOOR);
|
||||
if (crdbRule.hasFlag(RegRuleFlags::PTP_ONLY)
|
||||
|| crdbRule.hasFlag(RegRuleFlags::PTMP_ONLY))
|
||||
{
|
||||
channel.disabled = true;
|
||||
|
||||
}
|
||||
} else {
|
||||
channel.disabled = true;
|
||||
}
|
||||
}
|
||||
if ((!channel.disabled) && (!channel.radarDetection) && channel.ir)
|
||||
{
|
||||
WifiChannel ch;
|
||||
std::stringstream s;
|
||||
s << channel.band << channel.channelNumber;
|
||||
ch.channelId_ = s.str();
|
||||
|
||||
std::stringstream t;
|
||||
t << channel.channelNumber;
|
||||
if (channel.band == 'a')
|
||||
t << " (5GHz)";
|
||||
else
|
||||
t << " (2.4GHz)";
|
||||
|
||||
if (channel.indoorOnly) {
|
||||
t << " Indoor only";
|
||||
}
|
||||
ch.channelName_ = t.str();
|
||||
result.push_back(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
JSON_MAP_BEGIN(WifiChannel)
|
||||
JSON_MAP_REFERENCE(WifiChannel,channelId)
|
||||
JSON_MAP_REFERENCE(WifiChannel,channelName)
|
||||
JSON_MAP_END()
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
#pragma once
|
||||
#include "json.hpp"
|
||||
namespace pipedal {
|
||||
|
||||
class WifiChannel {
|
||||
public:
|
||||
std::string channelId_;
|
||||
std::string channelName_;
|
||||
|
||||
DECLARE_JSON_MAP(WifiChannel);
|
||||
};
|
||||
|
||||
std::vector<WifiChannel> getWifiChannels(const char*countryIso3661);
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#include "pch.h"
|
||||
#include "catch.hpp"
|
||||
#include <sstream>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
|
||||
#include "WifiChannels.hpp"
|
||||
|
||||
|
||||
|
||||
using namespace pipedal;
|
||||
|
||||
|
||||
|
||||
TEST_CASE( "Wifi Channel Test", "[wifi_channels_test]" ) {
|
||||
std::vector<WifiChannel> result = pipedal::getWifiChannels("CA");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
#include "pch.h"
|
||||
#include "WifiConfigSettings.hpp"
|
||||
|
||||
using namespace pipedal;
|
||||
|
||||
JSON_MAP_BEGIN(WifiConfigSettings)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings,valid)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings,wifiWarningGiven)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings,rebootRequired)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings,enable)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings,hotspotName)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings,hasPassword)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings,password)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings,countryCode)
|
||||
JSON_MAP_REFERENCE(WifiConfigSettings,channel)
|
||||
JSON_MAP_END()
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
#pragma once
|
||||
|
||||
#include "json.hpp"
|
||||
|
||||
namespace pipedal {
|
||||
|
||||
class WifiConfigSettings {
|
||||
public:
|
||||
bool valid_ = false;
|
||||
bool wifiWarningGiven_ = false;
|
||||
bool rebootRequired_ = false;
|
||||
bool enable_ = false;
|
||||
std::string countryCode_ = "US"; // iso 3661
|
||||
std::string hotspotName_ = "pipedal";
|
||||
bool hasPassword_ = false;
|
||||
std::string password_;
|
||||
std::string channel_ = "g6";
|
||||
public:
|
||||
DECLARE_JSON_MAP(WifiConfigSettings);
|
||||
};
|
||||
}
|
||||
@@ -5,9 +5,9 @@
|
||||
#include <string>
|
||||
|
||||
|
||||
#include <json.hpp>
|
||||
#include "json.hpp"
|
||||
|
||||
using namespace piddle;
|
||||
using namespace pipedal;
|
||||
|
||||
class JsonTestTarget {
|
||||
private:
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "pch.h"
|
||||
#define CATCH_CONFIG_MAIN
|
||||
#include <catch/catch.hpp>
|
||||
|
||||
uint16_t g_ShutdownPort = 0;
|
||||
@@ -3,9 +3,10 @@ Features:
|
||||
|
||||
Patches.
|
||||
|
||||
8 Updload/download patches.
|
||||
9 Upload/download banks.
|
||||
|
||||
9 Hotspot config.
|
||||
9 Upload/download banks.
|
||||
9 Delete bank warning dialo.
|
||||
7 Settings dialog doesn't have back button nav.
|
||||
|
||||
- have to make sure it's set in the USER's environment.
|
||||
|
||||
@@ -30,8 +31,7 @@ pulseaudio --kill
|
||||
|
||||
Reconnect of controls after config change.
|
||||
|
||||
|
||||
Layout of 2nd and subsequent splits.
|
||||
Run when there's no midi device.
|
||||
|
||||
Crash when changing input channels to mono.
|
||||
|
||||
@@ -55,6 +55,12 @@ Open source copyrights.
|
||||
|
||||
add pipedal.local to etc/hosts.
|
||||
|
||||
/etc/dhcpcd.config:
|
||||
nohook wpa_supplicant
|
||||
|
||||
Dependents:
|
||||
|
||||
libnl-3-dev libnl-genl-3-dev
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user